Compare commits

...

12 Commits

Author SHA1 Message Date
Mosiur Rahman
114b100659 Merge branch 'master' of http://103.209.42.141:3500/mosiur/ToDo 2026-05-11 20:22:44 +06:00
Mosiur Rahman
be24dafc25 Merge remote master with local project 2026-05-05 10:43:09 +06:00
Mosiur Rahman
dde0525402 Merge branch 'master' of http://103.209.42.141:3500/mosiur/ToDo 2026-05-05 10:42:16 +06:00
Mosiur
f462329114 App:final 2026-04-25 22:47:50 +06:00
Mosiur
4e6a1ef71f Completed the ToDo App 2026-04-25 22:45:00 +06:00
Mosiur
c295362495 React 2026-04-24 21:03:01 +06:00
Mosiur Rahman
ad313f3b21 Phase 3 server side configuration done 2026-04-23 16:10:00 +06:00
Mosiur Rahman
bd2c58f9ef Phase 2 done 2026-04-22 16:10:04 +06:00
Mosiur Rahman
6888405b59 added another API for db connection 2026-04-22 12:44:37 +06:00
Mosiur Rahman
5001b7fe97 phase 1 done 2026-04-22 10:09:53 +06:00
Mosiur Rahman
3a414cfabd Completed the server setup for health checkup 2026-04-21 19:04:07 +06:00
Mosiur Rahman
cff98994fd Created Frontend and backend server and using claude to deploy db.ts and env.ts 2026-04-20 16:03:37 +06:00
2750 changed files with 885195 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
# .gitignore
node_modules/
dist/
.env
*.env

9
Phase.txt Normal file
View File

@@ -0,0 +1,9 @@
1. Project setup — backend init, MongoDB connect, folder structure
2. User model + Register/Login endpoints + JWT
3. Todo model + full CRUD endpoints + middleware
4. React project setup + routing + Tailwind
5. Auth UI (Login/Register forms, AuthContext)
6. Todo UI (list, create, update, delete, toggle)
7. Filtering, priority, due dates
8. Polish — responsive design, UX details
9. Polish — responsive design, UX details

24
client/.gitignore vendored Normal file
View File

@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

73
client/README.md Normal file
View File

@@ -0,0 +1,73 @@
# React + TypeScript + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs)
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/)
## React Compiler
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
## Expanding the ESLint configuration
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
```js
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Remove tseslint.configs.recommended and replace with this
tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
tseslint.configs.stylisticTypeChecked,
// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```
You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
```js
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```

23
client/eslint.config.js Normal file
View File

@@ -0,0 +1,23 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { defineConfig, globalIgnores } from 'eslint/config'
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
},
])

13
client/index.html Normal file
View File

@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>client</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

3777
client/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

38
client/package.json Normal file
View File

@@ -0,0 +1,38 @@
{
"name": "client",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"axios": "^1.15.2",
"react": "^19.2.5",
"react-dom": "^19.2.5",
"react-hot-toast": "^2.6.0",
"react-router-dom": "^7.14.2"
},
"devDependencies": {
"@eslint/js": "^9.39.4",
"@tailwindcss/vite": "^4.2.4",
"@types/node": "^24.12.2",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@types/react-router-dom": "^5.3.3",
"@vitejs/plugin-react": "^6.0.1",
"autoprefixer": "^10.5.0",
"eslint": "^9.39.4",
"eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-react-refresh": "^0.5.2",
"globals": "^17.5.0",
"postcss": "^8.5.10",
"tailwindcss": "^4.2.4",
"typescript": "~6.0.2",
"typescript-eslint": "^8.58.2",
"vite": "^8.0.9"
}
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.3 KiB

24
client/public/icons.svg Normal file
View File

@@ -0,0 +1,24 @@
<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="bluesky-icon" viewBox="0 0 16 17">
<g clip-path="url(#bluesky-clip)"><path fill="#08060d" d="M7.75 7.735c-.693-1.348-2.58-3.86-4.334-5.097-1.68-1.187-2.32-.981-2.74-.79C.188 2.065.1 2.812.1 3.251s.241 3.602.398 4.13c.52 1.744 2.367 2.333 4.07 2.145-2.495.37-4.71 1.278-1.805 4.512 3.196 3.309 4.38-.71 4.987-2.746.608 2.036 1.307 5.91 4.93 2.746 2.72-2.746.747-4.143-1.747-4.512 1.702.189 3.55-.4 4.07-2.145.156-.528.397-3.691.397-4.13s-.088-1.186-.575-1.406c-.42-.19-1.06-.395-2.741.79-1.755 1.24-3.64 3.752-4.334 5.099"/></g>
<defs><clipPath id="bluesky-clip"><path fill="#fff" d="M.1.85h15.3v15.3H.1z"/></clipPath></defs>
</symbol>
<symbol id="discord-icon" viewBox="0 0 20 19">
<path fill="#08060d" d="M16.224 3.768a14.5 14.5 0 0 0-3.67-1.153c-.158.286-.343.67-.47.976a13.5 13.5 0 0 0-4.067 0c-.128-.306-.317-.69-.476-.976A14.4 14.4 0 0 0 3.868 3.77C1.546 7.28.916 10.703 1.231 14.077a14.7 14.7 0 0 0 4.5 2.306q.545-.748.965-1.587a9.5 9.5 0 0 1-1.518-.74q.191-.14.372-.293c2.927 1.369 6.107 1.369 8.999 0q.183.152.372.294-.723.437-1.52.74.418.838.963 1.588a14.6 14.6 0 0 0 4.504-2.308c.37-3.911-.63-7.302-2.644-10.309m-9.13 8.234c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.894 0 1.614.82 1.599 1.82.001 1-.705 1.82-1.6 1.82m5.91 0c-.878 0-1.599-.82-1.599-1.82 0-.998.705-1.82 1.6-1.82.893 0 1.614.82 1.599 1.82 0 1-.706 1.82-1.6 1.82"/>
</symbol>
<symbol id="documentation-icon" viewBox="0 0 21 20">
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="m15.5 13.333 1.533 1.322c.645.555.967.833.967 1.178s-.322.623-.967 1.179L15.5 18.333m-3.333-5-1.534 1.322c-.644.555-.966.833-.966 1.178s.322.623.966 1.179l1.534 1.321"/>
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M17.167 10.836v-4.32c0-1.41 0-2.117-.224-2.68-.359-.906-1.118-1.621-2.08-1.96-.599-.21-1.349-.21-2.848-.21-2.623 0-3.935 0-4.983.369-1.684.591-3.013 1.842-3.641 3.428C3 6.449 3 7.684 3 10.154v2.122c0 2.558 0 3.838.706 4.726q.306.383.713.671c.76.536 1.79.64 3.581.66"/>
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M3 10a2.78 2.78 0 0 1 2.778-2.778c.555 0 1.209.097 1.748-.047.48-.129.854-.503.982-.982.145-.54.048-1.194.048-1.749a2.78 2.78 0 0 1 2.777-2.777"/>
</symbol>
<symbol id="github-icon" viewBox="0 0 19 19">
<path fill="#08060d" fill-rule="evenodd" d="M9.356 1.85C5.05 1.85 1.57 5.356 1.57 9.694a7.84 7.84 0 0 0 5.324 7.44c.387.079.528-.168.528-.376 0-.182-.013-.805-.013-1.454-2.165.467-2.616-.935-2.616-.935-.349-.91-.864-1.143-.864-1.143-.71-.48.051-.48.051-.48.787.051 1.2.805 1.2.805.695 1.194 1.817.857 2.268.649.064-.507.27-.857.49-1.052-1.728-.182-3.545-.857-3.545-3.87 0-.857.31-1.558.8-2.104-.078-.195-.349-1 .077-2.078 0 0 .657-.208 2.14.805a7.5 7.5 0 0 1 1.946-.26c.657 0 1.328.092 1.946.26 1.483-1.013 2.14-.805 2.14-.805.426 1.078.155 1.883.078 2.078.502.546.799 1.247.799 2.104 0 3.013-1.818 3.675-3.558 3.87.284.247.528.714.528 1.454 0 1.052-.012 1.896-.012 2.156 0 .208.142.455.528.377a7.84 7.84 0 0 0 5.324-7.441c.013-4.338-3.48-7.844-7.773-7.844" clip-rule="evenodd"/>
</symbol>
<symbol id="social-icon" viewBox="0 0 20 20">
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M12.5 6.667a4.167 4.167 0 1 0-8.334 0 4.167 4.167 0 0 0 8.334 0"/>
<path fill="none" stroke="#aa3bff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.35" d="M2.5 16.667a5.833 5.833 0 0 1 8.75-5.053m3.837.474.513 1.035c.07.144.257.282.414.309l.93.155c.596.1.736.536.307.965l-.723.73a.64.64 0 0 0-.152.531l.207.903c.164.715-.213.991-.84.618l-.872-.52a.63.63 0 0 0-.577 0l-.872.52c-.624.373-1.003.094-.84-.618l.207-.903a.64.64 0 0 0-.152-.532l-.723-.729c-.426-.43-.289-.864.306-.964l.93-.156a.64.64 0 0 0 .412-.31l.513-1.034c.28-.562.735-.562 1.012 0"/>
</symbol>
<symbol id="x-icon" viewBox="0 0 19 19">
<path fill="#08060d" fill-rule="evenodd" d="M1.893 1.98c.052.072 1.245 1.769 2.653 3.77l2.892 4.114c.183.261.333.48.333.486s-.068.089-.152.183l-.522.593-.765.867-3.597 4.087c-.375.426-.734.834-.798.905a1 1 0 0 0-.118.148c0 .01.236.017.664.017h.663l.729-.83c.4-.457.796-.906.879-.999a692 692 0 0 0 1.794-2.038c.034-.037.301-.34.594-.675l.551-.624.345-.392a7 7 0 0 1 .34-.374c.006 0 .93 1.306 2.052 2.903l2.084 2.965.045.063h2.275c1.87 0 2.273-.003 2.266-.021-.008-.02-1.098-1.572-3.894-5.547-2.013-2.862-2.28-3.246-2.273-3.266.008-.019.282-.332 2.085-2.38l2-2.274 1.567-1.782c.022-.028-.016-.03-.65-.03h-.674l-.3.342a871 871 0 0 1-1.782 2.025c-.067.075-.405.458-.75.852a100 100 0 0 1-.803.91c-.148.172-.299.344-.99 1.127-.304.343-.32.358-.345.327-.015-.019-.904-1.282-1.976-2.808L6.365 1.85H1.8zm1.782.91 8.078 11.294c.772 1.08 1.413 1.973 1.425 1.984.016.017.241.02 1.05.017l1.03-.004-2.694-3.766L7.796 5.75 5.722 2.852l-1.039-.004-1.039-.004z" clip-rule="evenodd"/>
</symbol>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

184
client/src/App.css Normal file
View File

@@ -0,0 +1,184 @@
.counter {
font-size: 16px;
padding: 5px 10px;
border-radius: 5px;
color: var(--accent);
background: var(--accent-bg);
border: 2px solid transparent;
transition: border-color 0.3s;
margin-bottom: 24px;
&:hover {
border-color: var(--accent-border);
}
&:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
}
.hero {
position: relative;
.base,
.framework,
.vite {
inset-inline: 0;
margin: 0 auto;
}
.base {
width: 170px;
position: relative;
z-index: 0;
}
.framework,
.vite {
position: absolute;
}
.framework {
z-index: 1;
top: 34px;
height: 28px;
transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg)
scale(1.4);
}
.vite {
z-index: 0;
top: 107px;
height: 26px;
width: auto;
transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg)
scale(0.8);
}
}
#center {
display: flex;
flex-direction: column;
gap: 25px;
place-content: center;
place-items: center;
flex-grow: 1;
@media (max-width: 1024px) {
padding: 32px 20px 24px;
gap: 18px;
}
}
#next-steps {
display: flex;
border-top: 1px solid var(--border);
text-align: left;
& > div {
flex: 1 1 0;
padding: 32px;
@media (max-width: 1024px) {
padding: 24px 20px;
}
}
.icon {
margin-bottom: 16px;
width: 22px;
height: 22px;
}
@media (max-width: 1024px) {
flex-direction: column;
text-align: center;
}
}
#docs {
border-right: 1px solid var(--border);
@media (max-width: 1024px) {
border-right: none;
border-bottom: 1px solid var(--border);
}
}
#next-steps ul {
list-style: none;
padding: 0;
display: flex;
gap: 8px;
margin: 32px 0 0;
.logo {
height: 18px;
}
a {
color: var(--text-h);
font-size: 16px;
border-radius: 6px;
background: var(--social-bg);
display: flex;
padding: 6px 12px;
align-items: center;
gap: 8px;
text-decoration: none;
transition: box-shadow 0.3s;
&:hover {
box-shadow: var(--shadow);
}
.button-icon {
height: 18px;
width: 18px;
}
}
@media (max-width: 1024px) {
margin-top: 20px;
flex-wrap: wrap;
justify-content: center;
li {
flex: 1 1 calc(50% - 8px);
}
a {
width: 100%;
justify-content: center;
box-sizing: border-box;
}
}
}
#spacer {
height: 88px;
border-top: 1px solid var(--border);
@media (max-width: 1024px) {
height: 48px;
}
}
.ticks {
position: relative;
width: 100%;
&::before,
&::after {
content: '';
position: absolute;
top: -4.5px;
border: 5px solid transparent;
}
&::before {
left: 0;
border-left-color: var(--border);
}
&::after {
right: 0;
border-right-color: var(--border);
}
}

39
client/src/App.tsx Normal file
View File

@@ -0,0 +1,39 @@
import type { ReactNode } from 'react'
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom'
import { AuthProvider, useAuth } from './context/AuthContext'
import LoginPage from './pages/LoginPage'
import RegisterPage from './pages/RegisterPage'
import DashboardPage from './pages/DashboardPage'
const ProtectedRoute = ({ children }: { children: ReactNode }) => {
const { isAuthenticated } = useAuth()
if (!isAuthenticated) {
return <Navigate to="/login" />
}
return <>{children}</>
}
const RootRedirect = () => {
const { isAuthenticated } = useAuth()
return <Navigate to={isAuthenticated ? '/dashboard' : '/login'} />
}
function App() {
return (
<AuthProvider>
<BrowserRouter>
<Routes>
<Route path="/" element={<RootRedirect />} />
<Route path="/login" element={<LoginPage />} />
<Route path="/register" element={<RegisterPage />} />
<Route path="/dashboard" element={
<ProtectedRoute>
<DashboardPage />
</ProtectedRoute>
} />
</Routes>
</BrowserRouter>
</AuthProvider>
)
}
export default App

16
client/src/api/axios.ts Normal file
View File

@@ -0,0 +1,16 @@
import axios from 'axios';
const api = axios.create({
baseURL: "/api",
})
api.interceptors.request.use((config)=>{
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
})
export default api

BIN
client/src/assets/hero.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

@@ -0,0 +1,36 @@
// src/components/Navbar.tsx
import { useAuth } from '../context/AuthContext'
const Navbar = () => {
const { user, logout } = useAuth()
return (
<nav className="bg-white border-b border-gray-200 px-6 py-4">
<div className="max-w-3xl mx-auto flex items-center justify-between">
{/* Logo */}
<div className="flex items-center gap-2">
<span className="font-bold text-gray-900 text-lg">
TodoApp
</span>
</div>
{/* Right side — user + logout */}
<div className="flex items-center gap-4">
<span className="text-sm text-gray-600">
{user?.name}
</span>
<button
onClick={logout}
className="text-sm text-gray-500 hover:text-red-500 transition font-medium"
>
Logout
</button>
</div>
</div>
</nav>
)
}
export default Navbar

View File

@@ -0,0 +1,105 @@
// src/components/todos/TodoForm.tsx
import { useState } from 'react'
// Props — what this component receives from parent
interface TodoFormProps {
onSubmit: (data: {
title: string
priority: 'low' | 'medium' | 'high'
description?: string
dueDate?: string
}) => Promise<void>
}
const TodoForm = ({ onSubmit }: TodoFormProps) => {
const [title, setTitle] = useState('')
const [priority, setPriority] = useState<'low' | 'medium' | 'high'>('medium')
const [isExpanded, setIsExpanded] = useState(false)
const [description, setDescription] = useState('')
const [dueDate, setDueDate] = useState('')
const [isLoading, setIsLoading] = useState(false)
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (!title.trim()) return // dont submit empty title
setIsLoading(true)
await onSubmit({
title: title.trim(),
priority,
description: description || undefined,
dueDate: dueDate || undefined
})
// Reset form after submit
setTitle('')
setDescription('')
setDueDate('')
setPriority('medium')
setIsExpanded(false)
setIsLoading(false)
}
return (
<form
onSubmit={handleSubmit}
className="bg-white rounded-xl border border-gray-200 p-4 mb-6"
>
{/* Main input row */}
<div className="flex gap-3">
<input
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
onFocus={() => setIsExpanded(true)}
placeholder="Add a new todo..."
className="flex-1 text-sm outline-none text-gray-800 placeholder-gray-400"
/>
<button
type="submit"
disabled={!title.trim() || isLoading}
className="bg-blue-600 hover:bg-blue-700 disabled:bg-gray-300 disabled:cursor-not-allowed text-white text-sm font-medium px-4 py-2 rounded-lg transition"
>
{isLoading ? 'Adding...' : 'Add'}
</button>
</div>
{/* Expanded options — show when input is focused */}
{isExpanded && (
<div className="mt-4 pt-4 border-t border-gray-100 flex flex-wrap gap-3">
{/* Priority selector */}
<select
value={priority}
onChange={(e) => setPriority(e.target.value as 'low' | 'medium' | 'high')}
className="text-sm border border-gray-200 rounded-lg px-3 py-1.5 outline-none text-gray-700"
>
<option value="low">🟢 Low</option>
<option value="medium">🟡 Medium</option>
<option value="high">🔴 High</option>
</select>
{/* Due date */}
<input
type="date"
value={dueDate}
onChange={(e) => setDueDate(e.target.value)}
className="text-sm border border-gray-200 rounded-lg px-3 py-1.5 outline-none text-gray-700"
/>
{/* Description */}
<input
type="text"
value={description}
onChange={(e) => setDescription(e.target.value)}
placeholder="Add description..."
className="flex-1 text-sm border border-gray-200 rounded-lg px-3 py-1.5 outline-none text-gray-700"
/>
</div>
)}
</form>
)
}
export default TodoForm

View File

@@ -0,0 +1,198 @@
// src/components/todos/TodoItem.tsx
import { useState } from 'react'
import type { Todo } from '../../types'
interface TodoItemProps {
todo: Todo
onToggle: (id: string) => void
onDelete: (id: string) => void
onUpdate: (id: string, data: Partial<Todo>) => void
}
const priorityConfig = {
high: { label: 'High', className: 'bg-red-100 text-red-600' },
medium: { label: 'Medium', className: 'bg-yellow-100 text-yellow-600' },
low: { label: 'Low', className: 'bg-green-100 text-green-600' },
}
const TodoItem = ({ todo, onToggle, onDelete, onUpdate }: TodoItemProps) => {
const [isEditing, setIsEditing] = useState(false)
const [editTitle, setEditTitle] = useState(todo.title)
const [editPriority, setEditPriority] = useState(todo.priority)
const priority = priorityConfig[todo.priority]
// Save edit
const handleSave = () => {
if (!editTitle.trim()) return
onUpdate(todo._id, {
title: editTitle.trim(),
priority: editPriority
})
setIsEditing(false)
}
// Cancel edit — reset to original values
const handleCancel = () => {
setEditTitle(todo.title)
setEditPriority(todo.priority)
setIsEditing(false)
}
// Save on Enter, cancel on Escape
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter') handleSave()
if (e.key === 'Escape') handleCancel()
}
// ── Edit Mode UI ───────────────────────────────────
if (isEditing) {
return (
<div className="flex items-center gap-3 p-4 rounded-xl border border-blue-300 bg-blue-50">
<input
autoFocus
type="text"
value={editTitle}
onChange={(e) => setEditTitle(e.target.value)}
onKeyDown={handleKeyDown}
className="flex-1 text-sm bg-white border border-gray-200 rounded-lg px-3 py-2 outline-none focus:ring-2 focus:ring-blue-500"
/>
<select
value={editPriority}
onChange={(e) => setEditPriority(e.target.value as 'low' | 'medium' | 'high')}
className="text-sm border border-gray-200 rounded-lg px-2 py-2 outline-none bg-white"
>
<option value="low">🟢 Low</option>
<option value="medium">🟡 Medium</option>
<option value="high">🔴 High</option>
</select>
{/* Save button */}
<button
onClick={handleSave}
className="text-sm bg-blue-600 hover:bg-blue-700 text-white px-3 py-2 rounded-lg transition font-medium"
>
Save
</button>
{/* Cancel button */}
<button
onClick={handleCancel}
className="text-sm text-gray-500 hover:text-gray-700 px-3 py-2 rounded-lg transition"
>
Cancel
</button>
</div>
)
}
// ── Normal Mode UI ─────────────────────────────────
return (
<div className={`
flex items-center gap-4 p-4 rounded-xl border transition group
${todo.completed
? 'bg-gray-50 border-gray-100'
: 'bg-white border-gray-200 hover:border-gray-300'
}
`}>
{/* Checkbox */}
<button
onClick={() => onToggle(todo._id)}
className={`
w-5 h-5 rounded-full border-2 flex items-center
justify-center flex-shrink-0 transition
${todo.completed
? 'bg-blue-600 border-blue-600'
: 'border-gray-300 hover:border-blue-400'
}
`}
>
{todo.completed && (
<svg className="w-3 h-3 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
</svg>
)}
</button>
{/* Content */}
<div className="flex-1 min-w-0">
<p className={`
text-sm font-medium truncate
${todo.completed ? 'line-through text-gray-400' : 'text-gray-800'}
`}>
{todo.title}
</p>
<div className="flex items-center gap-3 mt-0.5">
{todo.description && (
<span className="text-xs text-gray-400 truncate">
{todo.description}
</span>
)}
{todo.dueDate && (
<DueDateBadge dueDate={todo.dueDate} completed={todo.completed} />
)}
</div>
</div>
{/* Priority badge */}
<span className={`
text-xs font-medium px-2.5 py-1 rounded-full flex-shrink-0
${priority.className}
`}>
{priority.label}
</span>
{/* Edit button — visible on hover */}
<button
onClick={() => setIsEditing(true)}
className="text-gray-300 hover:text-blue-500 transition flex-shrink-0 opacity-0 group-hover:opacity-100"
>
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
</svg>
</button>
{/* Delete button */}
<button
onClick={() => onDelete(todo._id)}
className="text-gray-300 hover:text-red-500 transition flex-shrink-0 opacity-0 group-hover:opacity-100"
>
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
)
}
// ── Due Date Badge ─────────────────────────────────────
// Separate small component — single responsibility
const DueDateBadge = ({ dueDate, completed }: { dueDate: string, completed: boolean }) => {
const date = new Date(dueDate)
const today = new Date()
today.setHours(0, 0, 0, 0)
const isOverdue = date < today && !completed
const isToday = date.toDateString() === today.toDateString()
return (
<span className={`
text-xs flex items-center gap-1
${isOverdue ? 'text-red-500 font-medium' : ''}
${isToday ? 'text-orange-500 font-medium' : ''}
${!isOverdue && !isToday ? 'text-gray-400' : ''}
`}>
📅 {isOverdue && '⚠️ '}
{date.toLocaleDateString()}
{isToday && ' (Today)'}
</span>
)
}
export default TodoItem

View File

@@ -0,0 +1,50 @@
// src/components/todos/TodoList.tsx
import type { Todo } from '../../types'
import TodoItem from './TodoItem'
interface TodoListProps {
todos: Todo[]
onToggle: (id: string) => void
onDelete: (id: string) => void
onUpdate: (id: string, data: Partial<Todo>) => void // ← add this
isLoading: boolean
}
const TodoList = ({ todos, onToggle, onDelete, onUpdate, isLoading }: TodoListProps) => {
if (isLoading) {
return (
<div className="flex flex-col gap-2">
{[1,2,3].map(i => (
<div key={i} className="h-16 bg-white rounded-xl border border-gray-200 animate-pulse" />
))}
</div>
)
}
if (todos.length === 0) {
return (
<div className="text-center py-12">
<p className="text-4xl mb-3">✅</p>
<p className="text-gray-500 text-sm font-medium">No todos here!</p>
<p className="text-gray-400 text-xs mt-1">Add one above to get started</p>
</div>
)
}
return (
<div className="flex flex-col gap-2">
{todos.map(todo => (
<TodoItem
key={todo._id}
todo={todo}
onToggle={onToggle}
onDelete={onDelete}
onUpdate={onUpdate} // ← pass down
/>
))}
</div>
)
}
export default TodoList

View File

@@ -0,0 +1,60 @@
import type { AuthResponse, User } from "../types"
import { createContext, useContext, useState, ReactNode } from 'react'
interface AuthContextType {
user: User | null
token: string | null
login: (data: AuthResponse) => void
logout: () => void
isAuthenticated: boolean
}
const AuthContext = createContext<AuthContextType | null>(null)
export const AuthProvider = ({ children }: { children: ReactNode }) => {
const [user,setUser] = useState<User | null>(()=> {
const stored = localStorage.getItem('user')
return stored ? JSON.parse(stored) : null
})
const [token, setToken] = useState<string | null>(
localStorage.getItem('token')
)
const login = (data: AuthResponse) => {
setUser(data.user)
setToken(data.token)
localStorage.setItem('token',data.token)
localStorage.setItem('user',JSON.stringify(data.user))
}
const logout = () => {
setUser(null)
setToken(null)
localStorage.removeItem('token')
localStorage.removeItem('user')
}
const value: AuthContextType = {
user,
token,
login,
logout,
isAuthenticated: !!token
}
return(
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
)
}
export const useAuth = () => {
const context = useContext(AuthContext)
if (!context) {
throw new Error ('useAuth must be used within AuthProvider')
}
return context
}

View File

@@ -0,0 +1,94 @@
// src/hooks/useTodos.ts
import { useState, useEffect } from 'react'
import toast from 'react-hot-toast'
import api from '../api/axios'
import type { Todo } from '../types'
export const useTodos = () => {
const [todos, setTodos] = useState<Todo[]>([])
const [isLoading, setIsLoading] = useState<boolean>(false)
const [error, setError] = useState<string>('')
const fetchTodos = async () => {
setIsLoading(true)
try {
const response = await api.get<{ todos: Todo[] }>('/todos')
setTodos(response.data.todos)
} catch {
toast.error('Failed to load todos')
setError('Failed to fetch todos')
} finally {
setIsLoading(false)
}
}
const createTodo = async (data: {
title: string
description?: string
priority?: 'low' | 'medium' | 'high'
dueDate?: string
}) => {
try {
const response = await api.post<{ todo: Todo }>('/todos', data)
setTodos(prev => [response.data.todo, ...prev])
toast.success('Todo created!')
} catch {
toast.error('Failed to create todo')
}
}
const toggleTodo = async (id: string) => {
try {
const response = await api.patch<{ todo: Todo }>(`/todos/${id}/toggle`)
setTodos(prev =>
prev.map(todo =>
todo._id === id ? response.data.todo : todo
)
)
// Dynamic message based on new state
const isNowComplete = response.data.todo.completed
toast.success(isNowComplete ? 'Todo completed! 🎉' : 'Todo reopened')
} catch {
toast.error('Failed to update todo')
}
}
const deleteTodo = async (id: string) => {
try {
await api.delete(`/todos/${id}`)
setTodos(prev => prev.filter(todo => todo._id !== id))
toast.success('Todo deleted')
} catch {
toast.error('Failed to delete todo')
}
}
const updateTodo = async (id: string, data: Partial<Todo>) => {
try {
const response = await api.put<{ todo: Todo }>(`/todos/${id}`, data)
setTodos(prev =>
prev.map(todo =>
todo._id === id ? response.data.todo : todo
)
)
toast.success('Todo updated!')
} catch {
toast.error('Failed to update todo')
}
}
useEffect(() => {
fetchTodos()
}, [])
return {
todos,
isLoading,
error,
createTodo,
toggleTodo,
deleteTodo,
updateTodo,
fetchTodos
}
}

1
client/src/index.css Normal file
View File

@@ -0,0 +1 @@
@import "tailwindcss";

24
client/src/main.tsx Normal file
View File

@@ -0,0 +1,24 @@
// src/main.tsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { Toaster } from 'react-hot-toast'
import './index.css'
import App from './App.tsx'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
<Toaster
position="bottom-right"
toastOptions={{
duration: 3000,
style: {
background: '#1f2937',
color: '#f9fafb',
fontSize: '14px',
borderRadius: '10px',
},
}}
/>
</StrictMode>
)

View File

@@ -0,0 +1,86 @@
// src/pages/DashboardPage.tsx
import { useState } from 'react'
import { useAuth } from '../context/AuthContext'
import { useTodos } from '../hooks/useTodos'
import Navbar from '../components/Navbar'
import TodoForm from '../components/todos/TodoForm'
import TodoList from '../components/todos/TodoList'
type FilterType = 'all' | 'pending' | 'completed'
const DashboardPage = () => {
const { user } = useAuth()
const { todos, isLoading, createTodo, toggleTodo, deleteTodo, updateTodo } = useTodos()
const [filter, setFilter] = useState<FilterType>('all')
const filteredTodos = todos.filter(todo => {
if (filter === 'completed') return todo.completed
if (filter === 'pending') return !todo.completed
return true
})
const filters: { label: string; value: FilterType; count: number }[] = [
{ label: 'All', value: 'all', count: todos.length },
{ label: 'Pending', value: 'pending', count: todos.filter(t => !t.completed).length },
{ label: 'Completed', value: 'completed', count: todos.filter(t => t.completed).length },
]
return (
<div className="min-h-screen bg-gray-50">
<Navbar />
<main className="max-w-3xl mx-auto px-4 py-8">
<div className="mb-8">
<h1 className="text-2xl font-bold text-gray-900">
Good day, {user?.name}!
</h1>
<p className="text-gray-500 text-sm mt-1">
You have {todos.filter(t => !t.completed).length} pending todos
</p>
</div>
<TodoForm onSubmit={createTodo} />
<div className="flex gap-2 mb-4">
{filters.map(f => (
<button
key={f.value}
onClick={() => setFilter(f.value)}
className={`
px-4 py-2 rounded-lg text-sm font-medium transition
flex items-center gap-2
${filter === f.value
? 'bg-blue-600 text-white'
: 'bg-white text-gray-600 border border-gray-200 hover:border-gray-300'
}
`}
>
{f.label}
<span className={`
text-xs px-1.5 py-0.5 rounded-full
${filter === f.value
? 'bg-blue-500 text-white'
: 'bg-gray-100 text-gray-500'
}
`}>
{f.count}
</span>
</button>
))}
</div>
<TodoList
todos={filteredTodos}
onToggle={toggleTodo}
onDelete={deleteTodo}
onUpdate={updateTodo}
isLoading={isLoading}
/>
</main>
</div>
)
}
export default DashboardPage

View File

@@ -0,0 +1,132 @@
// src/pages/LoginPage.tsx
import { useState } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import { useAuth } from '../context/AuthContext'
import api from '../api/axios'
import type { AuthResponse } from '../types'
import axios from 'axios'
const LoginPage = () => {
// ── State ──────────────────────────────────────────
const [email, setEmail] = useState<string>('')
const [password, setPassword] = useState<string>('')
const [error, setError] = useState<string>('')
const [isLoading, setIsLoading] = useState<boolean>(false)
// ── Hooks ──────────────────────────────────────────
const { login } = useAuth() // get login function from context
const navigate = useNavigate() // programmatic navigation
// ── Submit Handler ─────────────────────────────────
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
setError('') // clear previous errors
setIsLoading(true)
try {
const response = await api.post<AuthResponse>('/auth/login', {
email,
password
})
login(response.data) // save token + user to context
navigate('/dashboard') // redirect to dashboard
} catch (err: unknown) {
// Axios wraps errors — need to extract message
if (axios.isAxiosError(err)) {
setError(
err.response?.data?.message || 'Login failed'
)
} else {
setError('Something went wrong')
}
} finally {
setIsLoading(false)
}
}
// ── UI ─────────────────────────────────────────────
return (
// Full screen centered layout
<div className="min-h-screen bg-gray-50 flex items-center justify-center p-4">
{/* Card container */}
<div className="bg-white rounded-2xl shadow-sm border border-gray-200 w-full max-w-md p-8">
{/* Header */}
<div className="text-center mb-8">
<h1 className="text-2xl font-bold text-gray-900">
Welcome back
</h1>
<p className="text-gray-500 mt-2 text-sm">
Sign in to your account
</p>
</div>
{/* Error message */}
{error && (
<div className="bg-red-50 text-red-600 text-sm px-4 py-3 rounded-lg mb-6">
{error}
</div>
)}
{/* Form */}
<form onSubmit={handleSubmit} className="space-y-5">
{/* Email field */}
<div>
<label className="block text-sm font-medium text-gray-700 mb-1.5">
Email
</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="you@example.com"
required
className="w-full px-4 py-2.5 rounded-lg border border-gray-300 text-sm outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition"
/>
</div>
{/* Password field */}
<div>
<label className="block text-sm font-medium text-gray-700 mb-1.5">
Password
</label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="••••••••"
required
className="w-full px-4 py-2.5 rounded-lg border border-gray-300 text-sm outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition"
/>
</div>
{/* Submit button */}
<button
type="submit"
disabled={isLoading}
className="w-full bg-blue-600 hover:bg-blue-700 disabled:bg-blue-400 disabled:cursor-not-allowed text-white font-medium py-2.5 px-4 rounded-lg text-sm transition"
>
{isLoading ? 'Signing in...' : 'Sign in'}
</button>
</form>
{/* Register link */}
<p className="text-center text-sm text-gray-500 mt-6">
Don't have an account?{' '}
<Link
to="/register"
className="text-blue-600 hover:underline font-medium"
>
Register
</Link>
</p>
</div>
</div>
)
}
export default LoginPage

View File

@@ -0,0 +1,145 @@
import { useState } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import { useAuth } from '../context/AuthContext'
import api from '../api/axios'
import type { AuthResponse } from '../types'
import axios from 'axios'
const RegisterPage = () => {
const [name, setName] = useState<string>('')
const [email, setEmail] = useState<string>('')
const [password, setPassword] = useState<string>('')
const [confirmPassword, setConfirmPassword] = useState<string>('')
const [error, setError] = useState<string>('')
const [isLoading, setIsLoading] = useState<boolean>(false)
const { login } = useAuth()
const navigate = useNavigate()
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
setError('')
// Validate passwords match BEFORE api call
if (password !== confirmPassword) {
setError('Passwords do not match')
return
}
setIsLoading(true)
try {
const response = await api.post<AuthResponse>('/auth/register', {
name,
email,
password
})
login(response.data) // ← auto login
navigate('/dashboard') // ← redirect
} catch (err: unknown) {
if (axios.isAxiosError(err)) {
setError(err.response?.data?.message || 'Register failed')
} else {
setError('Something went wrong')
}
} finally {
setIsLoading(false)
}
}
return (
<div className="min-h-screen bg-gray-50 flex items-center justify-center p-4">
<div className="bg-white rounded-2xl shadow-sm border border-gray-200 w-full max-w-md p-8">
<div className="text-center mb-8">
<h1 className="text-2xl font-bold text-gray-900">
Create account
</h1>
<p className="text-gray-500 mt-2 text-sm">
Sign up for a new account
</p>
</div>
{error && (
<div className="bg-red-50 text-red-600 text-sm px-4 py-3 rounded-lg mb-6">
{error}
</div>
)}
<form onSubmit={handleSubmit} className="space-y-5">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1.5">
Full Name
</label>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="John Doe"
required
className="w-full px-4 py-2.5 rounded-lg border border-gray-300 text-sm outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1.5">
Email
</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="you@example.com"
required
className="w-full px-4 py-2.5 rounded-lg border border-gray-300 text-sm outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1.5">
Password
</label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="••••••••"
required
className="w-full px-4 py-2.5 rounded-lg border border-gray-300 text-sm outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1.5">
Confirm Password
</label>
<input
type="password"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
placeholder="••••••••"
required
className="w-full px-4 py-2.5 rounded-lg border border-gray-300 text-sm outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition"
/>
</div>
<button
type="submit"
disabled={isLoading}
className="w-full bg-blue-600 hover:bg-blue-700 disabled:bg-blue-400 disabled:cursor-not-allowed text-white font-medium py-2.5 px-4 rounded-lg text-sm transition"
>
{isLoading ? 'Creating account...' : 'Create account'}
</button>
</form>
<p className="text-center text-sm text-gray-500 mt-6">
Already have an account?{' '}
<Link to="/login" className="text-blue-600 hover:underline font-medium">
Sign in
</Link>
</p>
</div>
</div>
)
}
export default RegisterPage

26
client/src/types/index.ts Normal file
View File

@@ -0,0 +1,26 @@
export interface User {
_id: string,
name: string,
email: string
}
export interface Todo {
_id: string
title: string
description?: string
completed: boolean
priority: 'low' | 'medium' | 'high'
dueDate?: string
user: string
createdAt: string
updatedAt: string
}``
export interface AuthResponse {
token: string,
user: User
}
export interface TodosResponse {
todos: Todo[]
}

25
client/tsconfig.app.json Normal file
View File

@@ -0,0 +1,25 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "es2023",
"lib": ["ES2023", "DOM"],
"module": "esnext",
"types": ["vite/client"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"noUnusedLocals": true,
"noUnusedParameters": true,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}

7
client/tsconfig.json Normal file
View File

@@ -0,0 +1,7 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
]
}

24
client/tsconfig.node.json Normal file
View File

@@ -0,0 +1,24 @@
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "es2023",
"lib": ["ES2023"],
"module": "esnext",
"types": ["node"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"noUnusedLocals": true,
"noUnusedParameters": true,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true
},
"include": ["vite.config.ts"]
}

14
client/vite.config.ts Normal file
View File

@@ -0,0 +1,14 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
// https://vite.dev/config/
export default defineConfig({
plugins: [react(), tailwindcss()],
server: {
proxy: {
'/api': 'http://localhost:5000' //forward api calls to Express
},
},
});

6
package-lock.json generated Normal file
View File

@@ -0,0 +1,6 @@
{
"name": "ToDo",
"lockfileVersion": 3,
"requires": true,
"packages": {}
}

16
server/node_modules/.bin/acorn generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../acorn/bin/acorn" "$@"
else
exec node "$basedir/../acorn/bin/acorn" "$@"
fi

17
server/node_modules/.bin/acorn.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\acorn\bin\acorn" %*

28
server/node_modules/.bin/acorn.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../acorn/bin/acorn" $args
} else {
& "$basedir/node$exe" "$basedir/../acorn/bin/acorn" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../acorn/bin/acorn" $args
} else {
& "node$exe" "$basedir/../acorn/bin/acorn" $args
}
$ret=$LASTEXITCODE
}
exit $ret

16
server/node_modules/.bin/bcrypt generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../bcryptjs/bin/bcrypt" "$@"
else
exec node "$basedir/../bcryptjs/bin/bcrypt" "$@"
fi

17
server/node_modules/.bin/bcrypt.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\bcryptjs\bin\bcrypt" %*

28
server/node_modules/.bin/bcrypt.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../bcryptjs/bin/bcrypt" $args
} else {
& "$basedir/node$exe" "$basedir/../bcryptjs/bin/bcrypt" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../bcryptjs/bin/bcrypt" $args
} else {
& "node$exe" "$basedir/../bcryptjs/bin/bcrypt" $args
}
$ret=$LASTEXITCODE
}
exit $ret

16
server/node_modules/.bin/mkdirp generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../mkdirp/bin/cmd.js" "$@"
else
exec node "$basedir/../mkdirp/bin/cmd.js" "$@"
fi

17
server/node_modules/.bin/mkdirp.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mkdirp\bin\cmd.js" %*

28
server/node_modules/.bin/mkdirp.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../mkdirp/bin/cmd.js" $args
} else {
& "$basedir/node$exe" "$basedir/../mkdirp/bin/cmd.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../mkdirp/bin/cmd.js" $args
} else {
& "node$exe" "$basedir/../mkdirp/bin/cmd.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret

16
server/node_modules/.bin/resolve generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../resolve/bin/resolve" "$@"
else
exec node "$basedir/../resolve/bin/resolve" "$@"
fi

17
server/node_modules/.bin/resolve.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\resolve\bin\resolve" %*

28
server/node_modules/.bin/resolve.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../resolve/bin/resolve" $args
} else {
& "$basedir/node$exe" "$basedir/../resolve/bin/resolve" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../resolve/bin/resolve" $args
} else {
& "node$exe" "$basedir/../resolve/bin/resolve" $args
}
$ret=$LASTEXITCODE
}
exit $ret

16
server/node_modules/.bin/rimraf generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../rimraf/bin.js" "$@"
else
exec node "$basedir/../rimraf/bin.js" "$@"
fi

17
server/node_modules/.bin/rimraf.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\rimraf\bin.js" %*

28
server/node_modules/.bin/rimraf.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../rimraf/bin.js" $args
} else {
& "$basedir/node$exe" "$basedir/../rimraf/bin.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../rimraf/bin.js" $args
} else {
& "node$exe" "$basedir/../rimraf/bin.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret

16
server/node_modules/.bin/semver generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../semver/bin/semver.js" "$@"
else
exec node "$basedir/../semver/bin/semver.js" "$@"
fi

17
server/node_modules/.bin/semver.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\semver\bin\semver.js" %*

28
server/node_modules/.bin/semver.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args
} else {
& "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../semver/bin/semver.js" $args
} else {
& "node$exe" "$basedir/../semver/bin/semver.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret

16
server/node_modules/.bin/tree-kill generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../tree-kill/cli.js" "$@"
else
exec node "$basedir/../tree-kill/cli.js" "$@"
fi

17
server/node_modules/.bin/tree-kill.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\tree-kill\cli.js" %*

28
server/node_modules/.bin/tree-kill.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../tree-kill/cli.js" $args
} else {
& "$basedir/node$exe" "$basedir/../tree-kill/cli.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../tree-kill/cli.js" $args
} else {
& "node$exe" "$basedir/../tree-kill/cli.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret

16
server/node_modules/.bin/ts-node generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../ts-node/dist/bin.js" "$@"
else
exec node "$basedir/../ts-node/dist/bin.js" "$@"
fi

16
server/node_modules/.bin/ts-node-cwd generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../ts-node/dist/bin-cwd.js" "$@"
else
exec node "$basedir/../ts-node/dist/bin-cwd.js" "$@"
fi

17
server/node_modules/.bin/ts-node-cwd.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\ts-node\dist\bin-cwd.js" %*

28
server/node_modules/.bin/ts-node-cwd.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../ts-node/dist/bin-cwd.js" $args
} else {
& "$basedir/node$exe" "$basedir/../ts-node/dist/bin-cwd.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../ts-node/dist/bin-cwd.js" $args
} else {
& "node$exe" "$basedir/../ts-node/dist/bin-cwd.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret

16
server/node_modules/.bin/ts-node-dev generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../ts-node-dev/lib/bin.js" "$@"
else
exec node "$basedir/../ts-node-dev/lib/bin.js" "$@"
fi

17
server/node_modules/.bin/ts-node-dev.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\ts-node-dev\lib\bin.js" %*

28
server/node_modules/.bin/ts-node-dev.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../ts-node-dev/lib/bin.js" $args
} else {
& "$basedir/node$exe" "$basedir/../ts-node-dev/lib/bin.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../ts-node-dev/lib/bin.js" $args
} else {
& "node$exe" "$basedir/../ts-node-dev/lib/bin.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret

16
server/node_modules/.bin/ts-node-esm generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../ts-node/dist/bin-esm.js" "$@"
else
exec node "$basedir/../ts-node/dist/bin-esm.js" "$@"
fi

17
server/node_modules/.bin/ts-node-esm.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\ts-node\dist\bin-esm.js" %*

28
server/node_modules/.bin/ts-node-esm.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../ts-node/dist/bin-esm.js" $args
} else {
& "$basedir/node$exe" "$basedir/../ts-node/dist/bin-esm.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../ts-node/dist/bin-esm.js" $args
} else {
& "node$exe" "$basedir/../ts-node/dist/bin-esm.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret

16
server/node_modules/.bin/ts-node-script generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../ts-node/dist/bin-script.js" "$@"
else
exec node "$basedir/../ts-node/dist/bin-script.js" "$@"
fi

17
server/node_modules/.bin/ts-node-script.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\ts-node\dist\bin-script.js" %*

28
server/node_modules/.bin/ts-node-script.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../ts-node/dist/bin-script.js" $args
} else {
& "$basedir/node$exe" "$basedir/../ts-node/dist/bin-script.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../ts-node/dist/bin-script.js" $args
} else {
& "node$exe" "$basedir/../ts-node/dist/bin-script.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret

16
server/node_modules/.bin/ts-node-transpile-only generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../ts-node/dist/bin-transpile.js" "$@"
else
exec node "$basedir/../ts-node/dist/bin-transpile.js" "$@"
fi

17
server/node_modules/.bin/ts-node-transpile-only.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\ts-node\dist\bin-transpile.js" %*

28
server/node_modules/.bin/ts-node-transpile-only.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../ts-node/dist/bin-transpile.js" $args
} else {
& "$basedir/node$exe" "$basedir/../ts-node/dist/bin-transpile.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../ts-node/dist/bin-transpile.js" $args
} else {
& "node$exe" "$basedir/../ts-node/dist/bin-transpile.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret

17
server/node_modules/.bin/ts-node.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\ts-node\dist\bin.js" %*

28
server/node_modules/.bin/ts-node.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../ts-node/dist/bin.js" $args
} else {
& "$basedir/node$exe" "$basedir/../ts-node/dist/bin.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../ts-node/dist/bin.js" $args
} else {
& "node$exe" "$basedir/../ts-node/dist/bin.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret

16
server/node_modules/.bin/ts-script generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../ts-node/dist/bin-script-deprecated.js" "$@"
else
exec node "$basedir/../ts-node/dist/bin-script-deprecated.js" "$@"
fi

17
server/node_modules/.bin/ts-script.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\ts-node\dist\bin-script-deprecated.js" %*

28
server/node_modules/.bin/ts-script.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../ts-node/dist/bin-script-deprecated.js" $args
} else {
& "$basedir/node$exe" "$basedir/../ts-node/dist/bin-script-deprecated.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../ts-node/dist/bin-script-deprecated.js" $args
} else {
& "node$exe" "$basedir/../ts-node/dist/bin-script-deprecated.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret

16
server/node_modules/.bin/tsc generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@"
else
exec node "$basedir/../typescript/bin/tsc" "$@"
fi

17
server/node_modules/.bin/tsc.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\typescript\bin\tsc" %*

28
server/node_modules/.bin/tsc.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../typescript/bin/tsc" $args
} else {
& "$basedir/node$exe" "$basedir/../typescript/bin/tsc" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../typescript/bin/tsc" $args
} else {
& "node$exe" "$basedir/../typescript/bin/tsc" $args
}
$ret=$LASTEXITCODE
}
exit $ret

16
server/node_modules/.bin/tsnd generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../ts-node-dev/lib/bin.js" "$@"
else
exec node "$basedir/../ts-node-dev/lib/bin.js" "$@"
fi

17
server/node_modules/.bin/tsnd.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\ts-node-dev\lib\bin.js" %*

28
server/node_modules/.bin/tsnd.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../ts-node-dev/lib/bin.js" $args
} else {
& "$basedir/node$exe" "$basedir/../ts-node-dev/lib/bin.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../ts-node-dev/lib/bin.js" $args
} else {
& "node$exe" "$basedir/../ts-node-dev/lib/bin.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret

16
server/node_modules/.bin/tsserver generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@"
else
exec node "$basedir/../typescript/bin/tsserver" "$@"
fi

17
server/node_modules/.bin/tsserver.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\typescript\bin\tsserver" %*

28
server/node_modules/.bin/tsserver.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../typescript/bin/tsserver" $args
} else {
& "$basedir/node$exe" "$basedir/../typescript/bin/tsserver" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../typescript/bin/tsserver" $args
} else {
& "node$exe" "$basedir/../typescript/bin/tsserver" $args
}
$ret=$LASTEXITCODE
}
exit $ret

2069
server/node_modules/.package-lock.json generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Evan Wallace
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,289 @@
# Source Map Support
[![NPM version](https://img.shields.io/npm/v/@cspotcode/source-map-support.svg?style=flat)](https://npmjs.org/package/@cspotcode/source-map-support)
[![NPM downloads](https://img.shields.io/npm/dm/@cspotcode/source-map-support.svg?style=flat)](https://npmjs.org/package/@cspotcode/source-map-support)
[![Build status](https://img.shields.io/github/workflow/status/cspotcode/node-source-map-support/Continuous%20Integration)](https://github.com/cspotcode/node-source-map-support/actions?query=workflow%3A%22Continuous+Integration%22)
This module provides source map support for stack traces in node via the [V8 stack trace API](https://github.com/v8/v8/wiki/Stack-Trace-API). It uses the [source-map](https://github.com/mozilla/source-map) module to replace the paths and line numbers of source-mapped files with their original paths and line numbers. The output mimics node's stack trace format with the goal of making every compile-to-JS language more of a first-class citizen. Source maps are completely general (not specific to any one language) so you can use source maps with multiple compile-to-JS languages in the same node process.
## Installation and Usage
#### Node support
```
$ npm install @cspotcode/source-map-support
```
Source maps can be generated using libraries such as [source-map-index-generator](https://github.com/twolfson/source-map-index-generator). Once you have a valid source map, place a source mapping comment somewhere in the file (usually done automatically or with an option by your transpiler):
```
//# sourceMappingURL=path/to/source.map
```
If multiple sourceMappingURL comments exist in one file, the last sourceMappingURL comment will be
respected (e.g. if a file mentions the comment in code, or went through multiple transpilers).
The path should either be absolute or relative to the compiled file.
From here you have two options.
##### CLI Usage
```bash
node -r @cspotcode/source-map-support/register compiled.js
# Or to enable hookRequire
node -r @cspotcode/source-map-support/register-hook-require compiled.js
```
##### Programmatic Usage
Put the following line at the top of the compiled file.
```js
require('@cspotcode/source-map-support').install();
```
It is also possible to install the source map support directly by
requiring the `register` module which can be handy with ES6:
```js
import '@cspotcode/source-map-support/register'
// Instead of:
import sourceMapSupport from '@cspotcode/source-map-support'
sourceMapSupport.install()
```
Note: if you're using babel-register, it includes source-map-support already.
It is also very useful with Mocha:
```
$ mocha --require @cspotcode/source-map-support/register tests/
```
#### Browser support
This library also works in Chrome. While the DevTools console already supports source maps, the V8 engine doesn't and `Error.prototype.stack` will be incorrect without this library. Everything will just work if you deploy your source files using [browserify](http://browserify.org/). Just make sure to pass the `--debug` flag to the browserify command so your source maps are included in the bundled code.
This library also works if you use another build process or just include the source files directly. In this case, include the file `browser-source-map-support.js` in your page and call `sourceMapSupport.install()`. It contains the whole library already bundled for the browser using browserify.
```html
<script src="browser-source-map-support.js"></script>
<script>sourceMapSupport.install();</script>
```
This library also works if you use AMD (Asynchronous Module Definition), which is used in tools like [RequireJS](http://requirejs.org/). Just list `browser-source-map-support` as a dependency:
```html
<script>
define(['browser-source-map-support'], function(sourceMapSupport) {
sourceMapSupport.install();
});
</script>
```
## Options
This module installs two things: a change to the `stack` property on `Error` objects and a handler for uncaught exceptions that mimics node's default exception handler (the handler can be seen in the demos below). You may want to disable the handler if you have your own uncaught exception handler. This can be done by passing an argument to the installer:
```js
require('@cspotcode/source-map-support').install({
handleUncaughtExceptions: false
});
```
This module loads source maps from the filesystem by default. You can provide alternate loading behavior through a callback as shown below. For example, [Meteor](https://github.com/meteor) keeps all source maps cached in memory to avoid disk access.
```js
require('@cspotcode/source-map-support').install({
retrieveSourceMap: function(source) {
if (source === 'compiled.js') {
return {
url: 'original.js',
map: fs.readFileSync('compiled.js.map', 'utf8')
};
}
return null;
}
});
```
The module will by default assume a browser environment if XMLHttpRequest and window are defined. If either of these do not exist it will instead assume a node environment.
In some rare cases, e.g. when running a browser emulation and where both variables are also set, you can explictly specify the environment to be either 'browser' or 'node'.
```js
require('@cspotcode/source-map-support').install({
environment: 'node'
});
```
To support files with inline source maps, the `hookRequire` options can be specified, which will monitor all source files for inline source maps.
```js
require('@cspotcode/source-map-support').install({
hookRequire: true
});
```
This monkey patches the `require` module loading chain, so is not enabled by default and is not recommended for any sort of production usage.
## Demos
#### Basic Demo
original.js:
```js
throw new Error('test'); // This is the original code
```
compiled.js:
```js
require('@cspotcode/source-map-support').install();
throw new Error('test'); // This is the compiled code
// The next line defines the sourceMapping.
//# sourceMappingURL=compiled.js.map
```
compiled.js.map:
```json
{
"version": 3,
"file": "compiled.js",
"sources": ["original.js"],
"names": [],
"mappings": ";;AAAA,MAAM,IAAI"
}
```
Run compiled.js using node (notice how the stack trace uses original.js instead of compiled.js):
```
$ node compiled.js
original.js:1
throw new Error('test'); // This is the original code
^
Error: test
at Object.<anonymous> (original.js:1:7)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:901:3
```
#### TypeScript Demo
demo.ts:
```typescript
declare function require(name: string);
require('@cspotcode/source-map-support').install();
class Foo {
constructor() { this.bar(); }
bar() { throw new Error('this is a demo'); }
}
new Foo();
```
Compile and run the file using the TypeScript compiler from the terminal:
```
$ npm install source-map-support typescript
$ node_modules/typescript/bin/tsc -sourcemap demo.ts
$ node demo.js
demo.ts:5
bar() { throw new Error('this is a demo'); }
^
Error: this is a demo
at Foo.bar (demo.ts:5:17)
at new Foo (demo.ts:4:24)
at Object.<anonymous> (demo.ts:7:1)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:901:3
```
There is also the option to use `-r source-map-support/register` with typescript, without the need add the `require('@cspotcode/source-map-support').install()` in the code base:
```
$ npm install source-map-support typescript
$ node_modules/typescript/bin/tsc -sourcemap demo.ts
$ node -r source-map-support/register demo.js
demo.ts:5
bar() { throw new Error('this is a demo'); }
^
Error: this is a demo
at Foo.bar (demo.ts:5:17)
at new Foo (demo.ts:4:24)
at Object.<anonymous> (demo.ts:7:1)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:901:3
```
#### CoffeeScript Demo
demo.coffee:
```coffee
require('@cspotcode/source-map-support').install()
foo = ->
bar = -> throw new Error 'this is a demo'
bar()
foo()
```
Compile and run the file using the CoffeeScript compiler from the terminal:
```sh
$ npm install @cspotcode/source-map-support coffeescript
$ node_modules/.bin/coffee --map --compile demo.coffee
$ node demo.js
demo.coffee:3
bar = -> throw new Error 'this is a demo'
^
Error: this is a demo
at bar (demo.coffee:3:22)
at foo (demo.coffee:4:3)
at Object.<anonymous> (demo.coffee:5:1)
at Object.<anonymous> (demo.coffee:1:1)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
```
## Tests
This repo contains both automated tests for node and manual tests for the browser. The automated tests can be run using mocha (type `mocha` in the root directory). To run the manual tests:
* Build the tests using `build.js`
* Launch the HTTP server (`npm run serve-tests`) and visit
* http://127.0.0.1:1336/amd-test
* http://127.0.0.1:1336/browser-test
* http://127.0.0.1:1336/browserify-test - **Currently not working** due to a bug with browserify (see [pull request #66](https://github.com/evanw/node-source-map-support/pull/66) for details).
* For `header-test`, run `server.js` inside that directory and visit http://127.0.0.1:1337/
## License
This code is available under the [MIT license](http://opensource.org/licenses/MIT).

View File

@@ -0,0 +1,114 @@
/*
* Support for source maps in V8 stack traces
* https://github.com/evanw/node-source-map-support
*/
/*
The buffer module from node.js, for the browser.
@author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
license MIT
*/
(this.define||function(R,U){this.sourceMapSupport=U()})("browser-source-map-support",function(R){(function e(C,J,A){function p(f,c){if(!J[f]){if(!C[f]){var l="function"==typeof require&&require;if(!c&&l)return l(f,!0);if(t)return t(f,!0);throw Error("Cannot find module '"+f+"'");}l=J[f]={exports:{}};C[f][0].call(l.exports,function(q){var r=C[f][1][q];return p(r?r:q)},l,l.exports,e,C,J,A)}return J[f].exports}for(var t="function"==typeof require&&require,m=0;m<A.length;m++)p(A[m]);return p})({1:[function(C,
J,A){R=C("./source-map-support")},{"./source-map-support":21}],2:[function(C,J,A){(function(e){function p(m){m=m.charCodeAt(0);if(43===m)return 62;if(47===m)return 63;if(48>m)return-1;if(58>m)return m-48+52;if(91>m)return m-65;if(123>m)return m-97+26}var t="undefined"!==typeof Uint8Array?Uint8Array:Array;e.toByteArray=function(m){function f(d){q[k++]=d}if(0<m.length%4)throw Error("Invalid string. Length must be a multiple of 4");var c=m.length;var l="="===m.charAt(c-2)?2:"="===m.charAt(c-1)?1:0;var q=
new t(3*m.length/4-l);var r=0<l?m.length-4:m.length;var k=0;for(c=0;c<r;c+=4){var u=p(m.charAt(c))<<18|p(m.charAt(c+1))<<12|p(m.charAt(c+2))<<6|p(m.charAt(c+3));f((u&16711680)>>16);f((u&65280)>>8);f(u&255)}2===l?(u=p(m.charAt(c))<<2|p(m.charAt(c+1))>>4,f(u&255)):1===l&&(u=p(m.charAt(c))<<10|p(m.charAt(c+1))<<4|p(m.charAt(c+2))>>2,f(u>>8&255),f(u&255));return q};e.fromByteArray=function(m){var f=m.length%3,c="",l;var q=0;for(l=m.length-f;q<l;q+=3){var r=(m[q]<<16)+(m[q+1]<<8)+m[q+2];r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>
18&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>12&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>6&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r&63);c+=r}switch(f){case 1:r=m[m.length-1];c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>2);c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r<<4&63);c+="==";break;case 2:r=(m[m.length-2]<<8)+
m[m.length-1],c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>10),c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>4&63),c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r<<2&63),c+="="}return c}})("undefined"===typeof A?this.base64js={}:A)},{}],3:[function(C,J,A){},{}],4:[function(C,J,A){(function(e){var p=Object.prototype.toString,t="function"===typeof e.alloc&&"function"===typeof e.allocUnsafe&&"function"===
typeof e.from;J.exports=function(m,f,c){if("number"===typeof m)throw new TypeError('"value" argument must not be a number');if("ArrayBuffer"===p.call(m).slice(8,-1)){f>>>=0;var l=m.byteLength-f;if(0>l)throw new RangeError("'offset' is out of bounds");if(void 0===c)c=l;else if(c>>>=0,c>l)throw new RangeError("'length' is out of bounds");return t?e.from(m.slice(f,f+c)):new e(new Uint8Array(m.slice(f,f+c)))}if("string"===typeof m){c=f;if("string"!==typeof c||""===c)c="utf8";if(!e.isEncoding(c))throw new TypeError('"encoding" must be a valid string encoding');
return t?e.from(m,c):new e(m,c)}return t?e.from(m):new e(m)}}).call(this,C("buffer").Buffer)},{buffer:5}],5:[function(C,J,A){function e(a,b,h){if(!(this instanceof e))return new e(a,b,h);var w=typeof a;if("number"===w)var y=0<a?a>>>0:0;else if("string"===w){if("base64"===b)for(a=(a.trim?a.trim():a.replace(/^\s+|\s+$/g,"")).replace(L,"");0!==a.length%4;)a+="=";y=e.byteLength(a,b)}else if("object"===w&&null!==a)"Buffer"===a.type&&z(a.data)&&(a=a.data),y=0<+a.length?Math.floor(+a.length):0;else throw new TypeError("must start with number, buffer, array or string");
if(this.length>G)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+G.toString(16)+" bytes");if(e.TYPED_ARRAY_SUPPORT)var I=e._augment(new Uint8Array(y));else I=this,I.length=y,I._isBuffer=!0;if(e.TYPED_ARRAY_SUPPORT&&"number"===typeof a.byteLength)I._set(a);else{var K=a;if(z(K)||e.isBuffer(K)||K&&"object"===typeof K&&"number"===typeof K.length)if(e.isBuffer(a))for(b=0;b<y;b++)I[b]=a.readUInt8(b);else for(b=0;b<y;b++)I[b]=(a[b]%256+256)%256;else if("string"===w)I.write(a,
0,b);else if("number"===w&&!e.TYPED_ARRAY_SUPPORT&&!h)for(b=0;b<y;b++)I[b]=0}return I}function p(a,b,h){var w="";for(h=Math.min(a.length,h);b<h;b++)w+=String.fromCharCode(a[b]);return w}function t(a,b,h){if(0!==a%1||0>a)throw new RangeError("offset is not uint");if(a+b>h)throw new RangeError("Trying to access beyond buffer length");}function m(a,b,h,w,y,I){if(!e.isBuffer(a))throw new TypeError("buffer must be a Buffer instance");if(b>y||b<I)throw new TypeError("value is out of bounds");if(h+w>a.length)throw new TypeError("index out of range");
}function f(a,b,h,w){0>b&&(b=65535+b+1);for(var y=0,I=Math.min(a.length-h,2);y<I;y++)a[h+y]=(b&255<<8*(w?y:1-y))>>>8*(w?y:1-y)}function c(a,b,h,w){0>b&&(b=4294967295+b+1);for(var y=0,I=Math.min(a.length-h,4);y<I;y++)a[h+y]=b>>>8*(w?y:3-y)&255}function l(a,b,h,w,y,I){if(b>y||b<I)throw new TypeError("value is out of bounds");if(h+w>a.length)throw new TypeError("index out of range");}function q(a,b,h,w,y){y||l(a,b,h,4,3.4028234663852886E38,-3.4028234663852886E38);v.write(a,b,h,w,23,4);return h+4}function r(a,
b,h,w,y){y||l(a,b,h,8,1.7976931348623157E308,-1.7976931348623157E308);v.write(a,b,h,w,52,8);return h+8}function k(a){for(var b=[],h=0;h<a.length;h++){var w=a.charCodeAt(h);if(127>=w)b.push(w);else{var y=h;55296<=w&&57343>=w&&h++;w=encodeURIComponent(a.slice(y,h+1)).substr(1).split("%");for(y=0;y<w.length;y++)b.push(parseInt(w[y],16))}}return b}function u(a){for(var b=[],h=0;h<a.length;h++)b.push(a.charCodeAt(h)&255);return b}function d(a,b,h,w,y){y&&(w-=w%y);for(y=0;y<w&&!(y+h>=b.length||y>=a.length);y++)b[y+
h]=a[y];return y}function g(a){try{return decodeURIComponent(a)}catch(b){return String.fromCharCode(65533)}}var n=C("base64-js"),v=C("ieee754"),z=C("is-array");A.Buffer=e;A.SlowBuffer=e;A.INSPECT_MAX_BYTES=50;e.poolSize=8192;var G=1073741823;e.TYPED_ARRAY_SUPPORT=function(){try{var a=new ArrayBuffer(0),b=new Uint8Array(a);b.foo=function(){return 42};return 42===b.foo()&&"function"===typeof b.subarray&&0===(new Uint8Array(1)).subarray(1,1).byteLength}catch(h){return!1}}();e.isBuffer=function(a){return!(null==
a||!a._isBuffer)};e.compare=function(a,b){if(!e.isBuffer(a)||!e.isBuffer(b))throw new TypeError("Arguments must be Buffers");for(var h=a.length,w=b.length,y=0,I=Math.min(h,w);y<I&&a[y]===b[y];y++);y!==I&&(h=a[y],w=b[y]);return h<w?-1:w<h?1:0};e.isEncoding=function(a){switch(String(a).toLowerCase()){case "hex":case "utf8":case "utf-8":case "ascii":case "binary":case "base64":case "raw":case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":return!0;default:return!1}};e.concat=function(a,b){if(!z(a))throw new TypeError("Usage: Buffer.concat(list[, length])");
if(0===a.length)return new e(0);if(1===a.length)return a[0];var h;if(void 0===b)for(h=b=0;h<a.length;h++)b+=a[h].length;var w=new e(b),y=0;for(h=0;h<a.length;h++){var I=a[h];I.copy(w,y);y+=I.length}return w};e.byteLength=function(a,b){a+="";switch(b||"utf8"){case "ascii":case "binary":case "raw":var h=a.length;break;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":h=2*a.length;break;case "hex":h=a.length>>>1;break;case "utf8":case "utf-8":h=k(a).length;break;case "base64":h=n.toByteArray(a).length;
break;default:h=a.length}return h};e.prototype.length=void 0;e.prototype.parent=void 0;e.prototype.toString=function(a,b,h){var w=!1;b>>>=0;h=void 0===h||Infinity===h?this.length:h>>>0;a||(a="utf8");0>b&&(b=0);h>this.length&&(h=this.length);if(h<=b)return"";for(;;)switch(a){case "hex":a=b;b=h;h=this.length;if(!a||0>a)a=0;if(!b||0>b||b>h)b=h;w="";for(h=a;h<b;h++)a=w,w=this[h],w=16>w?"0"+w.toString(16):w.toString(16),w=a+w;return w;case "utf8":case "utf-8":w=a="";for(h=Math.min(this.length,h);b<h;b++)127>=
this[b]?(a+=g(w)+String.fromCharCode(this[b]),w=""):w+="%"+this[b].toString(16);return a+g(w);case "ascii":return p(this,b,h);case "binary":return p(this,b,h);case "base64":return b=0===b&&h===this.length?n.fromByteArray(this):n.fromByteArray(this.slice(b,h)),b;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":b=this.slice(b,h);h="";for(a=0;a<b.length;a+=2)h+=String.fromCharCode(b[a]+256*b[a+1]);return h;default:if(w)throw new TypeError("Unknown encoding: "+a);a=(a+"").toLowerCase();w=!0}};
e.prototype.equals=function(a){if(!e.isBuffer(a))throw new TypeError("Argument must be a Buffer");return 0===e.compare(this,a)};e.prototype.inspect=function(){var a="",b=A.INSPECT_MAX_BYTES;0<this.length&&(a=this.toString("hex",0,b).match(/.{2}/g).join(" "),this.length>b&&(a+=" ... "));return"<Buffer "+a+">"};e.prototype.compare=function(a){if(!e.isBuffer(a))throw new TypeError("Argument must be a Buffer");return e.compare(this,a)};e.prototype.get=function(a){console.log(".get() is deprecated. Access using array indexes instead.");
return this.readUInt8(a)};e.prototype.set=function(a,b){console.log(".set() is deprecated. Access using array indexes instead.");return this.writeUInt8(a,b)};e.prototype.write=function(a,b,h,w){if(isFinite(b))isFinite(h)||(w=h,h=void 0);else{var y=w;w=b;b=h;h=y}b=Number(b)||0;y=this.length-b;h?(h=Number(h),h>y&&(h=y)):h=y;w=String(w||"utf8").toLowerCase();switch(w){case "hex":b=Number(b)||0;w=this.length-b;h?(h=Number(h),h>w&&(h=w)):h=w;w=a.length;if(0!==w%2)throw Error("Invalid hex string");h>w/
2&&(h=w/2);for(w=0;w<h;w++){y=parseInt(a.substr(2*w,2),16);if(isNaN(y))throw Error("Invalid hex string");this[b+w]=y}a=w;break;case "utf8":case "utf-8":a=d(k(a),this,b,h);break;case "ascii":a=d(u(a),this,b,h);break;case "binary":a=d(u(a),this,b,h);break;case "base64":a=d(n.toByteArray(a),this,b,h);break;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":y=[];for(var I=0;I<a.length;I++){var K=a.charCodeAt(I);w=K>>8;K%=256;y.push(K);y.push(w)}a=d(y,this,b,h,2);break;default:throw new TypeError("Unknown encoding: "+
w);}return a};e.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};e.prototype.slice=function(a,b){var h=this.length;a=~~a;b=void 0===b?h:~~b;0>a?(a+=h,0>a&&(a=0)):a>h&&(a=h);0>b?(b+=h,0>b&&(b=0)):b>h&&(b=h);b<a&&(b=a);if(e.TYPED_ARRAY_SUPPORT)return e._augment(this.subarray(a,b));h=b-a;for(var w=new e(h,void 0,!0),y=0;y<h;y++)w[y]=this[y+a];return w};e.prototype.readUInt8=function(a,b){b||t(a,1,this.length);return this[a]};e.prototype.readUInt16LE=
function(a,b){b||t(a,2,this.length);return this[a]|this[a+1]<<8};e.prototype.readUInt16BE=function(a,b){b||t(a,2,this.length);return this[a]<<8|this[a+1]};e.prototype.readUInt32LE=function(a,b){b||t(a,4,this.length);return(this[a]|this[a+1]<<8|this[a+2]<<16)+16777216*this[a+3]};e.prototype.readUInt32BE=function(a,b){b||t(a,4,this.length);return 16777216*this[a]+(this[a+1]<<16|this[a+2]<<8|this[a+3])};e.prototype.readInt8=function(a,b){b||t(a,1,this.length);return this[a]&128?-1*(255-this[a]+1):this[a]};
e.prototype.readInt16LE=function(a,b){b||t(a,2,this.length);var h=this[a]|this[a+1]<<8;return h&32768?h|4294901760:h};e.prototype.readInt16BE=function(a,b){b||t(a,2,this.length);var h=this[a+1]|this[a]<<8;return h&32768?h|4294901760:h};e.prototype.readInt32LE=function(a,b){b||t(a,4,this.length);return this[a]|this[a+1]<<8|this[a+2]<<16|this[a+3]<<24};e.prototype.readInt32BE=function(a,b){b||t(a,4,this.length);return this[a]<<24|this[a+1]<<16|this[a+2]<<8|this[a+3]};e.prototype.readFloatLE=function(a,
b){b||t(a,4,this.length);return v.read(this,a,!0,23,4)};e.prototype.readFloatBE=function(a,b){b||t(a,4,this.length);return v.read(this,a,!1,23,4)};e.prototype.readDoubleLE=function(a,b){b||t(a,8,this.length);return v.read(this,a,!0,52,8)};e.prototype.readDoubleBE=function(a,b){b||t(a,8,this.length);return v.read(this,a,!1,52,8)};e.prototype.writeUInt8=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,1,255,0);e.TYPED_ARRAY_SUPPORT||(a=Math.floor(a));this[b]=a;return b+1};e.prototype.writeUInt16LE=function(a,
b,h){a=+a;b>>>=0;h||m(this,a,b,2,65535,0);e.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8):f(this,a,b,!0);return b+2};e.prototype.writeUInt16BE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,2,65535,0);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>8,this[b+1]=a):f(this,a,b,!1);return b+2};e.prototype.writeUInt32LE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,4,4294967295,0);e.TYPED_ARRAY_SUPPORT?(this[b+3]=a>>>24,this[b+2]=a>>>16,this[b+1]=a>>>8,this[b]=a):c(this,a,b,!0);return b+4};e.prototype.writeUInt32BE=function(a,
b,h){a=+a;b>>>=0;h||m(this,a,b,4,4294967295,0);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>24,this[b+1]=a>>>16,this[b+2]=a>>>8,this[b+3]=a):c(this,a,b,!1);return b+4};e.prototype.writeInt8=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,1,127,-128);e.TYPED_ARRAY_SUPPORT||(a=Math.floor(a));0>a&&(a=255+a+1);this[b]=a;return b+1};e.prototype.writeInt16LE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,2,32767,-32768);e.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8):f(this,a,b,!0);return b+2};e.prototype.writeInt16BE=function(a,
b,h){a=+a;b>>>=0;h||m(this,a,b,2,32767,-32768);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>8,this[b+1]=a):f(this,a,b,!1);return b+2};e.prototype.writeInt32LE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,4,2147483647,-2147483648);e.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8,this[b+2]=a>>>16,this[b+3]=a>>>24):c(this,a,b,!0);return b+4};e.prototype.writeInt32BE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,4,2147483647,-2147483648);0>a&&(a=4294967295+a+1);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>24,this[b+1]=a>>>16,this[b+
2]=a>>>8,this[b+3]=a):c(this,a,b,!1);return b+4};e.prototype.writeFloatLE=function(a,b,h){return q(this,a,b,!0,h)};e.prototype.writeFloatBE=function(a,b,h){return q(this,a,b,!1,h)};e.prototype.writeDoubleLE=function(a,b,h){return r(this,a,b,!0,h)};e.prototype.writeDoubleBE=function(a,b,h){return r(this,a,b,!1,h)};e.prototype.copy=function(a,b,h,w){h||(h=0);w||0===w||(w=this.length);b||(b=0);if(w!==h&&0!==a.length&&0!==this.length){if(w<h)throw new TypeError("sourceEnd < sourceStart");if(0>b||b>=a.length)throw new TypeError("targetStart out of bounds");
if(0>h||h>=this.length)throw new TypeError("sourceStart out of bounds");if(0>w||w>this.length)throw new TypeError("sourceEnd out of bounds");w>this.length&&(w=this.length);a.length-b<w-h&&(w=a.length-b+h);w-=h;if(1E3>w||!e.TYPED_ARRAY_SUPPORT)for(var y=0;y<w;y++)a[y+b]=this[y+h];else a._set(this.subarray(h,h+w),b)}};e.prototype.fill=function(a,b,h){a||(a=0);b||(b=0);h||(h=this.length);if(h<b)throw new TypeError("end < start");if(h!==b&&0!==this.length){if(0>b||b>=this.length)throw new TypeError("start out of bounds");
if(0>h||h>this.length)throw new TypeError("end out of bounds");if("number"===typeof a)for(;b<h;b++)this[b]=a;else{a=k(a.toString());for(var w=a.length;b<h;b++)this[b]=a[b%w]}return this}};e.prototype.toArrayBuffer=function(){if("undefined"!==typeof Uint8Array){if(e.TYPED_ARRAY_SUPPORT)return(new e(this)).buffer;for(var a=new Uint8Array(this.length),b=0,h=a.length;b<h;b+=1)a[b]=this[b];return a.buffer}throw new TypeError("Buffer.toArrayBuffer not supported in this browser");};var D=e.prototype;e._augment=
function(a){a.constructor=e;a._isBuffer=!0;a._get=a.get;a._set=a.set;a.get=D.get;a.set=D.set;a.write=D.write;a.toString=D.toString;a.toLocaleString=D.toString;a.toJSON=D.toJSON;a.equals=D.equals;a.compare=D.compare;a.copy=D.copy;a.slice=D.slice;a.readUInt8=D.readUInt8;a.readUInt16LE=D.readUInt16LE;a.readUInt16BE=D.readUInt16BE;a.readUInt32LE=D.readUInt32LE;a.readUInt32BE=D.readUInt32BE;a.readInt8=D.readInt8;a.readInt16LE=D.readInt16LE;a.readInt16BE=D.readInt16BE;a.readInt32LE=D.readInt32LE;a.readInt32BE=
D.readInt32BE;a.readFloatLE=D.readFloatLE;a.readFloatBE=D.readFloatBE;a.readDoubleLE=D.readDoubleLE;a.readDoubleBE=D.readDoubleBE;a.writeUInt8=D.writeUInt8;a.writeUInt16LE=D.writeUInt16LE;a.writeUInt16BE=D.writeUInt16BE;a.writeUInt32LE=D.writeUInt32LE;a.writeUInt32BE=D.writeUInt32BE;a.writeInt8=D.writeInt8;a.writeInt16LE=D.writeInt16LE;a.writeInt16BE=D.writeInt16BE;a.writeInt32LE=D.writeInt32LE;a.writeInt32BE=D.writeInt32BE;a.writeFloatLE=D.writeFloatLE;a.writeFloatBE=D.writeFloatBE;a.writeDoubleLE=
D.writeDoubleLE;a.writeDoubleBE=D.writeDoubleBE;a.fill=D.fill;a.inspect=D.inspect;a.toArrayBuffer=D.toArrayBuffer;return a};var L=/[^+\/0-9A-z]/g},{"base64-js":2,ieee754:6,"is-array":7}],6:[function(C,J,A){A.read=function(e,p,t,m,f){var c=8*f-m-1;var l=(1<<c)-1,q=l>>1,r=-7;f=t?f-1:0;var k=t?-1:1,u=e[p+f];f+=k;t=u&(1<<-r)-1;u>>=-r;for(r+=c;0<r;t=256*t+e[p+f],f+=k,r-=8);c=t&(1<<-r)-1;t>>=-r;for(r+=m;0<r;c=256*c+e[p+f],f+=k,r-=8);if(0===t)t=1-q;else{if(t===l)return c?NaN:Infinity*(u?-1:1);c+=Math.pow(2,
m);t-=q}return(u?-1:1)*c*Math.pow(2,t-m)};A.write=function(e,p,t,m,f,c){var l,q=8*c-f-1,r=(1<<q)-1,k=r>>1,u=23===f?Math.pow(2,-24)-Math.pow(2,-77):0;c=m?0:c-1;var d=m?1:-1,g=0>p||0===p&&0>1/p?1:0;p=Math.abs(p);isNaN(p)||Infinity===p?(p=isNaN(p)?1:0,m=r):(m=Math.floor(Math.log(p)/Math.LN2),1>p*(l=Math.pow(2,-m))&&(m--,l*=2),p=1<=m+k?p+u/l:p+u*Math.pow(2,1-k),2<=p*l&&(m++,l/=2),m+k>=r?(p=0,m=r):1<=m+k?(p=(p*l-1)*Math.pow(2,f),m+=k):(p=p*Math.pow(2,k-1)*Math.pow(2,f),m=0));for(;8<=f;e[t+c]=p&255,c+=
d,p/=256,f-=8);m=m<<f|p;for(q+=f;0<q;e[t+c]=m&255,c+=d,m/=256,q-=8);e[t+c-d]|=128*g}},{}],7:[function(C,J,A){var e=Object.prototype.toString;J.exports=Array.isArray||function(p){return!!p&&"[object Array]"==e.call(p)}},{}],8:[function(C,J,A){(function(e){function p(c,l){for(var q=0,r=c.length-1;0<=r;r--){var k=c[r];"."===k?c.splice(r,1):".."===k?(c.splice(r,1),q++):q&&(c.splice(r,1),q--)}if(l)for(;q--;q)c.unshift("..");return c}function t(c,l){if(c.filter)return c.filter(l);for(var q=[],r=0;r<c.length;r++)l(c[r],
r,c)&&q.push(c[r]);return q}var m=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;A.resolve=function(){for(var c="",l=!1,q=arguments.length-1;-1<=q&&!l;q--){var r=0<=q?arguments[q]:e.cwd();if("string"!==typeof r)throw new TypeError("Arguments to path.resolve must be strings");r&&(c=r+"/"+c,l="/"===r.charAt(0))}c=p(t(c.split("/"),function(k){return!!k}),!l).join("/");return(l?"/":"")+c||"."};A.normalize=function(c){var l=A.isAbsolute(c),q="/"===f(c,-1);(c=p(t(c.split("/"),function(r){return!!r}),
!l).join("/"))||l||(c=".");c&&q&&(c+="/");return(l?"/":"")+c};A.isAbsolute=function(c){return"/"===c.charAt(0)};A.join=function(){var c=Array.prototype.slice.call(arguments,0);return A.normalize(t(c,function(l,q){if("string"!==typeof l)throw new TypeError("Arguments to path.join must be strings");return l}).join("/"))};A.relative=function(c,l){function q(n){for(var v=0;v<n.length&&""===n[v];v++);for(var z=n.length-1;0<=z&&""===n[z];z--);return v>z?[]:n.slice(v,z-v+1)}c=A.resolve(c).substr(1);l=A.resolve(l).substr(1);
for(var r=q(c.split("/")),k=q(l.split("/")),u=Math.min(r.length,k.length),d=u,g=0;g<u;g++)if(r[g]!==k[g]){d=g;break}u=[];for(g=d;g<r.length;g++)u.push("..");u=u.concat(k.slice(d));return u.join("/")};A.sep="/";A.delimiter=":";A.dirname=function(c){var l=m.exec(c).slice(1);c=l[0];l=l[1];if(!c&&!l)return".";l&&(l=l.substr(0,l.length-1));return c+l};A.basename=function(c,l){var q=m.exec(c).slice(1)[2];l&&q.substr(-1*l.length)===l&&(q=q.substr(0,q.length-l.length));return q};A.extname=function(c){return m.exec(c).slice(1)[3]};
var f="b"==="ab".substr(-1)?function(c,l,q){return c.substr(l,q)}:function(c,l,q){0>l&&(l=c.length+l);return c.substr(l,q)}}).call(this,C("g5I+bs"))},{"g5I+bs":9}],9:[function(C,J,A){function e(){}C=J.exports={};C.nextTick=function(){if("undefined"!==typeof window&&window.setImmediate)return function(t){return window.setImmediate(t)};if("undefined"!==typeof window&&window.postMessage&&window.addEventListener){var p=[];window.addEventListener("message",function(t){var m=t.source;m!==window&&null!==
m||"process-tick"!==t.data||(t.stopPropagation(),0<p.length&&p.shift()())},!0);return function(t){p.push(t);window.postMessage("process-tick","*")}}return function(t){setTimeout(t,0)}}();C.title="browser";C.browser=!0;C.env={};C.argv=[];C.on=e;C.addListener=e;C.once=e;C.off=e;C.removeListener=e;C.removeAllListeners=e;C.emit=e;C.binding=function(p){throw Error("process.binding is not supported");};C.cwd=function(){return"/"};C.chdir=function(p){throw Error("process.chdir is not supported");}},{}],
10:[function(C,J,A){function e(){this._array=[];this._set=m?new Map:Object.create(null)}var p=C("./util"),t=Object.prototype.hasOwnProperty,m="undefined"!==typeof Map;e.fromArray=function(f,c){for(var l=new e,q=0,r=f.length;q<r;q++)l.add(f[q],c);return l};e.prototype.size=function(){return m?this._set.size:Object.getOwnPropertyNames(this._set).length};e.prototype.add=function(f,c){var l=m?f:p.toSetString(f),q=m?this.has(f):t.call(this._set,l),r=this._array.length;q&&!c||this._array.push(f);q||(m?
this._set.set(f,r):this._set[l]=r)};e.prototype.has=function(f){if(m)return this._set.has(f);f=p.toSetString(f);return t.call(this._set,f)};e.prototype.indexOf=function(f){if(m){var c=this._set.get(f);if(0<=c)return c}else if(c=p.toSetString(f),t.call(this._set,c))return this._set[c];throw Error('"'+f+'" is not in the set.');};e.prototype.at=function(f){if(0<=f&&f<this._array.length)return this._array[f];throw Error("No element indexed by "+f);};e.prototype.toArray=function(){return this._array.slice()};
A.ArraySet=e},{"./util":19}],11:[function(C,J,A){var e=C("./base64");A.encode=function(p){var t="",m=0>p?(-p<<1)+1:p<<1;do p=m&31,m>>>=5,0<m&&(p|=32),t+=e.encode(p);while(0<m);return t};A.decode=function(p,t,m){var f=p.length,c=0,l=0;do{if(t>=f)throw Error("Expected more digits in base 64 VLQ value.");var q=e.decode(p.charCodeAt(t++));if(-1===q)throw Error("Invalid base64 digit: "+p.charAt(t-1));var r=!!(q&32);q&=31;c+=q<<l;l+=5}while(r);p=c>>1;m.value=1===(c&1)?-p:p;m.rest=t}},{"./base64":12}],12:[function(C,
J,A){var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");A.encode=function(p){if(0<=p&&p<e.length)return e[p];throw new TypeError("Must be between 0 and 63: "+p);};A.decode=function(p){return 65<=p&&90>=p?p-65:97<=p&&122>=p?p-97+26:48<=p&&57>=p?p-48+52:43==p?62:47==p?63:-1}},{}],13:[function(C,J,A){function e(p,t,m,f,c,l){var q=Math.floor((t-p)/2)+p,r=c(m,f[q],!0);return 0===r?q:0<r?1<t-q?e(q,t,m,f,c,l):l==A.LEAST_UPPER_BOUND?t<f.length?t:-1:q:1<q-p?e(p,q,m,f,c,l):l==
A.LEAST_UPPER_BOUND?q:0>p?-1:p}A.GREATEST_LOWER_BOUND=1;A.LEAST_UPPER_BOUND=2;A.search=function(p,t,m,f){if(0===t.length)return-1;p=e(-1,t.length,p,t,m,f||A.GREATEST_LOWER_BOUND);if(0>p)return-1;for(;0<=p-1&&0===m(t[p],t[p-1],!0);)--p;return p}},{}],14:[function(C,J,A){function e(){this._array=[];this._sorted=!0;this._last={generatedLine:-1,generatedColumn:0}}var p=C("./util");e.prototype.unsortedForEach=function(t,m){this._array.forEach(t,m)};e.prototype.add=function(t){var m=this._last,f=m.generatedLine,
c=t.generatedLine,l=m.generatedColumn,q=t.generatedColumn;c>f||c==f&&q>=l||0>=p.compareByGeneratedPositionsInflated(m,t)?this._last=t:this._sorted=!1;this._array.push(t)};e.prototype.toArray=function(){this._sorted||(this._array.sort(p.compareByGeneratedPositionsInflated),this._sorted=!0);return this._array};A.MappingList=e},{"./util":19}],15:[function(C,J,A){function e(t,m,f){var c=t[m];t[m]=t[f];t[f]=c}function p(t,m,f,c){if(f<c){var l=f-1;e(t,Math.round(f+Math.random()*(c-f)),c);for(var q=t[c],
r=f;r<c;r++)0>=m(t[r],q)&&(l+=1,e(t,l,r));e(t,l+1,r);l+=1;p(t,m,f,l-1);p(t,m,l+1,c)}}A.quickSort=function(t,m){p(t,m,0,t.length-1)}},{}],16:[function(C,J,A){function e(k,u){var d=k;"string"===typeof k&&(d=f.parseSourceMapInput(k));return null!=d.sections?new m(d,u):new p(d,u)}function p(k,u){var d=k;"string"===typeof k&&(d=f.parseSourceMapInput(k));var g=f.getArg(d,"version"),n=f.getArg(d,"sources"),v=f.getArg(d,"names",[]),z=f.getArg(d,"sourceRoot",null),G=f.getArg(d,"sourcesContent",null),D=f.getArg(d,
"mappings");d=f.getArg(d,"file",null);if(g!=this._version)throw Error("Unsupported version: "+g);z&&(z=f.normalize(z));n=n.map(String).map(f.normalize).map(function(L){return z&&f.isAbsolute(z)&&f.isAbsolute(L)?f.relative(z,L):L});this._names=l.fromArray(v.map(String),!0);this._sources=l.fromArray(n,!0);this.sourceRoot=z;this.sourcesContent=G;this._mappings=D;this._sourceMapURL=u;this.file=d}function t(){this.generatedColumn=this.generatedLine=0;this.name=this.originalColumn=this.originalLine=this.source=
null}function m(k,u){var d=k;"string"===typeof k&&(d=f.parseSourceMapInput(k));var g=f.getArg(d,"version");d=f.getArg(d,"sections");if(g!=this._version)throw Error("Unsupported version: "+g);this._sources=new l;this._names=new l;var n={line:-1,column:0};this._sections=d.map(function(v){if(v.url)throw Error("Support for url field in sections not implemented.");var z=f.getArg(v,"offset"),G=f.getArg(z,"line"),D=f.getArg(z,"column");if(G<n.line||G===n.line&&D<n.column)throw Error("Section offsets must be ordered and non-overlapping.");
n=z;return{generatedOffset:{generatedLine:G+1,generatedColumn:D+1},consumer:new e(f.getArg(v,"map"),u)}})}var f=C("./util"),c=C("./binary-search"),l=C("./array-set").ArraySet,q=C("./base64-vlq"),r=C("./quick-sort").quickSort;e.fromSourceMap=function(k){return p.fromSourceMap(k)};e.prototype._version=3;e.prototype.__generatedMappings=null;Object.defineProperty(e.prototype,"_generatedMappings",{configurable:!0,enumerable:!0,get:function(){this.__generatedMappings||this._parseMappings(this._mappings,
this.sourceRoot);return this.__generatedMappings}});e.prototype.__originalMappings=null;Object.defineProperty(e.prototype,"_originalMappings",{configurable:!0,enumerable:!0,get:function(){this.__originalMappings||this._parseMappings(this._mappings,this.sourceRoot);return this.__originalMappings}});e.prototype._charIsMappingSeparator=function(k,u){var d=k.charAt(u);return";"===d||","===d};e.prototype._parseMappings=function(k,u){throw Error("Subclasses must implement _parseMappings");};e.GENERATED_ORDER=
1;e.ORIGINAL_ORDER=2;e.GREATEST_LOWER_BOUND=1;e.LEAST_UPPER_BOUND=2;e.prototype.eachMapping=function(k,u,d){u=u||null;switch(d||e.GENERATED_ORDER){case e.GENERATED_ORDER:d=this._generatedMappings;break;case e.ORIGINAL_ORDER:d=this._originalMappings;break;default:throw Error("Unknown order of iteration.");}var g=this.sourceRoot;d.map(function(n){var v=null===n.source?null:this._sources.at(n.source);v=f.computeSourceURL(g,v,this._sourceMapURL);return{source:v,generatedLine:n.generatedLine,generatedColumn:n.generatedColumn,
originalLine:n.originalLine,originalColumn:n.originalColumn,name:null===n.name?null:this._names.at(n.name)}},this).forEach(k,u)};e.prototype.allGeneratedPositionsFor=function(k){var u=f.getArg(k,"line"),d={source:f.getArg(k,"source"),originalLine:u,originalColumn:f.getArg(k,"column",0)};null!=this.sourceRoot&&(d.source=f.relative(this.sourceRoot,d.source));if(!this._sources.has(d.source))return[];d.source=this._sources.indexOf(d.source);var g=[];d=this._findMapping(d,this._originalMappings,"originalLine",
"originalColumn",f.compareByOriginalPositions,c.LEAST_UPPER_BOUND);if(0<=d){var n=this._originalMappings[d];if(void 0===k.column)for(u=n.originalLine;n&&n.originalLine===u;)g.push({line:f.getArg(n,"generatedLine",null),column:f.getArg(n,"generatedColumn",null),lastColumn:f.getArg(n,"lastGeneratedColumn",null)}),n=this._originalMappings[++d];else for(k=n.originalColumn;n&&n.originalLine===u&&n.originalColumn==k;)g.push({line:f.getArg(n,"generatedLine",null),column:f.getArg(n,"generatedColumn",null),
lastColumn:f.getArg(n,"lastGeneratedColumn",null)}),n=this._originalMappings[++d]}return g};A.SourceMapConsumer=e;p.prototype=Object.create(e.prototype);p.prototype.consumer=e;p.fromSourceMap=function(k,u){var d=Object.create(p.prototype),g=d._names=l.fromArray(k._names.toArray(),!0),n=d._sources=l.fromArray(k._sources.toArray(),!0);d.sourceRoot=k._sourceRoot;d.sourcesContent=k._generateSourcesContent(d._sources.toArray(),d.sourceRoot);d.file=k._file;d._sourceMapURL=u;for(var v=k._mappings.toArray().slice(),
z=d.__generatedMappings=[],G=d.__originalMappings=[],D=0,L=v.length;D<L;D++){var a=v[D],b=new t;b.generatedLine=a.generatedLine;b.generatedColumn=a.generatedColumn;a.source&&(b.source=n.indexOf(a.source),b.originalLine=a.originalLine,b.originalColumn=a.originalColumn,a.name&&(b.name=g.indexOf(a.name)),G.push(b));z.push(b)}r(d.__originalMappings,f.compareByOriginalPositions);return d};p.prototype._version=3;Object.defineProperty(p.prototype,"sources",{get:function(){return this._sources.toArray().map(function(k){return f.computeSourceURL(this.sourceRoot,
k,this._sourceMapURL)},this)}});p.prototype._parseMappings=function(k,u){for(var d=1,g=0,n=0,v=0,z=0,G=0,D=k.length,L=0,a={},b={},h=[],w=[],y,I,K,N,P;L<D;)if(";"===k.charAt(L))d++,L++,g=0;else if(","===k.charAt(L))L++;else{y=new t;y.generatedLine=d;for(N=L;N<D&&!this._charIsMappingSeparator(k,N);N++);I=k.slice(L,N);if(K=a[I])L+=I.length;else{for(K=[];L<N;)q.decode(k,L,b),P=b.value,L=b.rest,K.push(P);if(2===K.length)throw Error("Found a source, but no line and column");if(3===K.length)throw Error("Found a source and line, but no column");
a[I]=K}y.generatedColumn=g+K[0];g=y.generatedColumn;1<K.length&&(y.source=z+K[1],z+=K[1],y.originalLine=n+K[2],n=y.originalLine,y.originalLine+=1,y.originalColumn=v+K[3],v=y.originalColumn,4<K.length&&(y.name=G+K[4],G+=K[4]));w.push(y);"number"===typeof y.originalLine&&h.push(y)}r(w,f.compareByGeneratedPositionsDeflated);this.__generatedMappings=w;r(h,f.compareByOriginalPositions);this.__originalMappings=h};p.prototype._findMapping=function(k,u,d,g,n,v){if(0>=k[d])throw new TypeError("Line must be greater than or equal to 1, got "+
k[d]);if(0>k[g])throw new TypeError("Column must be greater than or equal to 0, got "+k[g]);return c.search(k,u,n,v)};p.prototype.computeColumnSpans=function(){for(var k=0;k<this._generatedMappings.length;++k){var u=this._generatedMappings[k];if(k+1<this._generatedMappings.length){var d=this._generatedMappings[k+1];if(u.generatedLine===d.generatedLine){u.lastGeneratedColumn=d.generatedColumn-1;continue}}u.lastGeneratedColumn=Infinity}};p.prototype.originalPositionFor=function(k){var u={generatedLine:f.getArg(k,
"line"),generatedColumn:f.getArg(k,"column")};k=this._findMapping(u,this._generatedMappings,"generatedLine","generatedColumn",f.compareByGeneratedPositionsDeflated,f.getArg(k,"bias",e.GREATEST_LOWER_BOUND));if(0<=k&&(k=this._generatedMappings[k],k.generatedLine===u.generatedLine)){u=f.getArg(k,"source",null);null!==u&&(u=this._sources.at(u),u=f.computeSourceURL(this.sourceRoot,u,this._sourceMapURL));var d=f.getArg(k,"name",null);null!==d&&(d=this._names.at(d));return{source:u,line:f.getArg(k,"originalLine",
null),column:f.getArg(k,"originalColumn",null),name:d}}return{source:null,line:null,column:null,name:null}};p.prototype.hasContentsOfAllSources=function(){return this.sourcesContent?this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some(function(k){return null==k}):!1};p.prototype.sourceContentFor=function(k,u){if(!this.sourcesContent)return null;var d=k;null!=this.sourceRoot&&(d=f.relative(this.sourceRoot,d));if(this._sources.has(d))return this.sourcesContent[this._sources.indexOf(d)];
var g=this.sources,n;for(n=0;n<g.length;++n)if(g[n]==k)return this.sourcesContent[n];var v;if(null!=this.sourceRoot&&(v=f.urlParse(this.sourceRoot))){g=d.replace(/^file:\/\//,"");if("file"==v.scheme&&this._sources.has(g))return this.sourcesContent[this._sources.indexOf(g)];if((!v.path||"/"==v.path)&&this._sources.has("/"+d))return this.sourcesContent[this._sources.indexOf("/"+d)]}if(u)return null;throw Error('"'+d+'" is not in the SourceMap.');};p.prototype.generatedPositionFor=function(k){var u=
f.getArg(k,"source");null!=this.sourceRoot&&(u=f.relative(this.sourceRoot,u));if(!this._sources.has(u))return{line:null,column:null,lastColumn:null};u=this._sources.indexOf(u);u={source:u,originalLine:f.getArg(k,"line"),originalColumn:f.getArg(k,"column")};k=this._findMapping(u,this._originalMappings,"originalLine","originalColumn",f.compareByOriginalPositions,f.getArg(k,"bias",e.GREATEST_LOWER_BOUND));return 0<=k&&(k=this._originalMappings[k],k.source===u.source)?{line:f.getArg(k,"generatedLine",
null),column:f.getArg(k,"generatedColumn",null),lastColumn:f.getArg(k,"lastGeneratedColumn",null)}:{line:null,column:null,lastColumn:null}};A.BasicSourceMapConsumer=p;m.prototype=Object.create(e.prototype);m.prototype.constructor=e;m.prototype._version=3;Object.defineProperty(m.prototype,"sources",{get:function(){for(var k=[],u=0;u<this._sections.length;u++)for(var d=0;d<this._sections[u].consumer.sources.length;d++)k.push(this._sections[u].consumer.sources[d]);return k}});m.prototype.originalPositionFor=
function(k){var u={generatedLine:f.getArg(k,"line"),generatedColumn:f.getArg(k,"column")},d=c.search(u,this._sections,function(g,n){var v=g.generatedLine-n.generatedOffset.generatedLine;return v?v:g.generatedColumn-n.generatedOffset.generatedColumn});return(d=this._sections[d])?d.consumer.originalPositionFor({line:u.generatedLine-(d.generatedOffset.generatedLine-1),column:u.generatedColumn-(d.generatedOffset.generatedLine===u.generatedLine?d.generatedOffset.generatedColumn-1:0),bias:k.bias}):{source:null,
line:null,column:null,name:null}};m.prototype.hasContentsOfAllSources=function(){return this._sections.every(function(k){return k.consumer.hasContentsOfAllSources()})};m.prototype.sourceContentFor=function(k,u){for(var d=0;d<this._sections.length;d++){var g=this._sections[d].consumer.sourceContentFor(k,!0);if(g)return g}if(u)return null;throw Error('"'+k+'" is not in the SourceMap.');};m.prototype.generatedPositionFor=function(k){for(var u=0;u<this._sections.length;u++){var d=this._sections[u];if(-1!==
d.consumer.sources.indexOf(f.getArg(k,"source"))){var g=d.consumer.generatedPositionFor(k);if(g)return{line:g.line+(d.generatedOffset.generatedLine-1),column:g.column+(d.generatedOffset.generatedLine===g.line?d.generatedOffset.generatedColumn-1:0)}}}return{line:null,column:null}};m.prototype._parseMappings=function(k,u){this.__generatedMappings=[];this.__originalMappings=[];for(var d=0;d<this._sections.length;d++)for(var g=this._sections[d],n=g.consumer._generatedMappings,v=0;v<n.length;v++){var z=
n[v],G=g.consumer._sources.at(z.source);G=f.computeSourceURL(g.consumer.sourceRoot,G,this._sourceMapURL);this._sources.add(G);G=this._sources.indexOf(G);var D=null;z.name&&(D=g.consumer._names.at(z.name),this._names.add(D),D=this._names.indexOf(D));z={source:G,generatedLine:z.generatedLine+(g.generatedOffset.generatedLine-1),generatedColumn:z.generatedColumn+(g.generatedOffset.generatedLine===z.generatedLine?g.generatedOffset.generatedColumn-1:0),originalLine:z.originalLine,originalColumn:z.originalColumn,
name:D};this.__generatedMappings.push(z);"number"===typeof z.originalLine&&this.__originalMappings.push(z)}r(this.__generatedMappings,f.compareByGeneratedPositionsDeflated);r(this.__originalMappings,f.compareByOriginalPositions)};A.IndexedSourceMapConsumer=m},{"./array-set":10,"./base64-vlq":11,"./binary-search":13,"./quick-sort":15,"./util":19}],17:[function(C,J,A){function e(c){c||(c={});this._file=t.getArg(c,"file",null);this._sourceRoot=t.getArg(c,"sourceRoot",null);this._skipValidation=t.getArg(c,
"skipValidation",!1);this._sources=new m;this._names=new m;this._mappings=new f;this._sourcesContents=null}var p=C("./base64-vlq"),t=C("./util"),m=C("./array-set").ArraySet,f=C("./mapping-list").MappingList;e.prototype._version=3;e.fromSourceMap=function(c){var l=c.sourceRoot,q=new e({file:c.file,sourceRoot:l});c.eachMapping(function(r){var k={generated:{line:r.generatedLine,column:r.generatedColumn}};null!=r.source&&(k.source=r.source,null!=l&&(k.source=t.relative(l,k.source)),k.original={line:r.originalLine,
column:r.originalColumn},null!=r.name&&(k.name=r.name));q.addMapping(k)});c.sources.forEach(function(r){var k=r;null!==l&&(k=t.relative(l,r));q._sources.has(k)||q._sources.add(k);k=c.sourceContentFor(r);null!=k&&q.setSourceContent(r,k)});return q};e.prototype.addMapping=function(c){var l=t.getArg(c,"generated"),q=t.getArg(c,"original",null),r=t.getArg(c,"source",null);c=t.getArg(c,"name",null);this._skipValidation||this._validateMapping(l,q,r,c);null!=r&&(r=String(r),this._sources.has(r)||this._sources.add(r));
null!=c&&(c=String(c),this._names.has(c)||this._names.add(c));this._mappings.add({generatedLine:l.line,generatedColumn:l.column,originalLine:null!=q&&q.line,originalColumn:null!=q&&q.column,source:r,name:c})};e.prototype.setSourceContent=function(c,l){var q=c;null!=this._sourceRoot&&(q=t.relative(this._sourceRoot,q));null!=l?(this._sourcesContents||(this._sourcesContents=Object.create(null)),this._sourcesContents[t.toSetString(q)]=l):this._sourcesContents&&(delete this._sourcesContents[t.toSetString(q)],
0===Object.keys(this._sourcesContents).length&&(this._sourcesContents=null))};e.prototype.applySourceMap=function(c,l,q){var r=l;if(null==l){if(null==c.file)throw Error('SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map\'s "file" property. Both were omitted.');r=c.file}var k=this._sourceRoot;null!=k&&(r=t.relative(k,r));var u=new m,d=new m;this._mappings.unsortedForEach(function(g){if(g.source===r&&null!=g.originalLine){var n=c.originalPositionFor({line:g.originalLine,
column:g.originalColumn});null!=n.source&&(g.source=n.source,null!=q&&(g.source=t.join(q,g.source)),null!=k&&(g.source=t.relative(k,g.source)),g.originalLine=n.line,g.originalColumn=n.column,null!=n.name&&(g.name=n.name))}n=g.source;null==n||u.has(n)||u.add(n);g=g.name;null==g||d.has(g)||d.add(g)},this);this._sources=u;this._names=d;c.sources.forEach(function(g){var n=c.sourceContentFor(g);null!=n&&(null!=q&&(g=t.join(q,g)),null!=k&&(g=t.relative(k,g)),this.setSourceContent(g,n))},this)};e.prototype._validateMapping=
function(c,l,q,r){if(l&&"number"!==typeof l.line&&"number"!==typeof l.column)throw Error("original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values.");if(!(c&&"line"in c&&"column"in c&&0<c.line&&0<=c.column&&!l&&!q&&!r||c&&"line"in c&&"column"in c&&l&&"line"in l&&"column"in l&&0<c.line&&0<=c.column&&0<l.line&&0<=l.column&&
q))throw Error("Invalid mapping: "+JSON.stringify({generated:c,source:q,original:l,name:r}));};e.prototype._serializeMappings=function(){for(var c=0,l=1,q=0,r=0,k=0,u=0,d="",g,n,v,z=this._mappings.toArray(),G=0,D=z.length;G<D;G++){n=z[G];g="";if(n.generatedLine!==l)for(c=0;n.generatedLine!==l;)g+=";",l++;else if(0<G){if(!t.compareByGeneratedPositionsInflated(n,z[G-1]))continue;g+=","}g+=p.encode(n.generatedColumn-c);c=n.generatedColumn;null!=n.source&&(v=this._sources.indexOf(n.source),g+=p.encode(v-
u),u=v,g+=p.encode(n.originalLine-1-r),r=n.originalLine-1,g+=p.encode(n.originalColumn-q),q=n.originalColumn,null!=n.name&&(n=this._names.indexOf(n.name),g+=p.encode(n-k),k=n));d+=g}return d};e.prototype._generateSourcesContent=function(c,l){return c.map(function(q){if(!this._sourcesContents)return null;null!=l&&(q=t.relative(l,q));q=t.toSetString(q);return Object.prototype.hasOwnProperty.call(this._sourcesContents,q)?this._sourcesContents[q]:null},this)};e.prototype.toJSON=function(){var c={version:this._version,
sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};null!=this._file&&(c.file=this._file);null!=this._sourceRoot&&(c.sourceRoot=this._sourceRoot);this._sourcesContents&&(c.sourcesContent=this._generateSourcesContent(c.sources,c.sourceRoot));return c};e.prototype.toString=function(){return JSON.stringify(this.toJSON())};A.SourceMapGenerator=e},{"./array-set":10,"./base64-vlq":11,"./mapping-list":14,"./util":19}],18:[function(C,J,A){function e(f,c,l,q,r){this.children=
[];this.sourceContents={};this.line=null==f?null:f;this.column=null==c?null:c;this.source=null==l?null:l;this.name=null==r?null:r;this.$$$isSourceNode$$$=!0;null!=q&&this.add(q)}var p=C("./source-map-generator").SourceMapGenerator,t=C("./util"),m=/(\r?\n)/;e.fromStringWithSourceMap=function(f,c,l){function q(z,G){if(null===z||void 0===z.source)r.add(G);else{var D=l?t.join(l,z.source):z.source;r.add(new e(z.originalLine,z.originalColumn,D,G,z.name))}}var r=new e,k=f.split(m),u=0,d=function(){var z=
u<k.length?k[u++]:void 0,G=(u<k.length?k[u++]:void 0)||"";return z+G},g=1,n=0,v=null;c.eachMapping(function(z){if(null!==v)if(g<z.generatedLine)q(v,d()),g++,n=0;else{var G=k[u]||"",D=G.substr(0,z.generatedColumn-n);k[u]=G.substr(z.generatedColumn-n);n=z.generatedColumn;q(v,D);v=z;return}for(;g<z.generatedLine;)r.add(d()),g++;n<z.generatedColumn&&(G=k[u]||"",r.add(G.substr(0,z.generatedColumn)),k[u]=G.substr(z.generatedColumn),n=z.generatedColumn);v=z},this);u<k.length&&(v&&q(v,d()),r.add(k.splice(u).join("")));
c.sources.forEach(function(z){var G=c.sourceContentFor(z);null!=G&&(null!=l&&(z=t.join(l,z)),r.setSourceContent(z,G))});return r};e.prototype.add=function(f){if(Array.isArray(f))f.forEach(function(c){this.add(c)},this);else if(f.$$$isSourceNode$$$||"string"===typeof f)f&&this.children.push(f);else throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+f);return this};e.prototype.prepend=function(f){if(Array.isArray(f))for(var c=f.length-1;0<=c;c--)this.prepend(f[c]);
else if(f.$$$isSourceNode$$$||"string"===typeof f)this.children.unshift(f);else throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+f);return this};e.prototype.walk=function(f){for(var c,l=0,q=this.children.length;l<q;l++)c=this.children[l],c.$$$isSourceNode$$$?c.walk(f):""!==c&&f(c,{source:this.source,line:this.line,column:this.column,name:this.name})};e.prototype.join=function(f){var c,l=this.children.length;if(0<l){var q=[];for(c=0;c<l-1;c++)q.push(this.children[c]),
q.push(f);q.push(this.children[c]);this.children=q}return this};e.prototype.replaceRight=function(f,c){var l=this.children[this.children.length-1];l.$$$isSourceNode$$$?l.replaceRight(f,c):"string"===typeof l?this.children[this.children.length-1]=l.replace(f,c):this.children.push("".replace(f,c));return this};e.prototype.setSourceContent=function(f,c){this.sourceContents[t.toSetString(f)]=c};e.prototype.walkSourceContents=function(f){for(var c=0,l=this.children.length;c<l;c++)this.children[c].$$$isSourceNode$$$&&
this.children[c].walkSourceContents(f);var q=Object.keys(this.sourceContents);c=0;for(l=q.length;c<l;c++)f(t.fromSetString(q[c]),this.sourceContents[q[c]])};e.prototype.toString=function(){var f="";this.walk(function(c){f+=c});return f};e.prototype.toStringWithSourceMap=function(f){var c="",l=1,q=0,r=new p(f),k=!1,u=null,d=null,g=null,n=null;this.walk(function(v,z){c+=v;null!==z.source&&null!==z.line&&null!==z.column?(u===z.source&&d===z.line&&g===z.column&&n===z.name||r.addMapping({source:z.source,
original:{line:z.line,column:z.column},generated:{line:l,column:q},name:z.name}),u=z.source,d=z.line,g=z.column,n=z.name,k=!0):k&&(r.addMapping({generated:{line:l,column:q}}),u=null,k=!1);for(var G=0,D=v.length;G<D;G++)10===v.charCodeAt(G)?(l++,q=0,G+1===D?(u=null,k=!1):k&&r.addMapping({source:z.source,original:{line:z.line,column:z.column},generated:{line:l,column:q},name:z.name})):q++});this.walkSourceContents(function(v,z){r.setSourceContent(v,z)});return{code:c,map:r}};A.SourceNode=e},{"./source-map-generator":17,
"./util":19}],19:[function(C,J,A){function e(d){return(d=d.match(k))?{scheme:d[1],auth:d[2],host:d[3],port:d[4],path:d[5]}:null}function p(d){var g="";d.scheme&&(g+=d.scheme+":");g+="//";d.auth&&(g+=d.auth+"@");d.host&&(g+=d.host);d.port&&(g+=":"+d.port);d.path&&(g+=d.path);return g}function t(d){var g=d,n=e(d);if(n){if(!n.path)return d;g=n.path}d=A.isAbsolute(g);g=g.split(/\/+/);for(var v,z=0,G=g.length-1;0<=G;G--)v=g[G],"."===v?g.splice(G,1):".."===v?z++:0<z&&(""===v?(g.splice(G+1,z),z=0):(g.splice(G,
2),z--));g=g.join("/");""===g&&(g=d?"/":".");return n?(n.path=g,p(n)):g}function m(d,g){""===d&&(d=".");""===g&&(g=".");var n=e(g),v=e(d);v&&(d=v.path||"/");if(n&&!n.scheme)return v&&(n.scheme=v.scheme),p(n);if(n||g.match(u))return g;if(v&&!v.host&&!v.path)return v.host=g,p(v);n="/"===g.charAt(0)?g:t(d.replace(/\/+$/,"")+"/"+g);return v?(v.path=n,p(v)):n}function f(d){return d}function c(d){return q(d)?"$"+d:d}function l(d){return q(d)?d.slice(1):d}function q(d){if(!d)return!1;var g=d.length;if(9>
g||95!==d.charCodeAt(g-1)||95!==d.charCodeAt(g-2)||111!==d.charCodeAt(g-3)||116!==d.charCodeAt(g-4)||111!==d.charCodeAt(g-5)||114!==d.charCodeAt(g-6)||112!==d.charCodeAt(g-7)||95!==d.charCodeAt(g-8)||95!==d.charCodeAt(g-9))return!1;for(g-=10;0<=g;g--)if(36!==d.charCodeAt(g))return!1;return!0}function r(d,g){return d===g?0:null===d?1:null===g?-1:d>g?1:-1}A.getArg=function(d,g,n){if(g in d)return d[g];if(3===arguments.length)return n;throw Error('"'+g+'" is a required argument.');};var k=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/,
u=/^data:.+,.+$/;A.urlParse=e;A.urlGenerate=p;A.normalize=t;A.join=m;A.isAbsolute=function(d){return"/"===d.charAt(0)||k.test(d)};A.relative=function(d,g){""===d&&(d=".");d=d.replace(/\/$/,"");for(var n=0;0!==g.indexOf(d+"/");){var v=d.lastIndexOf("/");if(0>v)return g;d=d.slice(0,v);if(d.match(/^([^\/]+:\/)?\/*$/))return g;++n}return Array(n+1).join("../")+g.substr(d.length+1)};C=!("__proto__"in Object.create(null));A.toSetString=C?f:c;A.fromSetString=C?f:l;A.compareByOriginalPositions=function(d,
g,n){var v=r(d.source,g.source);if(0!==v)return v;v=d.originalLine-g.originalLine;if(0!==v)return v;v=d.originalColumn-g.originalColumn;if(0!==v||n)return v;v=d.generatedColumn-g.generatedColumn;if(0!==v)return v;v=d.generatedLine-g.generatedLine;return 0!==v?v:r(d.name,g.name)};A.compareByGeneratedPositionsDeflated=function(d,g,n){var v=d.generatedLine-g.generatedLine;if(0!==v)return v;v=d.generatedColumn-g.generatedColumn;if(0!==v||n)return v;v=r(d.source,g.source);if(0!==v)return v;v=d.originalLine-
g.originalLine;if(0!==v)return v;v=d.originalColumn-g.originalColumn;return 0!==v?v:r(d.name,g.name)};A.compareByGeneratedPositionsInflated=function(d,g){var n=d.generatedLine-g.generatedLine;if(0!==n)return n;n=d.generatedColumn-g.generatedColumn;if(0!==n)return n;n=r(d.source,g.source);if(0!==n)return n;n=d.originalLine-g.originalLine;if(0!==n)return n;n=d.originalColumn-g.originalColumn;return 0!==n?n:r(d.name,g.name)};A.parseSourceMapInput=function(d){return JSON.parse(d.replace(/^\)]}'[^\n]*\n/,
""))};A.computeSourceURL=function(d,g,n){g=g||"";d&&("/"!==d[d.length-1]&&"/"!==g[0]&&(d+="/"),g=d+g);if(n){d=e(n);if(!d)throw Error("sourceMapURL could not be parsed");d.path&&(n=d.path.lastIndexOf("/"),0<=n&&(d.path=d.path.substring(0,n+1)));g=m(p(d),g)}return t(g)}},{}],20:[function(C,J,A){A.SourceMapGenerator=C("./lib/source-map-generator").SourceMapGenerator;A.SourceMapConsumer=C("./lib/source-map-consumer").SourceMapConsumer;A.SourceNode=C("./lib/source-node").SourceNode},{"./lib/source-map-consumer":16,
"./lib/source-map-generator":17,"./lib/source-node":18}],21:[function(C,J,A){(function(e){function p(){return"browser"===a?!0:"node"===a?!1:"undefined"!==typeof window&&"function"===typeof XMLHttpRequest&&!(window.require&&window.module&&window.process&&"renderer"===window.process.type)}function t(x){return function(B){for(var F=0;F<x.length;F++){var E=x[F](B);if(E)return E}return null}}function m(x,B){if(!x)return B;var F=n.dirname(x),E=/^\w+:\/\/[^\/]*/.exec(F);E=E?E[0]:"";var H=F.slice(E.length);
return E&&/^\/\w:/.test(H)?(E+="/",E+n.resolve(F.slice(E.length),B).replace(/\\/g,"/")):E+n.resolve(F.slice(E.length),B)}function f(x){var B=h[x.source];if(!B){var F=N(x.source);F?(B=h[x.source]={url:F.url,map:new g(F.map)},B.map.sourcesContent&&B.map.sources.forEach(function(E,H){var M=B.map.sourcesContent[H];if(M){var S=m(B.url,E);b[S]=M}})):B=h[x.source]={url:null,map:null}}return B&&B.map&&"function"===typeof B.map.originalPositionFor&&(F=B.map.originalPositionFor(x),null!==F.source)?(F.source=
m(B.url,F.source),F):x}function c(x){var B=/^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(x);return B?(x=f({source:B[2],line:+B[3],column:B[4]-1}),"eval at "+B[1]+" ("+x.source+":"+x.line+":"+(x.column+1)+")"):(B=/^eval at ([^(]+) \((.+)\)$/.exec(x))?"eval at "+B[1]+" ("+c(B[2])+")":x}function l(){var x="";if(this.isNative())x="native";else{var B=this.getScriptNameOrSourceURL();!B&&this.isEval()&&(x=this.getEvalOrigin(),x+=", ");x=B?x+B:x+"<anonymous>";B=this.getLineNumber();null!=B&&(x+=":"+B,(B=
this.getColumnNumber())&&(x+=":"+B))}B="";var F=this.getFunctionName(),E=!0,H=this.isConstructor();if(this.isToplevel()||H)H?B+="new "+(F||"<anonymous>"):F?B+=F:(B+=x,E=!1);else{H=this.getTypeName();"[object Object]"===H&&(H="null");var M=this.getMethodName();F?(H&&0!=F.indexOf(H)&&(B+=H+"."),B+=F,M&&F.indexOf("."+M)!=F.length-M.length-1&&(B+=" [as "+M+"]")):B+=H+"."+(M||"<anonymous>")}E&&(B+=" ("+x+")");return B}function q(x){var B={};Object.getOwnPropertyNames(Object.getPrototypeOf(x)).forEach(function(F){B[F]=
/^(?:is|get)/.test(F)?function(){return x[F].call(x)}:x[F]});B.toString=l;return B}function r(x,B){void 0===B&&(B={nextPosition:null,curPosition:null});if(x.isNative())return B.curPosition=null,x;var F=x.getFileName()||x.getScriptNameOrSourceURL();if(F){var E=x.getLineNumber(),H=x.getColumnNumber()-1,M=/^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/,S=M.test;var V="object"===typeof e&&null!==e?e.version:"";M=S.call(M,V)?0:62;1===E&&H>M&&!p()&&!x.isEval()&&(H-=M);var O=
f({source:F,line:E,column:H});B.curPosition=O;x=q(x);var T=x.getFunctionName;x.getFunctionName=function(){return null==B.nextPosition?T():B.nextPosition.name||T()};x.getFileName=function(){return O.source};x.getLineNumber=function(){return O.line};x.getColumnNumber=function(){return O.column+1};x.getScriptNameOrSourceURL=function(){return O.source};return x}var Q=x.isEval()&&x.getEvalOrigin();Q&&(Q=c(Q),x=q(x),x.getEvalOrigin=function(){return Q});return x}function k(x,B){L&&(b={},h={});for(var F=
(x.name||"Error")+": "+(x.message||""),E={nextPosition:null,curPosition:null},H=[],M=B.length-1;0<=M;M--)H.push("\n at "+r(B[M],E)),E.nextPosition=E.curPosition;E.curPosition=E.nextPosition=null;return F+H.reverse().join("")}function u(x){var B=/\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(x.stack);if(B){x=B[1];var F=+B[2];B=+B[3];var E=b[x];if(!E&&v&&v.existsSync(x))try{E=v.readFileSync(x,"utf8")}catch(H){E=""}if(E&&(E=E.split(/(?:\r\n|\r|\n)/)[F-1]))return x+":"+F+"\n"+E+"\n"+Array(B).join(" ")+
"^"}return null}function d(){var x=e.emit;e.emit=function(B){if("uncaughtException"===B){var F=arguments[1]&&arguments[1].stack,E=0<this.listeners(B).length;if(F&&!E){F=arguments[1];E=u(F);var H="object"===typeof e&&null!==e?e.stderr:void 0;H&&H._handle&&H._handle.setBlocking&&H._handle.setBlocking(!0);E&&(console.error(),console.error(E));console.error(F.stack);"object"===typeof e&&null!==e&&"function"===typeof e.exit&&e.exit(1);return}}return x.apply(this,arguments)}}var g=C("source-map").SourceMapConsumer,
n=C("path");try{var v=C("fs");v.existsSync&&v.readFileSync||(v=null)}catch(x){}var z=C("buffer-from"),G=!1,D=!1,L=!1,a="auto",b={},h={},w=/^data:application\/json[^,]+base64,/,y=[],I=[],K=t(y);y.push(function(x){x=x.trim();/^file:/.test(x)&&(x=x.replace(/file:\/\/\/(\w:)?/,function(E,H){return H?"":"/"}));if(x in b)return b[x];var B="";try{if(v)v.existsSync(x)&&(B=v.readFileSync(x,"utf8"));else{var F=new XMLHttpRequest;F.open("GET",x,!1);F.send(null);4===F.readyState&&200===F.status&&(B=F.responseText)}}catch(E){}return b[x]=
B});var N=t(I);I.push(function(x){a:{if(p())try{var B=new XMLHttpRequest;B.open("GET",x,!1);B.send(null);var F=B.getResponseHeader("SourceMap")||B.getResponseHeader("X-SourceMap");if(F){var E=F;break a}}catch(M){}E=K(x);B=/(?:\/\/[@#][\s]*sourceMappingURL=([^\s'"]+)[\s]*$)|(?:\/\*[@#][\s]*sourceMappingURL=([^\s*'"]+)[\s]*(?:\*\/)[\s]*$)/mg;for(var H;F=B.exec(E);)H=F;E=H?H[1]:null}if(!E)return null;w.test(E)?(H=E.slice(E.indexOf(",")+1),H=z(H,"base64").toString(),E=x):(E=m(x,E),H=K(E));return H?{url:E,
map:H}:null});var P=y.slice(0),W=I.slice(0);A.wrapCallSite=r;A.getErrorSource=u;A.mapSourcePosition=f;A.retrieveSourceMap=N;A.install=function(x){x=x||{};if(x.environment&&(a=x.environment,-1===["node","browser","auto"].indexOf(a)))throw Error("environment "+a+" was unknown. Available options are {auto, browser, node}");x.retrieveFile&&(x.overrideRetrieveFile&&(y.length=0),y.unshift(x.retrieveFile));x.retrieveSourceMap&&(x.overrideRetrieveSourceMap&&(I.length=0),I.unshift(x.retrieveSourceMap));if(x.hookRequire&&
!p()){var B=J.require("module"),F=B.prototype._compile;F.__sourceMapSupport||(B.prototype._compile=function(E,H){b[H]=E;h[H]=void 0;return F.call(this,E,H)},B.prototype._compile.__sourceMapSupport=!0)}L||(L="emptyCacheBetweenOperations"in x?x.emptyCacheBetweenOperations:!1);G||(G=!0,Error.prepareStackTrace=k);if(!D){x="handleUncaughtExceptions"in x?x.handleUncaughtExceptions:!0;try{!1===J.require("worker_threads").isMainThread&&(x=!1)}catch(E){}x&&"object"===typeof e&&null!==e&&"function"===typeof e.on&&
(D=!0,d())}};A.resetRetrieveHandlers=function(){y.length=0;I.length=0;y=P.slice(0);I=W.slice(0);N=t(I);K=t(y)}}).call(this,C("g5I+bs"))},{"buffer-from":4,fs:3,"g5I+bs":9,path:8,"source-map":20}]},{},[1]);return R});

View File

@@ -0,0 +1,50 @@
{
"name": "@cspotcode/source-map-support",
"description": "Fixes stack traces for files with source maps",
"version": "0.8.1",
"main": "./source-map-support.js",
"types": "./source-map-support.d.ts",
"scripts": {
"build": "node build.js",
"serve-tests": "http-server -p 1336",
"test": "mocha"
},
"files": [
"/register.d.ts",
"/register.js",
"/register-hook-require.d.ts",
"/register-hook-require.js",
"/source-map-support.d.ts",
"/source-map-support.js",
"/browser-source-map-support.js"
],
"dependencies": {
"@jridgewell/trace-mapping": "0.3.9"
},
"devDependencies": {
"@types/lodash": "^4.14.182",
"browserify": "^4.2.3",
"coffeescript": "^1.12.7",
"http-server": "^0.11.1",
"lodash": "^4.17.21",
"mocha": "^3.5.3",
"semver": "^7.3.7",
"source-map": "0.6.1",
"webpack": "^1.15.0"
},
"repository": {
"type": "git",
"url": "https://github.com/cspotcode/node-source-map-support"
},
"bugs": {
"url": "https://github.com/cspotcode/node-source-map-support/issues"
},
"license": "MIT",
"engines": {
"node": ">=12"
},
"volta": {
"node": "16.11.0",
"npm": "7.24.2"
}
}

View File

@@ -0,0 +1,7 @@
// tslint:disable:no-useless-files
// For following usage:
// import '@cspotcode/source-map-support/register-hook-require'
// Instead of:
// import sourceMapSupport from '@cspotcode/source-map-support'
// sourceMapSupport.install({hookRequire: true})

View File

@@ -0,0 +1,3 @@
require('./').install({
hookRequire: true
});

View File

@@ -0,0 +1,7 @@
// tslint:disable:no-useless-files
// For following usage:
// import '@cspotcode/source-map-support/register'
// Instead of:
// import sourceMapSupport from '@cspotcode/source-map-support'
// sourceMapSupport.install()

View File

@@ -0,0 +1 @@
require('./').install();

View File

@@ -0,0 +1,76 @@
// Type definitions for source-map-support 0.5
// Project: https://github.com/evanw/node-source-map-support
// Definitions by: Bart van der Schoor <https://github.com/Bartvds>
// Jason Cheatham <https://github.com/jason0x43>
// Alcedo Nathaniel De Guzman Jr <https://github.com/natealcedo>
// Griffin Yourick <https://github.com/tough-griff>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
export interface RawSourceMap {
version: 3;
sources: string[];
names: string[];
sourceRoot?: string;
sourcesContent?: string[];
mappings: string;
file: string;
}
/**
* Output of retrieveSourceMap().
* From source-map-support:
* The map field may be either a string or the parsed JSON object (i.e.,
* it must be a valid argument to the SourceMapConsumer constructor).
*/
export interface UrlAndMap {
url: string;
map: string | RawSourceMap;
}
/**
* Options to install().
*/
export interface Options {
handleUncaughtExceptions?: boolean | undefined;
hookRequire?: boolean | undefined;
emptyCacheBetweenOperations?: boolean | undefined;
environment?: 'auto' | 'browser' | 'node' | undefined;
overrideRetrieveFile?: boolean | undefined;
overrideRetrieveSourceMap?: boolean | undefined;
retrieveFile?(path: string): string;
retrieveSourceMap?(source: string): UrlAndMap | null;
/**
* Set false to disable redirection of require / import `source-map-support` to `@cspotcode/source-map-support`
*/
redirectConflictingLibrary?: boolean;
/**
* Callback will be called every time we redirect due to `redirectConflictingLibrary`
* This allows consumers to log helpful warnings if they choose.
* @param parent NodeJS.Module which made the require() or require.resolve() call
* @param options options object internally passed to node's `_resolveFilename` hook
*/
onConflictingLibraryRedirect?: (request: string, parent: any, isMain: boolean, options: any, redirectedRequest: string) => void;
}
export interface Position {
source: string;
line: number;
column: number;
}
export function wrapCallSite(frame: any /* StackFrame */): any /* StackFrame */;
export function getErrorSource(error: Error): string | null;
export function mapSourcePosition(position: Position): Position;
export function retrieveSourceMap(source: string): UrlAndMap | null;
export function resetRetrieveHandlers(): void;
/**
* Install SourceMap support.
* @param options Can be used to e.g. disable uncaughtException handler.
*/
export function install(options?: Options): void;
/**
* Uninstall SourceMap support.
*/
export function uninstall(): void;

View File

@@ -0,0 +1,938 @@
const { TraceMap, originalPositionFor, AnyMap } = require('@jridgewell/trace-mapping');
var path = require('path');
const { fileURLToPath, pathToFileURL } = require('url');
var util = require('util');
var fs;
try {
fs = require('fs');
if (!fs.existsSync || !fs.readFileSync) {
// fs doesn't have all methods we need
fs = null;
}
} catch (err) {
/* nop */
}
/**
* Requires a module which is protected against bundler minification.
*
* @param {NodeModule} mod
* @param {string} request
*/
function dynamicRequire(mod, request) {
return mod.require(request);
}
/**
* @typedef {{
* enabled: boolean;
* originalValue: any;
* installedValue: any;
* }} HookState
* Used for installing and uninstalling hooks
*/
// Increment this if the format of sharedData changes in a breaking way.
var sharedDataVersion = 1;
/**
* @template T
* @param {T} defaults
* @returns {T}
*/
function initializeSharedData(defaults) {
var sharedDataKey = 'source-map-support/sharedData';
if (typeof Symbol !== 'undefined') {
sharedDataKey = Symbol.for(sharedDataKey);
}
var sharedData = this[sharedDataKey];
if (!sharedData) {
sharedData = { version: sharedDataVersion };
if (Object.defineProperty) {
Object.defineProperty(this, sharedDataKey, { value: sharedData });
} else {
this[sharedDataKey] = sharedData;
}
}
if (sharedDataVersion !== sharedData.version) {
throw new Error("Multiple incompatible instances of source-map-support were loaded");
}
for (var key in defaults) {
if (!(key in sharedData)) {
sharedData[key] = defaults[key];
}
}
return sharedData;
}
// If multiple instances of source-map-support are loaded into the same
// context, they shouldn't overwrite each other. By storing handlers, caches,
// and other state on a shared object, different instances of
// source-map-support can work together in a limited way. This does require
// that future versions of source-map-support continue to support the fields on
// this object. If this internal contract ever needs to be broken, increment
// sharedDataVersion. (This version number is not the same as any of the
// package's version numbers, which should reflect the *external* API of
// source-map-support.)
var sharedData = initializeSharedData({
// Only install once if called multiple times
// Remember how the environment looked before installation so we can restore if able
/** @type {HookState} */
errorPrepareStackTraceHook: undefined,
/** @type {HookState} */
processEmitHook: undefined,
/** @type {HookState} */
moduleResolveFilenameHook: undefined,
/** @type {Array<(request: string, parent: any, isMain: boolean, options: any, redirectedRequest: string) => void>} */
onConflictingLibraryRedirectArr: [],
// If true, the caches are reset before a stack trace formatting operation
emptyCacheBetweenOperations: false,
// Maps a file path to a string containing the file contents
fileContentsCache: Object.create(null),
// Maps a file path to a source map for that file
/** @type {Record<string, {url: string, map: TraceMap}} */
sourceMapCache: Object.create(null),
// Priority list of retrieve handlers
retrieveFileHandlers: [],
retrieveMapHandlers: [],
// Priority list of internally-implemented handlers.
// When resetting state, we must keep these.
internalRetrieveFileHandlers: [],
internalRetrieveMapHandlers: [],
});
// Supports {browser, node, auto}
var environment = "auto";
// Regex for detecting source maps
var reSourceMap = /^data:application\/json[^,]+base64,/;
function isInBrowser() {
if (environment === "browser")
return true;
if (environment === "node")
return false;
return ((typeof window !== 'undefined') && (typeof XMLHttpRequest === 'function') && !(window.require && window.module && window.process && window.process.type === "renderer"));
}
function hasGlobalProcessEventEmitter() {
return ((typeof process === 'object') && (process !== null) && (typeof process.on === 'function'));
}
function tryFileURLToPath(v) {
if(isFileUrl(v)) {
return fileURLToPath(v);
}
return v;
}
// TODO un-copy these from resolve-uri; see if they can be exported from that lib
function isFileUrl(input) {
return input.startsWith('file:');
}
function isAbsoluteUrl(input) {
return schemeRegex.test(input);
}
// Matches the scheme of a URL, eg "http://"
const schemeRegex = /^[\w+.-]+:\/\//;
function isSchemeRelativeUrl(input) {
return input.startsWith('//');
}
// #region Caches
/** @param {string} pathOrFileUrl */
function getCacheKey(pathOrFileUrl) {
if(pathOrFileUrl.startsWith('node:')) return pathOrFileUrl;
if(isFileUrl(pathOrFileUrl)) {
// Must normalize spaces to %20, stuff like that
return new URL(pathOrFileUrl).toString();
} else {
try {
return pathToFileURL(pathOrFileUrl).toString();
} catch {
return pathOrFileUrl;
}
}
}
function getFileContentsCache(key) {
return sharedData.fileContentsCache[getCacheKey(key)];
}
function hasFileContentsCacheFromKey(key) {
return Object.prototype.hasOwnProperty.call(sharedData.fileContentsCache, key);
}
function getFileContentsCacheFromKey(key) {
return sharedData.fileContentsCache[key];
}
function setFileContentsCache(key, value) {
return sharedData.fileContentsCache[getCacheKey(key)] = value;
}
function getSourceMapCache(key) {
return sharedData.sourceMapCache[getCacheKey(key)];
}
function setSourceMapCache(key, value) {
return sharedData.sourceMapCache[getCacheKey(key)] = value;
}
function clearCaches() {
sharedData.fileContentsCache = Object.create(null);
sharedData.sourceMapCache = Object.create(null);
}
// #endregion Caches
function handlerExec(list, internalList) {
return function(arg) {
for (var i = 0; i < list.length; i++) {
var ret = list[i](arg);
if (ret) {
return ret;
}
}
for (var i = 0; i < internalList.length; i++) {
var ret = internalList[i](arg);
if (ret) {
return ret;
}
}
return null;
};
}
var retrieveFile = handlerExec(sharedData.retrieveFileHandlers, sharedData.internalRetrieveFileHandlers);
sharedData.internalRetrieveFileHandlers.push(function(path) {
// Trim the path to make sure there is no extra whitespace.
path = path.trim();
if (/^file:/.test(path)) {
// existsSync/readFileSync can't handle file protocol, but once stripped, it works
path = path.replace(/file:\/\/\/(\w:)?/, function(protocol, drive) {
return drive ?
'' : // file:///C:/dir/file -> C:/dir/file
'/'; // file:///root-dir/file -> /root-dir/file
});
}
const key = getCacheKey(path);
if(hasFileContentsCacheFromKey(key)) {
return getFileContentsCacheFromKey(key);
}
var contents = '';
try {
if (!fs) {
// Use SJAX if we are in the browser
var xhr = new XMLHttpRequest();
xhr.open('GET', path, /** async */ false);
xhr.send(null);
if (xhr.readyState === 4 && xhr.status === 200) {
contents = xhr.responseText;
}
} else if (fs.existsSync(path)) {
// Otherwise, use the filesystem
contents = fs.readFileSync(path, 'utf8');
}
} catch (er) {
/* ignore any errors */
}
return setFileContentsCache(path, contents);
});
// Support URLs relative to a directory, but be careful about a protocol prefix
// in case we are in the browser (i.e. directories may start with "http://" or "file:///")
function supportRelativeURL(file, url) {
if(!file) return url;
// given that this happens within error formatting codepath, probably best to
// fallback instead of throwing if anything goes wrong
try {
// if should output a URL
if(isAbsoluteUrl(file) || isSchemeRelativeUrl(file)) {
if(isAbsoluteUrl(url) || isSchemeRelativeUrl(url)) {
return new URL(url, file).toString();
}
if(path.isAbsolute(url)) {
return new URL(pathToFileURL(url), file).toString();
}
// url is relative path or URL
return new URL(url.replace(/\\/g, '/'), file).toString();
}
// if should output a path (unless URL is something like https://)
if(path.isAbsolute(file)) {
if(isFileUrl(url)) {
return fileURLToPath(url);
}
if(isSchemeRelativeUrl(url)) {
return fileURLToPath(new URL(url, 'file://'));
}
if(isAbsoluteUrl(url)) {
// url is a non-file URL
// Go with the URL
return url;
}
if(path.isAbsolute(url)) {
// Normalize at all? decodeURI or normalize slashes?
return path.normalize(url);
}
// url is relative path or URL
return path.join(file, '..', decodeURI(url));
}
// If we get here, file is relative.
// Shouldn't happen since node identifies modules with absolute paths or URLs.
// But we can take a stab at returning something meaningful anyway.
if(isAbsoluteUrl(url) || isSchemeRelativeUrl(url)) {
return url;
}
return path.join(file, '..', url);
} catch(e) {
return url;
}
}
// Return pathOrUrl in the same style as matchStyleOf: either a file URL or a native path
function matchStyleOfPathOrUrl(matchStyleOf, pathOrUrl) {
try {
if(isAbsoluteUrl(matchStyleOf) || isSchemeRelativeUrl(matchStyleOf)) {
if(isAbsoluteUrl(pathOrUrl) || isSchemeRelativeUrl(pathOrUrl)) return pathOrUrl;
if(path.isAbsolute(pathOrUrl)) return pathToFileURL(pathOrUrl).toString();
} else if(path.isAbsolute(matchStyleOf)) {
if(isAbsoluteUrl(pathOrUrl) || isSchemeRelativeUrl(pathOrUrl)) {
return fileURLToPath(new URL(pathOrUrl, 'file://'));
}
}
return pathOrUrl;
} catch(e) {
return pathOrUrl;
}
}
function retrieveSourceMapURL(source) {
var fileData;
if (isInBrowser()) {
try {
var xhr = new XMLHttpRequest();
xhr.open('GET', source, false);
xhr.send(null);
fileData = xhr.readyState === 4 ? xhr.responseText : null;
// Support providing a sourceMappingURL via the SourceMap header
var sourceMapHeader = xhr.getResponseHeader("SourceMap") ||
xhr.getResponseHeader("X-SourceMap");
if (sourceMapHeader) {
return sourceMapHeader;
}
} catch (e) {
}
}
// Get the URL of the source map
fileData = retrieveFile(tryFileURLToPath(source));
var re = /(?:\/\/[@#][\s]*sourceMappingURL=([^\s'"]+)[\s]*$)|(?:\/\*[@#][\s]*sourceMappingURL=([^\s*'"]+)[\s]*(?:\*\/)[\s]*$)/mg;
// Keep executing the search to find the *last* sourceMappingURL to avoid
// picking up sourceMappingURLs from comments, strings, etc.
var lastMatch, match;
while (match = re.exec(fileData)) lastMatch = match;
if (!lastMatch) return null;
return lastMatch[1];
};
// Can be overridden by the retrieveSourceMap option to install. Takes a
// generated source filename; returns a {map, optional url} object, or null if
// there is no source map. The map field may be either a string or the parsed
// JSON object (ie, it must be a valid argument to the SourceMapConsumer
// constructor).
/** @type {(source: string) => import('./source-map-support').UrlAndMap | null} */
var retrieveSourceMap = handlerExec(sharedData.retrieveMapHandlers, sharedData.internalRetrieveMapHandlers);
sharedData.internalRetrieveMapHandlers.push(function(source) {
var sourceMappingURL = retrieveSourceMapURL(source);
if (!sourceMappingURL) return null;
// Read the contents of the source map
var sourceMapData;
if (reSourceMap.test(sourceMappingURL)) {
// Support source map URL as a data url
var rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(',') + 1);
sourceMapData = Buffer.from(rawData, "base64").toString();
sourceMappingURL = source;
} else {
// Support source map URLs relative to the source URL
sourceMappingURL = supportRelativeURL(source, sourceMappingURL);
sourceMapData = retrieveFile(tryFileURLToPath(sourceMappingURL));
}
if (!sourceMapData) {
return null;
}
return {
url: sourceMappingURL,
map: sourceMapData
};
});
function mapSourcePosition(position) {
var sourceMap = getSourceMapCache(position.source);
if (!sourceMap) {
// Call the (overrideable) retrieveSourceMap function to get the source map.
var urlAndMap = retrieveSourceMap(position.source);
if (urlAndMap) {
sourceMap = setSourceMapCache(position.source, {
url: urlAndMap.url,
map: new AnyMap(urlAndMap.map, urlAndMap.url)
});
// Overwrite trace-mapping's resolutions, because they do not handle
// Windows paths the way we want.
// TODO Remove now that windows path support was added to resolve-uri and thus trace-mapping?
sourceMap.map.resolvedSources = sourceMap.map.sources.map(s => supportRelativeURL(sourceMap.url, s));
// Load all sources stored inline with the source map into the file cache
// to pretend like they are already loaded. They may not exist on disk.
if (sourceMap.map.sourcesContent) {
sourceMap.map.resolvedSources.forEach(function(resolvedSource, i) {
var contents = sourceMap.map.sourcesContent[i];
if (contents) {
setFileContentsCache(resolvedSource, contents);
}
});
}
} else {
sourceMap = setSourceMapCache(position.source, {
url: null,
map: null
});
}
}
// Resolve the source URL relative to the URL of the source map
if (sourceMap && sourceMap.map) {
var originalPosition = originalPositionFor(sourceMap.map, position);
// Only return the original position if a matching line was found. If no
// matching line is found then we return position instead, which will cause
// the stack trace to print the path and line for the compiled file. It is
// better to give a precise location in the compiled file than a vague
// location in the original file.
if (originalPosition.source !== null) {
// originalPosition.source has *already* been resolved against sourceMap.url
// so is *already* as absolute as possible.
// However, we want to ensure we output in same format as input: URL or native path
originalPosition.source = matchStyleOfPathOrUrl(
position.source, originalPosition.source);
return originalPosition;
}
}
return position;
}
// Parses code generated by FormatEvalOrigin(), a function inside V8:
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js
function mapEvalOrigin(origin) {
// Most eval() calls are in this format
var match = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(origin);
if (match) {
var position = mapSourcePosition({
source: match[2],
line: +match[3],
column: match[4] - 1
});
return 'eval at ' + match[1] + ' (' + position.source + ':' +
position.line + ':' + (position.column + 1) + ')';
}
// Parse nested eval() calls using recursion
match = /^eval at ([^(]+) \((.+)\)$/.exec(origin);
if (match) {
return 'eval at ' + match[1] + ' (' + mapEvalOrigin(match[2]) + ')';
}
// Make sure we still return useful information if we didn't find anything
return origin;
}
// This is copied almost verbatim from the V8 source code at
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js
// Update 2022-04-29:
// https://github.com/v8/v8/blob/98f6f100c5ab8e390e51422747c4ef644d5ac6f2/src/builtins/builtins-callsite.cc#L175-L179
// https://github.com/v8/v8/blob/98f6f100c5ab8e390e51422747c4ef644d5ac6f2/src/objects/call-site-info.cc#L795-L804
// https://github.com/v8/v8/blob/98f6f100c5ab8e390e51422747c4ef644d5ac6f2/src/objects/call-site-info.cc#L717-L750
// The implementation of wrapCallSite() used to just forward to the actual source
// code of CallSite.prototype.toString but unfortunately a new release of V8
// did something to the prototype chain and broke the shim. The only fix I
// could find was copy/paste.
function CallSiteToString() {
var fileName;
var fileLocation = "";
if (this.isNative()) {
fileLocation = "native";
} else {
fileName = this.getScriptNameOrSourceURL();
if (!fileName && this.isEval()) {
fileLocation = this.getEvalOrigin();
fileLocation += ", "; // Expecting source position to follow.
}
if (fileName) {
fileLocation += fileName;
} else {
// Source code does not originate from a file and is not native, but we
// can still get the source position inside the source string, e.g. in
// an eval string.
fileLocation += "<anonymous>";
}
var lineNumber = this.getLineNumber();
if (lineNumber != null) {
fileLocation += ":" + lineNumber;
var columnNumber = this.getColumnNumber();
if (columnNumber) {
fileLocation += ":" + columnNumber;
}
}
}
var line = "";
var isAsync = this.isAsync ? this.isAsync() : false;
if(isAsync) {
line += 'async ';
var isPromiseAll = this.isPromiseAll ? this.isPromiseAll() : false;
var isPromiseAny = this.isPromiseAny ? this.isPromiseAny() : false;
if(isPromiseAny || isPromiseAll) {
line += isPromiseAll ? 'Promise.all (index ' : 'Promise.any (index ';
var promiseIndex = this.getPromiseIndex();
line += promiseIndex + ')';
}
}
var functionName = this.getFunctionName();
var addSuffix = true;
var isConstructor = this.isConstructor();
var isMethodCall = !(this.isToplevel() || isConstructor);
if (isMethodCall) {
var typeName = this.getTypeName();
// Fixes shim to be backward compatable with Node v0 to v4
if (typeName === "[object Object]") {
typeName = "null";
}
var methodName = this.getMethodName();
if (functionName) {
if (typeName && functionName.indexOf(typeName) != 0) {
line += typeName + ".";
}
line += functionName;
if (methodName && functionName.indexOf("." + methodName) != functionName.length - methodName.length - 1) {
line += " [as " + methodName + "]";
}
} else {
line += typeName + "." + (methodName || "<anonymous>");
}
} else if (isConstructor) {
line += "new " + (functionName || "<anonymous>");
} else if (functionName) {
line += functionName;
} else {
line += fileLocation;
addSuffix = false;
}
if (addSuffix) {
line += " (" + fileLocation + ")";
}
return line;
}
function cloneCallSite(frame) {
var object = {};
Object.getOwnPropertyNames(Object.getPrototypeOf(frame)).forEach(function(name) {
object[name] = /^(?:is|get)/.test(name) ? function() { return frame[name].call(frame); } : frame[name];
});
object.toString = CallSiteToString;
return object;
}
function wrapCallSite(frame, state) {
// provides interface backward compatibility
if (state === undefined) {
state = { nextPosition: null, curPosition: null }
}
if(frame.isNative()) {
state.curPosition = null;
return frame;
}
// Most call sites will return the source file from getFileName(), but code
// passed to eval() ending in "//# sourceURL=..." will return the source file
// from getScriptNameOrSourceURL() instead
var source = frame.getFileName() || frame.getScriptNameOrSourceURL();
if (source) {
// v8 does not expose its internal isWasm, etc methods, so we do this instead.
if(source.startsWith('wasm://')) {
state.curPosition = null;
return frame;
}
var line = frame.getLineNumber();
var column = frame.getColumnNumber() - 1;
// Fix position in Node where some (internal) code is prepended.
// See https://github.com/evanw/node-source-map-support/issues/36
// Header removed in node at ^10.16 || >=11.11.0
// v11 is not an LTS candidate, we can just test the one version with it.
// Test node versions for: 10.16-19, 10.20+, 12-19, 20-99, 100+, or 11.11
var noHeader = /^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/;
var headerLength = noHeader.test(process.version) ? 0 : 62;
if (line === 1 && column > headerLength && !isInBrowser() && !frame.isEval()) {
column -= headerLength;
}
var position = mapSourcePosition({
source: source,
line: line,
column: column
});
state.curPosition = position;
frame = cloneCallSite(frame);
var originalFunctionName = frame.getFunctionName;
frame.getFunctionName = function() {
if (state.nextPosition == null) {
return originalFunctionName();
}
return state.nextPosition.name || originalFunctionName();
};
frame.getFileName = function() { return position.source; };
frame.getLineNumber = function() { return position.line; };
frame.getColumnNumber = function() { return position.column + 1; };
frame.getScriptNameOrSourceURL = function() { return position.source; };
return frame;
}
// Code called using eval() needs special handling
var origin = frame.isEval() && frame.getEvalOrigin();
if (origin) {
origin = mapEvalOrigin(origin);
frame = cloneCallSite(frame);
frame.getEvalOrigin = function() { return origin; };
return frame;
}
// If we get here then we were unable to change the source position
return frame;
}
var kIsNodeError = undefined;
try {
// Get a deliberate ERR_INVALID_ARG_TYPE
// TODO is there a better way to reliably get an instance of NodeError?
path.resolve(123);
} catch(e) {
const symbols = Object.getOwnPropertySymbols(e);
const symbol = symbols.find(function (s) {return s.toString().indexOf('kIsNodeError') >= 0});
if(symbol) kIsNodeError = symbol;
}
const ErrorPrototypeToString = (err) =>Error.prototype.toString.call(err);
/** @param {HookState} hookState */
function createPrepareStackTrace(hookState) {
return prepareStackTrace;
// This function is part of the V8 stack trace API, for more info see:
// https://v8.dev/docs/stack-trace-api
function prepareStackTrace(error, stack) {
if(!hookState.enabled) return hookState.originalValue.apply(this, arguments);
if (sharedData.emptyCacheBetweenOperations) {
clearCaches();
}
// node gives its own errors special treatment. Mimic that behavior
// https://github.com/nodejs/node/blob/3cbaabc4622df1b4009b9d026a1a970bdbae6e89/lib/internal/errors.js#L118-L128
// https://github.com/nodejs/node/pull/39182
var errorString;
if (kIsNodeError) {
if(kIsNodeError in error) {
errorString = `${error.name} [${error.code}]: ${error.message}`;
} else {
errorString = ErrorPrototypeToString(error);
}
} else {
var name = error.name || 'Error';
var message = error.message || '';
errorString = message ? name + ": " + message : name;
}
var state = { nextPosition: null, curPosition: null };
var processedStack = [];
for (var i = stack.length - 1; i >= 0; i--) {
processedStack.push('\n at ' + wrapCallSite(stack[i], state));
state.nextPosition = state.curPosition;
}
state.curPosition = state.nextPosition = null;
return errorString + processedStack.reverse().join('');
}
}
// Generate position and snippet of original source with pointer
function getErrorSource(error) {
var match = /\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(error.stack);
if (match) {
var source = match[1];
var line = +match[2];
var column = +match[3];
// Support the inline sourceContents inside the source map
var contents = getFileContentsCache(source);
const sourceAsPath = tryFileURLToPath(source);
// Support files on disk
if (!contents && fs && fs.existsSync(sourceAsPath)) {
try {
contents = fs.readFileSync(sourceAsPath, 'utf8');
} catch (er) {
contents = '';
}
}
// Format the line from the original source code like node does
if (contents) {
var code = contents.split(/(?:\r\n|\r|\n)/)[line - 1];
if (code) {
return source + ':' + line + '\n' + code + '\n' +
new Array(column).join(' ') + '^';
}
}
}
return null;
}
function printFatalErrorUponExit (error) {
var source = getErrorSource(error);
// Ensure error is printed synchronously and not truncated
if (process.stderr._handle && process.stderr._handle.setBlocking) {
process.stderr._handle.setBlocking(true);
}
if (source) {
console.error(source);
}
// Matches node's behavior for colorized output
console.error(
util.inspect(error, {
customInspect: false,
colors: process.stderr.isTTY
})
);
}
function shimEmitUncaughtException () {
const originalValue = process.emit;
var hook = sharedData.processEmitHook = {
enabled: true,
originalValue,
installedValue: undefined
};
var isTerminatingDueToFatalException = false;
var fatalException;
process.emit = sharedData.processEmitHook.installedValue = function (type) {
const hadListeners = originalValue.apply(this, arguments);
if(hook.enabled) {
if (type === 'uncaughtException' && !hadListeners) {
isTerminatingDueToFatalException = true;
fatalException = arguments[1];
process.exit(1);
}
if (type === 'exit' && isTerminatingDueToFatalException) {
printFatalErrorUponExit(fatalException);
}
}
return hadListeners;
};
}
var originalRetrieveFileHandlers = sharedData.retrieveFileHandlers.slice(0);
var originalRetrieveMapHandlers = sharedData.retrieveMapHandlers.slice(0);
exports.wrapCallSite = wrapCallSite;
exports.getErrorSource = getErrorSource;
exports.mapSourcePosition = mapSourcePosition;
exports.retrieveSourceMap = retrieveSourceMap;
exports.install = function(options) {
options = options || {};
if (options.environment) {
environment = options.environment;
if (["node", "browser", "auto"].indexOf(environment) === -1) {
throw new Error("environment " + environment + " was unknown. Available options are {auto, browser, node}")
}
}
// Use dynamicRequire to avoid including in browser bundles
var Module = dynamicRequire(module, 'module');
// Redirect subsequent imports of "source-map-support"
// to this package
const {redirectConflictingLibrary = true, onConflictingLibraryRedirect} = options;
if(redirectConflictingLibrary) {
if (!sharedData.moduleResolveFilenameHook) {
const originalValue = Module._resolveFilename;
const moduleResolveFilenameHook = sharedData.moduleResolveFilenameHook = {
enabled: true,
originalValue,
installedValue: undefined,
}
Module._resolveFilename = sharedData.moduleResolveFilenameHook.installedValue = function (request, parent, isMain, options) {
if (moduleResolveFilenameHook.enabled) {
// Match all source-map-support entrypoints: source-map-support, source-map-support/register
let requestRedirect;
if (request === 'source-map-support') {
requestRedirect = './';
} else if (request === 'source-map-support/register') {
requestRedirect = './register';
}
if (requestRedirect !== undefined) {
const newRequest = require.resolve(requestRedirect);
for (const cb of sharedData.onConflictingLibraryRedirectArr) {
cb(request, parent, isMain, options, newRequest);
}
request = newRequest;
}
}
return originalValue.call(this, request, parent, isMain, options);
}
}
if (onConflictingLibraryRedirect) {
sharedData.onConflictingLibraryRedirectArr.push(onConflictingLibraryRedirect);
}
}
// Allow sources to be found by methods other than reading the files
// directly from disk.
if (options.retrieveFile) {
if (options.overrideRetrieveFile) {
sharedData.retrieveFileHandlers.length = 0;
}
sharedData.retrieveFileHandlers.unshift(options.retrieveFile);
}
// Allow source maps to be found by methods other than reading the files
// directly from disk.
if (options.retrieveSourceMap) {
if (options.overrideRetrieveSourceMap) {
sharedData.retrieveMapHandlers.length = 0;
}
sharedData.retrieveMapHandlers.unshift(options.retrieveSourceMap);
}
// Support runtime transpilers that include inline source maps
if (options.hookRequire && !isInBrowser()) {
var $compile = Module.prototype._compile;
if (!$compile.__sourceMapSupport) {
Module.prototype._compile = function(content, filename) {
setFileContentsCache(filename, content);
setSourceMapCache(filename, undefined);
return $compile.call(this, content, filename);
};
Module.prototype._compile.__sourceMapSupport = true;
}
}
// Configure options
if (!sharedData.emptyCacheBetweenOperations) {
sharedData.emptyCacheBetweenOperations = 'emptyCacheBetweenOperations' in options ?
options.emptyCacheBetweenOperations : false;
}
// Install the error reformatter
if (!sharedData.errorPrepareStackTraceHook) {
const originalValue = Error.prepareStackTrace;
sharedData.errorPrepareStackTraceHook = {
enabled: true,
originalValue,
installedValue: undefined
};
Error.prepareStackTrace = sharedData.errorPrepareStackTraceHook.installedValue = createPrepareStackTrace(sharedData.errorPrepareStackTraceHook);
}
if (!sharedData.processEmitHook) {
var installHandler = 'handleUncaughtExceptions' in options ?
options.handleUncaughtExceptions : true;
// Do not override 'uncaughtException' with our own handler in Node.js
// Worker threads. Workers pass the error to the main thread as an event,
// rather than printing something to stderr and exiting.
try {
// We need to use `dynamicRequire` because `require` on it's own will be optimized by WebPack/Browserify.
var worker_threads = dynamicRequire(module, 'worker_threads');
if (worker_threads.isMainThread === false) {
installHandler = false;
}
} catch(e) {}
// Provide the option to not install the uncaught exception handler. This is
// to support other uncaught exception handlers (in test frameworks, for
// example). If this handler is not installed and there are no other uncaught
// exception handlers, uncaught exceptions will be caught by node's built-in
// exception handler and the process will still be terminated. However, the
// generated JavaScript code will be shown above the stack trace instead of
// the original source code.
if (installHandler && hasGlobalProcessEventEmitter()) {
shimEmitUncaughtException();
}
}
};
exports.uninstall = function() {
if(sharedData.processEmitHook) {
// Disable behavior
sharedData.processEmitHook.enabled = false;
// If possible, remove our hook function. May not be possible if subsequent third-party hooks have wrapped around us.
if(process.emit === sharedData.processEmitHook.installedValue) {
process.emit = sharedData.processEmitHook.originalValue;
}
sharedData.processEmitHook = undefined;
}
if(sharedData.errorPrepareStackTraceHook) {
// Disable behavior
sharedData.errorPrepareStackTraceHook.enabled = false;
// If possible or necessary, remove our hook function.
// In vanilla environments, prepareStackTrace is `undefined`.
// We cannot delegate to `undefined` the way we can to a function w/`.apply()`; our only option is to remove the function.
// If we are the *first* hook installed, and another was installed on top of us, we have no choice but to remove both.
if(Error.prepareStackTrace === sharedData.errorPrepareStackTraceHook.installedValue || typeof sharedData.errorPrepareStackTraceHook.originalValue !== 'function') {
Error.prepareStackTrace = sharedData.errorPrepareStackTraceHook.originalValue;
}
sharedData.errorPrepareStackTraceHook = undefined;
}
if (sharedData.moduleResolveFilenameHook) {
// Disable behavior
sharedData.moduleResolveFilenameHook.enabled = false;
// If possible, remove our hook function. May not be possible if subsequent third-party hooks have wrapped around us.
var Module = dynamicRequire(module, 'module');
if(Module._resolveFilename === sharedData.moduleResolveFilenameHook.installedValue) {
Module._resolveFilename = sharedData.moduleResolveFilenameHook.originalValue;
}
sharedData.moduleResolveFilenameHook = undefined;
}
sharedData.onConflictingLibraryRedirectArr.length = 0;
}
exports.resetRetrieveHandlers = function() {
sharedData.retrieveFileHandlers.length = 0;
sharedData.retrieveMapHandlers.length = 0;
}

19
server/node_modules/@jridgewell/resolve-uri/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright 2019 Justin Ridgewell <jridgewell@google.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

40
server/node_modules/@jridgewell/resolve-uri/README.md generated vendored Normal file
View File

@@ -0,0 +1,40 @@
# @jridgewell/resolve-uri
> Resolve a URI relative to an optional base URI
Resolve any combination of absolute URIs, protocol-realtive URIs, absolute paths, or relative paths.
## Installation
```sh
npm install @jridgewell/resolve-uri
```
## Usage
```typescript
function resolve(input: string, base?: string): string;
```
```js
import resolve from '@jridgewell/resolve-uri';
resolve('foo', 'https://example.com'); // => 'https://example.com/foo'
```
| Input | Base | Resolution | Explanation |
|-----------------------|-------------------------|--------------------------------|--------------------------------------------------------------|
| `https://example.com` | _any_ | `https://example.com/` | Input is normalized only |
| `//example.com` | `https://base.com/` | `https://example.com/` | Input inherits the base's protocol |
| `//example.com` | _rest_ | `//example.com/` | Input is normalized only |
| `/example` | `https://base.com/` | `https://base.com/example` | Input inherits the base's origin |
| `/example` | `//base.com/` | `//base.com/example` | Input inherits the base's host and remains protocol relative |
| `/example` | _rest_ | `/example` | Input is normalized only |
| `example` | `https://base.com/dir/` | `https://base.com/dir/example` | Input is joined with the base |
| `example` | `https://base.com/file` | `https://base.com/example` | Input is joined with the base without its file |
| `example` | `//base.com/dir/` | `//base.com/dir/example` | Input is joined with the base's last directory |
| `example` | `//base.com/file` | `//base.com/example` | Input is joined with the base without its file |
| `example` | `/base/dir/` | `/base/dir/example` | Input is joined with the base's last directory |
| `example` | `/base/file` | `/base/example` | Input is joined with the base without its file |
| `example` | `base/dir/` | `base/dir/example` | Input is joined with the base's last directory |
| `example` | `base/file` | `base/example` | Input is joined with the base without its file |

View File

@@ -0,0 +1,232 @@
// Matches the scheme of a URL, eg "http://"
const schemeRegex = /^[\w+.-]+:\/\//;
/**
* Matches the parts of a URL:
* 1. Scheme, including ":", guaranteed.
* 2. User/password, including "@", optional.
* 3. Host, guaranteed.
* 4. Port, including ":", optional.
* 5. Path, including "/", optional.
* 6. Query, including "?", optional.
* 7. Hash, including "#", optional.
*/
const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/;
/**
* File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start
* with a leading `/`, they can have a domain (but only if they don't start with a Windows drive).
*
* 1. Host, optional.
* 2. Path, which may include "/", guaranteed.
* 3. Query, including "?", optional.
* 4. Hash, including "#", optional.
*/
const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i;
function isAbsoluteUrl(input) {
return schemeRegex.test(input);
}
function isSchemeRelativeUrl(input) {
return input.startsWith('//');
}
function isAbsolutePath(input) {
return input.startsWith('/');
}
function isFileUrl(input) {
return input.startsWith('file:');
}
function isRelative(input) {
return /^[.?#]/.test(input);
}
function parseAbsoluteUrl(input) {
const match = urlRegex.exec(input);
return makeUrl(match[1], match[2] || '', match[3], match[4] || '', match[5] || '/', match[6] || '', match[7] || '');
}
function parseFileUrl(input) {
const match = fileRegex.exec(input);
const path = match[2];
return makeUrl('file:', '', match[1] || '', '', isAbsolutePath(path) ? path : '/' + path, match[3] || '', match[4] || '');
}
function makeUrl(scheme, user, host, port, path, query, hash) {
return {
scheme,
user,
host,
port,
path,
query,
hash,
type: 7 /* Absolute */,
};
}
function parseUrl(input) {
if (isSchemeRelativeUrl(input)) {
const url = parseAbsoluteUrl('http:' + input);
url.scheme = '';
url.type = 6 /* SchemeRelative */;
return url;
}
if (isAbsolutePath(input)) {
const url = parseAbsoluteUrl('http://foo.com' + input);
url.scheme = '';
url.host = '';
url.type = 5 /* AbsolutePath */;
return url;
}
if (isFileUrl(input))
return parseFileUrl(input);
if (isAbsoluteUrl(input))
return parseAbsoluteUrl(input);
const url = parseAbsoluteUrl('http://foo.com/' + input);
url.scheme = '';
url.host = '';
url.type = input
? input.startsWith('?')
? 3 /* Query */
: input.startsWith('#')
? 2 /* Hash */
: 4 /* RelativePath */
: 1 /* Empty */;
return url;
}
function stripPathFilename(path) {
// If a path ends with a parent directory "..", then it's a relative path with excess parent
// paths. It's not a file, so we can't strip it.
if (path.endsWith('/..'))
return path;
const index = path.lastIndexOf('/');
return path.slice(0, index + 1);
}
function mergePaths(url, base) {
normalizePath(base, base.type);
// If the path is just a "/", then it was an empty path to begin with (remember, we're a relative
// path).
if (url.path === '/') {
url.path = base.path;
}
else {
// Resolution happens relative to the base path's directory, not the file.
url.path = stripPathFilename(base.path) + url.path;
}
}
/**
* The path can have empty directories "//", unneeded parents "foo/..", or current directory
* "foo/.". We need to normalize to a standard representation.
*/
function normalizePath(url, type) {
const rel = type <= 4 /* RelativePath */;
const pieces = url.path.split('/');
// We need to preserve the first piece always, so that we output a leading slash. The item at
// pieces[0] is an empty string.
let pointer = 1;
// Positive is the number of real directories we've output, used for popping a parent directory.
// Eg, "foo/bar/.." will have a positive 2, and we can decrement to be left with just "foo".
let positive = 0;
// We need to keep a trailing slash if we encounter an empty directory (eg, splitting "foo/" will
// generate `["foo", ""]` pieces). And, if we pop a parent directory. But once we encounter a
// real directory, we won't need to append, unless the other conditions happen again.
let addTrailingSlash = false;
for (let i = 1; i < pieces.length; i++) {
const piece = pieces[i];
// An empty directory, could be a trailing slash, or just a double "//" in the path.
if (!piece) {
addTrailingSlash = true;
continue;
}
// If we encounter a real directory, then we don't need to append anymore.
addTrailingSlash = false;
// A current directory, which we can always drop.
if (piece === '.')
continue;
// A parent directory, we need to see if there are any real directories we can pop. Else, we
// have an excess of parents, and we'll need to keep the "..".
if (piece === '..') {
if (positive) {
addTrailingSlash = true;
positive--;
pointer--;
}
else if (rel) {
// If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute
// URL, protocol relative URL, or an absolute path, we don't need to keep excess.
pieces[pointer++] = piece;
}
continue;
}
// We've encountered a real directory. Move it to the next insertion pointer, which accounts for
// any popped or dropped directories.
pieces[pointer++] = piece;
positive++;
}
let path = '';
for (let i = 1; i < pointer; i++) {
path += '/' + pieces[i];
}
if (!path || (addTrailingSlash && !path.endsWith('/..'))) {
path += '/';
}
url.path = path;
}
/**
* Attempts to resolve `input` URL/path relative to `base`.
*/
function resolve(input, base) {
if (!input && !base)
return '';
const url = parseUrl(input);
let inputType = url.type;
if (base && inputType !== 7 /* Absolute */) {
const baseUrl = parseUrl(base);
const baseType = baseUrl.type;
switch (inputType) {
case 1 /* Empty */:
url.hash = baseUrl.hash;
// fall through
case 2 /* Hash */:
url.query = baseUrl.query;
// fall through
case 3 /* Query */:
case 4 /* RelativePath */:
mergePaths(url, baseUrl);
// fall through
case 5 /* AbsolutePath */:
// The host, user, and port are joined, you can't copy one without the others.
url.user = baseUrl.user;
url.host = baseUrl.host;
url.port = baseUrl.port;
// fall through
case 6 /* SchemeRelative */:
// The input doesn't have a schema at least, so we need to copy at least that over.
url.scheme = baseUrl.scheme;
}
if (baseType > inputType)
inputType = baseType;
}
normalizePath(url, inputType);
const queryHash = url.query + url.hash;
switch (inputType) {
// This is impossible, because of the empty checks at the start of the function.
// case UrlType.Empty:
case 2 /* Hash */:
case 3 /* Query */:
return queryHash;
case 4 /* RelativePath */: {
// The first char is always a "/", and we need it to be relative.
const path = url.path.slice(1);
if (!path)
return queryHash || '.';
if (isRelative(base || input) && !isRelative(path)) {
// If base started with a leading ".", or there is no base and input started with a ".",
// then we need to ensure that the relative path starts with a ".". We don't know if
// relative starts with a "..", though, so check before prepending.
return './' + path + queryHash;
}
return path + queryHash;
}
case 5 /* AbsolutePath */:
return url.path + queryHash;
default:
return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash;
}
}
export { resolve as default };
//# sourceMappingURL=resolve-uri.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,240 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.resolveURI = factory());
})(this, (function () { 'use strict';
// Matches the scheme of a URL, eg "http://"
const schemeRegex = /^[\w+.-]+:\/\//;
/**
* Matches the parts of a URL:
* 1. Scheme, including ":", guaranteed.
* 2. User/password, including "@", optional.
* 3. Host, guaranteed.
* 4. Port, including ":", optional.
* 5. Path, including "/", optional.
* 6. Query, including "?", optional.
* 7. Hash, including "#", optional.
*/
const urlRegex = /^([\w+.-]+:)\/\/([^@/#?]*@)?([^:/#?]*)(:\d+)?(\/[^#?]*)?(\?[^#]*)?(#.*)?/;
/**
* File URLs are weird. They dont' need the regular `//` in the scheme, they may or may not start
* with a leading `/`, they can have a domain (but only if they don't start with a Windows drive).
*
* 1. Host, optional.
* 2. Path, which may include "/", guaranteed.
* 3. Query, including "?", optional.
* 4. Hash, including "#", optional.
*/
const fileRegex = /^file:(?:\/\/((?![a-z]:)[^/#?]*)?)?(\/?[^#?]*)(\?[^#]*)?(#.*)?/i;
function isAbsoluteUrl(input) {
return schemeRegex.test(input);
}
function isSchemeRelativeUrl(input) {
return input.startsWith('//');
}
function isAbsolutePath(input) {
return input.startsWith('/');
}
function isFileUrl(input) {
return input.startsWith('file:');
}
function isRelative(input) {
return /^[.?#]/.test(input);
}
function parseAbsoluteUrl(input) {
const match = urlRegex.exec(input);
return makeUrl(match[1], match[2] || '', match[3], match[4] || '', match[5] || '/', match[6] || '', match[7] || '');
}
function parseFileUrl(input) {
const match = fileRegex.exec(input);
const path = match[2];
return makeUrl('file:', '', match[1] || '', '', isAbsolutePath(path) ? path : '/' + path, match[3] || '', match[4] || '');
}
function makeUrl(scheme, user, host, port, path, query, hash) {
return {
scheme,
user,
host,
port,
path,
query,
hash,
type: 7 /* Absolute */,
};
}
function parseUrl(input) {
if (isSchemeRelativeUrl(input)) {
const url = parseAbsoluteUrl('http:' + input);
url.scheme = '';
url.type = 6 /* SchemeRelative */;
return url;
}
if (isAbsolutePath(input)) {
const url = parseAbsoluteUrl('http://foo.com' + input);
url.scheme = '';
url.host = '';
url.type = 5 /* AbsolutePath */;
return url;
}
if (isFileUrl(input))
return parseFileUrl(input);
if (isAbsoluteUrl(input))
return parseAbsoluteUrl(input);
const url = parseAbsoluteUrl('http://foo.com/' + input);
url.scheme = '';
url.host = '';
url.type = input
? input.startsWith('?')
? 3 /* Query */
: input.startsWith('#')
? 2 /* Hash */
: 4 /* RelativePath */
: 1 /* Empty */;
return url;
}
function stripPathFilename(path) {
// If a path ends with a parent directory "..", then it's a relative path with excess parent
// paths. It's not a file, so we can't strip it.
if (path.endsWith('/..'))
return path;
const index = path.lastIndexOf('/');
return path.slice(0, index + 1);
}
function mergePaths(url, base) {
normalizePath(base, base.type);
// If the path is just a "/", then it was an empty path to begin with (remember, we're a relative
// path).
if (url.path === '/') {
url.path = base.path;
}
else {
// Resolution happens relative to the base path's directory, not the file.
url.path = stripPathFilename(base.path) + url.path;
}
}
/**
* The path can have empty directories "//", unneeded parents "foo/..", or current directory
* "foo/.". We need to normalize to a standard representation.
*/
function normalizePath(url, type) {
const rel = type <= 4 /* RelativePath */;
const pieces = url.path.split('/');
// We need to preserve the first piece always, so that we output a leading slash. The item at
// pieces[0] is an empty string.
let pointer = 1;
// Positive is the number of real directories we've output, used for popping a parent directory.
// Eg, "foo/bar/.." will have a positive 2, and we can decrement to be left with just "foo".
let positive = 0;
// We need to keep a trailing slash if we encounter an empty directory (eg, splitting "foo/" will
// generate `["foo", ""]` pieces). And, if we pop a parent directory. But once we encounter a
// real directory, we won't need to append, unless the other conditions happen again.
let addTrailingSlash = false;
for (let i = 1; i < pieces.length; i++) {
const piece = pieces[i];
// An empty directory, could be a trailing slash, or just a double "//" in the path.
if (!piece) {
addTrailingSlash = true;
continue;
}
// If we encounter a real directory, then we don't need to append anymore.
addTrailingSlash = false;
// A current directory, which we can always drop.
if (piece === '.')
continue;
// A parent directory, we need to see if there are any real directories we can pop. Else, we
// have an excess of parents, and we'll need to keep the "..".
if (piece === '..') {
if (positive) {
addTrailingSlash = true;
positive--;
pointer--;
}
else if (rel) {
// If we're in a relativePath, then we need to keep the excess parents. Else, in an absolute
// URL, protocol relative URL, or an absolute path, we don't need to keep excess.
pieces[pointer++] = piece;
}
continue;
}
// We've encountered a real directory. Move it to the next insertion pointer, which accounts for
// any popped or dropped directories.
pieces[pointer++] = piece;
positive++;
}
let path = '';
for (let i = 1; i < pointer; i++) {
path += '/' + pieces[i];
}
if (!path || (addTrailingSlash && !path.endsWith('/..'))) {
path += '/';
}
url.path = path;
}
/**
* Attempts to resolve `input` URL/path relative to `base`.
*/
function resolve(input, base) {
if (!input && !base)
return '';
const url = parseUrl(input);
let inputType = url.type;
if (base && inputType !== 7 /* Absolute */) {
const baseUrl = parseUrl(base);
const baseType = baseUrl.type;
switch (inputType) {
case 1 /* Empty */:
url.hash = baseUrl.hash;
// fall through
case 2 /* Hash */:
url.query = baseUrl.query;
// fall through
case 3 /* Query */:
case 4 /* RelativePath */:
mergePaths(url, baseUrl);
// fall through
case 5 /* AbsolutePath */:
// The host, user, and port are joined, you can't copy one without the others.
url.user = baseUrl.user;
url.host = baseUrl.host;
url.port = baseUrl.port;
// fall through
case 6 /* SchemeRelative */:
// The input doesn't have a schema at least, so we need to copy at least that over.
url.scheme = baseUrl.scheme;
}
if (baseType > inputType)
inputType = baseType;
}
normalizePath(url, inputType);
const queryHash = url.query + url.hash;
switch (inputType) {
// This is impossible, because of the empty checks at the start of the function.
// case UrlType.Empty:
case 2 /* Hash */:
case 3 /* Query */:
return queryHash;
case 4 /* RelativePath */: {
// The first char is always a "/", and we need it to be relative.
const path = url.path.slice(1);
if (!path)
return queryHash || '.';
if (isRelative(base || input) && !isRelative(path)) {
// If base started with a leading ".", or there is no base and input started with a ".",
// then we need to ensure that the relative path starts with a ".". We don't know if
// relative starts with a "..", though, so check before prepending.
return './' + path + queryHash;
}
return path + queryHash;
}
case 5 /* AbsolutePath */:
return url.path + queryHash;
default:
return url.scheme + '//' + url.user + url.host + url.port + url.path + queryHash;
}
}
return resolve;
}));
//# sourceMappingURL=resolve-uri.umd.js.map

Some files were not shown because too many files have changed in this diff Show More