1
1
mirror of https://github.com/theoludwig/theoludwig.git synced 2025-05-29 22:37:44 +02:00

Compare commits

...

17 Commits

65 changed files with 4710 additions and 3403 deletions

View File

@ -1,2 +1 @@
ARG VARIANT="16"
FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT}
FROM mcr.microsoft.com/devcontainers/javascript-node:18

View File

@ -1,5 +1,5 @@
{
"name": "divlo",
"name": "Divlo",
"dockerComposeFile": "./docker-compose.yml",
"service": "workspace",
"workspaceFolder": "/workspace",
@ -10,8 +10,6 @@
"editorconfig.editorconfig",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"divlo.vscode-styled-jsx-syntax",
"divlo.vscode-styled-jsx-languageserver",
"bradlc.vscode-tailwindcss",
"mikestead.dotenv",
"davidanson.vscode-markdownlint",

View File

@ -10,6 +10,7 @@
},
"rules": {
"prettier/prettier": "error",
"unicorn/prefer-node-protocol": "error"
"unicorn/prefer-node-protocol": "error",
"@next/next/no-img-element": "off"
}
}

View File

@ -16,12 +16,12 @@ jobs:
language: ['javascript']
steps:
- uses: 'actions/checkout@v3.0.0'
- uses: 'actions/checkout@v3.1.0'
- name: 'Initialize CodeQL'
uses: 'github/codeql-action/init@v1'
uses: 'github/codeql-action/init@v2'
with:
languages: ${{ matrix.language }}
- name: 'Perform CodeQL Analysis'
uses: 'github/codeql-action/analyze@v1'
uses: 'github/codeql-action/analyze@v2'

View File

@ -10,12 +10,12 @@ jobs:
build:
runs-on: 'ubuntu-latest'
steps:
- uses: 'actions/checkout@v3.0.0'
- uses: 'actions/checkout@v3.1.0'
- name: 'Use Node.js'
uses: 'actions/setup-node@v3.0.0'
uses: 'actions/setup-node@v3.5.1'
with:
node-version: '16.x'
node-version: '18.x'
cache: 'npm'
- name: 'Install'

View File

@ -10,12 +10,12 @@ jobs:
lint:
runs-on: 'ubuntu-latest'
steps:
- uses: 'actions/checkout@v3.0.0'
- uses: 'actions/checkout@v3.1.0'
- name: 'Use Node.js'
uses: 'actions/setup-node@v3.0.0'
uses: 'actions/setup-node@v3.5.1'
with:
node-version: '16.x'
node-version: '18.x'
cache: 'npm'
- name: 'Install'

View File

@ -8,7 +8,7 @@ jobs:
release:
runs-on: 'ubuntu-latest'
steps:
- uses: 'actions/checkout@v3.0.0'
- uses: 'actions/checkout@v3.1.0'
with:
fetch-depth: 0
persist-credentials: false
@ -21,9 +21,9 @@ jobs:
git_commit_gpgsign: true
- name: 'Use Node.js'
uses: 'actions/setup-node@v3.0.0'
uses: 'actions/setup-node@v3.5.1'
with:
node-version: '16.x'
node-version: '18.x'
cache: 'npm'
- name: 'Install'

View File

@ -10,12 +10,12 @@ jobs:
test-unit:
runs-on: 'ubuntu-latest'
steps:
- uses: 'actions/checkout@v3.0.0'
- uses: 'actions/checkout@v3.1.0'
- name: 'Use Node.js'
uses: 'actions/setup-node@v3.0.0'
uses: 'actions/setup-node@v3.5.1'
with:
node-version: '16.x'
node-version: '18.x'
cache: 'npm'
- name: 'Install'
@ -27,12 +27,12 @@ jobs:
test-lighthouse:
runs-on: 'ubuntu-latest'
steps:
- uses: 'actions/checkout@v3.0.0'
- uses: 'actions/checkout@v3.1.0'
- name: 'Use Node.js'
uses: 'actions/setup-node@v3.0.0'
uses: 'actions/setup-node@v3.5.1'
with:
node-version: '16.x'
node-version: '18.x'
cache: 'npm'
- name: 'Install'
@ -52,12 +52,12 @@ jobs:
test-e2e:
runs-on: 'ubuntu-latest'
steps:
- uses: 'actions/checkout@v3.0.0'
- uses: 'actions/checkout@v3.1.0'
- name: 'Use Node.js'
uses: 'actions/setup-node@v3.0.0'
uses: 'actions/setup-node@v3.5.1'
with:
node-version: '16.x'
node-version: '18.x'
cache: 'npm'
- name: 'Install'

4
.gitignore vendored
View File

@ -49,3 +49,7 @@ npm-debug.log*
.DS_Store
.lighthouseci
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts

View File

@ -1,8 +1,8 @@
{
"urls": [
"http://localhost:3000/",
"http://localhost:3000/blog",
"http://localhost:3000/blog/hello-world"
"http://127.0.0.1:3000/",
"http://127.0.0.1:3000/blog",
"http://127.0.0.1:3000/blog/hello-world"
],
"files": ["./public/curriculum-vitae/index.html"]
}

View File

@ -5,9 +5,9 @@
"startServerReadyPattern": "ready on",
"startServerReadyTimeout": 20000,
"url": [
"http://localhost:3000/",
"http://localhost:3000/blog",
"http://localhost:3000/blog/hello-world"
"http://127.0.0.1:3000/",
"http://127.0.0.1:3000/blog",
"http://127.0.0.1:3000/blog/hello-world"
],
"numberOfRuns": 1
},

View File

@ -3,8 +3,6 @@
"editorconfig.editorconfig",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"divlo.vscode-styled-jsx-syntax",
"divlo.vscode-styled-jsx-languageserver",
"bradlc.vscode-tailwindcss",
"mikestead.dotenv",
"davidanson.vscode-markdownlint",

View File

@ -86,4 +86,4 @@ docker compose up --build
### Services started
- website : `http://localhost:3000`
- website : `http://127.0.0.1:3000`

View File

@ -1,23 +1,21 @@
FROM node:16.16.0 AS dependencies
FROM node:18.11.0 AS dependencies
WORKDIR /usr/src/app
COPY ./package*.json ./
RUN npm install
FROM node:16.16.0 AS builder
FROM node:18.11.0 AS builder
WORKDIR /usr/src/app
COPY ./ ./
COPY --from=dependencies /usr/src/app/node_modules ./node_modules
RUN npm run build
FROM node:16.16.0 AS runner
FROM node:18.11.0 AS runner
WORKDIR /usr/src/app
ENV NODE_ENV=production
COPY --from=builder /usr/src/app/next.config.js ./next.config.js
ENV NEXT_TELEMETRY_DISABLED=1
COPY --from=builder /usr/src/app/.next/standalone ./
COPY --from=builder /usr/src/app/.next/static ./.next/static
COPY --from=builder /usr/src/app/public ./public
COPY --from=builder /usr/src/app/.next ./.next
COPY --from=builder /usr/src/app/i18n.json ./i18n.json
COPY --from=builder /usr/src/app/locales ./locales
COPY --from=builder /usr/src/app/pages ./pages
COPY --from=builder /usr/src/app/node_modules ./node_modules
RUN npx next telemetry disable
CMD ["node_modules/.bin/next", "start", "--port", "${PORT}"]
COPY --from=builder /usr/src/app/next.config.js ./next.config.js
CMD ["node", "server.js"]

View File

@ -1,7 +1,7 @@
<h1 align="center"><a href="https://divlo.fr/">Divlo</a></h1>
<p align="center">
<strong>Developer Full Stack Junior • Passionate about High-Tech</strong>
<strong>Developer Full Stack • Passionate about High-Tech</strong>
</p>
<p align="center">
@ -26,14 +26,20 @@
"birthDate": "31/03/2003",
"nationality": "Alsace, France",
"interests": [
"Developer Full Stack Junior",
"Developer Full Stack",
"Passionate about High-Tech",
"Open-Source enthusiast"
],
"skills": {
"programmingLanguages": ["JavaScript", "TypeScript", "Python", "C/C++"],
"programmingLanguages": [
"JavaScript",
"TypeScript",
"Python",
"C/C++",
"PHP"
],
"frontEnd": ["HTML", "CSS", "Tailwind CSS", "React.js (+ Next.js)"],
"backEnd": ["Node.js", "Fastify", "Prisma", "PostgreSQL", "MySQL"],
"backEnd": ["Laravel", "Node.js", "Fastify", "Prisma", "PostgreSQL"],
"tools": ["GNU/Linux", "Ubuntu", "Visual Studio Code", "Git", "Docker"]
}
}

View File

@ -1,17 +1,24 @@
import useTranslation from 'next-translate/useTranslation'
import Link from 'next/link'
export interface ErrorPageProps {
import type { FooterProps } from './Footer'
import { Footer } from './Footer'
import { Header } from './Header'
export interface ErrorPageProps extends FooterProps {
statusCode: number
message: string
}
export const ErrorPage: React.FC<ErrorPageProps> = (props) => {
const { message, statusCode } = props
const { message, statusCode, version } = props
const { t } = useTranslation()
return (
<>
<div className='flex h-screen flex-col pt-0'>
<Header showLanguage />
<main className='flex min-w-full flex-1 flex-col items-center justify-center'>
<h1 className='my-6 text-4xl font-semibold'>
{t('errors:error')}{' '}
<span
@ -23,31 +30,16 @@ export const ErrorPage: React.FC<ErrorPageProps> = (props) => {
</h1>
<p className='text-center text-lg'>
{message}{' '}
<Link href='/'>
<a className='text-yellow hover:underline dark:text-yellow-dark'>
<Link
href='/'
className='text-yellow hover:underline dark:text-yellow-dark'
>
{t('errors:return-to-home-page')}
</a>
</Link>
</p>
<style jsx global>
{`
main {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-width: 100vw;
flex: 1;
}
#__next {
display: flex;
flex-direction: column;
padding-top: 0;
height: 100vh;
}
`}
</style>
</main>
<Footer version={version} />
</div>
</>
)
}

View File

@ -17,10 +17,11 @@ export const Footer: React.FC<FooterProps> = (props) => {
return (
<footer className='flex flex-col items-center justify-center border-t-2 border-gray-600 bg-white py-6 text-lg dark:border-gray-400 dark:bg-black'>
<p>
<Link href='/'>
<a className='text-yellow hover:underline dark:text-yellow-dark'>
<Link
href='/'
className='text-yellow hover:underline dark:text-yellow-dark'
>
Divlo
</a>
</Link>{' '}
| {t('common:all-rights-reserved')}
</p>

View File

@ -11,7 +11,7 @@ export const Head: React.FC<HeadProps> = (props) => {
const {
title = 'Divlo',
image = 'https://divlo.fr/images/icons/icon-96x96.png',
description = 'Divlo - Developer Full Stack Junior • Passionate about High-Tech',
description = 'Divlo - Developer Full Stack • Passionate about High-Tech',
url = 'https://divlo.fr/'
} = props

View File

@ -14,7 +14,9 @@ export const Language: React.FC = () => {
const languageClickRef = useRef<HTMLDivElement | null>(null)
const handleHiddenMenu = useCallback(() => {
setHiddenMenu((oldHiddenMenu) => !oldHiddenMenu)
setHiddenMenu((oldHiddenMenu) => {
return !oldHiddenMenu
})
}, [])
useEffect(() => {
@ -65,7 +67,9 @@ export const Language: React.FC = () => {
<li
key={index}
className='flex h-12 w-full items-center justify-center pl-2 hover:bg-[#4f545c] hover:bg-opacity-20'
onClick={async () => await handleLanguage(language)}
onClick={async () => {
return await handleLanguage(language)
}}
>
<LanguageFlag language={language} />
</li>

View File

@ -1,4 +1,5 @@
import { useEffect, useState } from 'react'
import classNames from 'clsx'
import { useTheme } from 'next-themes'
export const SwitchTheme: React.FC = () => {
@ -18,109 +19,60 @@ export const SwitchTheme: React.FC = () => {
}
return (
<>
<div
className='flex items-center'
data-cy='switch-theme-click'
onClick={handleClick}
>
<div className='toggle-theme-button relative inline-block cursor-pointer bg-transparent'>
<div className='toggle-track'>
<div className='relative inline-block cursor-pointer touch-pan-x select-none border-0 bg-transparent p-0'>
<div className='h-[24px] w-[50px] rounded-[30px] bg-[#4d4d4d] p-0 text-white transition-all duration-200 ease-in-out'>
<div
data-cy='switch-theme-dark'
className='toggle-track-check absolute'
className={classNames(
'absolute top-0 bottom-0 left-[8px] mt-auto mb-auto h-[10px] w-[14px] leading-[0] transition-opacity duration-[250ms] ease-in-out',
{
'opacity-100': theme === 'dark',
'opacity-0': theme === 'light'
}
)}
>
<span className='toggle_Dark relative flex items-center justify-center'>
<span className='relative flex h-[10px] w-[10px] items-center justify-center'>
🌜
</span>
</div>
<div
data-cy='switch-theme-light'
className='toggle-track-x absolute'
className={classNames(
'absolute right-[10px] top-0 bottom-0 mt-auto mb-auto h-[10px] w-[10px] leading-[0]',
{
'opacity-100': theme === 'light',
'opacity-0': theme === 'dark'
}
)}
>
<span className='toggle_Light relative flex items-center justify-center'>
<span className='relative flex h-[10px] w-[10px] items-center justify-center'>
🌞
</span>
</div>
</div>
<div className='toggle-thumb absolute' />
<div
className={classNames(
'absolute top-[1px] box-border h-[22px] w-[22px] rounded-[50%] bg-[#fafafa] text-white transition-all duration-[250ms] ease-in-out',
{
'left-[27px]': theme === 'dark',
'left-0': theme === 'light'
}
)}
style={{ border: '1px solid #4d4d4d' }}
/>
<input
data-cy='switch-theme-input'
type='checkbox'
aria-label='Dark mode toggle'
className='toggle-screenreader-only absolute overflow-hidden'
className='absolute m-[-1px] h-[1px] w-[1px] overflow-hidden border-0 p-0'
defaultChecked
/>
</div>
</div>
<style jsx>
{`
.toggle-theme-button {
touch-action: pan-x;
border: 0;
padding: 0;
user-select: none;
}
.toggle-track {
width: 50px;
height: 24px;
padding: 0;
border-radius: 30px;
background-color: #4d4d4d;
transition: all 0.2s ease;
color: #fff;
}
.toggle-track-check {
width: 14px;
height: 10px;
top: 0;
bottom: 0;
margin-top: auto;
margin-bottom: auto;
line-height: 0;
left: 8px;
opacity: ${theme === 'dark' ? 1 : 0};
transition: opacity 0.25s ease;
}
.toggle-track-x {
width: 10px;
height: 10px;
top: 0;
bottom: 0;
margin-top: auto;
margin-bottom: auto;
line-height: 0;
right: 10px;
opacity: ${theme === 'dark' ? 0 : 1};
}
.toggle_Dark,
.toggle_Light {
height: 10px;
width: 10px;
}
.toggle-thumb {
left: ${theme === 'dark' ? '27px' : '0px'};
width: 22px;
height: 22px;
border: 1px solid #4d4d4d;
border-radius: 50%;
background-color: #fafafa;
box-sizing: border-box;
transition: all 0.25s ease;
top: 1px;
color: #fff;
}
.toggle-screenreader-only {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
padding: 0;
width: 1px;
}
`}
</style>
</>
)
}

View File

@ -14,7 +14,6 @@ export const Header: React.FC<HeaderProps> = (props) => {
return (
<header className='sticky top-0 z-50 flex w-full justify-between border-b-2 border-gray-600 bg-white px-6 py-2 dark:border-gray-400 dark:bg-black'>
<Link href='/'>
<a>
<div className='flex items-center justify-center'>
<Image
quality={100}
@ -27,17 +26,15 @@ export const Header: React.FC<HeaderProps> = (props) => {
Divlo
</strong>
</div>
</a>
</Link>
<div className='flex justify-between'>
<div className='flex flex-col items-center justify-center px-6'>
<Link href='/blog'>
<a
<Link
href='/blog'
data-cy='header-blog-link'
className='text-yellow hover:underline dark:text-yellow-dark'
>
Blog
</a>
</Link>
</div>
{showLanguage && <Language />}

View File

@ -1,5 +1,5 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { IconDefinition } from '@fortawesome/free-solid-svg-icons'
import type { IconDefinition } from '@fortawesome/free-solid-svg-icons'
interface InterestItemProps {
title: string

View File

@ -7,10 +7,7 @@ export const InterestsList: React.FC = () => {
return (
<div className='my-4 flex justify-center'>
<ul className='m-0 flex w-96 list-none justify-around p-0'>
<InterestItem
title='Developer Full Stack Junior'
fontAwesomeIcon={faCode}
/>
<InterestItem title='Developer Full Stack' fontAwesomeIcon={faCode} />
<InterestItem
title='Passionate about High-Tech'
fontAwesomeIcon={faMicrochip}

View File

@ -1,6 +1,7 @@
import useTranslation from 'next-translate/useTranslation'
import { InterestParagraph, InterestParagraphProps } from './InterestParagraph'
import type { InterestParagraphProps } from './InterestParagraph'
import { InterestParagraph } from './InterestParagraph'
import { InterestsList } from './InterestsList'
export const Interests: React.FC = () => {

View File

@ -24,7 +24,7 @@ export const PortfolioItem: React.FC<PortfolioItemProps> = (props) => {
<div className='flex justify-center'>
<Image
quality={100}
className='transition-opacity duration-500 group-hover:opacity-20 dark:group-hover:opacity-5'
className='h-auto w-auto transition-opacity duration-500 group-hover:opacity-20 dark:group-hover:opacity-5'
width={300}
height={300}
src={image}

View File

@ -1,6 +1,7 @@
import useTranslation from 'next-translate/useTranslation'
import { PortfolioItem, PortfolioItemProps } from './PortfolioItem'
import type { PortfolioItemProps } from './PortfolioItem'
import { PortfolioItem } from './PortfolioItem'
export const Portfolio: React.FC = () => {
const { t } = useTranslation('home')

View File

@ -5,7 +5,7 @@ import DivloLogo from 'public/images/divlo_logo.png'
export const ProfileLogo: React.FC = () => {
return (
<div className='max-h-[370px] max-w-[370px] px-2 py-6'>
<Image quality={100} src={DivloLogo} alt='Divlo' />
<Image quality={100} src={DivloLogo} alt='Divlo' priority />
</div>
)
}

View File

@ -2,10 +2,11 @@ import { useTheme } from 'next-themes'
import Image from 'next/image'
import { useMemo } from 'react'
import type { SkillName } from './skills'
import { skills } from './skills'
export interface SkillComponentProps {
skill: string
skill: SkillName
}
export const SkillComponent: React.FC<SkillComponentProps> = (props) => {
@ -14,10 +15,13 @@ export const SkillComponent: React.FC<SkillComponentProps> = (props) => {
const { theme } = useTheme()
const image = useMemo(() => {
if (typeof skillProperties.image !== 'string') {
return skillProperties.image[theme ?? 'light']
}
if (typeof skillProperties.image === 'string') {
return skillProperties.image
}
if (theme === 'light') {
return skillProperties.image.light
}
return skillProperties.image.dark
}, [skillProperties, theme])
return (
@ -28,7 +32,14 @@ export const SkillComponent: React.FC<SkillComponentProps> = (props) => {
rel='noopener noreferrer'
>
<div className='text-center'>
<Image quality={100} width={60} height={60} alt={skill} src={image} />
<Image
className='inline h-auto w-auto'
quality={100}
width={60}
height={60}
alt={skill}
src={image}
/>
<p className='mt-1'>{skill}</p>
</div>
</a>

View File

@ -13,6 +13,7 @@ export const Skills: React.FC = () => {
<SkillComponent skill='TypeScript' />
<SkillComponent skill='Python' />
<SkillComponent skill='C/C++' />
<SkillComponent skill='PHP' />
</SkillsSection>
<SkillsSection title='Front-end'>
@ -23,11 +24,11 @@ export const Skills: React.FC = () => {
</SkillsSection>
<SkillsSection title='Back-end'>
<SkillComponent skill='Laravel' />
<SkillComponent skill='Node.js' />
<SkillComponent skill='Fastify' />
<SkillComponent skill='Prisma' />
<SkillComponent skill='PostgreSQL' />
<SkillComponent skill='MySQL' />
</SkillsSection>
<SkillsSection title={t('home:skills.software-tools')}>

View File

@ -3,11 +3,7 @@ export interface Skill {
image: string | { [key: string]: string }
}
export interface Skills {
[key: string]: Skill
}
export const skills: Skills = {
export const skills = {
JavaScript: {
link: 'https://developer.mozilla.org/docs/Web/JavaScript',
image: '/images/skills/JavaScript.png'
@ -24,6 +20,14 @@ export const skills: Skills = {
link: 'https://isocpp.org/',
image: '/images/skills/C-Cpp.png'
},
PHP: {
link: 'https://www.php.net/',
image: '/images/skills/PHP.png'
},
Laravel: {
link: 'https://laravel.com/',
image: '/images/skills/Laravel.png'
},
Dart: {
link: 'https://dart.dev/',
image: '/images/skills/Dart.png'
@ -107,3 +111,5 @@ export const skills: Skills = {
image: '/images/skills/Docker.png'
}
} as const
export type SkillName = keyof typeof skills

View File

@ -3,14 +3,11 @@ import { defineConfig } from 'cypress'
export default defineConfig({
fixturesFolder: false,
video: false,
downloadsFolder: undefined,
screenshotOnRunFailure: false,
e2e: {
baseUrl: 'http://localhost:3000',
baseUrl: 'http://127.0.0.1:3000',
supportFile: false
},
component: {
devServer: {
framework: 'next',

View File

@ -14,5 +14,3 @@ describe('<Footer />', () => {
)
})
})
export {}

View File

@ -1,5 +1,7 @@
describe('Common > Header', () => {
beforeEach(() => cy.visit('/'))
beforeEach(() => {
return cy.visit('/')
})
it('should redirect to /blog on click of the blog link', () => {
cy.get('[data-cy=header-blog-link]')

View File

@ -1,5 +1,7 @@
describe('Page /404', () => {
beforeEach(() => cy.visit('/404', { failOnStatusCode: false }))
beforeEach(() => {
return cy.visit('/404', { failOnStatusCode: false })
})
it('should display the statusCode of 404', () => {
cy.get('[data-cy=status-code]').contains('404')

View File

@ -1,5 +1,7 @@
describe('Page /500', () => {
beforeEach(() => cy.visit('/500', { failOnStatusCode: false }))
beforeEach(() => {
return cy.visit('/500', { failOnStatusCode: false })
})
it('should display the statusCode of 500', () => {
cy.get('[data-cy=status-code]').contains('500')

View File

@ -1,13 +1,10 @@
describe('Page /', () => {
beforeEach(() => cy.visit('/'))
beforeEach(() => {
return cy.visit('/')
})
it('should reveals the sections while scrolling except the about section', () => {
const sectionsReveals = [
'#interests',
'#skills',
'#portfolio',
'#open-source'
]
const sectionsReveals = ['#interests', '#skills', '#portfolio']
cy.get('#about').should('be.visible')
for (const section of sectionsReveals) {
cy.get(section)

View File

@ -1,6 +1,7 @@
import { mount } from 'cypress/react'
import './commands'
import '../../styles/global.css'
declare global {
namespace Cypress {

View File

@ -5,7 +5,7 @@ services:
build:
context: './'
ports:
- '${PORT}:${PORT}'
- '${PORT-3000}:${PORT-3000}'
environment:
PORT: ${PORT}
PORT: ${PORT-3000}
env_file: './.env'

View File

@ -11,12 +11,44 @@
"modern-normalize": "1.1.0"
},
"devDependencies": {
"@types/node": "18.6.2",
"@types/node": "18.11.9",
"date-and-time": "2.4.1",
"vite": "3.0.3",
"vite": "3.2.3",
"vite-plugin-html": "3.2.0"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.13.tgz",
"integrity": "sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.13.tgz",
"integrity": "sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag==",
"cpu": [
"loong64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
@ -66,13 +98,13 @@
"dev": true
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.14",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz",
"integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==",
"version": "0.3.17",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
"integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
"dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
"@jridgewell/resolve-uri": "3.1.0",
"@jridgewell/sourcemap-codec": "1.4.14"
}
},
"node_modules/@nodelib/fs.scandir": {
@ -124,15 +156,15 @@
}
},
"node_modules/@types/node": {
"version": "18.6.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.2.tgz",
"integrity": "sha512-KcfkBq9H4PI6Vpu5B/KoPeuVDAbmi+2mDBqGPGUgoL7yXQtcWGu2vJWmmRkneWK3Rh0nIAX192Aa87AqKHYChQ==",
"version": "18.11.9",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz",
"integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==",
"dev": true
},
"node_modules/acorn": {
"version": "8.8.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
"integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
"version": "8.8.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
"integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
@ -394,9 +426,9 @@
}
},
"node_modules/dotenv": {
"version": "16.0.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz",
"integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==",
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
"integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==",
"dev": true,
"engines": {
"node": ">=12"
@ -436,9 +468,9 @@
}
},
"node_modules/esbuild": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.51.tgz",
"integrity": "sha512-+CvnDitD7Q5sT7F+FM65sWkF8wJRf+j9fPcprxYV4j+ohmzVj2W7caUqH2s5kCaCJAfcAICjSlKhDCcvDpU7nw==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.13.tgz",
"integrity": "sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==",
"dev": true,
"hasInstallScript": true,
"bin": {
@ -448,32 +480,34 @@
"node": ">=12"
},
"optionalDependencies": {
"esbuild-android-64": "0.14.51",
"esbuild-android-arm64": "0.14.51",
"esbuild-darwin-64": "0.14.51",
"esbuild-darwin-arm64": "0.14.51",
"esbuild-freebsd-64": "0.14.51",
"esbuild-freebsd-arm64": "0.14.51",
"esbuild-linux-32": "0.14.51",
"esbuild-linux-64": "0.14.51",
"esbuild-linux-arm": "0.14.51",
"esbuild-linux-arm64": "0.14.51",
"esbuild-linux-mips64le": "0.14.51",
"esbuild-linux-ppc64le": "0.14.51",
"esbuild-linux-riscv64": "0.14.51",
"esbuild-linux-s390x": "0.14.51",
"esbuild-netbsd-64": "0.14.51",
"esbuild-openbsd-64": "0.14.51",
"esbuild-sunos-64": "0.14.51",
"esbuild-windows-32": "0.14.51",
"esbuild-windows-64": "0.14.51",
"esbuild-windows-arm64": "0.14.51"
"@esbuild/android-arm": "0.15.13",
"@esbuild/linux-loong64": "0.15.13",
"esbuild-android-64": "0.15.13",
"esbuild-android-arm64": "0.15.13",
"esbuild-darwin-64": "0.15.13",
"esbuild-darwin-arm64": "0.15.13",
"esbuild-freebsd-64": "0.15.13",
"esbuild-freebsd-arm64": "0.15.13",
"esbuild-linux-32": "0.15.13",
"esbuild-linux-64": "0.15.13",
"esbuild-linux-arm": "0.15.13",
"esbuild-linux-arm64": "0.15.13",
"esbuild-linux-mips64le": "0.15.13",
"esbuild-linux-ppc64le": "0.15.13",
"esbuild-linux-riscv64": "0.15.13",
"esbuild-linux-s390x": "0.15.13",
"esbuild-netbsd-64": "0.15.13",
"esbuild-openbsd-64": "0.15.13",
"esbuild-sunos-64": "0.15.13",
"esbuild-windows-32": "0.15.13",
"esbuild-windows-64": "0.15.13",
"esbuild-windows-arm64": "0.15.13"
}
},
"node_modules/esbuild-android-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.51.tgz",
"integrity": "sha512-6FOuKTHnC86dtrKDmdSj2CkcKF8PnqkaIXqvgydqfJmqBazCPdw+relrMlhGjkvVdiiGV70rpdnyFmA65ekBCQ==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.13.tgz",
"integrity": "sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g==",
"cpu": [
"x64"
],
@ -487,9 +521,9 @@
}
},
"node_modules/esbuild-android-arm64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.51.tgz",
"integrity": "sha512-vBtp//5VVkZWmYYvHsqBRCMMi1MzKuMIn5XDScmnykMTu9+TD9v0NMEDqQxvtFToeYmojdo5UCV2vzMQWJcJ4A==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.13.tgz",
"integrity": "sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w==",
"cpu": [
"arm64"
],
@ -503,9 +537,9 @@
}
},
"node_modules/esbuild-darwin-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.51.tgz",
"integrity": "sha512-YFmXPIOvuagDcwCejMRtCDjgPfnDu+bNeh5FU2Ryi68ADDVlWEpbtpAbrtf/lvFTWPexbgyKgzppNgsmLPr8PA==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.13.tgz",
"integrity": "sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg==",
"cpu": [
"x64"
],
@ -519,9 +553,9 @@
}
},
"node_modules/esbuild-darwin-arm64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.51.tgz",
"integrity": "sha512-juYD0QnSKwAMfzwKdIF6YbueXzS6N7y4GXPDeDkApz/1RzlT42mvX9jgNmyOlWKN7YzQAYbcUEJmZJYQGdf2ow==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.13.tgz",
"integrity": "sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A==",
"cpu": [
"arm64"
],
@ -535,9 +569,9 @@
}
},
"node_modules/esbuild-freebsd-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.51.tgz",
"integrity": "sha512-cLEI/aXjb6vo5O2Y8rvVSQ7smgLldwYY5xMxqh/dQGfWO+R1NJOFsiax3IS4Ng300SVp7Gz3czxT6d6qf2cw0g==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.13.tgz",
"integrity": "sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA==",
"cpu": [
"x64"
],
@ -551,9 +585,9 @@
}
},
"node_modules/esbuild-freebsd-arm64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.51.tgz",
"integrity": "sha512-TcWVw/rCL2F+jUgRkgLa3qltd5gzKjIMGhkVybkjk6PJadYInPtgtUBp1/hG+mxyigaT7ib+od1Xb84b+L+1Mg==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.13.tgz",
"integrity": "sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q==",
"cpu": [
"arm64"
],
@ -567,9 +601,9 @@
}
},
"node_modules/esbuild-linux-32": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.51.tgz",
"integrity": "sha512-RFqpyC5ChyWrjx8Xj2K0EC1aN0A37H6OJfmUXIASEqJoHcntuV3j2Efr9RNmUhMfNE6yEj2VpYuDteZLGDMr0w==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.13.tgz",
"integrity": "sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w==",
"cpu": [
"ia32"
],
@ -583,9 +617,9 @@
}
},
"node_modules/esbuild-linux-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.51.tgz",
"integrity": "sha512-dxjhrqo5i7Rq6DXwz5v+MEHVs9VNFItJmHBe1CxROWNf4miOGoQhqSG8StStbDkQ1Mtobg6ng+4fwByOhoQoeA==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.13.tgz",
"integrity": "sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A==",
"cpu": [
"x64"
],
@ -599,9 +633,9 @@
}
},
"node_modules/esbuild-linux-arm": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.51.tgz",
"integrity": "sha512-LsJynDxYF6Neg7ZC7748yweCDD+N8ByCv22/7IAZglIEniEkqdF4HCaa49JNDLw1UQGlYuhOB8ZT/MmcSWzcWg==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.13.tgz",
"integrity": "sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ==",
"cpu": [
"arm"
],
@ -615,9 +649,9 @@
}
},
"node_modules/esbuild-linux-arm64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.51.tgz",
"integrity": "sha512-D9rFxGutoqQX3xJPxqd6o+kvYKeIbM0ifW2y0bgKk5HPgQQOo2k9/2Vpto3ybGYaFPCE5qTGtqQta9PoP6ZEzw==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.13.tgz",
"integrity": "sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ==",
"cpu": [
"arm64"
],
@ -631,9 +665,9 @@
}
},
"node_modules/esbuild-linux-mips64le": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.51.tgz",
"integrity": "sha512-vS54wQjy4IinLSlb5EIlLoln8buh1yDgliP4CuEHumrPk4PvvP4kTRIG4SzMXm6t19N0rIfT4bNdAxzJLg2k6A==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.13.tgz",
"integrity": "sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A==",
"cpu": [
"mips64el"
],
@ -647,9 +681,9 @@
}
},
"node_modules/esbuild-linux-ppc64le": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.51.tgz",
"integrity": "sha512-xcdd62Y3VfGoyphNP/aIV9LP+RzFw5M5Z7ja+zdpQHHvokJM7d0rlDRMN+iSSwvUymQkqZO+G/xjb4/75du8BQ==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.13.tgz",
"integrity": "sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA==",
"cpu": [
"ppc64"
],
@ -663,9 +697,9 @@
}
},
"node_modules/esbuild-linux-riscv64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.51.tgz",
"integrity": "sha512-syXHGak9wkAnFz0gMmRBoy44JV0rp4kVCEA36P5MCeZcxFq8+fllBC2t6sKI23w3qd8Vwo9pTADCgjTSf3L3rA==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.13.tgz",
"integrity": "sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow==",
"cpu": [
"riscv64"
],
@ -679,9 +713,9 @@
}
},
"node_modules/esbuild-linux-s390x": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.51.tgz",
"integrity": "sha512-kFAJY3dv+Wq8o28K/C7xkZk/X34rgTwhknSsElIqoEo8armCOjMJ6NsMxm48KaWY2h2RUYGtQmr+RGuUPKBhyw==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.13.tgz",
"integrity": "sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag==",
"cpu": [
"s390x"
],
@ -695,9 +729,9 @@
}
},
"node_modules/esbuild-netbsd-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.51.tgz",
"integrity": "sha512-ZZBI7qrR1FevdPBVHz/1GSk1x5GDL/iy42Zy8+neEm/HA7ma+hH/bwPEjeHXKWUDvM36CZpSL/fn1/y9/Hb+1A==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.13.tgz",
"integrity": "sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ==",
"cpu": [
"x64"
],
@ -711,9 +745,9 @@
}
},
"node_modules/esbuild-openbsd-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.51.tgz",
"integrity": "sha512-7R1/p39M+LSVQVgDVlcY1KKm6kFKjERSX1lipMG51NPcspJD1tmiZSmmBXoY5jhHIu6JL1QkFDTx94gMYK6vfA==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.13.tgz",
"integrity": "sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w==",
"cpu": [
"x64"
],
@ -727,9 +761,9 @@
}
},
"node_modules/esbuild-sunos-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.51.tgz",
"integrity": "sha512-HoHaCswHxLEYN8eBTtyO0bFEWvA3Kdb++hSQ/lLG7TyKF69TeSG0RNoBRAs45x/oCeWaTDntEZlYwAfQlhEtJA==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.13.tgz",
"integrity": "sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw==",
"cpu": [
"x64"
],
@ -743,9 +777,9 @@
}
},
"node_modules/esbuild-windows-32": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.51.tgz",
"integrity": "sha512-4rtwSAM35A07CBt1/X8RWieDj3ZUHQqUOaEo5ZBs69rt5WAFjP4aqCIobdqOy4FdhYw1yF8Z0xFBTyc9lgPtEg==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.13.tgz",
"integrity": "sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA==",
"cpu": [
"ia32"
],
@ -759,9 +793,9 @@
}
},
"node_modules/esbuild-windows-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.51.tgz",
"integrity": "sha512-HoN/5HGRXJpWODprGCgKbdMvrC3A2gqvzewu2eECRw2sYxOUoh2TV1tS+G7bHNapPGI79woQJGV6pFH7GH7qnA==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.13.tgz",
"integrity": "sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ==",
"cpu": [
"x64"
],
@ -775,9 +809,9 @@
}
},
"node_modules/esbuild-windows-arm64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.51.tgz",
"integrity": "sha512-JQDqPjuOH7o+BsKMSddMfmVJXrnYZxXDHsoLHc0xgmAZkOOCflRmC43q31pk79F9xuyWY45jDBPolb5ZgGOf9g==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.13.tgz",
"integrity": "sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg==",
"cpu": [
"arm64"
],
@ -797,9 +831,9 @@
"dev": true
},
"node_modules/fast-glob": {
"version": "3.2.11",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
"integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
"version": "3.2.12",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
"integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
"dev": true,
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
@ -967,9 +1001,9 @@
}
},
"node_modules/is-core-module": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
"integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
"integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
"dev": true,
"dependencies": {
"has": "^1.0.3"
@ -1115,9 +1149,9 @@
}
},
"node_modules/node-html-parser": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-5.3.3.tgz",
"integrity": "sha512-ncg1033CaX9UexbyA7e1N0aAoAYRDiV8jkTvzEnfd1GDvzFdrsXLzR4p4ik8mwLgnaKP/jyUFWDy9q3jvRT2Jw==",
"version": "5.4.2",
"resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-5.4.2.tgz",
"integrity": "sha512-RaBPP3+51hPne/OolXxcz89iYvQvKOydaqoePpOgXcrOKZhjVIzmpKZz+Hd/RBO2/zN2q6CNJhQzucVz+u3Jyw==",
"dev": true,
"dependencies": {
"css-select": "^4.2.1",
@ -1187,9 +1221,9 @@
}
},
"node_modules/postcss": {
"version": "8.4.14",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
"integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==",
"version": "8.4.18",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz",
"integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==",
"dev": true,
"funding": [
{
@ -1267,9 +1301,9 @@
}
},
"node_modules/rollup": {
"version": "2.77.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.2.tgz",
"integrity": "sha512-m/4YzYgLcpMQbxX3NmAqDvwLATZzxt8bIegO78FZLl+lAgKJBd1DRAOeEiZcKOIOPjxE6ewHWHNgGEalFXuz1g==",
"version": "2.79.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
"integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
"dev": true,
"bin": {
"rollup": "dist/bin/rollup"
@ -1357,9 +1391,9 @@
}
},
"node_modules/terser": {
"version": "5.14.2",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz",
"integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==",
"version": "5.15.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz",
"integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==",
"dev": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.2",
@ -1393,9 +1427,9 @@
}
},
"node_modules/tslib": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
"integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
"dev": true
},
"node_modules/universalify": {
@ -1408,15 +1442,15 @@
}
},
"node_modules/vite": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.0.3.tgz",
"integrity": "sha512-sDIpIcl3mv1NUaSzZwiXGEy1ZoWwwC2vkxUHY6yiDacR6zf//ZFuBJrozO62gedpE43pmxnLATNR5IYUdAEkMQ==",
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.2.3.tgz",
"integrity": "sha512-h8jl1TZ76eGs3o2dIBSsvXDLb1m/Ec1iej8ZMdz+PsaFUsftZeWe2CZOI3qogEsMNaywc17gu0q6cQDzh/weCQ==",
"dev": true,
"dependencies": {
"esbuild": "^0.14.47",
"postcss": "^8.4.14",
"esbuild": "^0.15.9",
"postcss": "^8.4.18",
"resolve": "^1.22.1",
"rollup": "^2.75.6"
"rollup": "^2.79.1"
},
"bin": {
"vite": "bin/vite.js"
@ -1428,12 +1462,17 @@
"fsevents": "~2.3.2"
},
"peerDependencies": {
"@types/node": ">= 14",
"less": "*",
"sass": "*",
"stylus": "*",
"sugarss": "*",
"terser": "^5.4.0"
},
"peerDependenciesMeta": {
"@types/node": {
"optional": true
},
"less": {
"optional": true
},
@ -1443,6 +1482,9 @@
"stylus": {
"optional": true
},
"sugarss": {
"optional": true
},
"terser": {
"optional": true
}
@ -1473,6 +1515,20 @@
}
},
"dependencies": {
"@esbuild/android-arm": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.13.tgz",
"integrity": "sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw==",
"dev": true,
"optional": true
},
"@esbuild/linux-loong64": {
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.13.tgz",
"integrity": "sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag==",
"dev": true,
"optional": true
},
"@jridgewell/gen-mapping": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
@ -1513,13 +1569,13 @@
"dev": true
},
"@jridgewell/trace-mapping": {
"version": "0.3.14",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz",
"integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==",
"version": "0.3.17",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
"integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
"dev": true,
"requires": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
"@jridgewell/resolve-uri": "3.1.0",
"@jridgewell/sourcemap-codec": "1.4.14"
}
},
"@nodelib/fs.scandir": {
@ -1559,15 +1615,15 @@
}
},
"@types/node": {
"version": "18.6.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.2.tgz",
"integrity": "sha512-KcfkBq9H4PI6Vpu5B/KoPeuVDAbmi+2mDBqGPGUgoL7yXQtcWGu2vJWmmRkneWK3Rh0nIAX192Aa87AqKHYChQ==",
"version": "18.11.9",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz",
"integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==",
"dev": true
},
"acorn": {
"version": "8.8.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
"integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
"version": "8.8.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
"integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
"dev": true
},
"ansi-styles": {
@ -1769,9 +1825,9 @@
}
},
"dotenv": {
"version": "16.0.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz",
"integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==",
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
"integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==",
"dev": true
},
"dotenv-expand": {
@ -1796,170 +1852,172 @@
"dev": true
},
"esbuild": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.51.tgz",
"integrity": "sha512-+CvnDitD7Q5sT7F+FM65sWkF8wJRf+j9fPcprxYV4j+ohmzVj2W7caUqH2s5kCaCJAfcAICjSlKhDCcvDpU7nw==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.13.tgz",
"integrity": "sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==",
"dev": true,
"requires": {
"esbuild-android-64": "0.14.51",
"esbuild-android-arm64": "0.14.51",
"esbuild-darwin-64": "0.14.51",
"esbuild-darwin-arm64": "0.14.51",
"esbuild-freebsd-64": "0.14.51",
"esbuild-freebsd-arm64": "0.14.51",
"esbuild-linux-32": "0.14.51",
"esbuild-linux-64": "0.14.51",
"esbuild-linux-arm": "0.14.51",
"esbuild-linux-arm64": "0.14.51",
"esbuild-linux-mips64le": "0.14.51",
"esbuild-linux-ppc64le": "0.14.51",
"esbuild-linux-riscv64": "0.14.51",
"esbuild-linux-s390x": "0.14.51",
"esbuild-netbsd-64": "0.14.51",
"esbuild-openbsd-64": "0.14.51",
"esbuild-sunos-64": "0.14.51",
"esbuild-windows-32": "0.14.51",
"esbuild-windows-64": "0.14.51",
"esbuild-windows-arm64": "0.14.51"
"@esbuild/android-arm": "0.15.13",
"@esbuild/linux-loong64": "0.15.13",
"esbuild-android-64": "0.15.13",
"esbuild-android-arm64": "0.15.13",
"esbuild-darwin-64": "0.15.13",
"esbuild-darwin-arm64": "0.15.13",
"esbuild-freebsd-64": "0.15.13",
"esbuild-freebsd-arm64": "0.15.13",
"esbuild-linux-32": "0.15.13",
"esbuild-linux-64": "0.15.13",
"esbuild-linux-arm": "0.15.13",
"esbuild-linux-arm64": "0.15.13",
"esbuild-linux-mips64le": "0.15.13",
"esbuild-linux-ppc64le": "0.15.13",
"esbuild-linux-riscv64": "0.15.13",
"esbuild-linux-s390x": "0.15.13",
"esbuild-netbsd-64": "0.15.13",
"esbuild-openbsd-64": "0.15.13",
"esbuild-sunos-64": "0.15.13",
"esbuild-windows-32": "0.15.13",
"esbuild-windows-64": "0.15.13",
"esbuild-windows-arm64": "0.15.13"
}
},
"esbuild-android-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.51.tgz",
"integrity": "sha512-6FOuKTHnC86dtrKDmdSj2CkcKF8PnqkaIXqvgydqfJmqBazCPdw+relrMlhGjkvVdiiGV70rpdnyFmA65ekBCQ==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.13.tgz",
"integrity": "sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g==",
"dev": true,
"optional": true
},
"esbuild-android-arm64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.51.tgz",
"integrity": "sha512-vBtp//5VVkZWmYYvHsqBRCMMi1MzKuMIn5XDScmnykMTu9+TD9v0NMEDqQxvtFToeYmojdo5UCV2vzMQWJcJ4A==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.15.13.tgz",
"integrity": "sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w==",
"dev": true,
"optional": true
},
"esbuild-darwin-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.51.tgz",
"integrity": "sha512-YFmXPIOvuagDcwCejMRtCDjgPfnDu+bNeh5FU2Ryi68ADDVlWEpbtpAbrtf/lvFTWPexbgyKgzppNgsmLPr8PA==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.15.13.tgz",
"integrity": "sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg==",
"dev": true,
"optional": true
},
"esbuild-darwin-arm64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.51.tgz",
"integrity": "sha512-juYD0QnSKwAMfzwKdIF6YbueXzS6N7y4GXPDeDkApz/1RzlT42mvX9jgNmyOlWKN7YzQAYbcUEJmZJYQGdf2ow==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.13.tgz",
"integrity": "sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A==",
"dev": true,
"optional": true
},
"esbuild-freebsd-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.51.tgz",
"integrity": "sha512-cLEI/aXjb6vo5O2Y8rvVSQ7smgLldwYY5xMxqh/dQGfWO+R1NJOFsiax3IS4Ng300SVp7Gz3czxT6d6qf2cw0g==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.13.tgz",
"integrity": "sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA==",
"dev": true,
"optional": true
},
"esbuild-freebsd-arm64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.51.tgz",
"integrity": "sha512-TcWVw/rCL2F+jUgRkgLa3qltd5gzKjIMGhkVybkjk6PJadYInPtgtUBp1/hG+mxyigaT7ib+od1Xb84b+L+1Mg==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.13.tgz",
"integrity": "sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q==",
"dev": true,
"optional": true
},
"esbuild-linux-32": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.51.tgz",
"integrity": "sha512-RFqpyC5ChyWrjx8Xj2K0EC1aN0A37H6OJfmUXIASEqJoHcntuV3j2Efr9RNmUhMfNE6yEj2VpYuDteZLGDMr0w==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.15.13.tgz",
"integrity": "sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w==",
"dev": true,
"optional": true
},
"esbuild-linux-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.51.tgz",
"integrity": "sha512-dxjhrqo5i7Rq6DXwz5v+MEHVs9VNFItJmHBe1CxROWNf4miOGoQhqSG8StStbDkQ1Mtobg6ng+4fwByOhoQoeA==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.15.13.tgz",
"integrity": "sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A==",
"dev": true,
"optional": true
},
"esbuild-linux-arm": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.51.tgz",
"integrity": "sha512-LsJynDxYF6Neg7ZC7748yweCDD+N8ByCv22/7IAZglIEniEkqdF4HCaa49JNDLw1UQGlYuhOB8ZT/MmcSWzcWg==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.15.13.tgz",
"integrity": "sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ==",
"dev": true,
"optional": true
},
"esbuild-linux-arm64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.51.tgz",
"integrity": "sha512-D9rFxGutoqQX3xJPxqd6o+kvYKeIbM0ifW2y0bgKk5HPgQQOo2k9/2Vpto3ybGYaFPCE5qTGtqQta9PoP6ZEzw==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.13.tgz",
"integrity": "sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ==",
"dev": true,
"optional": true
},
"esbuild-linux-mips64le": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.51.tgz",
"integrity": "sha512-vS54wQjy4IinLSlb5EIlLoln8buh1yDgliP4CuEHumrPk4PvvP4kTRIG4SzMXm6t19N0rIfT4bNdAxzJLg2k6A==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.13.tgz",
"integrity": "sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A==",
"dev": true,
"optional": true
},
"esbuild-linux-ppc64le": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.51.tgz",
"integrity": "sha512-xcdd62Y3VfGoyphNP/aIV9LP+RzFw5M5Z7ja+zdpQHHvokJM7d0rlDRMN+iSSwvUymQkqZO+G/xjb4/75du8BQ==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.13.tgz",
"integrity": "sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA==",
"dev": true,
"optional": true
},
"esbuild-linux-riscv64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.51.tgz",
"integrity": "sha512-syXHGak9wkAnFz0gMmRBoy44JV0rp4kVCEA36P5MCeZcxFq8+fllBC2t6sKI23w3qd8Vwo9pTADCgjTSf3L3rA==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.13.tgz",
"integrity": "sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow==",
"dev": true,
"optional": true
},
"esbuild-linux-s390x": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.51.tgz",
"integrity": "sha512-kFAJY3dv+Wq8o28K/C7xkZk/X34rgTwhknSsElIqoEo8armCOjMJ6NsMxm48KaWY2h2RUYGtQmr+RGuUPKBhyw==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.13.tgz",
"integrity": "sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag==",
"dev": true,
"optional": true
},
"esbuild-netbsd-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.51.tgz",
"integrity": "sha512-ZZBI7qrR1FevdPBVHz/1GSk1x5GDL/iy42Zy8+neEm/HA7ma+hH/bwPEjeHXKWUDvM36CZpSL/fn1/y9/Hb+1A==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.13.tgz",
"integrity": "sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ==",
"dev": true,
"optional": true
},
"esbuild-openbsd-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.51.tgz",
"integrity": "sha512-7R1/p39M+LSVQVgDVlcY1KKm6kFKjERSX1lipMG51NPcspJD1tmiZSmmBXoY5jhHIu6JL1QkFDTx94gMYK6vfA==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.13.tgz",
"integrity": "sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w==",
"dev": true,
"optional": true
},
"esbuild-sunos-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.51.tgz",
"integrity": "sha512-HoHaCswHxLEYN8eBTtyO0bFEWvA3Kdb++hSQ/lLG7TyKF69TeSG0RNoBRAs45x/oCeWaTDntEZlYwAfQlhEtJA==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.15.13.tgz",
"integrity": "sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw==",
"dev": true,
"optional": true
},
"esbuild-windows-32": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.51.tgz",
"integrity": "sha512-4rtwSAM35A07CBt1/X8RWieDj3ZUHQqUOaEo5ZBs69rt5WAFjP4aqCIobdqOy4FdhYw1yF8Z0xFBTyc9lgPtEg==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.15.13.tgz",
"integrity": "sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA==",
"dev": true,
"optional": true
},
"esbuild-windows-64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.51.tgz",
"integrity": "sha512-HoN/5HGRXJpWODprGCgKbdMvrC3A2gqvzewu2eECRw2sYxOUoh2TV1tS+G7bHNapPGI79woQJGV6pFH7GH7qnA==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.15.13.tgz",
"integrity": "sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ==",
"dev": true,
"optional": true
},
"esbuild-windows-arm64": {
"version": "0.14.51",
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.51.tgz",
"integrity": "sha512-JQDqPjuOH7o+BsKMSddMfmVJXrnYZxXDHsoLHc0xgmAZkOOCflRmC43q31pk79F9xuyWY45jDBPolb5ZgGOf9g==",
"version": "0.15.13",
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.13.tgz",
"integrity": "sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg==",
"dev": true,
"optional": true
},
@ -1970,9 +2028,9 @@
"dev": true
},
"fast-glob": {
"version": "3.2.11",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
"integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
"version": "3.2.12",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
"integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
"dev": true,
"requires": {
"@nodelib/fs.stat": "^2.0.2",
@ -2105,9 +2163,9 @@
}
},
"is-core-module": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
"integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
"integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
"dev": true,
"requires": {
"has": "^1.0.3"
@ -2212,9 +2270,9 @@
}
},
"node-html-parser": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-5.3.3.tgz",
"integrity": "sha512-ncg1033CaX9UexbyA7e1N0aAoAYRDiV8jkTvzEnfd1GDvzFdrsXLzR4p4ik8mwLgnaKP/jyUFWDy9q3jvRT2Jw==",
"version": "5.4.2",
"resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-5.4.2.tgz",
"integrity": "sha512-RaBPP3+51hPne/OolXxcz89iYvQvKOydaqoePpOgXcrOKZhjVIzmpKZz+Hd/RBO2/zN2q6CNJhQzucVz+u3Jyw==",
"dev": true,
"requires": {
"css-select": "^4.2.1",
@ -2275,9 +2333,9 @@
"dev": true
},
"postcss": {
"version": "8.4.14",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
"integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==",
"version": "8.4.18",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz",
"integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==",
"dev": true,
"requires": {
"nanoid": "^3.3.4",
@ -2315,9 +2373,9 @@
"dev": true
},
"rollup": {
"version": "2.77.2",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.2.tgz",
"integrity": "sha512-m/4YzYgLcpMQbxX3NmAqDvwLATZzxt8bIegO78FZLl+lAgKJBd1DRAOeEiZcKOIOPjxE6ewHWHNgGEalFXuz1g==",
"version": "2.79.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
"integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
"dev": true,
"requires": {
"fsevents": "~2.3.2"
@ -2370,9 +2428,9 @@
"dev": true
},
"terser": {
"version": "5.14.2",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz",
"integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==",
"version": "5.15.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz",
"integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==",
"dev": true,
"requires": {
"@jridgewell/source-map": "^0.3.2",
@ -2399,9 +2457,9 @@
}
},
"tslib": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
"integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
"dev": true
},
"universalify": {
@ -2411,16 +2469,16 @@
"dev": true
},
"vite": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.0.3.tgz",
"integrity": "sha512-sDIpIcl3mv1NUaSzZwiXGEy1ZoWwwC2vkxUHY6yiDacR6zf//ZFuBJrozO62gedpE43pmxnLATNR5IYUdAEkMQ==",
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.2.3.tgz",
"integrity": "sha512-h8jl1TZ76eGs3o2dIBSsvXDLb1m/Ec1iej8ZMdz+PsaFUsftZeWe2CZOI3qogEsMNaywc17gu0q6cQDzh/weCQ==",
"dev": true,
"requires": {
"esbuild": "^0.14.47",
"esbuild": "^0.15.9",
"fsevents": "~2.3.2",
"postcss": "^8.4.14",
"postcss": "^8.4.18",
"resolve": "^1.22.1",
"rollup": "^2.75.6"
"rollup": "^2.79.1"
}
},
"vite-plugin-html": {

View File

@ -12,9 +12,9 @@
"modern-normalize": "1.1.0"
},
"devDependencies": {
"@types/node": "18.6.2",
"@types/node": "18.11.9",
"date-and-time": "2.4.1",
"vite": "3.0.3",
"vite": "3.2.3",
"vite-plugin-html": "3.2.0"
}
}

View File

@ -11,7 +11,8 @@ const publicResumeOutputURL = new URL(
)
await build({
root: fileURLToPath(jsonResumeThemeCustom)
root: fileURLToPath(jsonResumeThemeCustom),
base: '/curriculum-vitae/'
})
await fs.promises.cp(jsonResumeThemeCustomDist, publicResumeOutputURL, {

View File

@ -1,7 +1,7 @@
{
"about": {
"i-am": "I am",
"description": "Developer Full Stack Junior • Passionate about High-Tech",
"description": "Developer Full Stack • Passionate about High-Tech",
"full-name": "Full name",
"birth-date": "Birth date",
"years-old": "years old",
@ -12,7 +12,7 @@
"title": "Interests",
"paragraphs": [
{
"title": "Developer Full Stack Junior",
"title": "Developer Full Stack",
"description": "Computer programming is my main hobby, I love it! <br/> Mostly web development for the moment but I'm programming in others programming language too."
},
{

View File

@ -2,5 +2,5 @@
"return-to-home-page": "Revenir à la page d'accueil ?",
"error": "Erreur",
"server-error": "Erreur Interne du Serveur !",
"not-found": "Cette page n'existe pas!"
"not-found": "Cette page n'existe pas !"
}

View File

@ -1,7 +1,7 @@
{
"about": {
"i-am": "Je suis",
"description": "Développeur Full Stack Junior • Passionné de High-Tech",
"description": "Développeur Full Stack • Passionné de High-Tech",
"full-name": "Prénom NOM",
"birth-date": "Date de naissance",
"years-old": "ans",
@ -12,7 +12,7 @@
"title": "Intérêts",
"paragraphs": [
{
"title": "Développeur Full Stack Junior",
"title": "Développeur Full Stack",
"description": "La programmation informatique est mon loisir principal, j'adore! <br/> Principalement du développement Web pour le moment, mais je programme aussi dans d'autres langages de programmation."
},
{

5
next-env.d.ts vendored
View File

@ -1,5 +0,0 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.

View File

@ -1,41 +1,13 @@
const nextPWA = require('next-pwa')
const nextTranslate = require('next-translate')
const { createSecureHeaders } = require('next-secure-headers')
/** @type {import("next").NextConfig} */
module.exports = nextTranslate(
nextPWA({
reactStrictMode: true,
pwa: {
const nextPWA = require('next-pwa')({
disable: process.env.NODE_ENV !== 'production',
dest: 'public'
},
headers() {
return [
{
source: '/:path*',
headers: createSecureHeaders({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: [
"'self'",
'data:',
"'unsafe-eval'",
"'unsafe-inline'"
],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ['*', 'data:', 'blob:'],
mediaSrc: "'none'",
connectSrc: '*',
objectSrc: "'none'",
fontSrc: "'self'",
baseURI: "'none'"
}
}
})
}
]
}
})
)
})
const nextTranslate = require('next-translate')
/** @type {import("next").NextConfig} */
const nextConfig = {
reactStrictMode: true,
output: 'standalone'
}
module.exports = nextTranslate(nextPWA(nextConfig))

6518
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "divlo",
"version": "2.3.2",
"version": "2.5.1",
"private": true,
"repository": {
"type": "git",
@ -22,77 +22,77 @@
"lint:prettier": "prettier \".\" --check --ignore-path \".gitignore\"",
"lint:staged": "lint-staged",
"test:unit": "cypress run --component",
"test:html-w3c-validator": "start-server-and-test \"start\" \"http://localhost:3000\" \"html-w3c-validator\"",
"test:html-w3c-validator": "start-server-and-test \"start\" \"http://127.0.0.1:3000\" \"html-w3c-validator\"",
"test:lighthouse": "lhci autorun",
"test:e2e": "start-server-and-test \"start\" \"http://localhost:3000\" \"cypress run\"",
"test:dev": "start-server-and-test \"dev\" \"http://localhost:3000\" \"cypress open\"",
"test:e2e": "start-server-and-test \"start\" \"http://127.0.0.1:3000\" \"cypress run\"",
"test:dev": "start-server-and-test \"dev\" \"http://127.0.0.1:3000\" \"cypress open\"",
"resume:build": "node ./jsonresume-theme-custom/scripts/build.js",
"release": "semantic-release",
"deploy": "vercel",
"postinstall": "husky install"
},
"dependencies": {
"@fontsource/montserrat": "4.5.11",
"@fortawesome/fontawesome-svg-core": "6.1.2",
"@fortawesome/free-brands-svg-icons": "6.1.2",
"@fortawesome/free-solid-svg-icons": "6.1.2",
"@fontsource/montserrat": "4.5.13",
"@fortawesome/fontawesome-svg-core": "6.2.0",
"@fortawesome/free-brands-svg-icons": "6.2.0",
"@fortawesome/free-solid-svg-icons": "6.2.0",
"@fortawesome/react-fontawesome": "0.2.0",
"@giscus/react": "2.2.2",
"clsx": "1.2.1",
"date-and-time": "2.4.1",
"gray-matter": "4.0.3",
"html-react-parser": "3.0.1",
"next": "12.2.2",
"next-mdx-remote": "4.1.0",
"next-pwa": "5.5.4",
"next-themes": "0.2.0",
"next-translate": "1.5.0",
"html-react-parser": "3.0.4",
"next": "13.0.2",
"next-mdx-remote": "4.2.0",
"next-pwa": "5.6.0",
"next-themes": "0.2.1",
"next-translate": "1.6.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"read-pkg": "7.1.0",
"rehype-raw": "6.1.1",
"rehype-slug": "5.0.1",
"rehype-slug": "5.1.0",
"remark-gfm": "3.0.1",
"sharp": "0.30.7",
"shiki": "0.10.1",
"sharp": "0.31.2",
"shiki": "0.11.1",
"unified": "10.1.2",
"unist-util-visit": "4.1.0",
"unist-util-visit": "4.1.1",
"universal-cookie": "4.0.4"
},
"devDependencies": {
"@commitlint/cli": "17.0.3",
"@commitlint/config-conventional": "17.0.3",
"@commitlint/cli": "17.2.0",
"@commitlint/config-conventional": "17.2.0",
"@lhci/cli": "0.9.0",
"@saithodev/semantic-release-backmerge": "2.1.2",
"@semantic-release/git": "10.0.1",
"@tailwindcss/typography": "0.5.4",
"@types/node": "18.6.2",
"@types/react": "18.0.15",
"@tailwindcss/typography": "0.5.8",
"@types/node": "18.11.9",
"@types/react": "18.0.25",
"@types/unist": "2.0.6",
"@typescript-eslint/eslint-plugin": "5.31.0",
"autoprefixer": "10.4.7",
"cypress": "10.3.1",
"@typescript-eslint/eslint-plugin": "5.42.1",
"autoprefixer": "10.4.13",
"cypress": "10.11.0",
"editorconfig-checker": "4.0.2",
"eslint": "8.20.0",
"eslint-config-conventions": "3.0.0",
"eslint-config-next": "12.2.2",
"eslint": "8.27.0",
"eslint-config-conventions": "5.0.0",
"eslint-config-next": "13.0.2",
"eslint-config-prettier": "8.5.0",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-prettier": "4.2.1",
"eslint-plugin-promise": "6.0.0",
"eslint-plugin-unicorn": "43.0.2",
"html-w3c-validator": "1.2.0",
"husky": "8.0.1",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-unicorn": "44.0.2",
"html-w3c-validator": "1.2.1",
"husky": "8.0.2",
"jsonresume-theme-custom": "file:./jsonresume-theme-custom",
"lint-staged": "13.0.3",
"markdownlint-cli2": "0.5.0",
"next-secure-headers": "2.2.0",
"postcss": "8.4.14",
"markdownlint-cli2": "0.5.1",
"postcss": "8.4.18",
"prettier": "2.7.1",
"prettier-plugin-tailwindcss": "0.1.13",
"semantic-release": "19.0.3",
"semantic-release": "19.0.5",
"start-server-and-test": "1.14.0",
"tailwindcss": "3.1.6",
"typescript": "4.7.4",
"vercel": "27.3.0"
"tailwindcss": "3.2.2",
"typescript": "4.8.4",
"vercel": "28.4.15"
}
}

View File

@ -1,10 +1,9 @@
import { GetStaticProps, NextPage } from 'next'
import type { GetStaticProps, NextPage } from 'next'
import useTranslation from 'next-translate/useTranslation'
import { ErrorPage } from 'components/ErrorPage'
import { Head } from 'components/Head'
import { Header } from 'components/Header'
import { Footer, FooterProps } from 'components/Footer'
import type { FooterProps } from 'components/Footer'
interface Error404Props extends FooterProps {}
@ -15,12 +14,11 @@ const Error404: NextPage<Error404Props> = (props) => {
return (
<>
<Head title='404 | Divlo' />
<Header showLanguage />
<main className='flex flex-col md:mx-auto md:max-w-4xl lg:max-w-7xl'>
<ErrorPage statusCode={404} message={t('errors:not-found')} />
</main>
<Footer version={version} />
<ErrorPage
statusCode={404}
message={t('errors:not-found')}
version={version}
/>
</>
)
}

View File

@ -1,10 +1,9 @@
import { GetStaticProps, NextPage } from 'next'
import type { GetStaticProps, NextPage } from 'next'
import useTranslation from 'next-translate/useTranslation'
import { ErrorPage } from 'components/ErrorPage'
import { Head } from 'components/Head'
import { Header } from 'components/Header'
import { Footer, FooterProps } from 'components/Footer'
import type { FooterProps } from 'components/Footer'
interface Error500Props extends FooterProps {}
@ -15,12 +14,11 @@ const Error500: NextPage<Error500Props> = (props) => {
return (
<>
<Head title='500 | Divlo' />
<Header showLanguage />
<main className='flex flex-col md:mx-auto md:max-w-4xl lg:max-w-7xl'>
<ErrorPage statusCode={500} message={t('errors:server-error')} />
</main>
<Footer version={version} />
<ErrorPage
statusCode={500}
message={t('errors:server-error')}
version={version}
/>
</>
)
}

View File

@ -1,5 +1,5 @@
import { useEffect } from 'react'
import { AppProps } from 'next/app'
import type { AppType } from 'next/app'
import { ThemeProvider } from 'next-themes'
import useTranslation from 'next-translate/useTranslation'
import UniversalCookie from 'universal-cookie'
@ -13,7 +13,7 @@ const universalCookie = new UniversalCookie()
/** how long in seconds, until the cookie expires (10 years) */
const COOKIE_MAX_AGE = 10 * 365.25 * 24 * 60 * 60
const Application = ({ Component, pageProps }: AppProps): JSX.Element => {
const Application: AppType = ({ Component, pageProps }) => {
const { lang } = useTranslation()
useEffect(() => {

View File

@ -1,10 +1,13 @@
import { GetStaticProps, GetStaticPaths, NextPage } from 'next'
import type { GetStaticProps, GetStaticPaths, NextPage } from 'next'
import { MDXRemote } from 'next-mdx-remote'
import date from 'date-and-time'
import Giscus from '@giscus/react'
import { useTheme } from 'next-themes'
import { Head } from 'components/Head'
import { Header } from 'components/Header'
import { Footer, FooterProps } from 'components/Footer'
import type { FooterProps } from 'components/Footer'
import { Footer } from 'components/Footer'
import type { Post } from 'utils/blog'
interface BlogPostPageProps extends FooterProps {
@ -14,6 +17,8 @@ interface BlogPostPageProps extends FooterProps {
const BlogPostPage: NextPage<BlogPostPageProps> = (props) => {
const { version, post } = props
const { theme = 'dark' } = useTheme()
return (
<>
<Head
@ -33,7 +38,13 @@ const BlogPostPage: NextPage<BlogPostPageProps> = (props) => {
<MDXRemote
{...post.source}
components={{
a: (props: React.ComponentPropsWithoutRef<'a'>) => {
img: (properties) => {
const { src, alt, ...props } = properties
let source = src
source = src?.replace('../public/', '/')
return <img src={source} alt={alt} {...props} />
},
a: (props) => {
if (props.href?.startsWith('#') ?? false) {
return <a {...props} />
}
@ -43,6 +54,20 @@ const BlogPostPage: NextPage<BlogPostPageProps> = (props) => {
}
}}
/>
<Giscus
id='comments'
repo='Divlo/Divlo'
repoId='MDEwOlJlcG9zaXRvcnkzNTg5NDg1NDQ='
category='General'
categoryId='DIC_kwDOFWUewM4CQ_WK'
mapping='pathname'
reactionsEnabled='1'
emitMetadata='0'
inputPosition='top'
theme={theme}
lang='en'
loading='lazy'
/>
</div>
</main>
<Footer version={version} />

View File

@ -1,10 +1,11 @@
import { GetStaticProps, NextPage } from 'next'
import type { GetStaticProps, NextPage } from 'next'
import Link from 'next/link'
import date from 'date-and-time'
import { Head } from 'components/Head'
import { Header } from 'components/Header'
import { Footer, FooterProps } from 'components/Footer'
import type { FooterProps } from 'components/Footer'
import { Footer } from 'components/Footer'
import { ShadowContainer } from 'components/design/ShadowContainer'
import type { PostMetadata } from 'utils/blog'
@ -38,8 +39,12 @@ const BlogPage: NextPage<BlogPageProps> = (props) => {
'DD/MM/YYYY'
)
return (
<Link href={`/blog/${post.slug}`} key={index} locale='en'>
<a data-cy={post.slug}>
<Link
href={`/blog/${post.slug}`}
key={index}
locale='en'
data-cy={post.slug}
>
<ShadowContainer className='cursor-pointer p-6 transition duration-200 ease-in-out hover:-translate-y-2'>
<h2
data-cy='blog-post-title'
@ -54,7 +59,6 @@ const BlogPage: NextPage<BlogPageProps> = (props) => {
{post.frontmatter.description}
</p>
</ShadowContainer>
</a>
</Link>
)
})}

View File

@ -1,4 +1,4 @@
import { GetStaticProps, NextPage } from 'next'
import type { GetStaticProps, NextPage } from 'next'
import useTranslation from 'next-translate/useTranslation'
import { RevealFade } from 'components/design/RevealFade'
@ -11,7 +11,8 @@ import { SocialMediaList } from 'components/Profile/SocialMediaList'
import { Skills } from 'components/Skills'
import { OpenSource } from 'components/OpenSource'
import { Header } from 'components/Header'
import { Footer, FooterProps } from 'components/Footer'
import type { FooterProps } from 'components/Footer'
import { Footer } from 'components/Footer'
interface HomeProps extends FooterProps {}

View File

@ -7,13 +7,13 @@ publishedOn: '2022-02-23T08:00:18.758Z'
Hello! 👋
Have you already heard of "**Clean Code**" or "**Design Patterns**" ?
Have you already heard of "**Clean Code**" or "**Design Patterns**"?
Even if you know what it is about, this blog post will probably still be useful to you, I will share some tips and tricks to make your code more readable and maintainable in the long term.
**Note:** Sources used to write this blog post are available at the [end of this post](#sources).
## Definition : Clean Code
## Definition: Clean Code
A clean code is a code that is **easy** to **read** and easy to **understand**.
@ -23,7 +23,7 @@ We could ask ourselves, what is **easy** to **read** and easy to **understand**
It depends of many factors, and is somewhat relative to each one of us. The **perfect** Clean code **doesn't exist**, but we can try to be **as perfect as possible**.
## Why is it so important ?
## Why is it so important?
Code like that works great, but it is not enough, even if the code will be read by the computer and understood by the machine, we should not forget that the code is **written by human** and will be also **read by human** not only a machine.

239
posts/git-ultimate-guide.md Normal file
View File

@ -0,0 +1,239 @@
---
title: '🗓️ Git version control: Ultimate Guide'
description: 'What is `git`, what are the most used commands, best practices, and tips and tricks. The Ultimate guide to master `git` in your daily workflow.'
isPublished: true
publishedOn: '2022-10-27T14:33:07.465Z'
---
Hello! 👋
Welcome to the Ultimate Guide to master `git` in your daily workflow, we will see what are the most used commands, what are the best practices, and tips and tricks.
This guide is a summary of the most important things to know when working with `git`, and in general, will link to the official documentation of `git` or other resources for more details, it is on purpose to not go in depth in each topic, it allows to summarize `git` and vocabulary about it (you can use it as a `git` cheatsheet).
**Note:** Sources used to write this blog post are available at the [end of this post](#sources).
## Introduction
**Git** is a free and open-source distributed **version control system** for keeping track of changes across a set of files.
Git was originally authored by [Linus Torvalds](https://en.wikipedia.org/wiki/Linus_Torvalds) in 2005 for the development of the [Linux kernel](https://kernel.org/).
Git allows:
- to be able to work with several people on the same codebase.
- track changes to know who did what and when.
- revert changes.
Git is **decentralized**, which means that every developer has a full copy of the repository and the complete history of the project.
## Get started with `git` and `.gitconfig` config file
The first thing you should do when you install Git is to set your user name and email address.
```sh
git config --global user.name "Username"
git config --global user.email "email@example.com"
```
These configurations are stored in the `.gitconfig` file in your home directory (e.g: `~/.gitconfig`) with this format:
```sh
[user]
name = Username
email = email@example.com
```
You can find more information and useful `git` configurations in the [official documentation](https://git-scm.com/docs/git-config).
## How `git` works?
Each `git` project is called a **repository** (or **repo** for short) and it contains all the files and folders for a project, as well as each file's revision history (**commits**) stored in the `.git` folder.
The history of a repository is represented by a graph.
Each node is called commit and contains:
- an instantaneous view (snapshot) of the state of the repository at a specific moment
- metadata: message, author, creation date, etc.
Commits are **snapshots** (not diffs on each file) of the project at specific moments in time.
There are several areas where the files in your project will live in Git:
- **Working directory**: the files that you see in your computer's file system.
- **Staging area**: the files that will go into your next commit (files added with `git add <filename>` command).
- **Local repository**: the `.git` directory, which contains all of your project's commits, branches, etc. (files added with `git commit -m "message"` command).
- **Remote repository**: the `.git` directory in a remote server (files added with `git push` command).
## Commands cheatsheet
You can find the official documentation of `git` commands at [git-scm.com/docs](https://git-scm.com/docs).
```sh
# Initialize a new git repository
git init
# Clone a repository
git clone <url>
# Add all the files to staging area
git add .
# Add specific file to staging area
git add <file>
# Commit changes
git commit -m "chore: initial commit"
# Add remote repository
git remote add <remote> <url>
# The main <remote> is often called `origin`
# Add forked repository
git remote add <remote> <url>
# The forked <remote> is often called `upstream`
# List all the remotes
git remote
# Sync forked repository
git fetch <remote>
git merge <remote>/<branch>
# Push changes to remote repository
git push <remote>
# Pull changes from remote repository
git pull <remote>
# Show the status of the working tree
git status
# Show the commit history
git log
# Create a new branch
git checkout -b <branch>
# Switch to a branch (or tag or commit)
git checkout <branch>
# Merge a branch into the current branch
git merge <branch>
# Delete a branch
git branch --delete <branch>
git push <remote> --delete <branch>
# Fetch branches from remote repository and prune
git fetch --prune
# Revert a commit
git revert <commit>
# Change several past commits (interactive rebase)
# HEAD points to the current consulted commit.
git rebase --interactive HEAD~<number-of-commits>
# Reset the current branch, delete all commits since <branch> (without removing the changes)
git reset --soft <branch>
# Apply the changes introduced by some existing commits
git cherry-pick <commit>
```
## `.gitignore` file
The `.gitignore` file is a text file that tells `git` which files (or patterns) it should ignore.
The `.gitignore` file is usually placed in the root directory of the repository.
We usually ignore files that are generated by the build process or files that contain sensitive information.
Example of `.gitignore` file:
```sh
.env
build
*.exe
```
## `.gitkeep` file
The `.gitkeep` file is a file that is used to keep an empty directory in a Git repository.
This is useful when you want to keep an empty directory in your repository but you don't want to commit any file inside it.
## Git remote repositories (GitHub/GitLab)
Once you are ready to share your code over the internet, you will need to create a remote repository on a service like [GitHub](https://github.com) or [GitLab](https://gitlab.com).
There are many other services, you can also self-host your own Git server.
### SSH vs HTTPS authentication
Once you have created a remote repository, you will need to authenticate to push and pull changes.
There are two main ways to authenticate:
- **SSH**: you will need to generate an SSH key pair and add the public key to your remote repository.
- **HTTPS**: you will need to provide your username and password each time you push or pull changes.
SSH authentication is the recommended way to authenticate to a remote repository.
You can find more information about SSH authentication in the [official documentation](https://git-scm.com/book/en/v2/Git-on-the-Server-Generating-Your-SSH-Public-Key).
### Sign `git` commits with `gpg`
As we have seen in the [Get started with `git` and `.gitconfig` config file](#get-started-with-git-and-gitconfig-config-file) section, we can configure `git` with a name and email address with a value of our choice.
That means that **anyone can create a commit with any name and email address and claim to be whoever they want** when they create a commit.
To avoid this, you can sign your commits with a <abbr title="GNU Privacy Guard">[GPG](https://gnupg.org/)</abbr> key.
You can find more information about signing commits in the [official documentation](https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work).
### Continous Integration/Continuous Delivery (CI/CD)
Once you have your code in a remote repository, everyone (with access) can potentially start contributing to the project. This is great, but it also means that you need to have a way to ensure that your code is working as expected for each change in the project.
You could do it manually, depending on the size and the complexity of the project, but it could be a tedious task.
Instead, you can use a **Continuous Integration** (CI) service to automate the process of testing your code, running linting, unit tests, e2e tests, etc.
There are many CI services, but the most popular ones are [GitHub Actions](https://github.com/features/actions), [GitLab CI](https://docs.gitlab.com/ee/ci/), [CircleCI](https://circleci.com/), [Travis CI](https://travis-ci.org/), and many others...
Then, once your code is ready, tested and working as expected, you can use a **Continuous Delivery** (CD) service to automate the process of **deploying your code**.
CI/CD services are usually integrated with remote repositories, so you can configure them to run automatically when you push changes to the remote repository.
## Best practices and `git` workflows
Commit messages are very important, they are a way to easily know what has changed in the project.
There are many conventions for commit messages, but the most popular one is the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification.
Then, we can use the commit messages to automatically determine a [semantic version](https://semver.org/) for the next release of the project.
When multiple developers are working on the same project, it is important to organize the work in a way that everyone can work on different features without conflicts (changes in the same files).
There are many ways to organize the work, but the most popular ones are:
- [GitFlow](https://nvie.com/posts/a-successful-git-branching-model/)
- [GitHub Flow](https://guides.github.com/introduction/flow/)
- [Trunk-based development](https://trunkbaseddevelopment.com/)
They are called **Git workflows**, or **Git branching strategies**.
## Conclusion
`git` is the tool that every programmer should know to do collaborative work (not only, `git` is also very powerful even when working alone) and keep track of changes across a set of files.
## Sources
- [Git official website and documentation](https://git-scm.com/)
- [Git Explained in 100 Seconds](https://www.youtube.com/watch?v=hwP7WQkmECE)
- [Understand Git in 7 minutes](https://www.jesuisundev.com/en/understand-git-in-7-minutes/)
- [How (and why) to sign Git commits | With Blue Ink](https://withblue.ink/2020/05/17/how-and-why-to-sign-git-commits.html?utm_source=tiktok&utm_campaign=codetok-sign)
- [What Are the Best Git Branching Strategies](https://www.flagship.io/git-branching-strategies/)

View File

@ -21,7 +21,7 @@ The source code is available on [GitHub](https://github.com/Thream).
The idea is that a user can create an account to authenticate with an email address, and a password, or directly use an account from another platform (currently supported: Google, GitHub, Discord). Once the user is authenticated, he/she can create and join "guilds", in other words communities, in order to discuss with other people in several channels to group discussions talking about the same subject.
![The Thream app on a community page](/images/posts/thream-v1-0-0/thream-ui.png)
![The Thream app on a community page](../public/images/posts/thream-v1-0-0/thream-ui.png)
[**Thream**](https://www.thream.divlo.fr/) is a website that works on any recent browser, accessible on [thream.divlo.fr](https://www.thream.divlo.fr/).
@ -33,7 +33,7 @@ The main goal is to put into **practice knowledge in web development** and compu
The development of the project begins under the name of **SocialProject**, on August 20, 2020, with colors close to the image of Divlo.
![SocialProject](/images/posts/thream-v1-0-0/social-project.jpg)
![SocialProject](../public/images/posts/thream-v1-0-0/social-project.jpg)
When I started the project, I had little knowledge of database design, real-time management or the architecture of such a large <abbr title="Information Technology">IT</abbr> project, so this will be accompanied by many technical problems, to which we will need to find appropriate solutions.
@ -53,12 +53,9 @@ Since the project is mainly developed during free time (mainly on weekends), the
- The **client** part, called **frontend**, what **the user sees on the screen**, such as forms, buttons and all the **graphic elements** with which the user can interact from a browser.
<p className='flex flex-col items-center justify-center'>
<img
alt='HTTP Communication Schema'
src='/images/posts/thream-v1-0-0/http-communication.png'
/>
</p>
<span className='flex flex-col items-center justify-center'>
![HTTP Communication Schema](../public/images/posts/thream-v1-0-0/http-communication.png)
</span>
This design allows the separation between the client and the server, as long as they both structure their communication according to the <abbr title="Representational state transfer">REST</abbr> architectural guidelines, using the <abbr title="Hypertext Transfer Protocol">HTTP</abbr> protocol, they will be able to communicate with each other, which makes it possible to work independently on the backend and on the frontend using different technologies and skills, really useful in teamwork.

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

View File

@ -5,12 +5,12 @@
},
"basics": {
"name": "Théo LUDWIG",
"label": "Développeur Full Stack Junior • Passionné de High-Tech",
"label": "Développeur Full Stack • Passionné de High-Tech",
"image": "https://divlo.fr/images/logo_orange.png",
"email": "contact@divlo.fr",
"location": {},
"url": "https://divlo.fr",
"summary": "Je me forme en autodidacte dans l'informatique en suivant des formations en ligne et je suis aussi un étudiant à l'université suivant la formation \"BUT Informatique\" (premre année). <br/> Je mets en pratique tout ce que j'apprends et réalise de nombreux projets."
"summary": "Je me forme en autodidacte dans l'informatique en suivant des formations en ligne et je suis aussi un étudiant à l'université suivant la formation \"BUT Informatique\" (deuxme année). <br/> Je mets en pratique tout ce que j'apprends et réalise de nombreux projets."
},
"education": [
{
@ -82,7 +82,7 @@
],
"interests": [
{
"name": "Développeur Full Stack Junior"
"name": "Développeur Full Stack"
},
{
"name": "Passionné de High-Tech"
@ -93,7 +93,7 @@
],
"skills": [
{
"keywords": ["JavaScript", "TypeScript", "Python", "C/C++"],
"keywords": ["JavaScript", "TypeScript", "Python", "C/C++", "PHP"],
"name": "Langages de programmation"
},
{
@ -101,7 +101,7 @@
"name": "Front-end"
},
{
"keywords": ["Node.js", "Fastify", "PostgreSQL", "MySQL"],
"keywords": ["Laravel", "Node.js", "Fastify", "PostgreSQL"],
"name": "Back-end"
},
{

View File

@ -1,4 +1,5 @@
module.exports = {
/** @type {import('tailwindcss').Config} */
const tailwindConfig = {
content: [
'./pages/**/*.{js,ts,jsx,tsx}',
'./components/**/*.{js,ts,jsx,tsx}'
@ -47,3 +48,5 @@ module.exports = {
},
plugins: [require('@tailwindcss/typography')]
}
module.exports = tailwindConfig

View File

@ -37,8 +37,8 @@ export const getPosts = async (): Promise<PostMetadata[]> => {
const posts = await fs.promises.readdir(POSTS_PATH)
const postsWithTime = await Promise.all(
posts.map(async (postFilename) => {
const [slug] = postFilename.split('.')
const blogPostPath = path.join(POSTS_PATH, `${slug}.mdx`)
const [slug, extension] = postFilename.split('.')
const blogPostPath = path.join(POSTS_PATH, `${slug}.${extension}`)
const blogPostContent = await fs.promises.readFile(blogPostPath, {
encoding: 'utf8'
})
@ -53,8 +53,12 @@ export const getPosts = async (): Promise<PostMetadata[]> => {
})
)
const postsWithTimeSorted = postsWithTime
.filter((post) => post.frontmatter.isPublished)
.sort((a, b) => b.time - a.time)
.filter((post) => {
return post.frontmatter.isPublished
})
.sort((a, b) => {
return b.time - a.time
})
return postsWithTimeSorted
}
@ -62,7 +66,9 @@ export const getPostBySlug = async (
slug?: string | string[]
): Promise<Post | undefined> => {
const posts = await getPosts()
const post = posts.find((post) => post.slug === slug)
const post = posts.find((post) => {
return post.slug === slug
})
if (post == null) {
return undefined
}

View File

@ -1,7 +1,7 @@
import { Plugin, Transformer } from 'unified'
import { Literal } from 'unist'
import type { Plugin, Transformer } from 'unified'
import type { Literal } from 'unist'
import { visit } from 'unist-util-visit'
import { Highlighter } from 'shiki'
import type { Highlighter } from 'shiki'
export interface RemarkSyntaxHighlightingPluginOptions {
highlighter: Highlighter