├── .env ├── .gitignore ├── controllers ├── admin.js ├── error.js └── shop.js ├── data ├── cart.json └── products.json ├── helper ├── NotFound.js ├── database.js └── path.js ├── index.js ├── models ├── cart.js ├── order.js ├── product.js └── user.js ├── package-lock.json ├── package.json ├── public ├── css │ ├── NotFound.css │ ├── add-product.css │ ├── cart.css │ ├── main.css │ ├── order.css │ └── product-details.css └── js │ └── main.js ├── readme.md ├── routes ├── admin.js └── shop.js └── views ├── 404.ejs ├── NotFound.html ├── NotFound.pug ├── add-product.html ├── add-product.pug ├── admin ├── add-product.ejs ├── edit-product.ejs └── products.ejs ├── includes ├── footer.ejs ├── header.ejs └── navbar.ejs ├── layouts └── main-layout.pug ├── shop.html ├── shop.pug └── shop ├── cart.ejs ├── checkout.ejs ├── index.ejs ├── orders.ejs ├── product-details.ejs └── product-list.ejs /.env: -------------------------------------------------------------------------------- 1 | mongo_DB_URI = 'mongodb+srv://:@cluster0.ajqdph4.mongodb.net/?retryWrites=true&w=majority' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # .gitignore 2 | node_modules/ 3 | ./helper/database.js -------------------------------------------------------------------------------- /controllers/admin.js: -------------------------------------------------------------------------------- 1 | const mongodb = require("mongodb"); 2 | const Product = require("../models/product"); 3 | const product = require("../models/product"); 4 | 5 | const ObjectId = mongodb.ObjectId; 6 | 7 | exports.getAddProduct = (req, res, next) => { 8 | // res.sendFile(path.join(rootDir, "views", "add-product.html")); 9 | res.render("admin/edit-product", { 10 | pageTitle: "Add-Product", 11 | editing: false, 12 | }); 13 | }; 14 | 15 | exports.postAddProduct = (req, res, next) => { 16 | const title = req.body.title; 17 | const imageURL = req.body.imageURL; 18 | const description = req.body.description; 19 | const price = req.body.price; 20 | 21 | // const product = new Product(title, price, description, imageURL,null,req.user._id); 22 | const product = new Product({ 23 | title: title, 24 | price: price, 25 | description: description, 26 | imageURL: imageURL, 27 | userId: req.user, 28 | }); 29 | 30 | product 31 | .save() 32 | .then(() => { 33 | console.log("Product Added Product"); 34 | res.redirect("/admin/products"); 35 | }) 36 | .catch((err) => { 37 | console.log(err); 38 | }); 39 | 40 | // product.save(); 41 | // res.redirect("/"); 42 | }; 43 | 44 | exports.getEditProduct = (req, res, next) => { 45 | const editMode = req.query.edit; 46 | if (!editMode) { 47 | return res.redirect("/"); 48 | } 49 | const pId = req.params.prodId; 50 | Product.findById(pId).then((product) => { 51 | if (!product) { 52 | return res.redirect("/"); 53 | } 54 | res.render("admin/edit-product", { 55 | pageTitle: "Edit-Product", 56 | editing: editMode, 57 | product: product, 58 | }); 59 | }); 60 | // res.redirect('/'); 61 | // res.sendFile(path.join(rootDir, "views", "add-product.html")); 62 | }; 63 | 64 | exports.postEditProduct = (req, res, next) => { 65 | const prodId = req.body.productId; 66 | const updatedTitle = req.body.title; 67 | const updatedImageURL = req.body.imageURL; 68 | const updatedDescription = req.body.description; 69 | const updatedPrice = req.body.price; 70 | 71 | // ------------------By Using MongoDB -------------------- 72 | // const product = new Product( 73 | // updatedTitle, 74 | // updatedPrice, 75 | // updatedDescription, 76 | // updatedImageURL, 77 | // new ObjectId(prodId) 78 | // ); 79 | 80 | // product 81 | // .save() 82 | // .then((result) => { 83 | // console.log("Product Updated Successfully..."); 84 | // res.redirect("/admin/products"); 85 | // }) 86 | // .catch((err) => { 87 | // console.log(err); 88 | // }); 89 | 90 | // ------------------By Using Mongoose -------------------- 91 | Product.findById(prodId) 92 | .then((product) => { 93 | product.title = updatedTitle; 94 | product.price = updatedPrice; 95 | product.description = updatedDescription; 96 | product.imageURL = updatedImageURL; 97 | return product.save(); 98 | }) 99 | .then((result) => { 100 | console.log("Product Updated Successfully..."); 101 | res.redirect("/admin/products"); 102 | }) 103 | .catch((err) => { 104 | console.log(err); 105 | }); 106 | }; 107 | 108 | exports.getProduct = (req, res, next) => { 109 | Product.find() 110 | // .select("title price -_id") 111 | // .populate("userId", "name") 112 | .then((products) => { 113 | console.log(products); 114 | res.render("admin/products", { 115 | prods: products, 116 | pageTitle: "Admin Products", 117 | }); 118 | }); 119 | }; 120 | 121 | exports.postDeleteProduct = (req, res, next) => { 122 | const prodId = req.body.productId; 123 | 124 | // ------------------By Using MongoDB -------------------- 125 | // Product.deleteById(prodId).then(() => { 126 | // console.log("Product Deleted Successfully..."); 127 | // res.redirect("/admin/products"); 128 | // }); 129 | 130 | // ------------------By Using Mongoose -------------------- 131 | Product.findByIdAndDelete(prodId).then(() => { 132 | console.log("Product Deleted Successfully..."); 133 | res.redirect("/admin/products"); 134 | }); 135 | }; 136 | -------------------------------------------------------------------------------- /controllers/error.js: -------------------------------------------------------------------------------- 1 | exports.pageNotFound = (req, res, next) => { 2 | // res.status(404).sendFile(path.join(rootDir, "views", "NotFound.html")); 3 | res.status(404).render("404", { pageTitle: "Not Found", path: "/404" }); 4 | }; 5 | -------------------------------------------------------------------------------- /controllers/shop.js: -------------------------------------------------------------------------------- 1 | const { redirect } = require("react-router"); 2 | const Product = require("../models/product"); 3 | const Cart = require("../models/cart"); 4 | const Order = require("../models/order"); 5 | 6 | exports.getProducts = (req, res, next) => { 7 | // console.log(adminData.products); 8 | // res.sendFile(path.join(rootDir, "views", "shop.html")); 9 | // const products = adminData.products; 10 | 11 | // ---------- With MongoDB ------------- 12 | // Product.fetchAll((products) => { 13 | // res.render("shop/product-list", { 14 | // prods: products, 15 | // pageTitle: "All Products", 16 | // }); 17 | // }); 18 | 19 | // ---------- With Mongoose ------------- 20 | Product.find() 21 | .then((products) => { 22 | res.render("shop/product-list", { 23 | prods: products, 24 | pageTitle: "All Products", 25 | }); 26 | }) 27 | .catch((err) => { 28 | console.log(err); 29 | }); 30 | }; 31 | 32 | exports.getProduct = (req, res, next) => { 33 | const prodId = req.params.productId; 34 | 35 | // ---------- With MongoDB ------------- 36 | // Product.getProductById(prodId).then((product) => { 37 | // res.render("shop/product-details", { 38 | // product: product, 39 | // pageTitle: product.title, 40 | // }); 41 | // }); 42 | 43 | // ---------- With Mongoose ------------- 44 | Product.findById(prodId).then((product) => { 45 | res.render("shop/product-details", { 46 | product: product, 47 | pageTitle: product.title, 48 | }); 49 | }); 50 | }; 51 | 52 | exports.getIndex = (req, res, next) => { 53 | // Product.fetchAll((products) => { 54 | // res.render("shop/index", { prods: products, pageTitle: "Shop" }); 55 | // }); 56 | 57 | // ---------- With MongoDB ------------- 58 | // Product.fetchAll((products) => { 59 | // res.render("shop/index", { prods: products, pageTitle: "Shop" }); 60 | // }); 61 | 62 | // ---------- With Mongoose ------------- 63 | Product.find().then((products) => { 64 | res.render("shop/index", { prods: products, pageTitle: "Shop" }); 65 | }); 66 | }; 67 | 68 | // exports.addToCart = (req, res, next) => { 69 | // res.render("shop/cart", { pageTitle: "your Cart" }); 70 | // }; 71 | 72 | exports.postCart = (req, res, next) => { 73 | const prodId = req.body.productId; 74 | 75 | // ---------- With MongoDB ------------- 76 | // Product.getProductById(prodId) 77 | // .then((product) => { 78 | // return req.user.addToCart(product); 79 | // }) 80 | // .then((result) => { 81 | // console.log(result); 82 | // res.redirect("/cart"); 83 | // }); 84 | 85 | // ----------------------Not this one----------------- 86 | // Product.getProductById(prodId, (product) => { 87 | // Cart.addproduct(prodId, product.price); 88 | // }); 89 | // console.log(prodId); 90 | 91 | // ---------- With Mongoose ------------- 92 | Product.findById(prodId) 93 | .then((product) => { 94 | return req.user.addToCart(product); 95 | }) 96 | .then((result) => { 97 | res.redirect("/cart"); 98 | }); 99 | }; 100 | 101 | exports.postCartDelete = (req, res, next) => { 102 | const prodId = req.body.productId; 103 | req.user 104 | .deleteItemFromCart(prodId) 105 | .then((result) => { 106 | res.redirect("/cart"); 107 | }) 108 | .catch((err) => { 109 | console.log(err); 110 | }); 111 | }; 112 | 113 | exports.getCart = (req, res, next) => { 114 | req.user 115 | // .getCart() 116 | .populate("cart.items.productId") 117 | .then((user) => { 118 | const products = user.cart.items; 119 | res.render("shop/cart", { 120 | pageTitle: "My Cart", 121 | products: products, 122 | }); 123 | }) 124 | .catch((err) => { 125 | console.log(err); 126 | }); 127 | }; 128 | 129 | exports.postOrder = (req, res, next) => { 130 | req.user 131 | .populate("cart.items.productId") 132 | .then((user) => { 133 | const products = user.cart.items.map((x) => { 134 | return { quantity: x.quantity, product: { ...x.productId._doc } }; 135 | }); 136 | const order = new Order({ 137 | user: { 138 | name: req.user.name, 139 | userId: req.user, 140 | }, 141 | products: products, 142 | }); 143 | order.save(); 144 | }) 145 | .then((result) => { 146 | return req.user.clearCart(); 147 | // res.render("shop/checkout", { pageTitle: "Checkout" }); 148 | }) 149 | .then(() => { 150 | res.redirect("/orders"); 151 | }) 152 | .catch((err) => { 153 | console.log(err); 154 | }); 155 | }; 156 | 157 | exports.getOrders = (req, res, next) => { 158 | 159 | // --------------- By Using MongoDB ------------- 160 | // req.user 161 | // .getOrders() 162 | // .then((orders) => { 163 | // res.render("shop/orders", { pageTitle: "My Orders", orders: orders }); 164 | // }) 165 | // .catch((err) => { 166 | // console.log(err); 167 | // }); 168 | 169 | 170 | // --------------- By Using Mongoose ------------- 171 | Order.find({ "user.userId": req.user._id }) 172 | .then((orders) => { 173 | res.render("shop/orders", { pageTitle: "My Orders", orders: orders }); 174 | }) 175 | .catch((err) => { 176 | console.log(err); 177 | }); 178 | 179 | }; 180 | -------------------------------------------------------------------------------- /data/cart.json: -------------------------------------------------------------------------------- 1 | {"products":[],"totalPrice":0} -------------------------------------------------------------------------------- /data/products.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "2456352", 4 | "title": "Rich Dad Poor Dad ", 5 | "imageURL": "data:image/jpeg;base64,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 ", 6 | "description": "Best book for financial knowledge ", 7 | "price": "349 " 8 | }, 9 | { 10 | "id": "13456345", 11 | "title": "Do Epic Shit", 12 | "imageURL": "data:image/jpg;base64,/9j/4AAQSkZJRgABAQEAdQB1AAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCACcAGQDAREAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD7tr/Lc/RQoAKACgAoAKACgAoAKdmJu242eaK1tXuZ5o7e2jGXmmcIij1JPArrw2DxONqexwtKU5dopyf3K5hXxFHDR5681Fd27L8SGw1Oy1ZXawvrW/VPvG0nWXb9dpNduNybMstSeOw06SfWUZRX3tJGGGzDB4zTD1oz9JJ/kyxXkcrR33CpACcCmlzOwB69vrx/Oq5dNxJ3DP8A+vtRyjCoegBTWoB3xg/lVONtwug79P8A61HL5iuL+lTYZg+OPFsHgbwvd6xcRiYxYSGFmwJJW4VSfTufYGv0XgLhDE8b8QUMloScYy1nJfZgtW/8vM+V4mz2lw7llTH1Fdr4V3k9kfNGvXll45aDUte8cB75gzyWj2MxW3YqpCRhQygbiwLegr/Vvhzh7C8GYWOAyTL1FR059HKX96T7vsfxtmeO/t6osVj8c239lp2j5JbaXsUNOsfDen6it7F4qvIzFIdk1jpkqyDgFVEm9dpPPY8V9FjoYnNKDwmNwcKkXup2afyd7Hl4WGDwVT21HFzi11imj3n4J/Ey48c2Nzp2psH1axG/zuAbiHOA5HZgcA+u4Gv84PG/wwo8D4qlmeVJ/VMQ2rb8k9+X0erXpY/qHw74wqcQUZ4PGv8AfUra9ZLv6rqelV/Llj9mJ7JFkuo1YZUnkHvW2HSlWhGSum1+ZnUbUG0fjlof/BRr9pTxNf8A2HR9Ui1W8ZWkFtY+H4JpNo6nasZOB61/c1Tw04QoU/aV6Fopbucl+PMj5D69iG7I7Hwz/wAFSfjR4C1eO08e+GdL1qAkNLb3djJp15t6fIy4UdD1javIxfhLw1mFG+AnKD6OMlNX873fyutDSOYVqcveR+iPwF+PXhX9o7wBD4q8KTOqI3kX2m3WBcWM+AfLcDggg5VhwwPqCB/LvFPC2M4UxrwmM1T1jK2kl+j7o+hw+KjiIcyJ/jl8cPCv7PPw9ufF/iu4cWgfybSytwDcX0xBKxxgkDOASSeAASfSs+G+F8fxPjPqmCVkvik9orz/AMh4jExoRvI/Nrxf/wAFJvj18W/ETWXw00tPDlqrExWOh6Uup3bp0HmPJG+T7oifjX9YYDww4YyWhzZjaq+spy5VddkuW3zb+R81PHV6z9zQqab/AMFBf2lvg/r0Q8f2smq2j8NpfijQFsCw6ko8ccT7sdCSwH901riPDjg/OaD/ALPSi/5qcr/rJfkKOMxNB3l+J+h37Mv7T/hX9qTwbNqugo+l6zYlU1TQ7lw0tqx6OrD78bYOGwOhBAIxX8wcYcG4zg/FqnXfPSl8M0tH5Ps+6PocNjFiI+Yz9qETS+ENEX/l0kv28zH9/wAptn6b6/o76MCw74hzCNT+IqPu+nMlL9PxPxDxh9rDK8PyfCp6+tnb9ThZbzXtalivG0/wjYvdxbRPK6JIVlUAlsMWB2n04ye+TX9uujg6SdF1KsrNrTvfXofiTqYyp++lTpRdv09XuLY+JLnUdJgml8YaTpKXIIksYNPgj8vEm3dh+egLZxkhcDkgVlXwkKVV8mGlK3VyY6WMnWpJTxUIJ9FBafOwvwVeb/hdMCwXq6hF5Nws13CMLNCI8K2McAsI/fIHrX5F49wox8Oqnto8sva0+VNptNyvZfK/yPovDqVWPFiVOfOrSTdt1a/52Pprj1r/ACzV0f2UnfYs6f8A8fsX1rXD/wAen/iX5ozq/Az8c/8AglexX9rG0wcZ0a+z/wB8rX9yeKra4Vr27w/9KR8fgv8AeEfpz+0b8DNB/aL+F2r+HNbsop9RW2kl0nUNoE1ndhSY2Vuu0nAZejKSPQj+U+D+JcXw5mtKvTm3Tk0pxu7NOyvbZtdD6TFYeFWm1Y/NH/glx8Rb7wX+04nhN2b+z/FNlc2NxCx+VZ4I3nikI7sPLkQf9dTX9UeK+X08dwzPE296i1JO2urs187q/ofO5fUcKyXcT/gpP441b4q/tX/8ITYM9zbaAlto+n2it8rXM6xySED+8zyKhP8A0zX0q/DLLqOTcLwxk1aVVOpJ+Sva/ey1XqGOm6tfl7H6d/Af4H+Hv2c/h1p3hHw7bxCWGNTqOprGFm1C5x88rt1PP3QSdq4UdK/kriziTGcTZlUxWIqPku1GN3ZR2Wm2trvufSYXDQo00ranQ/EH4f8Ah74ueEr/AMK+LdNh1fRr+MxtHKgLRMQQJI26o6nkMOQa8jJc5xeQYuGOwU3GUXqruzXZrqvI0r0IVYOLR+P/AMAdT1j9kz9ue08Om6l+z2+vt4avxjC3lnLMI1cr3BzFMo9VWv7jz/D0OL+Ep1bL36aqR8pJKWnbqvvPk6Llh8Rbzsfr/wCP/BkHjbw1faM8nkOSJLeU8iOVfusfbqDjsTX8jeH/ABhieCM+o51S1itJx/mhLdevVeZ08UZDT4lyqeBm7SesX2ktv8n5HzJrFppvguafTtZ8FyR6kPkjln1CUxSKQwLKVCg+oI9RnBFf6x5BnlDjHCxx2UZhGcJbpJXT35Wt7pNXP40zLBRyGq8Nj8E1NdXJ2fS6tpbQzrDxFaJqqmz8MWE8sgRYrQiSf5hu5UEkkncvX+6D2FfSYzDrD4Z1cbjHCEd27RXz1R4+HxUata2Gwak3olqz6M+Fng+80pH1zWrK0sdXubf7IltaRCMQQ+Y0h3Acb2c7j+HOc1/mf40+IuE4nxEMlyWcp4WjLmc22/aTta6/uxWifX7j+tOBOGq+XQlmWY0lCvNW5UkuWPnbq+vXud9gV/MF2fruxZ0//j9i+tb4f+PT/wAS/NGVX4Gfjj/wSyOP2sLP/sD33Hr8q1/cfit/yStf1h/6Uj5DA/7wj9c/FPiWx8D+Fda8R6pKsGnaRYzXtxJIdoCIjMefU4wPU1/F2U4KtmOYUMJh1eUpRt9+p9ZWmoU22fjx/wAE4vD934t/bK8M38EDNa6al/qt4y8iGP7PJGrH28yaJf8AgQr+4fEyvTwvCmLhKS95KK83zL9Ez5HApyxEbFj9tX7V8I/29tX8SS2/nxwapp3iG3RuBOgSGQge29HX/gJquBqlPNOEcPTjLXkcH5NXTX5CxS5MQ2+5+w+ka/pvi3RdP13RrpL/AEnU7dLy0uojlZYnUFSPw7dfyr+E8dga2XYmphMRHllBtNPyPsKU1OCki7GApLuwjjTLO7nAUDkkntxXJClUqtQpq7k7LzZpKaSbZ+K1xrA+P3/BQi31Lw+v2q01XxrDJayRgsHtYZ1xL9DFFvPpz6V/oDRp/wCrvByp4h2dKhrfpLlen3ux8U37bE3XVn7VTnMzHOfmPPrzX+fmlj7aOiK17aW2p27W97awXtuwwYbmISIfqrcV34HMcXllRVsDWlTn3i3F/gcuJweHxkPZ4impx7NJr8SrpXh/SdB3nS9J0/Sy4wxsbSOAn6lQM16WZcRZtnCUMxxlWtFdJzk19zbRzYbKsDg3zYehGD7qKX5Gh1r5o9YSgRZ0/wD4/Yc9M104VXxFO38y/Myq/Az8Bf2f/jP4p/Zy+ISeMfDek2d/qcdtNaeRq1tLJBtkADZEbo2Rjj5vzr/SDPMmwXEOBlgMbJ+zlZ+67PTXezPhqVSdGfPFanrPxD+Pf7Q/7bTReFoNGvLzSmlRn0TwxpskVoXyNrzuSx2g4OZX2KQDxjNfKZbw/wAK8ERli1KMJWfvzleVuy0372V3sb1KuIxWj1Pv39hn9kBv2XfCOo6h4gmtbvxzrqol21sd6WVuvIt0f+IlvmcjglVAyFBP82+InHEOKa0cNl9/q9Purc0u9u1tvv8AI97A4R0Vzy3F/bh/Y8i/ag8KWWp6DJBZeP8ARUKWck7BIr2A5Jt5G7ENyjHgEsDw2RHh3xyuFq8sJjL/AFao793GX83mu+3fpYWOwbrLnjuj8/8A4eftO/Hv9iWefwbf6a8Onws2zw/4tsZJLeIknLwsrI20nJBR9jdcHOa/pbM+F+GOOIRxqam3tOErP52vr6q62PCp16+FfLsXfiL+3L8d/wBqOwHgnSbCGyg1AGGbS/Bmnz+feqcgo7F5HK4JyqlVI+8DXNlPAfDPCc/7Qlq4689SS09LqKKqYqviPdX4H2H+wJ+xDd/s/wDn+OfHMUB8cXtv5Nlp6MJRpULgeYWYcecw+U7Twu4Anc1fiPiXx/Sz2H9k5XJuineUukmtku6X4s9XAYJwftKm59l56V/PDPoBKQBQAUAFADowzOAmd3bb1/CrgrySXUTslqc8nxR8GIoA8ZeGgB/CNTt8D/x6vp55Lnu8sNW/8BmcftMOuqFb4reEWG3/AITbw8F9BqsA/wDZq55ZJnMviwtV+sJ/5B7agtmjW0fVLHxDaJeaTf2mq2shMYuLGdJoywOCAykjPqK8/FYLE4OfscRTlCdk7STTd+yN4zjJcyehif8ACzPBnDf8Jl4e/wB06rb8f+P16P8AYGbxX+51dV/JLZ/Ij6zSvZyRdttc8NeOkNjBqWheJVXk2y3EN2B77QTUfVs1yte1cKlHztKP6EOVCoX9L0my0JXh0zTrTS1c/MlnbpCD+CgV52Jx2Kxb5sRWlP1k3+bNo0qcdUjPt/Gnhy/1UadB4k0e51MyNELKLUInm3rncuwNu3DByPY12VMozGhQ+szw0407fE4ySt622JVek3yqSua9eNY6CHUr+z0Wwe+1K9tdMsk+9dXsywxL9WYgCuvC4PEY6fssLTlUl2im3+BnOpGHxM5G0+OPwz1G7Nra/Ejwhc3YOPIi122Z8+mN9e9LhXPormlgKtv8Ev8AI5/rVF6KZ2yruhjlRkkikXckkbblYHoQa+bq05UpOE4uMl0as/uZ0xkpbMbWBZZ0/wD4/YvrXRhv49P/ABL8zKr8DPwN/Zi+ANx+0r8UovBdrrUOgSSWc939sngMygRgHbtDDrn1r/RniTP6fDOWzzKrTc1Gysnbd2PhqNF158kWfXjf8EdtYB/5Klp//gnk/wDjtfi8/GvA393BTf8A28j01ldR7SPtn9kb4Cz/ALNnwss/BN3rUOuzpfz3n2yCBoFIk24XaWPI29a/DuMOJKPFGc08ww9NwVopp73R6uHoSw9Fxkz8bP2Y/gbD+0T8bdL8Bzay+gR38d1J9ujtvtBTyonkA2FlznZjrX9rcTZ7/q3lNTM/Z8/JbS9t2lvZ9+x81Tpe2rOF7bnt/wC03/wT58R/sueDU+IGgeNl8R6XYXMS3U8Vq2n3dkzuqxSLiRww3kAkMCCVwDklfieEvEjA8W4p5bWoOnNptJvmUrJ3WytZLzujoxOCqYZc6eh9mf8ABN79pLW/j58M9U0rxXctqPiXwrcQQPqUuTJeW0obymkP8UimNwW6kBScksT+HeKvC+GyLH0cXgoqFOve8VspLf0TTTt6nq4DEyqwcZdD4i/Z6Qf8PLbdcDA8Yatgfjc1+9cTX/1Fq/8AXmH5RPGo/wC8r1P07/aU+Pelfs2/CjUvGWowre3YcWmmaezbftd2wJRCeoUBWZiP4VOOcV/JPB3DFfinM1gIPlgtZy/ljez+fY+oxmIWHp36n5R6T4f+Of8AwUO+It1dfaJNVjgcebcXczQaRpKMeEUDdtH+yis5xk7uTX9m18Rw54e5dGDtTjsrazk+763fnofKRjWxk7nsF9/wSB8fx6THJZeO/C1zquP3lrMLiKEf7sojYn8UX8K+EpeM2RzruFSjUUO9k7/K+h1vLKyVz6f/AOCe37Pvjr4C+AvE8Hjy6u4Lu81HybLRTfefa28MQIM8aglVMrMeRyVRMivyXxQ4pyviHEYeOVqMko3lPltJtte629dEj1cuw9Sinzn1XX4Ye0WdO/4/YfrXRhv49P8AxL80ZVfgZ+CX7LH7QLfsz/FaLxqugr4jMdlPafYmuzbf6wAbt+x+mOmOc1/ovxNw/T4ny2eWVKjgpNO6V9nc+Go1fYzU0rn2H/w+Kx/zR+LJ6/8AFRn/AORa/FZeCeFk7vHzv/gX+Z6n9q1H9lH21+yz8bT+0R8KNE8dHQ08PNfXFzCbBLn7QF8qRk3b9iZzj0r8N4t4fp8M5ystpVHUSUHdqz1ttY9ehiHiKDlJH49fsbfGDw/8Cv2jNE8ZeKDdDRrKK8jlNnD5smZIJI1wuRnlh3r+zuM8lxPEGQ1stwjXPPltd2WjT7PsfM0qio1+eWybPpD9tX/god4P+NPwhvfh/wCBNL1fy9VnhbUdR1WNIFWKKRZVSNVdixZ0XJbaAF77vl/NeAfDTG8PZks0zGpFyimoqLb1aafNdLSz03/z7cXj44iHJFHtf/BKn4J618O/hfrvi7XbWXT5fF1xbnT7WYbXNpCHKzFeoDtI2M9VUN0YE/B+MWeYfMMZh8tw81J0b81ujlbS/ey/Q68uoyhCU5dT5I/Z6/5SX2/p/wAJhq387mv2biZJ8C1U/wDnzD8onk0f95Xqel/8FgvE95N8SfAHhosf7Ps9Hl1FUAwDLNOyMffAt1+mT618j4K4WnHKsTi7e9OfK/SMU/xudmaSbnFdD7J/YZ8GWHgb9lDwBBp0aRtqtkNXvJFXmaef5izc8kLsT6IB2r8P8SMyrY/ifEqq7xpPliull/m7v5nrZfTUaKaR7oK/LXueqLSGJQIsacwN9D9a6sOrV6b/ALy/NGVX4GfjJ/wTL8O6V4o/aft9P1nSrHWLFtIvGNrqFuk8RICkHY4IyPpX92+JeKxOD4arVcJOUJ3hZxbT+Jdj47BRTrpS2P1r/wCFI+AD1+HHhP8A8Etr/wDEV/GU+Ic9v/vlX/wKep9OqNHrY6XwzoOm+F4rbTNH0qx0TTo3YpZadbpBCpJLMQiAAEk5JA715tfFYrG4mFfGVJTneOsr3srJb6vQ05IRptQ2PxJ/YR+Hnhv4pftSeH/DfivSYdb0S6hvmms52ZUcpbSupypB4ZQevav7v48zTF5Nw7XxuCny1I8tn6yS/U+ToQjUxHLLbU/V7w3+yH8EvCGpRahpfwx0FLuJg0cl1E1zsI6ECUsAffFfx1iuPuJ8VSlRq42Vpb2sn6XSR9PHA0Yu6R7FBIz3MeT0Ix7V8C5uT167na0lB2Pxw/Z6/wCUl1v/ANjhq387mv7u4mduBarf/PiH5RPi6P8AvK9T6U/4Ky/BO88U+DPDXxK0qBpz4eMmnatGgJZbaRwYZfZUk3qf+uy9ga/KvBrPaNCrWyWu7Sm+ePnaPvL1tr8j1M0ouyqId/wTn/bE8K3/AMONK+FXi7VrbQfEGkF4dJur6QR299AzFljEjEASqWKhTjcNu3JyA/FDgXG1cdPPcug6kJpc8VvFq+tuzVu+txZfjYwiqc9D7uuru1sLJr27vLW0s1G5riedEjUepcnFfzjDAYqrU9lClJy7JM911oWvcyPB3jrw38RdJn1Twrrtj4i0yC6ks3vNOmEsQljxuUOOG6ggjIIIIyOa680yfG5LVVDH0nTm0pJPs/6sFOtGqrxZt14huSWUqw3cTt90NzXTRkoVYTlsmn9zuZ1FzQaR+T9p/wAEl/jLZMs1v4w8EWsu370ep3qsM9QSLWv7On4wcN25eSq/+3F+sj5NZbiL3Ra/4dVfHI/8z74O/wDBvf8A/wAi1z/8Re4Z/wCfNX/wCP8A8kP+zcQfd/7G3wa8Q/s9fBuz8J+LNTsNU1WHUbm6a4024kmh8tyu0bpERs8HjbivwHjfP8DxDnUMwwSap8sVqrO68u/zPZwlCpTpOnPdnzP+yJ/wT4+Iv7P/AMe9B8d+INd8K3mlWcN0ksGnXdw9yfNgeNcK8CrwXGfm/Ov1DjPxIybP8ir5bhIVFUly25opLRp7qT7djgw+Cq06/PLbU+/MYwOp61/MU1Y+kvd2HwMEmRj0BGalK2opapo+CfhZ+wD8RPA/7XFv8Vr/AFvwrNoC6/e6o1rbXlw135Mxm2jaYAm794uRv/Gv6bznxHybMOGp5NRhU9q6cYq8Va6t15tvkfN08DVjX53tc+7b+xtdWsrqwvrWG+0+8jaG4tblA8UsbAhlZTkEEH0r+bsNWrYWrGvQk4zg7prdNdj6KdNSjaR+fHxy/wCCTVtrusXmrfCvxLZ6LDO3mL4f13f5MJPJWOdA7bfRWUn1av6f4f8AGWFOnChnlJ8yX8SGt/WP6p/I+dr5XK7dLY8Ss/8Aglj8dtQvPsV1J4dsbRD8t1dauWh+oVEZx/3zX39XxY4XhDn9rJt9ou5xLL67drH3j+xh+yjqP7KnhjX9P1HxeviKfWZYp5bK0t/LtbWRFILIzHcxYMoJwvCr8vev518QONcPxfOl9Xw/Iqd0pP4pLtboutj3MDhZYa/M9z6Ir8fPXGgZIA61aA8G/aN/bX+G/wCzTdf2TrUt3r3iloxIND0lVaSIMMqZpGIWMHjjlsEEKRzX6lwt4e5txPTWJhalR/ml1/wrVv126XueXicfCh7q1Z88eHv+CwPhm81NY9e+GGqaZp3e407WEvJV9xE8US/+Piv07E+CVdU39VxylJdJQaX3pt/gedHNUnrE+yfgz8bPBnx/8LL4h8E6m+oaeswtp0nt3hltptoYxurDqAw+6SOeCa/CeIeG8x4YxKw+YxSbTas001e11bWz87PyPbo4iFeDlDoeSeFv28fBHiv9oFvhDD4d8QQ+II9Yu9GN7KkAtvMgaQM+VkLbT5Rx8ueRX6DjvDLF4DJ5ZzUxUORQU7JSvrbT8TzoZgpVfZqJ9KZPbjB6nmvxV67nsrax8xfGL/goJ4E+Cvxi1P4cav4c8R32sWEttE11YLbmBjPDHKhBaQNwJQDx2OK/aMi8M8fn2U081pYiEYSUrJqV/dlJa2XdX9Dx6uYqlUdPlPXv2gfjVo37Onw6u/GWv2N/qWnQXUNq0GmhPO3SHAb5mVePrXxXC3DlbijHyy+hVUJKLldptO34rc7MRilh6anY4z4Z/tf+FPil8CvGfxV03Q9ZtND8MNcLc2d0kP2ifyYUlby9rlfuyAckcivfzTgDGZXneFyOdeMp11o1zWWrWq36HPDHKpSlV5djxIf8FcfhVjnwj4xB6nEVof8A2tX3b8FMyvpjKf8A4DI41m0f5RT/AMFcfhSP+ZQ8Y5/642n/AMerN+Cmar/mLp/dL/IP7Wj/ACn0J+zb+0v4c/af8K6trvhrS9V0q1029FlImqiMO7mMPldjsMYIHNfmnF3COI4RrUqGIqxqOpHm926tZ26no4TFrE3srWPWq/PT0RYQDMgblSRnNUJ7Ox+JPiGz0DUv27ddtvi7cS2/h2Txjdpq8xdlAi89wmWHKxn92CRyEJIPFf6K0JYilwpTnkqvJUo8nXWy2v139WfCO31h+176n6f63+xB8AfGfhaGC38AaTHp1xCGs9V0OZo5CjDKyLMjEPkcgtuB96/kKn4g8W5Xi39YrtyT96E1pv26bdPvPpFgsPUj7qPSvg18K/D/AMEfh9ofgnwxBJHpOnAnzLht01xKx3PLI2ACzMSeAAOAAAAB8VxFn+M4jxtTH41+89El8MYrZJdvnqdtHDxw9Nxiflr8Hh/xtQvcDP8AxXWudP8Afuq/sziOPNwFUX/TiH5RPlqX+9/Nn69m2lBIMbdfSv4Sk0t+p9ipLdH4z/t68ft++Kv+v3R//SG0r+7/AA9VuC8N/hqf+lzPjMT/ALy/l+h94f8ABUf/AJNO1v8A7C1j/wCh1/P3hF/yUsv+vcvzR7GY/wC7o4D/AIJb+H9N8W/smeNdD1mzTUNI1LxFdWt3ayEhZYntLYMpIIIyOODX0ni7jq+W8R4LF4WXLOELp6aPnfczyyCqUpRlsW/2w/2Svg78Of2YfHviPw14CsdJ1zT7e2Ntexzzu8Ra6hQkbpCM7WYcjvWHAfHHEObcQ4bBY3EuVOXNdWitot9EuxWMwdGlScorU8I/4JifAj4ffGzS/iS/jjwta+In0yTThaNcSSoYhILneBsZevlr+Vff+KnE+bcOfUnldZ0+fnvone3Lbf1ODAYenW5lNXsfpB8NPhD4K+DWk3mmeCfDtv4esbucXM8UEkj+ZIF27iXZj0AFfytnXEOZ8QzjVzOs6koqy0Strfoj6ajh4UNIHXV80dI38gffpWi3A+aP2rf2EPB/7TVw3iC0vH8I+OgixtqkcJlt7xVGFWePK5IGAJFIIGMhsAV+zcHeI+L4YpLBYiHtcOtlezXpo/u27W3PGxWAVZ8y0Z8I+I/Cn7R3/BPLU7a8tdXng8LzXGI7mxlN3pF02clJInH7tmA/iVWPO1uMj+jMLjeE/EWg4ShGc0tVJctSPo1rpfu0eHKGIwbv0/A/SL9kv9pvS/2pPh4mv29iNI13T51tNX01H3pFKRlXjY9Y3GSM8ggrk4yf5S464PnwjjfZKXPSqK8G9/NPzR9FhMV9Zpu+6Pyj8ZaB4z8T/tveOdM+HstxD4zn8ZayNNktbxbSUOLidm2ysyhflDfxD071/aVHEYHC8OUq2ZW9jGlByunJW5Vukn/Wp8tJTlWahvdntB/Zw/bn/wCf/wAUfh41tv8A5Kr4KXFXh3q37HX/AKcvr/24daoYvu/vPmr4jeHfHfhT4/nSviZNdT+N7e+sf7QkvL1byU7o4mi3SqzBv3RjxhjgYHbFfpOX4nLsZk/t8qt7BqXLyrlX2k7Kytqn031OKUZRq2nufqZ/wVG/5NO1z/sLWP8A6HX8k+EP/JSS/wCvcvzR9BmP8BHH/wDBJb/k2vxH/wBjVP8A+ktrXreNf/I6w3/Xt/8ApbDKf4bPVf2+f+TOfid/17Wf/pbBXxvhl/yVeE/7f/8ASGdeY/wGfNP/AARy/wCQT8Xf+uuk/wAruv1Hxv8Ahy//ALif+4zy8q3n/Xc/ROv5ZPpwoAqatq2neHdJvtW1e7Sw0rT7eS7u7qXO2KFFLOxxzgKCeOa9DA4WrjsVTwtBXnNqK9XoRUn7OLn2Pg/wT/wVy8JXmuahB4t8Fanpmkm6cWF/pDpNL5G4+X58TsoDbcbijN3wOlf0lmHgvXhRpywGKTlb3lNOzfVxa2V+j+8+fhmqu+ZGN+2X/wAFBfhd8SfgZ4g8BeDYtS8QX+upCpvLm0+z21oqTJKSd/ztJ8gAAXHOd3GD6PAXhvm+SZtHM8wnGEYXSSd3K6t06a+v3mWLx9OtDkitTY/4JAeCNV0nwh4/8U3UEsGk6zdWVpYu6kLO1v5xlZc9QDKq5HcMOory/G/G0Kk8Fg4NOcVOT12vZK66XtcrK4P35dDwX4Pcf8FUL3/setc/9Duq/UuJE1wHU/68R/KJwUv97+bP13bGTj/PNfwmz7Vbn41/t6/8n/eKv+v3R/8A0htK/u7w9/5IrD/4an/pcz4nFf70/VfofeP/AAVG5/ZO1z/sLWP/AKHX8++EOvEsrf8APuX5o9jMf93Rx/8AwSW/5Nr8R/8AY1T/APpLa163jX/yOsN/17f/AKUwyn+Gz1b9vgZ/Y5+Jv/XtZ/8ApbBXxvhjrxZg0v7/AP6QzrzH+Az5o/4I5caT8Xv+umk/yu6/UfG7bL/+4n/th5eVbz/rufonX8sn04UALwQysqurAqysMhgeoI9KuEnCamnZrW6FJKSsz57+Jf7AvwO+KGoTajd+EjoGpzHdLc+HrhrNXPcmIZiB7khMnPJr9XyzxP4jyyn7JVlUitlNc343T/Gx5VTLaM3fY5vwv/wTL+A/hrU472fSta8QiMhltdV1I+SSDkZESoSPYkg9wa9PFeL3EuJpunBwp30vGOv4tkRyyjF3ep9RaZZWmiWFnYabZ22nadZIIraytIVihhQDAVEUAKAOAAK/H8Vi62OrSxGKm5zlu3qz1IUowjyxVkeN6J+x18K/D3xdf4m2Oj3yeMX1G41Vrt9SlZDcTFzIfLzjGZG496/QcZ4iZ5jctllVScfZOKhpFJ8q03OGOApQqe0W57UTycdP5/54r81k4t6Hpnh3xG/Ys+EnxW+I19468R6HfXfiS8kglluItSliQtDGkaYRTgfLGo6c496/Scp8Q88ybL4ZZhZxVOPMleKb95t7+rZ5lTAUqk+d7nonxc+FPhn45eDLjwt4vs5r3Rp54rh4re4aBi8ZyvzLzj+dfM5FxDjeHsY8dgZJTaad0mrPyOitho1o8ktij8G/gj4P+APha78O+CbC40/Srq8a/ljuLp5yZmREJy5JHyxqMe1XxDxLj+J68MTmLTlBcqsrK12x0MPHDq0TX+I3w+0P4seBtW8IeJbaS80LVERLmGKZonYJIsi4ZeRhkU/hXBk2cYrIcbDMMFK1SF7XV1qrfky61GNeDhLY5f4Ifs4eAP2doNbj8DaXc6cusGE3guL2S43+Vv8ALxvJxjzG/Ovc4i4vzPilUlmU0/Z35bRS3tf8jChhIYf4D0uviDuCgAyKdgF4xSGFACZp2EFIAwaeg9ApAFMQUWAKQBQAUAFAEF1dwafaz3d1IIbW3jaaWRjgKijLE/QA16OAwdbMcXSweHjedSSil3bdkcuKxEMJQniKjtGCbfojzPwl8VfK0LXbvU5/7VliSHVIYbUr5iQTsEFvjON0T8HP99a/o/inwxhLHYDD5XT9jCXPSnKTTTqUYuTqadJrZeTPyPJeMaiw2Jr4yXtGrVIpaPkm7cuv8un3mhrPxJWw12wWeG5smtL+fT7uxDK3nTNbxvCAwO3B81DkkAHqeK87JvDdY3LMY6FSFbnoxq06lmuVRquM3Z63tFqy30O7H8XfV8Zh1Ui4JVJU5xutW4px20tqdRceKYbW6uoJoJEmtrq0tHQFTmS4KbcHuBv59dpxxX5rhuEcTi6NOvSqLlnTq1E7Pak2mvV7o+sqcQUaFSVGdN80Zwhv1nHm/Af4Q8S/8JXYm+WwlsrMyvHFLLKpaQK7IW2gnAyp61ycS8Ow4XxccHOvGtVSTkop2jezSu9G2n0NspzWedUJ1oU3CDuou6d7NptW2+Z5efiPrmnabdST3nmppdhcadPIyAGbUz5xi5x2EMf/AH9r+kYeHWRY3E06dKl72IqU68EnZLCqMfaffJvXyPyiXFeYYeDcpNqnGVOXW9Vt8l/kl952/wDwnX9lSLZTWN3fpa39potxqKyIAbuUR87CQxUGRcn1PAOK/HFwI8zpvG4evCm6sKteFO0n+6hKS+JJq+lkj7mPErwlqFanKXJKFKUrrWckns9euvoRnxg2taZo9/HFf6Rb3uoPb2xSSJjOywzk7wQcJmInggn5e1dWH4Np5djsTg6lSniJUqUJzVppwUpU78t7XlaXmiamfyxmFo4lRlTjKfLHVe9pLddroreCfiE2qeA9Auvs9zqd7MLew3vIsZuboxb5Mk/dA2sSx69geK7OKvD54HiPGYTnhQpRU61rOSp0lJKO2rbTWi1XU48k4q+tZTQxCg6lRuNPdLmnZ3306Pct3fxMt4IJpE0u7me0s5b6+iVkU20UcrxOclsOd0b4Ck8LnPIz50fDXEOu4yxVOMZ1PZ0pNS5aknFTj0vBNSWsuunQ9GfF1JRcqdGUpRi5TV4+6k3Hro9U9ih8ffirN8Hfgn4o8b6fpc+s3en2e+1ghgMqiVxtiklQMp8pWZC5ByF3elfIcLcOwzrP6WT4qSguZqWtm7bped1ofX18VbDqtT2aTXzPlv8AYj/bz8U/Hv4pXng/xjp1qBqHn3On3dlAypbFU3rbfImNuyOZt0rZJGM9Fr9e8QPDnKsjyj+0st5ounyppu6knK17vW92lp/meZg8dUqVeSfU+56/mQ+nWxW1DT7XVLGezvLdLq0nQxywyfddT1BrtweMr4HEQxOGm4Ti7prdPuc2IoQxVOVGqrxkrNMj1LR7HWnU39nDdlUMQaVRwhZWKjHbcinHbFezg+IczwDk8NiZR5pczt/M04369JP7zgr5ZhMTFKrSTsrL00dvvSIJvDmk3M1xNNplq8tyzPMzpkyMyLGxP1RVX6CtqHEmbYenGjSxc4xiuVJNpcvM5W0X8zbM6uT4CtOVSpRTlJ3d11ty39bDD4Y0htTttQbToGvLcIsUzrllCjC/XGTgnJHrWkOKM3p4OrgYYqSp1G3KK213t2v1S0fUl5NgJYiGKlRXtI2s/RWXXdLRO2xdsbG20y1jtrO3it7dGYrFGuFBZixP4kmvCxuNr5hWdfFVHKbSV/RWR6OGw1LC0lSoQ5Y66erv+epVl8MaRcQzQyaVaPDcXi38yNHw84IxIfcbV59unr7lPijN6M6dWnipKUKbpR1+Gm90vJ3Z5tTJMvqQnCVFNSlzvzn/ADDbvwnouoakdQudKtZb8yRzG4aMbvMTGx/TcMDB64AFThuKc4wmD/s+ji5qjZx5U/syd2r72b1tcKuSZdXxDxNSgnPe/nbffdd9ydND09LWztRYQfZ7SQzQRFfljchgSBn0d/8AvquV57mCr1cVHES9pVSUnfeKtZbdLJfI3eWYRUYUVSXLB3S7N9fxZWPhDQzZmz/sm2W2YRqYwmBiMYj6EYKjgEc4716EeK85Vf608ZJzV9W7v3viWqtZ6XW2hyTyLLpUpUfYRUXa6Wmq2eltfPfuMufBuh3lvawzaNZyRWyMkMbRjaik5KkfxAnkg5BPJrShxjnmHrVa9PGzUqrvJ9W7Wv5NJ6NWaRNTh/LKsIU54eLULW/W+uuve/fcvazommeJ9Hu9J1rTbTV9JvF8u50+/gWaGZeCA6MCpwQD04wMV83hswxGAxMcXhajjVi7qS3PclSjOHs5LQ4f4Sfs8/Dz4Gz39z4L8ORaVf34dbq+MjPLKjSGTZ12hQSAAAAAoFfSZ/xjnHEtGNDMa3NCLukklra1/P59TGjhKdCV4o9Er4c7QPSmgAdKGAjU0AlMAHWgB1SwCkAUAFABQAUAFABQB//Z", 13 | "description": "Written by Ankur Warikoo", 14 | "price": "219" 15 | }, 16 | { 17 | "id": "763523424", 18 | "title": "Physiology of Money", 19 | "imageURL": "https://rukminim2.flixcart.com/image/850/1000/xif0q/book/j/p/l/psychology-of-money-in-english-2023-paperback-morgan-housel-original-imagv6h6mjfjdyc5.jpeg?q=90", 20 | "description": "This book makes you look at money.", 21 | "price": "299" 22 | }, 23 | { 24 | "id": "253467556545", 25 | "title": "Life Amazing Secret", 26 | "imageURL": "data:image/jpeg;base64,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", 27 | "description": "Life's amazing secret by Gaur Gopal Das", 28 | "price": "399" 29 | }, 30 | { 31 | "id": "52452452", 32 | "title": "Power of subconscious mind", 33 | "imageURL": "https://www.theindianbookstore.in/cdn/shop/files/image-058.png?v=1696667013", 34 | "description": "Best book by Joseph Murphy", 35 | "price": "199" 36 | }, 37 | { 38 | "title": "The Subtitle art of not giving a f*ck", 39 | "imageURL": "https://m.media-amazon.com/images/W/MEDIAX_792452-T2/images/I/71t4GuxLCuL._AC_UF1000,1000_QL80_.jpg", 40 | "description": "Very good book ", 41 | "price": "239", 42 | "id": "0.7593276111445939" 43 | } 44 | ] 45 | -------------------------------------------------------------------------------- /helper/NotFound.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const errorController = require("../controllers/error"); 3 | const router = express.Router(); 4 | 5 | router.use(errorController.pageNotFound) 6 | 7 | module.exports = router; 8 | -------------------------------------------------------------------------------- /helper/database.js: -------------------------------------------------------------------------------- 1 | const mongodb = require("mongodb"); 2 | 3 | const MongoClient = mongodb.MongoClient; 4 | 5 | const options = { 6 | ssl: true, 7 | tls: true, 8 | }; 9 | 10 | let _db; 11 | 12 | const mongoConnect = (callback) => { 13 | MongoClient.connect( 14 | "mongodb+srv://:@cluster0.ajqdph4.mongodb.net/?retryWrites=true&w=majority", // MongoDB URI 15 | options 16 | ) 17 | .then((client) => { 18 | console.log("database connected.....!!!!!"); 19 | _db = client.db(); 20 | callback(); 21 | }) 22 | .catch((err) => { 23 | console.log(err); 24 | throw err; 25 | }); 26 | }; 27 | 28 | const getDb = () => { 29 | if (_db) { 30 | return _db; 31 | } else { 32 | throw "No Database found"; 33 | } 34 | }; 35 | 36 | exports.mongoConnect = mongoConnect; 37 | exports.getDb = getDb; 38 | -------------------------------------------------------------------------------- /helper/path.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | 4 | module.exports = path.dirname(process.mainModule.filename); -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | require("dotenv").config(); 2 | const express = require("express"); 3 | const adminRoutes = require("./routes/admin"); 4 | const shopRoutes = require("./routes/shop"); 5 | const PageNotFound = require("./helper/NotFound"); 6 | const bodyParser = require("body-parser"); 7 | const path = require("path"); 8 | // const mongoConnect = require("./helper/database").mongoConnect; 9 | const User = require("./models/user"); 10 | const mongoose = require("mongoose"); 11 | const mongo_DB_URI = process.env.MONGO_DB_URI; 12 | 13 | const app = express(); 14 | const PORT = 3000; 15 | // app.set("view engine", "pug"); 16 | app.set("view engine", "ejs"); 17 | app.set("views", "views"); 18 | 19 | // const rootDir = require("./helper/path"); 20 | app.use(express.static(path.join(__dirname, "public"))); 21 | app.use(bodyParser.urlencoded({ extended: false })); 22 | 23 | app.use((req, res, next) => { 24 | User.findById("65aaa79a8945687d161ef472") 25 | .then((user) => { 26 | req.user = user; 27 | next(); 28 | }) 29 | .catch((err) => { 30 | console.log(err); 31 | }); 32 | }); 33 | 34 | app.use("/admin", adminRoutes); 35 | 36 | app.use(shopRoutes); 37 | 38 | app.use(PageNotFound); 39 | 40 | mongoose 41 | .connect(mongo_DB_URI) 42 | .then((result) => { 43 | app.listen(PORT, () => { 44 | console.log("Database connected"); 45 | User.findOne().then((user) => { 46 | if (!user) { 47 | const user = new User({ 48 | name: "David", 49 | email: "david@gmail.com", 50 | cart: { 51 | items: [], 52 | }, 53 | }); 54 | user.save(); 55 | } else { 56 | console.log("User Already Exist"); 57 | } 58 | }); 59 | console.log("App is running on the port http://localhost:3000"); 60 | }); 61 | }) 62 | .catch((err) => { 63 | console.log(err); 64 | }); 65 | 66 | // mongoConnect(() => { 67 | // app.listen(PORT, () => { 68 | // console.log("App is running on the port http://localhost:3000"); 69 | // }); 70 | // }); 71 | -------------------------------------------------------------------------------- /models/cart.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | 4 | const p = path.join( 5 | path.dirname(process.mainModule.filename), 6 | "data", 7 | "cart.json" 8 | ); 9 | 10 | module.exports = class Cart { 11 | static addproduct(id, productPrice) { 12 | // Fetch the previous cart 13 | fs.readFile(p, (err, fileContent) => { 14 | let cart = { products: [], totalPrice: 0 }; 15 | if (!err) { 16 | cart = JSON.parse(fileContent); 17 | } 18 | // Analyze the cart => Find existing product 19 | const existingProductIndex = cart.products.findIndex( 20 | (prod) => prod.id === id 21 | ); 22 | const existingProduct = cart.products[existingProductIndex]; 23 | let updatedProduct; 24 | // Add new product / increase quantity 25 | if (existingProduct) { 26 | updatedProduct = { ...existingProduct }; 27 | updatedProduct.qty = updatedProduct.qty + 1; 28 | cart.products = [...cart.products]; 29 | cart.products[existingProductIndex] = updatedProduct; 30 | } else { 31 | updatedProduct = { id: id, qty: 1 }; 32 | cart.products = [...cart.products, updatedProduct]; 33 | } 34 | cart.totalPrice = cart.totalPrice + +productPrice; 35 | fs.writeFile(p, JSON.stringify(cart), (err) => { 36 | console.log(err); 37 | }); 38 | }); 39 | } 40 | 41 | static deleteProduct(id, productPrice) { 42 | fs.readFile(p, (err, fileContent) => { 43 | if (err) { 44 | return; 45 | } 46 | const updatedCart = { ...JSON.parse(fileContent) }; 47 | const product = updatedCart.products.find((x) => x.id === id); 48 | if (!product) { 49 | return; 50 | } 51 | const productQty = product.qty; 52 | updatedCart.products = updatedCart.products.filter((x) => x.id !== id); 53 | updatedCart.totalPrice = 54 | updatedCart.totalPrice - productPrice * productQty; 55 | fs.writeFile(p, JSON.stringify(updatedCart), (err) => { 56 | console.log(err); 57 | }); 58 | }); 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /models/order.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const Schema = mongoose.Schema; 4 | 5 | const orderSchema = new Schema({ 6 | products: [ 7 | { 8 | product: { type: Object, required: true }, 9 | quantity: { type: Number, required: true }, 10 | }, 11 | ], 12 | user: { 13 | name: { 14 | type: String, 15 | required: true, 16 | }, 17 | userId: { 18 | type: Schema.Types.ObjectId, 19 | required: true, 20 | ref: "User", 21 | }, 22 | }, 23 | }); 24 | 25 | module.exports = mongoose.model("Order", orderSchema); 26 | -------------------------------------------------------------------------------- /models/product.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const Schema = mongoose.Schema; 4 | 5 | const productSchema = new Schema({ 6 | title: { 7 | type: String, 8 | required: true, 9 | }, 10 | price: { 11 | type: Number, 12 | required: true, 13 | }, 14 | description: { 15 | type: String, 16 | required: true, 17 | }, 18 | imageURL: { 19 | type: String, 20 | required: true, 21 | }, 22 | userId: { 23 | type: Schema.Types.ObjectId, 24 | ref: "User", 25 | required: true, 26 | }, 27 | }); 28 | 29 | module.exports = mongoose.model("Product", productSchema); 30 | 31 | // const mongodb = require("mongodb"); 32 | // const fs = require("fs"); 33 | // const path = require("path"); 34 | // const Cart = require("./cart"); 35 | // const getDb = require("../helper/database").getDb; 36 | 37 | // const p = path.join( 38 | // path.dirname(process.mainModule.filename), 39 | // "data", 40 | // "products.json" 41 | // ); 42 | 43 | // const getProductsFromDB = (callback) => { 44 | // const db = getDb(); 45 | // return db 46 | // .collection("products") 47 | // .find({}) 48 | // .toArray() 49 | // .then((product) => { 50 | // return callback(product); 51 | // }) 52 | // .catch((err) => { 53 | // console.log(err); 54 | // }); 55 | // }; 56 | 57 | // class Product { 58 | // constructor(title, price, description, imageURL, id, userId) { 59 | // this.title = title; 60 | // this.price = price; 61 | // this.description = description; 62 | // this.imageURL = imageURL; 63 | // this._id = id ? new mongodb.ObjectId(id) : null; 64 | // this.userId = userId; 65 | // } 66 | 67 | // save() { 68 | // const db = getDb(); 69 | // var dbOp; 70 | // if (this._id) { 71 | // dbOp = db 72 | // .collection("products") 73 | // .updateOne({ _id: this._id }, { $set: this }); 74 | // } else { 75 | // dbOp = db.collection("products").insertOne(this); 76 | // } 77 | // return dbOp 78 | // .then((result) => { 79 | // console.log(result); 80 | // }) 81 | // .catch((err) => { 82 | // console.log(err); 83 | // }); 84 | // } 85 | 86 | // static getProductById(prodId) { 87 | // const db = getDb(); 88 | // return db 89 | // .collection("products") 90 | // .find({ _id: new mongodb.ObjectId(prodId) }) 91 | // .next() 92 | // .then((product) => { 93 | // return product; 94 | // }) 95 | // .catch((err) => { 96 | // console.log(err); 97 | // }); 98 | // } 99 | 100 | // static fetchAll(callback) { 101 | // getProductsFromDB(callback); 102 | // } 103 | 104 | // static deleteById(prodId) { 105 | // if (prodId) { 106 | // const db = getDb(); 107 | // return db 108 | // .collection("products") 109 | // .deleteOne({ _id: new mongodb.ObjectId(prodId) }); 110 | // } else { 111 | // return; 112 | // } 113 | // } 114 | // } 115 | 116 | // // const getProductsFromFile = (callback) => { 117 | // // fs.readFile(p, (err, fileContent) => { 118 | // // if (err) { 119 | // // callback([]); 120 | // // } else { 121 | // // callback(JSON.parse(fileContent)); 122 | // // } 123 | // // }); 124 | // // }; 125 | 126 | // // module.exports = class Product { 127 | // // constructor(id, title, imageURL, description, price) { 128 | // // this.id = id; 129 | // // this.title = title; 130 | // // this.imageURL = imageURL; 131 | // // this.description = description; 132 | // // this.price = price; 133 | // // } 134 | 135 | // // save() { 136 | // // getProductsFromFile((products) => { 137 | // // if (this.id) { 138 | // // const existingProductIndex = products.findIndex( 139 | // // (x) => x.id === this.id 140 | // // ); 141 | // // const updatedProducts = [...products]; 142 | // // updatedProducts[existingProductIndex] = this; 143 | // // fs.writeFile(p, JSON.stringify(updatedProducts), (err) => { 144 | // // console.log(err); 145 | // // }); 146 | // // } else { 147 | // // this.id = Math.random().toString(); 148 | // // products.push(this); 149 | // // fs.writeFile(p, JSON.stringify(products), (err) => { 150 | // // console.log(err); 151 | // // }); 152 | // // } 153 | // // }); 154 | // // } 155 | 156 | // // static deleteById(id) { 157 | // // getProductsFromFile((products) => { 158 | // // const product = products.find((x) => x.id === id); 159 | // // const updatedProducts = products.filter((x) => x.id !== id); 160 | // // fs.writeFile(p, JSON.stringify(updatedProducts), (err) => { 161 | // // if (!err) { 162 | // // Cart.deleteProduct(id, product.price); 163 | // // } 164 | // // }); 165 | // // }); 166 | // // } 167 | 168 | // // static fetchAll(callback) { 169 | // // getProductsFromFile(callback); 170 | // // } 171 | 172 | // // static getProductById(id, callback) { 173 | // // getProductsFromFile((products) => { 174 | // // const product = products.find((x) => x.id === id); 175 | // // callback(product); 176 | // // }); 177 | // // } 178 | // // }; 179 | 180 | // module.exports = Product; 181 | -------------------------------------------------------------------------------- /models/user.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const Schema = mongoose.Schema; 4 | 5 | const userSchema = new Schema({ 6 | name: { 7 | type: String, 8 | required: true, 9 | }, 10 | email: { 11 | type: String, 12 | required: true, 13 | }, 14 | cart: { 15 | items: [ 16 | { 17 | productId: { 18 | type: Schema.Types.ObjectId, 19 | ref: "Product", 20 | required: true, 21 | }, 22 | quantity: { type: Number, required: true }, 23 | }, 24 | ], 25 | }, 26 | }); 27 | 28 | userSchema.methods.addToCart = function (product) { 29 | const cartProductIndex = this.cart.items.findIndex((x) => { 30 | return x.productId.toString() == product._id.toString(); 31 | }); 32 | let newQuantity = 1; 33 | const updatedCartItems = [...this.cart.items]; 34 | 35 | if (cartProductIndex >= 0) { 36 | newQuantity = this.cart.items[cartProductIndex].quantity + 1; 37 | updatedCartItems[cartProductIndex].quantity = newQuantity; 38 | } else { 39 | updatedCartItems.push({ 40 | productId: product._id, 41 | quantity: newQuantity, 42 | }); 43 | } 44 | const updatedCart = { 45 | items: updatedCartItems, 46 | }; 47 | this.cart = updatedCart; 48 | return this.save(); 49 | }; 50 | 51 | userSchema.methods.deleteItemFromCart = function (productId) { 52 | const updatedCartItems = this.cart.items.filter((item) => { 53 | return item.productId.toString() !== productId.toString(); 54 | }); 55 | this.cart.items = updatedCartItems; 56 | return this.save(); 57 | }; 58 | 59 | userSchema.methods.clearCart = function () { 60 | this.cart = { items: [] }; 61 | return this.save(); 62 | }; 63 | 64 | module.exports = mongoose.model("User", userSchema); 65 | 66 | // const { getDb } = require("../helper/database"); 67 | // const mongodb = require("mongodb"); 68 | // const ObjectId = mongodb.ObjectId; 69 | 70 | // class User { 71 | // constructor(name, email, cart, id) { 72 | // this.name = name; 73 | // this.email = email; 74 | // this.cart = cart; 75 | // this._id = id; 76 | // } 77 | 78 | // save() { 79 | // const db = getDb(); 80 | // db.collection("users") 81 | // .insertOne(this) 82 | // .then((user) => { 83 | // console.log("User created"); 84 | // }) 85 | // .catch((err) => { 86 | // console.log("some error occured"); 87 | // }); 88 | // } 89 | 90 | // addToCart(product) { 91 | // const cartProductIndex = this.cart.items.findIndex((x) => { 92 | // return x.productId.toString() == product._id.toString(); 93 | // }); 94 | // let newQuantity = 1; 95 | // const updatedCartItems = [...this.cart.items]; 96 | 97 | // if (cartProductIndex >= 0) { 98 | // newQuantity = this.cart.items[cartProductIndex].quantity + 1; 99 | // updatedCartItems[cartProductIndex].quantity = newQuantity; 100 | // } else { 101 | // updatedCartItems.push({ 102 | // productId: new ObjectId(product._id), 103 | // quantity: newQuantity, 104 | // }); 105 | // } 106 | // const updatedCart = { 107 | // items: updatedCartItems, 108 | // }; 109 | // const db = getDb(); 110 | // return db 111 | // .collection("users") 112 | // .updateOne( 113 | // { _id: new ObjectId(this._id) }, 114 | // { $set: { cart: updatedCart } } 115 | // ); 116 | // } 117 | 118 | // getCart() { 119 | // const db = getDb(); 120 | // const productIds = this.cart.items.map((x) => { 121 | // return x.productId; 122 | // }); 123 | // return db 124 | // .collection("products") 125 | // .find({ _id: { $in: productIds } }) 126 | // .toArray() 127 | // .then((products) => { 128 | // return products.map((x) => { 129 | // return { 130 | // ...x, 131 | // quantity: this.cart.items.find((i) => { 132 | // return i.productId.toString() === x._id.toString(); 133 | // }).quantity, 134 | // }; 135 | // }); 136 | // }); 137 | // } 138 | 139 | // deleteItemFromCart(productId) { 140 | // const updatedCartItems = this.cart.items.filter((item) => { 141 | // return item.productId.toString() !== productId.toString(); 142 | // }); 143 | // const db = getDb(); 144 | // return db 145 | // .collection("users") 146 | // .updateOne( 147 | // { _id: new ObjectId(this._id) }, 148 | // { $set: { cart: { items: updatedCartItems } } } 149 | // ); 150 | // } 151 | 152 | // addOrder() { 153 | // const db = getDb(); 154 | // return this.getCart() 155 | // .then((products) => { 156 | // const order = { 157 | // items: products, 158 | // user: { 159 | // _id: new ObjectId(this._id), 160 | // name: this.name, 161 | // }, 162 | // }; 163 | // return db.collection("orders").insertOne(order); 164 | // }) 165 | // .then((result) => { 166 | // this.cart = { items: [] }; 167 | // return db 168 | // .collection("users") 169 | // .updateOne( 170 | // { _id: new ObjectId(this._id) }, 171 | // { $set: { cart: { items: [] } } } 172 | // ); 173 | // }); 174 | // } 175 | 176 | // getOrders() { 177 | // const db = getDb(); 178 | // return db 179 | // .collection("orders") 180 | // .find({ "user._id": new ObjectId(this._id) }) 181 | // .toArray(); 182 | // } 183 | 184 | // static findById(userId) { 185 | // const db = getDb(); 186 | // return db 187 | // .collection("users") 188 | // .findOne({ _id: new ObjectId(userId) }) 189 | // .then((user) => { 190 | // console.log("User Found"); 191 | // console.log(user); 192 | // return user; 193 | // }) 194 | // .catch((err) => { 195 | // console.log("Error Occured"); 196 | // console.log(err); 197 | // }); 198 | // } 199 | // } 200 | 201 | // module.exports = User; 202 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopingkaro", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "shopingkaro", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "body-parser": "^1.20.2", 13 | "dotenv": "^16.3.2", 14 | "ejs": "^3.1.9", 15 | "express": "^4.18.2", 16 | "express-handlebars": "^7.1.2", 17 | "mongodb": "^6.3.0", 18 | "mongoose": "^8.1.0", 19 | "pug": "^3.0.2" 20 | }, 21 | "devDependencies": { 22 | "nodemon": "^3.0.1" 23 | } 24 | }, 25 | "node_modules/@babel/helper-string-parser": { 26 | "version": "7.23.4", 27 | "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", 28 | "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", 29 | "engines": { 30 | "node": ">=6.9.0" 31 | } 32 | }, 33 | "node_modules/@babel/helper-validator-identifier": { 34 | "version": "7.22.20", 35 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", 36 | "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", 37 | "engines": { 38 | "node": ">=6.9.0" 39 | } 40 | }, 41 | "node_modules/@babel/parser": { 42 | "version": "7.23.6", 43 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", 44 | "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", 45 | "bin": { 46 | "parser": "bin/babel-parser.js" 47 | }, 48 | "engines": { 49 | "node": ">=6.0.0" 50 | } 51 | }, 52 | "node_modules/@babel/types": { 53 | "version": "7.23.6", 54 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", 55 | "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", 56 | "dependencies": { 57 | "@babel/helper-string-parser": "^7.23.4", 58 | "@babel/helper-validator-identifier": "^7.22.20", 59 | "to-fast-properties": "^2.0.0" 60 | }, 61 | "engines": { 62 | "node": ">=6.9.0" 63 | } 64 | }, 65 | "node_modules/@isaacs/cliui": { 66 | "version": "8.0.2", 67 | "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", 68 | "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", 69 | "dependencies": { 70 | "string-width": "^5.1.2", 71 | "string-width-cjs": "npm:string-width@^4.2.0", 72 | "strip-ansi": "^7.0.1", 73 | "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", 74 | "wrap-ansi": "^8.1.0", 75 | "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" 76 | }, 77 | "engines": { 78 | "node": ">=12" 79 | } 80 | }, 81 | "node_modules/@mongodb-js/saslprep": { 82 | "version": "1.1.1", 83 | "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.1.tgz", 84 | "integrity": "sha512-t7c5K033joZZMspnHg/gWPE4kandgc2OxE74aYOtGKfgB9VPuVJPix0H6fhmm2erj5PBJ21mqcx34lpIGtUCsQ==", 85 | "dependencies": { 86 | "sparse-bitfield": "^3.0.3" 87 | } 88 | }, 89 | "node_modules/@pkgjs/parseargs": { 90 | "version": "0.11.0", 91 | "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", 92 | "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", 93 | "optional": true, 94 | "engines": { 95 | "node": ">=14" 96 | } 97 | }, 98 | "node_modules/@types/webidl-conversions": { 99 | "version": "7.0.3", 100 | "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", 101 | "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" 102 | }, 103 | "node_modules/@types/whatwg-url": { 104 | "version": "11.0.3", 105 | "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.3.tgz", 106 | "integrity": "sha512-z1ELvMijRL1QmU7QuzDkeYXSF2+dXI0ITKoQsIoVKcNBOiK5RMmWy+pYYxJTHFt8vkpZe7UsvRErQwcxZkjoUw==", 107 | "dependencies": { 108 | "@types/webidl-conversions": "*" 109 | } 110 | }, 111 | "node_modules/abbrev": { 112 | "version": "1.1.1", 113 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 114 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", 115 | "dev": true 116 | }, 117 | "node_modules/accepts": { 118 | "version": "1.3.8", 119 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 120 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 121 | "dependencies": { 122 | "mime-types": "~2.1.34", 123 | "negotiator": "0.6.3" 124 | }, 125 | "engines": { 126 | "node": ">= 0.6" 127 | } 128 | }, 129 | "node_modules/acorn": { 130 | "version": "7.4.1", 131 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", 132 | "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", 133 | "bin": { 134 | "acorn": "bin/acorn" 135 | }, 136 | "engines": { 137 | "node": ">=0.4.0" 138 | } 139 | }, 140 | "node_modules/ansi-regex": { 141 | "version": "6.0.1", 142 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", 143 | "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", 144 | "engines": { 145 | "node": ">=12" 146 | }, 147 | "funding": { 148 | "url": "https://github.com/chalk/ansi-regex?sponsor=1" 149 | } 150 | }, 151 | "node_modules/ansi-styles": { 152 | "version": "4.3.0", 153 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 154 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 155 | "dependencies": { 156 | "color-convert": "^2.0.1" 157 | }, 158 | "engines": { 159 | "node": ">=8" 160 | }, 161 | "funding": { 162 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 163 | } 164 | }, 165 | "node_modules/anymatch": { 166 | "version": "3.1.3", 167 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", 168 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", 169 | "dev": true, 170 | "dependencies": { 171 | "normalize-path": "^3.0.0", 172 | "picomatch": "^2.0.4" 173 | }, 174 | "engines": { 175 | "node": ">= 8" 176 | } 177 | }, 178 | "node_modules/array-flatten": { 179 | "version": "1.1.1", 180 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 181 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 182 | }, 183 | "node_modules/asap": { 184 | "version": "2.0.6", 185 | "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", 186 | "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" 187 | }, 188 | "node_modules/assert-never": { 189 | "version": "1.2.1", 190 | "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz", 191 | "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==" 192 | }, 193 | "node_modules/async": { 194 | "version": "3.2.5", 195 | "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", 196 | "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" 197 | }, 198 | "node_modules/babel-walk": { 199 | "version": "3.0.0-canary-5", 200 | "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", 201 | "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", 202 | "dependencies": { 203 | "@babel/types": "^7.9.6" 204 | }, 205 | "engines": { 206 | "node": ">= 10.0.0" 207 | } 208 | }, 209 | "node_modules/balanced-match": { 210 | "version": "1.0.2", 211 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 212 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 213 | }, 214 | "node_modules/binary-extensions": { 215 | "version": "2.2.0", 216 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", 217 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", 218 | "dev": true, 219 | "engines": { 220 | "node": ">=8" 221 | } 222 | }, 223 | "node_modules/body-parser": { 224 | "version": "1.20.2", 225 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", 226 | "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", 227 | "dependencies": { 228 | "bytes": "3.1.2", 229 | "content-type": "~1.0.5", 230 | "debug": "2.6.9", 231 | "depd": "2.0.0", 232 | "destroy": "1.2.0", 233 | "http-errors": "2.0.0", 234 | "iconv-lite": "0.4.24", 235 | "on-finished": "2.4.1", 236 | "qs": "6.11.0", 237 | "raw-body": "2.5.2", 238 | "type-is": "~1.6.18", 239 | "unpipe": "1.0.0" 240 | }, 241 | "engines": { 242 | "node": ">= 0.8", 243 | "npm": "1.2.8000 || >= 1.4.16" 244 | } 245 | }, 246 | "node_modules/body-parser/node_modules/debug": { 247 | "version": "2.6.9", 248 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 249 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 250 | "dependencies": { 251 | "ms": "2.0.0" 252 | } 253 | }, 254 | "node_modules/body-parser/node_modules/ms": { 255 | "version": "2.0.0", 256 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 257 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 258 | }, 259 | "node_modules/brace-expansion": { 260 | "version": "1.1.11", 261 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 262 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 263 | "dependencies": { 264 | "balanced-match": "^1.0.0", 265 | "concat-map": "0.0.1" 266 | } 267 | }, 268 | "node_modules/braces": { 269 | "version": "3.0.2", 270 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 271 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 272 | "dev": true, 273 | "dependencies": { 274 | "fill-range": "^7.0.1" 275 | }, 276 | "engines": { 277 | "node": ">=8" 278 | } 279 | }, 280 | "node_modules/bson": { 281 | "version": "6.2.0", 282 | "resolved": "https://registry.npmjs.org/bson/-/bson-6.2.0.tgz", 283 | "integrity": "sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q==", 284 | "engines": { 285 | "node": ">=16.20.1" 286 | } 287 | }, 288 | "node_modules/bytes": { 289 | "version": "3.1.2", 290 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 291 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 292 | "engines": { 293 | "node": ">= 0.8" 294 | } 295 | }, 296 | "node_modules/call-bind": { 297 | "version": "1.0.2", 298 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", 299 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", 300 | "dependencies": { 301 | "function-bind": "^1.1.1", 302 | "get-intrinsic": "^1.0.2" 303 | }, 304 | "funding": { 305 | "url": "https://github.com/sponsors/ljharb" 306 | } 307 | }, 308 | "node_modules/chalk": { 309 | "version": "4.1.2", 310 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 311 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 312 | "dependencies": { 313 | "ansi-styles": "^4.1.0", 314 | "supports-color": "^7.1.0" 315 | }, 316 | "engines": { 317 | "node": ">=10" 318 | }, 319 | "funding": { 320 | "url": "https://github.com/chalk/chalk?sponsor=1" 321 | } 322 | }, 323 | "node_modules/chalk/node_modules/has-flag": { 324 | "version": "4.0.0", 325 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 326 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 327 | "engines": { 328 | "node": ">=8" 329 | } 330 | }, 331 | "node_modules/chalk/node_modules/supports-color": { 332 | "version": "7.2.0", 333 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 334 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 335 | "dependencies": { 336 | "has-flag": "^4.0.0" 337 | }, 338 | "engines": { 339 | "node": ">=8" 340 | } 341 | }, 342 | "node_modules/character-parser": { 343 | "version": "2.2.0", 344 | "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", 345 | "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", 346 | "dependencies": { 347 | "is-regex": "^1.0.3" 348 | } 349 | }, 350 | "node_modules/chokidar": { 351 | "version": "3.5.3", 352 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", 353 | "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", 354 | "dev": true, 355 | "funding": [ 356 | { 357 | "type": "individual", 358 | "url": "https://paulmillr.com/funding/" 359 | } 360 | ], 361 | "dependencies": { 362 | "anymatch": "~3.1.2", 363 | "braces": "~3.0.2", 364 | "glob-parent": "~5.1.2", 365 | "is-binary-path": "~2.1.0", 366 | "is-glob": "~4.0.1", 367 | "normalize-path": "~3.0.0", 368 | "readdirp": "~3.6.0" 369 | }, 370 | "engines": { 371 | "node": ">= 8.10.0" 372 | }, 373 | "optionalDependencies": { 374 | "fsevents": "~2.3.2" 375 | } 376 | }, 377 | "node_modules/color-convert": { 378 | "version": "2.0.1", 379 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 380 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 381 | "dependencies": { 382 | "color-name": "~1.1.4" 383 | }, 384 | "engines": { 385 | "node": ">=7.0.0" 386 | } 387 | }, 388 | "node_modules/color-name": { 389 | "version": "1.1.4", 390 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 391 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 392 | }, 393 | "node_modules/concat-map": { 394 | "version": "0.0.1", 395 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 396 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" 397 | }, 398 | "node_modules/constantinople": { 399 | "version": "4.0.1", 400 | "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", 401 | "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", 402 | "dependencies": { 403 | "@babel/parser": "^7.6.0", 404 | "@babel/types": "^7.6.1" 405 | } 406 | }, 407 | "node_modules/content-disposition": { 408 | "version": "0.5.4", 409 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 410 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 411 | "dependencies": { 412 | "safe-buffer": "5.2.1" 413 | }, 414 | "engines": { 415 | "node": ">= 0.6" 416 | } 417 | }, 418 | "node_modules/content-type": { 419 | "version": "1.0.5", 420 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 421 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 422 | "engines": { 423 | "node": ">= 0.6" 424 | } 425 | }, 426 | "node_modules/cookie": { 427 | "version": "0.5.0", 428 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", 429 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", 430 | "engines": { 431 | "node": ">= 0.6" 432 | } 433 | }, 434 | "node_modules/cookie-signature": { 435 | "version": "1.0.6", 436 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 437 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 438 | }, 439 | "node_modules/cross-spawn": { 440 | "version": "7.0.3", 441 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", 442 | "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", 443 | "dependencies": { 444 | "path-key": "^3.1.0", 445 | "shebang-command": "^2.0.0", 446 | "which": "^2.0.1" 447 | }, 448 | "engines": { 449 | "node": ">= 8" 450 | } 451 | }, 452 | "node_modules/debug": { 453 | "version": "3.2.7", 454 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", 455 | "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", 456 | "dev": true, 457 | "dependencies": { 458 | "ms": "^2.1.1" 459 | } 460 | }, 461 | "node_modules/depd": { 462 | "version": "2.0.0", 463 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 464 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 465 | "engines": { 466 | "node": ">= 0.8" 467 | } 468 | }, 469 | "node_modules/destroy": { 470 | "version": "1.2.0", 471 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 472 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 473 | "engines": { 474 | "node": ">= 0.8", 475 | "npm": "1.2.8000 || >= 1.4.16" 476 | } 477 | }, 478 | "node_modules/doctypes": { 479 | "version": "1.1.0", 480 | "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", 481 | "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==" 482 | }, 483 | "node_modules/dotenv": { 484 | "version": "16.3.2", 485 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.2.tgz", 486 | "integrity": "sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ==", 487 | "engines": { 488 | "node": ">=12" 489 | }, 490 | "funding": { 491 | "url": "https://github.com/motdotla/dotenv?sponsor=1" 492 | } 493 | }, 494 | "node_modules/eastasianwidth": { 495 | "version": "0.2.0", 496 | "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", 497 | "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" 498 | }, 499 | "node_modules/ee-first": { 500 | "version": "1.1.1", 501 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 502 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 503 | }, 504 | "node_modules/ejs": { 505 | "version": "3.1.9", 506 | "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", 507 | "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", 508 | "dependencies": { 509 | "jake": "^10.8.5" 510 | }, 511 | "bin": { 512 | "ejs": "bin/cli.js" 513 | }, 514 | "engines": { 515 | "node": ">=0.10.0" 516 | } 517 | }, 518 | "node_modules/emoji-regex": { 519 | "version": "9.2.2", 520 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", 521 | "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" 522 | }, 523 | "node_modules/encodeurl": { 524 | "version": "1.0.2", 525 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 526 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 527 | "engines": { 528 | "node": ">= 0.8" 529 | } 530 | }, 531 | "node_modules/escape-html": { 532 | "version": "1.0.3", 533 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 534 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 535 | }, 536 | "node_modules/etag": { 537 | "version": "1.8.1", 538 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 539 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 540 | "engines": { 541 | "node": ">= 0.6" 542 | } 543 | }, 544 | "node_modules/express": { 545 | "version": "4.18.2", 546 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", 547 | "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", 548 | "dependencies": { 549 | "accepts": "~1.3.8", 550 | "array-flatten": "1.1.1", 551 | "body-parser": "1.20.1", 552 | "content-disposition": "0.5.4", 553 | "content-type": "~1.0.4", 554 | "cookie": "0.5.0", 555 | "cookie-signature": "1.0.6", 556 | "debug": "2.6.9", 557 | "depd": "2.0.0", 558 | "encodeurl": "~1.0.2", 559 | "escape-html": "~1.0.3", 560 | "etag": "~1.8.1", 561 | "finalhandler": "1.2.0", 562 | "fresh": "0.5.2", 563 | "http-errors": "2.0.0", 564 | "merge-descriptors": "1.0.1", 565 | "methods": "~1.1.2", 566 | "on-finished": "2.4.1", 567 | "parseurl": "~1.3.3", 568 | "path-to-regexp": "0.1.7", 569 | "proxy-addr": "~2.0.7", 570 | "qs": "6.11.0", 571 | "range-parser": "~1.2.1", 572 | "safe-buffer": "5.2.1", 573 | "send": "0.18.0", 574 | "serve-static": "1.15.0", 575 | "setprototypeof": "1.2.0", 576 | "statuses": "2.0.1", 577 | "type-is": "~1.6.18", 578 | "utils-merge": "1.0.1", 579 | "vary": "~1.1.2" 580 | }, 581 | "engines": { 582 | "node": ">= 0.10.0" 583 | } 584 | }, 585 | "node_modules/express-handlebars": { 586 | "version": "7.1.2", 587 | "resolved": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-7.1.2.tgz", 588 | "integrity": "sha512-ss9d3mBChOLTEtyfzXCsxlItUxpgS3i4cb/F70G6Q5ohQzmD12XB4x/Y9U6YboeeYBJZt7WQ5yUNu7ZSQ/EGyQ==", 589 | "dependencies": { 590 | "glob": "^10.3.3", 591 | "graceful-fs": "^4.2.11", 592 | "handlebars": "^4.7.8" 593 | }, 594 | "engines": { 595 | "node": ">=v16" 596 | } 597 | }, 598 | "node_modules/express/node_modules/body-parser": { 599 | "version": "1.20.1", 600 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", 601 | "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", 602 | "dependencies": { 603 | "bytes": "3.1.2", 604 | "content-type": "~1.0.4", 605 | "debug": "2.6.9", 606 | "depd": "2.0.0", 607 | "destroy": "1.2.0", 608 | "http-errors": "2.0.0", 609 | "iconv-lite": "0.4.24", 610 | "on-finished": "2.4.1", 611 | "qs": "6.11.0", 612 | "raw-body": "2.5.1", 613 | "type-is": "~1.6.18", 614 | "unpipe": "1.0.0" 615 | }, 616 | "engines": { 617 | "node": ">= 0.8", 618 | "npm": "1.2.8000 || >= 1.4.16" 619 | } 620 | }, 621 | "node_modules/express/node_modules/debug": { 622 | "version": "2.6.9", 623 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 624 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 625 | "dependencies": { 626 | "ms": "2.0.0" 627 | } 628 | }, 629 | "node_modules/express/node_modules/ms": { 630 | "version": "2.0.0", 631 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 632 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 633 | }, 634 | "node_modules/express/node_modules/raw-body": { 635 | "version": "2.5.1", 636 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", 637 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", 638 | "dependencies": { 639 | "bytes": "3.1.2", 640 | "http-errors": "2.0.0", 641 | "iconv-lite": "0.4.24", 642 | "unpipe": "1.0.0" 643 | }, 644 | "engines": { 645 | "node": ">= 0.8" 646 | } 647 | }, 648 | "node_modules/filelist": { 649 | "version": "1.0.4", 650 | "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", 651 | "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", 652 | "dependencies": { 653 | "minimatch": "^5.0.1" 654 | } 655 | }, 656 | "node_modules/filelist/node_modules/brace-expansion": { 657 | "version": "2.0.1", 658 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 659 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 660 | "dependencies": { 661 | "balanced-match": "^1.0.0" 662 | } 663 | }, 664 | "node_modules/filelist/node_modules/minimatch": { 665 | "version": "5.1.6", 666 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", 667 | "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", 668 | "dependencies": { 669 | "brace-expansion": "^2.0.1" 670 | }, 671 | "engines": { 672 | "node": ">=10" 673 | } 674 | }, 675 | "node_modules/fill-range": { 676 | "version": "7.0.1", 677 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 678 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 679 | "dev": true, 680 | "dependencies": { 681 | "to-regex-range": "^5.0.1" 682 | }, 683 | "engines": { 684 | "node": ">=8" 685 | } 686 | }, 687 | "node_modules/finalhandler": { 688 | "version": "1.2.0", 689 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", 690 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", 691 | "dependencies": { 692 | "debug": "2.6.9", 693 | "encodeurl": "~1.0.2", 694 | "escape-html": "~1.0.3", 695 | "on-finished": "2.4.1", 696 | "parseurl": "~1.3.3", 697 | "statuses": "2.0.1", 698 | "unpipe": "~1.0.0" 699 | }, 700 | "engines": { 701 | "node": ">= 0.8" 702 | } 703 | }, 704 | "node_modules/finalhandler/node_modules/debug": { 705 | "version": "2.6.9", 706 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 707 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 708 | "dependencies": { 709 | "ms": "2.0.0" 710 | } 711 | }, 712 | "node_modules/finalhandler/node_modules/ms": { 713 | "version": "2.0.0", 714 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 715 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 716 | }, 717 | "node_modules/foreground-child": { 718 | "version": "3.1.1", 719 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", 720 | "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", 721 | "dependencies": { 722 | "cross-spawn": "^7.0.0", 723 | "signal-exit": "^4.0.1" 724 | }, 725 | "engines": { 726 | "node": ">=14" 727 | }, 728 | "funding": { 729 | "url": "https://github.com/sponsors/isaacs" 730 | } 731 | }, 732 | "node_modules/forwarded": { 733 | "version": "0.2.0", 734 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 735 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 736 | "engines": { 737 | "node": ">= 0.6" 738 | } 739 | }, 740 | "node_modules/fresh": { 741 | "version": "0.5.2", 742 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 743 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 744 | "engines": { 745 | "node": ">= 0.6" 746 | } 747 | }, 748 | "node_modules/fsevents": { 749 | "version": "2.3.3", 750 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 751 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 752 | "dev": true, 753 | "hasInstallScript": true, 754 | "optional": true, 755 | "os": [ 756 | "darwin" 757 | ], 758 | "engines": { 759 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 760 | } 761 | }, 762 | "node_modules/function-bind": { 763 | "version": "1.1.2", 764 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 765 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 766 | "funding": { 767 | "url": "https://github.com/sponsors/ljharb" 768 | } 769 | }, 770 | "node_modules/get-intrinsic": { 771 | "version": "1.2.1", 772 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", 773 | "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", 774 | "dependencies": { 775 | "function-bind": "^1.1.1", 776 | "has": "^1.0.3", 777 | "has-proto": "^1.0.1", 778 | "has-symbols": "^1.0.3" 779 | }, 780 | "funding": { 781 | "url": "https://github.com/sponsors/ljharb" 782 | } 783 | }, 784 | "node_modules/glob": { 785 | "version": "10.3.10", 786 | "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", 787 | "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", 788 | "dependencies": { 789 | "foreground-child": "^3.1.0", 790 | "jackspeak": "^2.3.5", 791 | "minimatch": "^9.0.1", 792 | "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", 793 | "path-scurry": "^1.10.1" 794 | }, 795 | "bin": { 796 | "glob": "dist/esm/bin.mjs" 797 | }, 798 | "engines": { 799 | "node": ">=16 || 14 >=14.17" 800 | }, 801 | "funding": { 802 | "url": "https://github.com/sponsors/isaacs" 803 | } 804 | }, 805 | "node_modules/glob-parent": { 806 | "version": "5.1.2", 807 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 808 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 809 | "dev": true, 810 | "dependencies": { 811 | "is-glob": "^4.0.1" 812 | }, 813 | "engines": { 814 | "node": ">= 6" 815 | } 816 | }, 817 | "node_modules/glob/node_modules/brace-expansion": { 818 | "version": "2.0.1", 819 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 820 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 821 | "dependencies": { 822 | "balanced-match": "^1.0.0" 823 | } 824 | }, 825 | "node_modules/glob/node_modules/minimatch": { 826 | "version": "9.0.3", 827 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", 828 | "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", 829 | "dependencies": { 830 | "brace-expansion": "^2.0.1" 831 | }, 832 | "engines": { 833 | "node": ">=16 || 14 >=14.17" 834 | }, 835 | "funding": { 836 | "url": "https://github.com/sponsors/isaacs" 837 | } 838 | }, 839 | "node_modules/graceful-fs": { 840 | "version": "4.2.11", 841 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 842 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" 843 | }, 844 | "node_modules/handlebars": { 845 | "version": "4.7.8", 846 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", 847 | "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", 848 | "dependencies": { 849 | "minimist": "^1.2.5", 850 | "neo-async": "^2.6.2", 851 | "source-map": "^0.6.1", 852 | "wordwrap": "^1.0.0" 853 | }, 854 | "bin": { 855 | "handlebars": "bin/handlebars" 856 | }, 857 | "engines": { 858 | "node": ">=0.4.7" 859 | }, 860 | "optionalDependencies": { 861 | "uglify-js": "^3.1.4" 862 | } 863 | }, 864 | "node_modules/has": { 865 | "version": "1.0.4", 866 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", 867 | "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", 868 | "engines": { 869 | "node": ">= 0.4.0" 870 | } 871 | }, 872 | "node_modules/has-flag": { 873 | "version": "3.0.0", 874 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 875 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", 876 | "dev": true, 877 | "engines": { 878 | "node": ">=4" 879 | } 880 | }, 881 | "node_modules/has-proto": { 882 | "version": "1.0.1", 883 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", 884 | "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", 885 | "engines": { 886 | "node": ">= 0.4" 887 | }, 888 | "funding": { 889 | "url": "https://github.com/sponsors/ljharb" 890 | } 891 | }, 892 | "node_modules/has-symbols": { 893 | "version": "1.0.3", 894 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 895 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 896 | "engines": { 897 | "node": ">= 0.4" 898 | }, 899 | "funding": { 900 | "url": "https://github.com/sponsors/ljharb" 901 | } 902 | }, 903 | "node_modules/has-tostringtag": { 904 | "version": "1.0.0", 905 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", 906 | "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", 907 | "dependencies": { 908 | "has-symbols": "^1.0.2" 909 | }, 910 | "engines": { 911 | "node": ">= 0.4" 912 | }, 913 | "funding": { 914 | "url": "https://github.com/sponsors/ljharb" 915 | } 916 | }, 917 | "node_modules/hasown": { 918 | "version": "2.0.0", 919 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", 920 | "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", 921 | "dependencies": { 922 | "function-bind": "^1.1.2" 923 | }, 924 | "engines": { 925 | "node": ">= 0.4" 926 | } 927 | }, 928 | "node_modules/http-errors": { 929 | "version": "2.0.0", 930 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 931 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 932 | "dependencies": { 933 | "depd": "2.0.0", 934 | "inherits": "2.0.4", 935 | "setprototypeof": "1.2.0", 936 | "statuses": "2.0.1", 937 | "toidentifier": "1.0.1" 938 | }, 939 | "engines": { 940 | "node": ">= 0.8" 941 | } 942 | }, 943 | "node_modules/iconv-lite": { 944 | "version": "0.4.24", 945 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 946 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 947 | "dependencies": { 948 | "safer-buffer": ">= 2.1.2 < 3" 949 | }, 950 | "engines": { 951 | "node": ">=0.10.0" 952 | } 953 | }, 954 | "node_modules/ignore-by-default": { 955 | "version": "1.0.1", 956 | "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", 957 | "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", 958 | "dev": true 959 | }, 960 | "node_modules/inherits": { 961 | "version": "2.0.4", 962 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 963 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 964 | }, 965 | "node_modules/ipaddr.js": { 966 | "version": "1.9.1", 967 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 968 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 969 | "engines": { 970 | "node": ">= 0.10" 971 | } 972 | }, 973 | "node_modules/is-binary-path": { 974 | "version": "2.1.0", 975 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 976 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 977 | "dev": true, 978 | "dependencies": { 979 | "binary-extensions": "^2.0.0" 980 | }, 981 | "engines": { 982 | "node": ">=8" 983 | } 984 | }, 985 | "node_modules/is-core-module": { 986 | "version": "2.13.1", 987 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", 988 | "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", 989 | "dependencies": { 990 | "hasown": "^2.0.0" 991 | }, 992 | "funding": { 993 | "url": "https://github.com/sponsors/ljharb" 994 | } 995 | }, 996 | "node_modules/is-expression": { 997 | "version": "4.0.0", 998 | "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", 999 | "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", 1000 | "dependencies": { 1001 | "acorn": "^7.1.1", 1002 | "object-assign": "^4.1.1" 1003 | } 1004 | }, 1005 | "node_modules/is-extglob": { 1006 | "version": "2.1.1", 1007 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1008 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 1009 | "dev": true, 1010 | "engines": { 1011 | "node": ">=0.10.0" 1012 | } 1013 | }, 1014 | "node_modules/is-fullwidth-code-point": { 1015 | "version": "3.0.0", 1016 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 1017 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 1018 | "engines": { 1019 | "node": ">=8" 1020 | } 1021 | }, 1022 | "node_modules/is-glob": { 1023 | "version": "4.0.3", 1024 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 1025 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 1026 | "dev": true, 1027 | "dependencies": { 1028 | "is-extglob": "^2.1.1" 1029 | }, 1030 | "engines": { 1031 | "node": ">=0.10.0" 1032 | } 1033 | }, 1034 | "node_modules/is-number": { 1035 | "version": "7.0.0", 1036 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1037 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1038 | "dev": true, 1039 | "engines": { 1040 | "node": ">=0.12.0" 1041 | } 1042 | }, 1043 | "node_modules/is-promise": { 1044 | "version": "2.2.2", 1045 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", 1046 | "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" 1047 | }, 1048 | "node_modules/is-regex": { 1049 | "version": "1.1.4", 1050 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", 1051 | "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", 1052 | "dependencies": { 1053 | "call-bind": "^1.0.2", 1054 | "has-tostringtag": "^1.0.0" 1055 | }, 1056 | "engines": { 1057 | "node": ">= 0.4" 1058 | }, 1059 | "funding": { 1060 | "url": "https://github.com/sponsors/ljharb" 1061 | } 1062 | }, 1063 | "node_modules/isexe": { 1064 | "version": "2.0.0", 1065 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1066 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" 1067 | }, 1068 | "node_modules/jackspeak": { 1069 | "version": "2.3.6", 1070 | "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", 1071 | "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", 1072 | "dependencies": { 1073 | "@isaacs/cliui": "^8.0.2" 1074 | }, 1075 | "engines": { 1076 | "node": ">=14" 1077 | }, 1078 | "funding": { 1079 | "url": "https://github.com/sponsors/isaacs" 1080 | }, 1081 | "optionalDependencies": { 1082 | "@pkgjs/parseargs": "^0.11.0" 1083 | } 1084 | }, 1085 | "node_modules/jake": { 1086 | "version": "10.8.7", 1087 | "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", 1088 | "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", 1089 | "dependencies": { 1090 | "async": "^3.2.3", 1091 | "chalk": "^4.0.2", 1092 | "filelist": "^1.0.4", 1093 | "minimatch": "^3.1.2" 1094 | }, 1095 | "bin": { 1096 | "jake": "bin/cli.js" 1097 | }, 1098 | "engines": { 1099 | "node": ">=10" 1100 | } 1101 | }, 1102 | "node_modules/js-stringify": { 1103 | "version": "1.0.2", 1104 | "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", 1105 | "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==" 1106 | }, 1107 | "node_modules/jstransformer": { 1108 | "version": "1.0.0", 1109 | "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", 1110 | "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", 1111 | "dependencies": { 1112 | "is-promise": "^2.0.0", 1113 | "promise": "^7.0.1" 1114 | } 1115 | }, 1116 | "node_modules/kareem": { 1117 | "version": "2.5.1", 1118 | "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", 1119 | "integrity": "sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA==", 1120 | "engines": { 1121 | "node": ">=12.0.0" 1122 | } 1123 | }, 1124 | "node_modules/lru-cache": { 1125 | "version": "6.0.0", 1126 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", 1127 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", 1128 | "dev": true, 1129 | "dependencies": { 1130 | "yallist": "^4.0.0" 1131 | }, 1132 | "engines": { 1133 | "node": ">=10" 1134 | } 1135 | }, 1136 | "node_modules/media-typer": { 1137 | "version": "0.3.0", 1138 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 1139 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 1140 | "engines": { 1141 | "node": ">= 0.6" 1142 | } 1143 | }, 1144 | "node_modules/memory-pager": { 1145 | "version": "1.5.0", 1146 | "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", 1147 | "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" 1148 | }, 1149 | "node_modules/merge-descriptors": { 1150 | "version": "1.0.1", 1151 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 1152 | "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" 1153 | }, 1154 | "node_modules/methods": { 1155 | "version": "1.1.2", 1156 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1157 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 1158 | "engines": { 1159 | "node": ">= 0.6" 1160 | } 1161 | }, 1162 | "node_modules/mime": { 1163 | "version": "1.6.0", 1164 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 1165 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 1166 | "bin": { 1167 | "mime": "cli.js" 1168 | }, 1169 | "engines": { 1170 | "node": ">=4" 1171 | } 1172 | }, 1173 | "node_modules/mime-db": { 1174 | "version": "1.52.0", 1175 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 1176 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 1177 | "engines": { 1178 | "node": ">= 0.6" 1179 | } 1180 | }, 1181 | "node_modules/mime-types": { 1182 | "version": "2.1.35", 1183 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 1184 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1185 | "dependencies": { 1186 | "mime-db": "1.52.0" 1187 | }, 1188 | "engines": { 1189 | "node": ">= 0.6" 1190 | } 1191 | }, 1192 | "node_modules/minimatch": { 1193 | "version": "3.1.2", 1194 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1195 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1196 | "dependencies": { 1197 | "brace-expansion": "^1.1.7" 1198 | }, 1199 | "engines": { 1200 | "node": "*" 1201 | } 1202 | }, 1203 | "node_modules/minimist": { 1204 | "version": "1.2.8", 1205 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 1206 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 1207 | "funding": { 1208 | "url": "https://github.com/sponsors/ljharb" 1209 | } 1210 | }, 1211 | "node_modules/minipass": { 1212 | "version": "7.0.4", 1213 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", 1214 | "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", 1215 | "engines": { 1216 | "node": ">=16 || 14 >=14.17" 1217 | } 1218 | }, 1219 | "node_modules/mongodb": { 1220 | "version": "6.3.0", 1221 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.3.0.tgz", 1222 | "integrity": "sha512-tt0KuGjGtLUhLoU263+xvQmPHEGTw5LbcNC73EoFRYgSHwZt5tsoJC110hDyO1kjQzpgNrpdcSza9PknWN4LrA==", 1223 | "dependencies": { 1224 | "@mongodb-js/saslprep": "^1.1.0", 1225 | "bson": "^6.2.0", 1226 | "mongodb-connection-string-url": "^3.0.0" 1227 | }, 1228 | "engines": { 1229 | "node": ">=16.20.1" 1230 | }, 1231 | "peerDependencies": { 1232 | "@aws-sdk/credential-providers": "^3.188.0", 1233 | "@mongodb-js/zstd": "^1.1.0", 1234 | "gcp-metadata": "^5.2.0", 1235 | "kerberos": "^2.0.1", 1236 | "mongodb-client-encryption": ">=6.0.0 <7", 1237 | "snappy": "^7.2.2", 1238 | "socks": "^2.7.1" 1239 | }, 1240 | "peerDependenciesMeta": { 1241 | "@aws-sdk/credential-providers": { 1242 | "optional": true 1243 | }, 1244 | "@mongodb-js/zstd": { 1245 | "optional": true 1246 | }, 1247 | "gcp-metadata": { 1248 | "optional": true 1249 | }, 1250 | "kerberos": { 1251 | "optional": true 1252 | }, 1253 | "mongodb-client-encryption": { 1254 | "optional": true 1255 | }, 1256 | "snappy": { 1257 | "optional": true 1258 | }, 1259 | "socks": { 1260 | "optional": true 1261 | } 1262 | } 1263 | }, 1264 | "node_modules/mongodb-connection-string-url": { 1265 | "version": "3.0.0", 1266 | "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.0.tgz", 1267 | "integrity": "sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==", 1268 | "dependencies": { 1269 | "@types/whatwg-url": "^11.0.2", 1270 | "whatwg-url": "^13.0.0" 1271 | } 1272 | }, 1273 | "node_modules/mongoose": { 1274 | "version": "8.1.0", 1275 | "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.1.0.tgz", 1276 | "integrity": "sha512-kOA4Xnq2goqNpN9EmYElGNWfxA9H80fxcr7UdJKWi3UMflza0R7wpTihCpM67dE/0MNFljoa0sjQtlXVkkySAQ==", 1277 | "dependencies": { 1278 | "bson": "^6.2.0", 1279 | "kareem": "2.5.1", 1280 | "mongodb": "6.3.0", 1281 | "mpath": "0.9.0", 1282 | "mquery": "5.0.0", 1283 | "ms": "2.1.3", 1284 | "sift": "16.0.1" 1285 | }, 1286 | "engines": { 1287 | "node": ">=16.20.1" 1288 | }, 1289 | "funding": { 1290 | "type": "opencollective", 1291 | "url": "https://opencollective.com/mongoose" 1292 | } 1293 | }, 1294 | "node_modules/mpath": { 1295 | "version": "0.9.0", 1296 | "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", 1297 | "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", 1298 | "engines": { 1299 | "node": ">=4.0.0" 1300 | } 1301 | }, 1302 | "node_modules/mquery": { 1303 | "version": "5.0.0", 1304 | "resolved": "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz", 1305 | "integrity": "sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg==", 1306 | "dependencies": { 1307 | "debug": "4.x" 1308 | }, 1309 | "engines": { 1310 | "node": ">=14.0.0" 1311 | } 1312 | }, 1313 | "node_modules/mquery/node_modules/debug": { 1314 | "version": "4.3.4", 1315 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 1316 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 1317 | "dependencies": { 1318 | "ms": "2.1.2" 1319 | }, 1320 | "engines": { 1321 | "node": ">=6.0" 1322 | }, 1323 | "peerDependenciesMeta": { 1324 | "supports-color": { 1325 | "optional": true 1326 | } 1327 | } 1328 | }, 1329 | "node_modules/mquery/node_modules/ms": { 1330 | "version": "2.1.2", 1331 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1332 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 1333 | }, 1334 | "node_modules/ms": { 1335 | "version": "2.1.3", 1336 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1337 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 1338 | }, 1339 | "node_modules/negotiator": { 1340 | "version": "0.6.3", 1341 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 1342 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 1343 | "engines": { 1344 | "node": ">= 0.6" 1345 | } 1346 | }, 1347 | "node_modules/neo-async": { 1348 | "version": "2.6.2", 1349 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", 1350 | "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" 1351 | }, 1352 | "node_modules/nodemon": { 1353 | "version": "3.0.1", 1354 | "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.1.tgz", 1355 | "integrity": "sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==", 1356 | "dev": true, 1357 | "dependencies": { 1358 | "chokidar": "^3.5.2", 1359 | "debug": "^3.2.7", 1360 | "ignore-by-default": "^1.0.1", 1361 | "minimatch": "^3.1.2", 1362 | "pstree.remy": "^1.1.8", 1363 | "semver": "^7.5.3", 1364 | "simple-update-notifier": "^2.0.0", 1365 | "supports-color": "^5.5.0", 1366 | "touch": "^3.1.0", 1367 | "undefsafe": "^2.0.5" 1368 | }, 1369 | "bin": { 1370 | "nodemon": "bin/nodemon.js" 1371 | }, 1372 | "engines": { 1373 | "node": ">=10" 1374 | }, 1375 | "funding": { 1376 | "type": "opencollective", 1377 | "url": "https://opencollective.com/nodemon" 1378 | } 1379 | }, 1380 | "node_modules/nopt": { 1381 | "version": "1.0.10", 1382 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", 1383 | "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", 1384 | "dev": true, 1385 | "dependencies": { 1386 | "abbrev": "1" 1387 | }, 1388 | "bin": { 1389 | "nopt": "bin/nopt.js" 1390 | }, 1391 | "engines": { 1392 | "node": "*" 1393 | } 1394 | }, 1395 | "node_modules/normalize-path": { 1396 | "version": "3.0.0", 1397 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1398 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1399 | "dev": true, 1400 | "engines": { 1401 | "node": ">=0.10.0" 1402 | } 1403 | }, 1404 | "node_modules/object-assign": { 1405 | "version": "4.1.1", 1406 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1407 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 1408 | "engines": { 1409 | "node": ">=0.10.0" 1410 | } 1411 | }, 1412 | "node_modules/object-inspect": { 1413 | "version": "1.12.3", 1414 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", 1415 | "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", 1416 | "funding": { 1417 | "url": "https://github.com/sponsors/ljharb" 1418 | } 1419 | }, 1420 | "node_modules/on-finished": { 1421 | "version": "2.4.1", 1422 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 1423 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 1424 | "dependencies": { 1425 | "ee-first": "1.1.1" 1426 | }, 1427 | "engines": { 1428 | "node": ">= 0.8" 1429 | } 1430 | }, 1431 | "node_modules/parseurl": { 1432 | "version": "1.3.3", 1433 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1434 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 1435 | "engines": { 1436 | "node": ">= 0.8" 1437 | } 1438 | }, 1439 | "node_modules/path-key": { 1440 | "version": "3.1.1", 1441 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1442 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1443 | "engines": { 1444 | "node": ">=8" 1445 | } 1446 | }, 1447 | "node_modules/path-parse": { 1448 | "version": "1.0.7", 1449 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1450 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" 1451 | }, 1452 | "node_modules/path-scurry": { 1453 | "version": "1.10.1", 1454 | "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", 1455 | "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", 1456 | "dependencies": { 1457 | "lru-cache": "^9.1.1 || ^10.0.0", 1458 | "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" 1459 | }, 1460 | "engines": { 1461 | "node": ">=16 || 14 >=14.17" 1462 | }, 1463 | "funding": { 1464 | "url": "https://github.com/sponsors/isaacs" 1465 | } 1466 | }, 1467 | "node_modules/path-scurry/node_modules/lru-cache": { 1468 | "version": "10.1.0", 1469 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", 1470 | "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", 1471 | "engines": { 1472 | "node": "14 || >=16.14" 1473 | } 1474 | }, 1475 | "node_modules/path-to-regexp": { 1476 | "version": "0.1.7", 1477 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1478 | "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" 1479 | }, 1480 | "node_modules/picomatch": { 1481 | "version": "2.3.1", 1482 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1483 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1484 | "dev": true, 1485 | "engines": { 1486 | "node": ">=8.6" 1487 | }, 1488 | "funding": { 1489 | "url": "https://github.com/sponsors/jonschlinkert" 1490 | } 1491 | }, 1492 | "node_modules/promise": { 1493 | "version": "7.3.1", 1494 | "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", 1495 | "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", 1496 | "dependencies": { 1497 | "asap": "~2.0.3" 1498 | } 1499 | }, 1500 | "node_modules/proxy-addr": { 1501 | "version": "2.0.7", 1502 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1503 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1504 | "dependencies": { 1505 | "forwarded": "0.2.0", 1506 | "ipaddr.js": "1.9.1" 1507 | }, 1508 | "engines": { 1509 | "node": ">= 0.10" 1510 | } 1511 | }, 1512 | "node_modules/pstree.remy": { 1513 | "version": "1.1.8", 1514 | "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", 1515 | "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", 1516 | "dev": true 1517 | }, 1518 | "node_modules/pug": { 1519 | "version": "3.0.2", 1520 | "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz", 1521 | "integrity": "sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==", 1522 | "dependencies": { 1523 | "pug-code-gen": "^3.0.2", 1524 | "pug-filters": "^4.0.0", 1525 | "pug-lexer": "^5.0.1", 1526 | "pug-linker": "^4.0.0", 1527 | "pug-load": "^3.0.0", 1528 | "pug-parser": "^6.0.0", 1529 | "pug-runtime": "^3.0.1", 1530 | "pug-strip-comments": "^2.0.0" 1531 | } 1532 | }, 1533 | "node_modules/pug-attrs": { 1534 | "version": "3.0.0", 1535 | "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", 1536 | "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", 1537 | "dependencies": { 1538 | "constantinople": "^4.0.1", 1539 | "js-stringify": "^1.0.2", 1540 | "pug-runtime": "^3.0.0" 1541 | } 1542 | }, 1543 | "node_modules/pug-code-gen": { 1544 | "version": "3.0.2", 1545 | "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz", 1546 | "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==", 1547 | "dependencies": { 1548 | "constantinople": "^4.0.1", 1549 | "doctypes": "^1.1.0", 1550 | "js-stringify": "^1.0.2", 1551 | "pug-attrs": "^3.0.0", 1552 | "pug-error": "^2.0.0", 1553 | "pug-runtime": "^3.0.0", 1554 | "void-elements": "^3.1.0", 1555 | "with": "^7.0.0" 1556 | } 1557 | }, 1558 | "node_modules/pug-error": { 1559 | "version": "2.0.0", 1560 | "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz", 1561 | "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==" 1562 | }, 1563 | "node_modules/pug-filters": { 1564 | "version": "4.0.0", 1565 | "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", 1566 | "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", 1567 | "dependencies": { 1568 | "constantinople": "^4.0.1", 1569 | "jstransformer": "1.0.0", 1570 | "pug-error": "^2.0.0", 1571 | "pug-walk": "^2.0.0", 1572 | "resolve": "^1.15.1" 1573 | } 1574 | }, 1575 | "node_modules/pug-lexer": { 1576 | "version": "5.0.1", 1577 | "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", 1578 | "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", 1579 | "dependencies": { 1580 | "character-parser": "^2.2.0", 1581 | "is-expression": "^4.0.0", 1582 | "pug-error": "^2.0.0" 1583 | } 1584 | }, 1585 | "node_modules/pug-linker": { 1586 | "version": "4.0.0", 1587 | "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", 1588 | "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", 1589 | "dependencies": { 1590 | "pug-error": "^2.0.0", 1591 | "pug-walk": "^2.0.0" 1592 | } 1593 | }, 1594 | "node_modules/pug-load": { 1595 | "version": "3.0.0", 1596 | "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", 1597 | "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", 1598 | "dependencies": { 1599 | "object-assign": "^4.1.1", 1600 | "pug-walk": "^2.0.0" 1601 | } 1602 | }, 1603 | "node_modules/pug-parser": { 1604 | "version": "6.0.0", 1605 | "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", 1606 | "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", 1607 | "dependencies": { 1608 | "pug-error": "^2.0.0", 1609 | "token-stream": "1.0.0" 1610 | } 1611 | }, 1612 | "node_modules/pug-runtime": { 1613 | "version": "3.0.1", 1614 | "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", 1615 | "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==" 1616 | }, 1617 | "node_modules/pug-strip-comments": { 1618 | "version": "2.0.0", 1619 | "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", 1620 | "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", 1621 | "dependencies": { 1622 | "pug-error": "^2.0.0" 1623 | } 1624 | }, 1625 | "node_modules/pug-walk": { 1626 | "version": "2.0.0", 1627 | "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", 1628 | "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==" 1629 | }, 1630 | "node_modules/punycode": { 1631 | "version": "2.3.1", 1632 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", 1633 | "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", 1634 | "engines": { 1635 | "node": ">=6" 1636 | } 1637 | }, 1638 | "node_modules/qs": { 1639 | "version": "6.11.0", 1640 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", 1641 | "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", 1642 | "dependencies": { 1643 | "side-channel": "^1.0.4" 1644 | }, 1645 | "engines": { 1646 | "node": ">=0.6" 1647 | }, 1648 | "funding": { 1649 | "url": "https://github.com/sponsors/ljharb" 1650 | } 1651 | }, 1652 | "node_modules/range-parser": { 1653 | "version": "1.2.1", 1654 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1655 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 1656 | "engines": { 1657 | "node": ">= 0.6" 1658 | } 1659 | }, 1660 | "node_modules/raw-body": { 1661 | "version": "2.5.2", 1662 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", 1663 | "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", 1664 | "dependencies": { 1665 | "bytes": "3.1.2", 1666 | "http-errors": "2.0.0", 1667 | "iconv-lite": "0.4.24", 1668 | "unpipe": "1.0.0" 1669 | }, 1670 | "engines": { 1671 | "node": ">= 0.8" 1672 | } 1673 | }, 1674 | "node_modules/readdirp": { 1675 | "version": "3.6.0", 1676 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 1677 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 1678 | "dev": true, 1679 | "dependencies": { 1680 | "picomatch": "^2.2.1" 1681 | }, 1682 | "engines": { 1683 | "node": ">=8.10.0" 1684 | } 1685 | }, 1686 | "node_modules/resolve": { 1687 | "version": "1.22.8", 1688 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", 1689 | "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", 1690 | "dependencies": { 1691 | "is-core-module": "^2.13.0", 1692 | "path-parse": "^1.0.7", 1693 | "supports-preserve-symlinks-flag": "^1.0.0" 1694 | }, 1695 | "bin": { 1696 | "resolve": "bin/resolve" 1697 | }, 1698 | "funding": { 1699 | "url": "https://github.com/sponsors/ljharb" 1700 | } 1701 | }, 1702 | "node_modules/safe-buffer": { 1703 | "version": "5.2.1", 1704 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1705 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1706 | "funding": [ 1707 | { 1708 | "type": "github", 1709 | "url": "https://github.com/sponsors/feross" 1710 | }, 1711 | { 1712 | "type": "patreon", 1713 | "url": "https://www.patreon.com/feross" 1714 | }, 1715 | { 1716 | "type": "consulting", 1717 | "url": "https://feross.org/support" 1718 | } 1719 | ] 1720 | }, 1721 | "node_modules/safer-buffer": { 1722 | "version": "2.1.2", 1723 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1724 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1725 | }, 1726 | "node_modules/semver": { 1727 | "version": "7.5.4", 1728 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", 1729 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", 1730 | "dev": true, 1731 | "dependencies": { 1732 | "lru-cache": "^6.0.0" 1733 | }, 1734 | "bin": { 1735 | "semver": "bin/semver.js" 1736 | }, 1737 | "engines": { 1738 | "node": ">=10" 1739 | } 1740 | }, 1741 | "node_modules/send": { 1742 | "version": "0.18.0", 1743 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", 1744 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", 1745 | "dependencies": { 1746 | "debug": "2.6.9", 1747 | "depd": "2.0.0", 1748 | "destroy": "1.2.0", 1749 | "encodeurl": "~1.0.2", 1750 | "escape-html": "~1.0.3", 1751 | "etag": "~1.8.1", 1752 | "fresh": "0.5.2", 1753 | "http-errors": "2.0.0", 1754 | "mime": "1.6.0", 1755 | "ms": "2.1.3", 1756 | "on-finished": "2.4.1", 1757 | "range-parser": "~1.2.1", 1758 | "statuses": "2.0.1" 1759 | }, 1760 | "engines": { 1761 | "node": ">= 0.8.0" 1762 | } 1763 | }, 1764 | "node_modules/send/node_modules/debug": { 1765 | "version": "2.6.9", 1766 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1767 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1768 | "dependencies": { 1769 | "ms": "2.0.0" 1770 | } 1771 | }, 1772 | "node_modules/send/node_modules/debug/node_modules/ms": { 1773 | "version": "2.0.0", 1774 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1775 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 1776 | }, 1777 | "node_modules/serve-static": { 1778 | "version": "1.15.0", 1779 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", 1780 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", 1781 | "dependencies": { 1782 | "encodeurl": "~1.0.2", 1783 | "escape-html": "~1.0.3", 1784 | "parseurl": "~1.3.3", 1785 | "send": "0.18.0" 1786 | }, 1787 | "engines": { 1788 | "node": ">= 0.8.0" 1789 | } 1790 | }, 1791 | "node_modules/setprototypeof": { 1792 | "version": "1.2.0", 1793 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 1794 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 1795 | }, 1796 | "node_modules/shebang-command": { 1797 | "version": "2.0.0", 1798 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1799 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1800 | "dependencies": { 1801 | "shebang-regex": "^3.0.0" 1802 | }, 1803 | "engines": { 1804 | "node": ">=8" 1805 | } 1806 | }, 1807 | "node_modules/shebang-regex": { 1808 | "version": "3.0.0", 1809 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1810 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1811 | "engines": { 1812 | "node": ">=8" 1813 | } 1814 | }, 1815 | "node_modules/side-channel": { 1816 | "version": "1.0.4", 1817 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", 1818 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", 1819 | "dependencies": { 1820 | "call-bind": "^1.0.0", 1821 | "get-intrinsic": "^1.0.2", 1822 | "object-inspect": "^1.9.0" 1823 | }, 1824 | "funding": { 1825 | "url": "https://github.com/sponsors/ljharb" 1826 | } 1827 | }, 1828 | "node_modules/sift": { 1829 | "version": "16.0.1", 1830 | "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz", 1831 | "integrity": "sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ==" 1832 | }, 1833 | "node_modules/signal-exit": { 1834 | "version": "4.1.0", 1835 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", 1836 | "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", 1837 | "engines": { 1838 | "node": ">=14" 1839 | }, 1840 | "funding": { 1841 | "url": "https://github.com/sponsors/isaacs" 1842 | } 1843 | }, 1844 | "node_modules/simple-update-notifier": { 1845 | "version": "2.0.0", 1846 | "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", 1847 | "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", 1848 | "dev": true, 1849 | "dependencies": { 1850 | "semver": "^7.5.3" 1851 | }, 1852 | "engines": { 1853 | "node": ">=10" 1854 | } 1855 | }, 1856 | "node_modules/source-map": { 1857 | "version": "0.6.1", 1858 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1859 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1860 | "engines": { 1861 | "node": ">=0.10.0" 1862 | } 1863 | }, 1864 | "node_modules/sparse-bitfield": { 1865 | "version": "3.0.3", 1866 | "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", 1867 | "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", 1868 | "dependencies": { 1869 | "memory-pager": "^1.0.2" 1870 | } 1871 | }, 1872 | "node_modules/statuses": { 1873 | "version": "2.0.1", 1874 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 1875 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 1876 | "engines": { 1877 | "node": ">= 0.8" 1878 | } 1879 | }, 1880 | "node_modules/string-width": { 1881 | "version": "5.1.2", 1882 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", 1883 | "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", 1884 | "dependencies": { 1885 | "eastasianwidth": "^0.2.0", 1886 | "emoji-regex": "^9.2.2", 1887 | "strip-ansi": "^7.0.1" 1888 | }, 1889 | "engines": { 1890 | "node": ">=12" 1891 | }, 1892 | "funding": { 1893 | "url": "https://github.com/sponsors/sindresorhus" 1894 | } 1895 | }, 1896 | "node_modules/string-width-cjs": { 1897 | "name": "string-width", 1898 | "version": "4.2.3", 1899 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 1900 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 1901 | "dependencies": { 1902 | "emoji-regex": "^8.0.0", 1903 | "is-fullwidth-code-point": "^3.0.0", 1904 | "strip-ansi": "^6.0.1" 1905 | }, 1906 | "engines": { 1907 | "node": ">=8" 1908 | } 1909 | }, 1910 | "node_modules/string-width-cjs/node_modules/ansi-regex": { 1911 | "version": "5.0.1", 1912 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1913 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 1914 | "engines": { 1915 | "node": ">=8" 1916 | } 1917 | }, 1918 | "node_modules/string-width-cjs/node_modules/emoji-regex": { 1919 | "version": "8.0.0", 1920 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 1921 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" 1922 | }, 1923 | "node_modules/string-width-cjs/node_modules/strip-ansi": { 1924 | "version": "6.0.1", 1925 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1926 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1927 | "dependencies": { 1928 | "ansi-regex": "^5.0.1" 1929 | }, 1930 | "engines": { 1931 | "node": ">=8" 1932 | } 1933 | }, 1934 | "node_modules/strip-ansi": { 1935 | "version": "7.1.0", 1936 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", 1937 | "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", 1938 | "dependencies": { 1939 | "ansi-regex": "^6.0.1" 1940 | }, 1941 | "engines": { 1942 | "node": ">=12" 1943 | }, 1944 | "funding": { 1945 | "url": "https://github.com/chalk/strip-ansi?sponsor=1" 1946 | } 1947 | }, 1948 | "node_modules/strip-ansi-cjs": { 1949 | "name": "strip-ansi", 1950 | "version": "6.0.1", 1951 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1952 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1953 | "dependencies": { 1954 | "ansi-regex": "^5.0.1" 1955 | }, 1956 | "engines": { 1957 | "node": ">=8" 1958 | } 1959 | }, 1960 | "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { 1961 | "version": "5.0.1", 1962 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1963 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 1964 | "engines": { 1965 | "node": ">=8" 1966 | } 1967 | }, 1968 | "node_modules/supports-color": { 1969 | "version": "5.5.0", 1970 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1971 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1972 | "dev": true, 1973 | "dependencies": { 1974 | "has-flag": "^3.0.0" 1975 | }, 1976 | "engines": { 1977 | "node": ">=4" 1978 | } 1979 | }, 1980 | "node_modules/supports-preserve-symlinks-flag": { 1981 | "version": "1.0.0", 1982 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 1983 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 1984 | "engines": { 1985 | "node": ">= 0.4" 1986 | }, 1987 | "funding": { 1988 | "url": "https://github.com/sponsors/ljharb" 1989 | } 1990 | }, 1991 | "node_modules/to-fast-properties": { 1992 | "version": "2.0.0", 1993 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", 1994 | "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", 1995 | "engines": { 1996 | "node": ">=4" 1997 | } 1998 | }, 1999 | "node_modules/to-regex-range": { 2000 | "version": "5.0.1", 2001 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 2002 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 2003 | "dev": true, 2004 | "dependencies": { 2005 | "is-number": "^7.0.0" 2006 | }, 2007 | "engines": { 2008 | "node": ">=8.0" 2009 | } 2010 | }, 2011 | "node_modules/toidentifier": { 2012 | "version": "1.0.1", 2013 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 2014 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 2015 | "engines": { 2016 | "node": ">=0.6" 2017 | } 2018 | }, 2019 | "node_modules/token-stream": { 2020 | "version": "1.0.0", 2021 | "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", 2022 | "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==" 2023 | }, 2024 | "node_modules/touch": { 2025 | "version": "3.1.0", 2026 | "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", 2027 | "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", 2028 | "dev": true, 2029 | "dependencies": { 2030 | "nopt": "~1.0.10" 2031 | }, 2032 | "bin": { 2033 | "nodetouch": "bin/nodetouch.js" 2034 | } 2035 | }, 2036 | "node_modules/tr46": { 2037 | "version": "4.1.1", 2038 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", 2039 | "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", 2040 | "dependencies": { 2041 | "punycode": "^2.3.0" 2042 | }, 2043 | "engines": { 2044 | "node": ">=14" 2045 | } 2046 | }, 2047 | "node_modules/type-is": { 2048 | "version": "1.6.18", 2049 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 2050 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 2051 | "dependencies": { 2052 | "media-typer": "0.3.0", 2053 | "mime-types": "~2.1.24" 2054 | }, 2055 | "engines": { 2056 | "node": ">= 0.6" 2057 | } 2058 | }, 2059 | "node_modules/uglify-js": { 2060 | "version": "3.17.4", 2061 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", 2062 | "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", 2063 | "optional": true, 2064 | "bin": { 2065 | "uglifyjs": "bin/uglifyjs" 2066 | }, 2067 | "engines": { 2068 | "node": ">=0.8.0" 2069 | } 2070 | }, 2071 | "node_modules/undefsafe": { 2072 | "version": "2.0.5", 2073 | "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", 2074 | "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", 2075 | "dev": true 2076 | }, 2077 | "node_modules/unpipe": { 2078 | "version": "1.0.0", 2079 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 2080 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 2081 | "engines": { 2082 | "node": ">= 0.8" 2083 | } 2084 | }, 2085 | "node_modules/utils-merge": { 2086 | "version": "1.0.1", 2087 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 2088 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 2089 | "engines": { 2090 | "node": ">= 0.4.0" 2091 | } 2092 | }, 2093 | "node_modules/vary": { 2094 | "version": "1.1.2", 2095 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 2096 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 2097 | "engines": { 2098 | "node": ">= 0.8" 2099 | } 2100 | }, 2101 | "node_modules/void-elements": { 2102 | "version": "3.1.0", 2103 | "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", 2104 | "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", 2105 | "engines": { 2106 | "node": ">=0.10.0" 2107 | } 2108 | }, 2109 | "node_modules/webidl-conversions": { 2110 | "version": "7.0.0", 2111 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", 2112 | "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", 2113 | "engines": { 2114 | "node": ">=12" 2115 | } 2116 | }, 2117 | "node_modules/whatwg-url": { 2118 | "version": "13.0.0", 2119 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", 2120 | "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", 2121 | "dependencies": { 2122 | "tr46": "^4.1.1", 2123 | "webidl-conversions": "^7.0.0" 2124 | }, 2125 | "engines": { 2126 | "node": ">=16" 2127 | } 2128 | }, 2129 | "node_modules/which": { 2130 | "version": "2.0.2", 2131 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 2132 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 2133 | "dependencies": { 2134 | "isexe": "^2.0.0" 2135 | }, 2136 | "bin": { 2137 | "node-which": "bin/node-which" 2138 | }, 2139 | "engines": { 2140 | "node": ">= 8" 2141 | } 2142 | }, 2143 | "node_modules/with": { 2144 | "version": "7.0.2", 2145 | "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", 2146 | "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", 2147 | "dependencies": { 2148 | "@babel/parser": "^7.9.6", 2149 | "@babel/types": "^7.9.6", 2150 | "assert-never": "^1.2.1", 2151 | "babel-walk": "3.0.0-canary-5" 2152 | }, 2153 | "engines": { 2154 | "node": ">= 10.0.0" 2155 | } 2156 | }, 2157 | "node_modules/wordwrap": { 2158 | "version": "1.0.0", 2159 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 2160 | "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" 2161 | }, 2162 | "node_modules/wrap-ansi": { 2163 | "version": "8.1.0", 2164 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", 2165 | "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", 2166 | "dependencies": { 2167 | "ansi-styles": "^6.1.0", 2168 | "string-width": "^5.0.1", 2169 | "strip-ansi": "^7.0.1" 2170 | }, 2171 | "engines": { 2172 | "node": ">=12" 2173 | }, 2174 | "funding": { 2175 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 2176 | } 2177 | }, 2178 | "node_modules/wrap-ansi-cjs": { 2179 | "name": "wrap-ansi", 2180 | "version": "7.0.0", 2181 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 2182 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 2183 | "dependencies": { 2184 | "ansi-styles": "^4.0.0", 2185 | "string-width": "^4.1.0", 2186 | "strip-ansi": "^6.0.0" 2187 | }, 2188 | "engines": { 2189 | "node": ">=10" 2190 | }, 2191 | "funding": { 2192 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 2193 | } 2194 | }, 2195 | "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { 2196 | "version": "5.0.1", 2197 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 2198 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 2199 | "engines": { 2200 | "node": ">=8" 2201 | } 2202 | }, 2203 | "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { 2204 | "version": "8.0.0", 2205 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 2206 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" 2207 | }, 2208 | "node_modules/wrap-ansi-cjs/node_modules/string-width": { 2209 | "version": "4.2.3", 2210 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2211 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2212 | "dependencies": { 2213 | "emoji-regex": "^8.0.0", 2214 | "is-fullwidth-code-point": "^3.0.0", 2215 | "strip-ansi": "^6.0.1" 2216 | }, 2217 | "engines": { 2218 | "node": ">=8" 2219 | } 2220 | }, 2221 | "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { 2222 | "version": "6.0.1", 2223 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2224 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2225 | "dependencies": { 2226 | "ansi-regex": "^5.0.1" 2227 | }, 2228 | "engines": { 2229 | "node": ">=8" 2230 | } 2231 | }, 2232 | "node_modules/wrap-ansi/node_modules/ansi-styles": { 2233 | "version": "6.2.1", 2234 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", 2235 | "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", 2236 | "engines": { 2237 | "node": ">=12" 2238 | }, 2239 | "funding": { 2240 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 2241 | } 2242 | }, 2243 | "node_modules/yallist": { 2244 | "version": "4.0.0", 2245 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", 2246 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", 2247 | "dev": true 2248 | } 2249 | } 2250 | } 2251 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopingkaro", 3 | "version": "1.0.0", 4 | "description": "Learning Node.js using express in this project.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "nodemon index.js" 9 | }, 10 | "author": { 11 | "name": "Abhinav Kumar Arya", 12 | "github": "www.github.com/itzabhinavarya", 13 | "twitter": "www.twitter.com/itzabhinavarya", 14 | "Youtube": "https://www.youtube.com/channel/UCuKCJgq0NIUuFbdkLOCBe8A", 15 | "email": "itzabhinavarya@gmail.com", 16 | "Portfolio": "itzabhinavarya.netlify.app" 17 | }, 18 | "license": "ISC", 19 | "devDependencies": { 20 | "nodemon": "^3.0.1" 21 | }, 22 | "dependencies": { 23 | "body-parser": "^1.20.2", 24 | "dotenv": "^16.3.2", 25 | "ejs": "^3.1.9", 26 | "express": "^4.18.2", 27 | "express-handlebars": "^7.1.2", 28 | "mongodb": "^6.3.0", 29 | "mongoose": "^8.1.0", 30 | "pug": "^3.0.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /public/css/NotFound.css: -------------------------------------------------------------------------------- 1 | .error-msg { 2 | display: flex; 3 | align-items: center; 4 | justify-content: center; 5 | } 6 | -------------------------------------------------------------------------------- /public/css/add-product.css: -------------------------------------------------------------------------------- 1 | .form-hero p { 2 | font-weight: bold; 3 | } 4 | .form-hero input,textarea { 5 | width: 100%; 6 | padding: 10px; 7 | margin: 15px 0; 8 | display: flex; 9 | font-size: 14px; 10 | border: 2px solid #b4b4b4; 11 | border-radius: 2px; 12 | } 13 | 14 | .form-hero input::placeholder{ 15 | font-size: 15px; 16 | } 17 | /* .form-section { 18 | display: flex; 19 | } */ 20 | .form-button { 21 | display: flex; 22 | align-items: center; 23 | justify-content: center; 24 | } 25 | .form-button button { 26 | padding: 10px 15px; 27 | background-color: greenyellow; 28 | border: none; 29 | border-radius: 2px; 30 | cursor: pointer; 31 | font-size: 16px; 32 | font-weight: bold; 33 | } 34 | .form-button button:hover { 35 | color: greenyellow; 36 | background-color: black; 37 | transition: 0.3s all ease-in; 38 | } 39 | -------------------------------------------------------------------------------- /public/css/cart.css: -------------------------------------------------------------------------------- 1 | .cart-hero { 2 | display: flex; 3 | gap: 10px; 4 | flex-direction: column; 5 | margin-top: 10px; 6 | } 7 | .cart { 8 | display: flex; 9 | justify-content: space-between; 10 | padding: 1rem 2rem; 11 | background-color: rgb(225, 225, 225); 12 | } 13 | 14 | .cart-item-title p { 15 | font-size: 20px; 16 | font-weight: 500; 17 | } 18 | 19 | .cart-image img { 20 | display: flex; 21 | width: 50px; 22 | } 23 | .cart ul { 24 | display: flex; 25 | gap: 1rem; 26 | } 27 | .cart-item-details { 28 | display: flex; 29 | flex-direction: column; 30 | justify-content: space-between; 31 | } 32 | .cart ul li { 33 | list-style: none; 34 | } 35 | 36 | .cart-delete { 37 | display: flex; 38 | flex-direction: column; 39 | justify-content: space-between; 40 | } 41 | 42 | .cart-btn button{ 43 | border: none; 44 | padding: 5px 20px; 45 | border-radius: 2px; 46 | color: antiquewhite; 47 | font-weight: 500; 48 | font-size: 15px; 49 | cursor: pointer; 50 | } 51 | 52 | .cart-delete-btn button { 53 | background-color: rgba(221, 30, 30, 0.922); 54 | } 55 | 56 | .cart-order-btn button{ 57 | background-color: rgb(29, 200, 29); 58 | background-color: rgb(10, 139, 10); 59 | } 60 | 61 | .price p{ 62 | font-size: 18px; 63 | font-weight: 500; 64 | } 65 | 66 | .quantity-box { 67 | width: max-content; 68 | display: flex; 69 | justify-content: space-between; 70 | background-color: rgb(183, 181, 178); 71 | border-radius: 3px; 72 | } 73 | 74 | .control, 75 | .qty { 76 | padding: 5px 15px; 77 | } 78 | 79 | .control:nth-child(1) { 80 | border-right: 1px solid rgb(0, 0, 0); 81 | cursor: pointer; 82 | } 83 | .box-control { 84 | border-left: 1px solid rgb(0, 0, 0); 85 | cursor: pointer; 86 | } 87 | -------------------------------------------------------------------------------- /public/css/main.css: -------------------------------------------------------------------------------- 1 | * { 2 | padding: 0; 3 | margin: 0; 4 | font-family: "poppins"; 5 | } 6 | .main-header { 7 | height: 3.5rem; 8 | background-color: rgb(64, 66, 66); 9 | padding: 10px 50px; 10 | display: flex; 11 | align-items: center; 12 | } 13 | .header-nav ul { 14 | display: flex; 15 | gap: 3rem; 16 | } 17 | .header-nav ul li { 18 | list-style: none; 19 | text-decoration: none; 20 | } 21 | .header-nav ul li a { 22 | text-decoration: none; 23 | font-weight: bold; 24 | color: rgb(255, 255, 255); 25 | } 26 | .header-nav ul li a:hover { 27 | color: rgb(0, 255, 136); 28 | } 29 | 30 | main { 31 | padding: 10px 50px; 32 | } 33 | 34 | /* Product Card Css */ 35 | 36 | .grid { 37 | display: grid; 38 | grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); 39 | gap: 20px; 40 | } 41 | 42 | .card { 43 | /* width: 250px; */ 44 | border-radius: 3px; 45 | padding: 10px; 46 | box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px; 47 | } 48 | 49 | .card-image { 50 | display: flex; 51 | justify-content: center; 52 | align-items: center; 53 | } 54 | .card-image img { 55 | width: 250px; 56 | height: 250px; 57 | aspect-ratio: 2/2; 58 | object-fit: contain; 59 | } 60 | 61 | .card-actions { 62 | display: flex; 63 | padding-top: 10px; 64 | gap: 1rem; 65 | } 66 | 67 | .btn { 68 | padding: 4.8px 10px; 69 | background-color: greenyellow; 70 | border: none; 71 | border-radius: 2px; 72 | cursor: pointer; 73 | } 74 | .btn:hover { 75 | color: greenyellow; 76 | background-color: black; 77 | transition: 0.3s all ease-in; 78 | } 79 | 80 | .admin-card-action { 81 | display: flex; 82 | justify-content: center; 83 | align-content: center; 84 | gap: 1rem; 85 | } 86 | 87 | .admin-card{ 88 | display: flex; 89 | flex-direction: column; 90 | gap: 1rem; 91 | } 92 | 93 | .product-title{ 94 | font-size: 16px; 95 | } 96 | 97 | .product-price{ 98 | font-size: 18px; 99 | } 100 | 101 | .product-description{ 102 | font-size: 14px; 103 | } 104 | 105 | .edit { 106 | background-color: rgba(25, 164, 220, 0.847); 107 | } 108 | 109 | .delete { 110 | background-color: rgba(255, 43, 43, 0.797); 111 | } 112 | -------------------------------------------------------------------------------- /public/css/order.css: -------------------------------------------------------------------------------- 1 | .order{ 2 | margin-top: 10px; 3 | padding: 5px 15px; 4 | background-color: rgb(179, 179, 179); 5 | } 6 | 7 | .order-items{ 8 | margin-top: 15px; 9 | display: flex; 10 | flex-direction: column; 11 | gap: 10px; 12 | } 13 | 14 | .order-details{ 15 | display: flex; 16 | gap: 15px; 17 | } 18 | 19 | .order-image img{ 20 | width: 70px; 21 | display: flex; 22 | } 23 | 24 | .order-desc p{ 25 | font-size: 16px; 26 | font-weight: bold; 27 | } -------------------------------------------------------------------------------- /public/css/product-details.css: -------------------------------------------------------------------------------- 1 | .product-image{ 2 | width: 200px; 3 | } 4 | 5 | .product-section{ 6 | display: flex; 7 | gap: 2rem; 8 | } 9 | .product-image img{ 10 | width: inherit; 11 | height: inherit; 12 | } 13 | 14 | .product-description{ 15 | width: 100%; 16 | display: flex; 17 | flex-direction: column; 18 | gap: 1rem; 19 | } 20 | 21 | .description{ 22 | width: 100%; 23 | } 24 | 25 | .order-btn{ 26 | display: flex; 27 | gap: 1rem; 28 | } 29 | 30 | .buyBtn,.cartBtn{ 31 | padding: 7px 20px; 32 | font-weight: 500; 33 | cursor: pointer; 34 | } 35 | 36 | .buyBtn{ 37 | color: white; 38 | border: 1px solid transparent; 39 | background-color: rgb(35, 140, 35); 40 | } 41 | 42 | .cartBtn{ 43 | border: 1px solid transparent; 44 | color: black; 45 | background-color: rgb(255, 251, 0); 46 | } -------------------------------------------------------------------------------- /public/js/main.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/itzabhinavarya/ShopingKaro/8d5f6ff9961419016e92f088b6138251fe662e86/public/js/main.js -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # ShopingKaro 2 | 3 | ShopingKaro is a web application developed in Node.js that allows users to easily browse and shop for various products. With a user-friendly interface and a variety of features, ShopingKaro aims to provide a seamless online shopping experience. 4 | 5 | ## Table of Contents 6 | 7 | - [Features](#features) 8 | - [Tech Stack](#tech-stack) 9 | - [Installation](#installation) 10 | - [Usage](#usage) 11 | - [Contributing](#contributing) 12 | - [License](#license) 13 | 14 | ## Features 15 | 16 | - **User-friendly Interface:** Intuitive design for easy navigation and a pleasant user experience. 17 | - **Product Browsing:** Browse through a wide range of products conveniently categorized for quick access. 18 | - **Cart Management:** Add and remove items from the shopping cart with real-time updates. 19 | - **Responsive Design:** ShopingKaro is optimized for various devices, ensuring a seamless experience on desktops, tablets, and mobile phones. 20 | 21 | ## Tech Stack 22 | 23 | - **JavaScript (45.0%):** The primary programming language used for the functionality and interactivity of ShopingKaro. 24 | - **EJS (31.8%):** Embedded JavaScript templates for dynamic content rendering. 25 | - **CSS (12.5%):** Styling to enhance the visual appeal and user interface. 26 | - **HTML (5.6%):** The backbone for structuring the web pages. 27 | - **Pug (5.1%):** A templating engine for concise and readable HTML code. 28 | 29 | ## Installation 30 | 31 | 1. Clone the repository: 32 | 33 | ```bash 34 | git clone https://github.com/your-username/ShopingKaro.git 35 | 36 | 2. Install dependency: 37 | 38 | ```bash 39 | npm install 40 | 41 | 5. Setup MongoDB 42 | 43 | - Go to .env file 44 | - Create a database in MongoDb 45 | - Add a user and password in <yourDBUser> : <password> in below connection string. 46 | 47 | ``` 48 | "mongodb+srv://:@/?retryWrites=true&w=majority", 49 | 50 | 4. Run : 51 | 52 | ```bash 53 | npm run start 54 | 55 | Open your browser and visit http://localhost:3000 to access ShopingKaro. 56 | 57 | Explore the website, add products to your cart, and enjoy a seamless shopping experience. 58 | 59 | ## Contributing 60 | 61 | If you'd like to contribute to ShopingKaro, please follow these guidelines: 62 | 63 | - Fork the repository on GitHub. 64 | - Clone your forked repository to your local machine. 65 | - Create a new branch for your feature or bug fix. 66 | - Make your changes and commit them with descriptive commit messages. 67 | - Push your changes to your forked repository. 68 | - Create a pull request to the main repository. 69 | 70 | ## License 71 | 72 | This project is licensed under the MIT License. Feel free to use, modify, and distribute it as per the license terms. 73 | -------------------------------------------------------------------------------- /routes/admin.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | 3 | const adminController = require("../controllers/admin"); 4 | 5 | const router = express.Router(); 6 | 7 | router.get("/add-product", adminController.getAddProduct); 8 | 9 | router.get("/products", adminController.getProduct); 10 | 11 | router.post("/add-product", adminController.postAddProduct); 12 | 13 | router.get("/edit-product/:prodId", adminController.getEditProduct); 14 | 15 | router.post("/edit-product/", adminController.postEditProduct); 16 | 17 | router.post("/delete-product", adminController.postDeleteProduct); 18 | 19 | module.exports = router; 20 | // exports.routes = router; 21 | // exports.products = products; 22 | -------------------------------------------------------------------------------- /routes/shop.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const shopController = require("../controllers/shop"); 3 | const router = express.Router(); 4 | 5 | router.get("/", shopController.getIndex); 6 | 7 | router.get("/products", shopController.getProducts); 8 | 9 | router.get("/products/:productId", shopController.getProduct); 10 | 11 | router.get("/cart", shopController.getCart); 12 | 13 | router.post("/cart", shopController.postCart); 14 | 15 | router.post("/cart-delete-item", shopController.postCartDelete); 16 | 17 | router.post("/create-order", shopController.postOrder); 18 | 19 | router.get("/orders", shopController.getOrders); 20 | 21 | module.exports = router; 22 | -------------------------------------------------------------------------------- /views/404.ejs: -------------------------------------------------------------------------------- 1 | <%- include('includes/header.ejs') %> 2 | 3 | 4 | 5 | <%- include('includes/navbar.ejs') %> 6 |
7 |

Page not found 404

8 |
9 | <%- include('includes/footer.ejs') %> 10 | -------------------------------------------------------------------------------- /views/NotFound.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Not Found 7 | 8 | 9 | 10 | 11 |
12 | 18 |
19 |
20 |

Page not found 404

21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /views/NotFound.pug: -------------------------------------------------------------------------------- 1 | extends layouts/main-layout.pug 2 | 3 | block styles 4 | link(rel="stylesheet" href="/css/NotFound.css") 5 | 6 | block content 7 | h1.error-msg Page Not Found! -------------------------------------------------------------------------------- /views/add-product.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Add-Product 7 | 8 | 9 | 10 | 11 |
12 | 18 |
19 |
20 |
21 |
22 |
23 |

Title

24 | 25 |
26 |
27 | 28 |
29 |
30 |
31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /views/add-product.pug: -------------------------------------------------------------------------------- 1 | extends layouts/main-layout.pug 2 | 3 | block styles 4 | link(rel="stylesheet" href="/css/add-product.css") 5 | 6 | block content 7 | main 8 | form(action="/admin/add-product", method="POST") 9 | .form-section 10 | .form-hero 11 | p Title 12 | input(type="text", name="title" placeholder="Enter Products") 13 | .form-button 14 | button(type="submit") Add Product -------------------------------------------------------------------------------- /views/admin/add-product.ejs: -------------------------------------------------------------------------------- 1 | <%- include('../includes/header.ejs') %> 2 | 3 | 4 | 5 | 6 | <%- include('../includes/navbar.ejs') %> 7 |
8 |
9 |
10 |
11 | 12 |
13 |
14 | 15 |
16 |
17 | 18 |
19 |
20 | 21 |
22 |
23 | 24 |
25 |
26 |
27 |
28 | <%- include('../includes/footer.ejs') %> 29 | -------------------------------------------------------------------------------- /views/admin/edit-product.ejs: -------------------------------------------------------------------------------- 1 | <%- include('../includes/header.ejs') %> 2 | 3 | 4 | 5 | 6 | <%- include('../includes/navbar.ejs') %> 7 |
8 |
9 |
10 |
11 | 12 |
13 |
14 | 15 |
16 |
17 | 18 |
19 |
20 | 21 | 22 |
23 |
24 | 25 | <% if(editing) { %> 26 | 27 | <%}%> 28 |
29 |
30 |
31 |
32 | <%- include('../includes/footer.ejs') %> 33 | -------------------------------------------------------------------------------- /views/admin/products.ejs: -------------------------------------------------------------------------------- 1 | <%- include('../includes/header.ejs') %> 2 | 3 | 4 | <%- include('../includes/navbar.ejs') %> 5 |
6 |
7 | <% if(prods.length > 0) { %> 8 |
9 | <% for(let product of prods) { %> 10 |
11 |
12 |

<%= product.title %>

13 |
14 |
15 | 19 |
20 |
21 |

Rs.<%= product.price %>

22 |

<%= product.description %>

23 |
24 |
25 | 26 |
27 | 28 | 29 |
30 |
31 |
32 | <%}%> 33 |
34 | <% } else { %> 35 |
36 |

Product list is empty. Add some product

37 |
38 | <% } %> 39 |
40 |
41 | <%- include('../includes/footer.ejs') %> 42 | -------------------------------------------------------------------------------- /views/includes/footer.ejs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /views/includes/header.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | <%= pageTitle %> 7 | 8 | -------------------------------------------------------------------------------- /views/includes/navbar.ejs: -------------------------------------------------------------------------------- 1 |
2 | 12 |
13 | -------------------------------------------------------------------------------- /views/layouts/main-layout.pug: -------------------------------------------------------------------------------- 1 | doctype html 2 | html(lang="en") 3 | head 4 | meta(charset="UTF-8") 5 | meta(name="viewport" content="width=device-width, initial-scale=1.0") 6 | title #{pageTitle} 7 | link(rel="stylesheet" href="/css/main.css") 8 | block styles 9 | body 10 | header.main-header 11 | nav.header-nav 12 | ul 13 | li 14 | a(href="/") Shop 15 | li 16 | a(href="/admin/add-product") Add Product 17 | block content -------------------------------------------------------------------------------- /views/shop.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Shop 7 | 8 | 9 | 10 |
11 | 17 |
18 |
19 |

My Products

20 |

List of all products....

21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /views/shop.pug: -------------------------------------------------------------------------------- 1 | extends layouts/main-layout.pug 2 | 3 | block content 4 | main 5 | if prods.length > 0 6 | .grid 7 | each product in prods 8 | article.card.product-item 9 | header.card-header 10 | h1.product-title #{product.title} 11 | .card-image 12 | img(src="https://cdn.pixabay.com/photo/2016/03/31/20/51/book-1296045_960_720.png" alt="A book") 13 | .card-content 14 | h2.product-price Rs.243 15 | p.product-description Lorem ipsum dolor sit a de quisquam autemab a odit dolor molestiae. 16 | .card-actions 17 | button.btn Add to Cart 18 | else 19 | h1 Product list is empty. Add some product -------------------------------------------------------------------------------- /views/shop/cart.ejs: -------------------------------------------------------------------------------- 1 | <%- include('../includes/header.ejs') %> 2 | 3 | 4 | 5 | <%- include('../includes/navbar.ejs') %> 6 |
7 |

My Cart

8 |
9 | <% if(products.length > 0) { %> 10 |
11 | <% products.forEach( product => { %> 12 |
13 |
    14 |
    15 |
  • alt="">
  • 16 |
    17 |
    18 |
    19 |
  • 20 |

    <%= product.productId.title %>

    21 |
  • 22 |
    23 |
  • 24 |
    25 |
    26 | + 27 |
    28 |
    29 | <%= product.quantity %> 30 |
    31 |
    32 | - 33 |
    34 |
    35 |
  • 36 |
    37 |
38 |
39 |
40 |

Rs. <%= product.productId.price %>

41 |
42 |
43 | 44 |
45 | 46 |
47 |
48 |
49 |
50 | <% }) %> 51 |
52 |
53 |
54 | 55 |
56 |
57 |
58 |
59 | <% }else { %> 60 |

Cart is empty.

61 | <% } %> 62 |
63 | <%- include('../includes/footer.ejs') %> -------------------------------------------------------------------------------- /views/shop/checkout.ejs: -------------------------------------------------------------------------------- 1 | <%- include('../includes/header.ejs') %> 2 | 3 | 4 | <%- include('../includes/navbar.ejs') %> 5 |
6 |

This is Checkout page

7 |
8 | <%- include('../includes/footer.ejs') %> -------------------------------------------------------------------------------- /views/shop/index.ejs: -------------------------------------------------------------------------------- 1 | <%- include('../includes/header.ejs') %> 2 | 3 | 4 | <%- include('../includes/navbar.ejs') %> 5 |
6 |
7 | <% if(prods.length > 0) { %> 8 |
9 | <% for(let product of prods) { %> 10 |
11 |
12 |

<%= product.title %>

13 |
14 |
15 | 19 |
20 |
21 |

Rs.<%= product.price %>

22 |

<%= product.description %>

23 |
24 |
25 |
26 | 27 | 28 |
29 |
30 |
31 | <%}%> 32 |
33 | <% } else { %> 34 |
35 |

Product list is empty. Add some product

36 |
37 | <% } %> 38 |
39 |
40 | <%- include('../includes/footer.ejs') %> 41 | -------------------------------------------------------------------------------- /views/shop/orders.ejs: -------------------------------------------------------------------------------- 1 | <%- include('../includes/header.ejs') %> 2 | 3 | 4 | 5 | <%- include('../includes/navbar.ejs') %> 6 |
7 |

My Orders

8 |
9 | <% if (orders.length > 0) { %> 10 | <% orders.forEach(order => { %> 11 |
12 |

Order - #<%= order._id %>

13 |
14 | <% order.products.forEach(p => { %> 15 |
16 |
17 | alt=""> 18 |
19 |
20 |

<%= p.product.title %>

21 |

Qty : <%= p.quantity %>

22 |

Price : Rs.<%= p.product.price %>

23 |
24 |
25 | <% }) %> 26 |
27 |
28 | <% }) %> 29 | <% } else { %> 30 |

Oopss...! No orders available

31 | <% } %> 32 |
33 | <%- include('../includes/footer.ejs') %> 34 | -------------------------------------------------------------------------------- /views/shop/product-details.ejs: -------------------------------------------------------------------------------- 1 | <%- include('../includes/header.ejs') %> 2 | 3 | 4 | 5 | <%- include('../includes/navbar.ejs') %> 6 |
7 |
8 |
9 |

<%= product.title %>

10 |
11 |
12 |
13 |
14 | 15 |
16 |
17 |
18 |

<%= product.description %>

19 |
20 |
21 |

Rs.<%= product.price %>

22 |
23 |
24 | 25 |
26 | 27 | 28 |
29 |
30 |
31 |
32 |
33 |
34 | <%- include('../includes/footer.ejs') %> -------------------------------------------------------------------------------- /views/shop/product-list.ejs: -------------------------------------------------------------------------------- 1 | <%- include('../includes/header.ejs') %> 2 | 3 | 4 | <%- include('../includes/navbar.ejs') %> 5 |
6 |
7 | <% if(prods.length > 0) { %> 8 |
9 | <% for(let product of prods) { %> 10 |
11 |
12 |

<%= product.title %>

13 |
14 |
15 | 19 |
20 |
21 |

Rs.<%= product.price %>

22 |

<%= product.description %>

23 |
24 |
25 | 26 |
27 | 28 | 29 |
30 |
31 |
32 | <%}%> 33 |
34 | <% } else { %> 35 |
36 |

Product list is empty. Add some product

37 |
38 | <% } %> 39 |
40 |
41 | <%- include('../includes/footer.ejs') %> 42 | --------------------------------------------------------------------------------