diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..fcfe9d86d --- /dev/null +++ b/.prettierignore @@ -0,0 +1,7 @@ +app-dist +dist +.idea +.github +public +node_modules +pnpm-lock.yaml diff --git a/astro.config.mjs b/astro.config.mjs index fc3860775..172dd6c47 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -26,7 +26,7 @@ export default defineConfig({ 'https://github.com/kamranahmedse', 'https://thenewstack.io', 'https://cs.fyi', - 'https://roadmap.sh' + 'https://roadmap.sh', ]; if (whiteListedStarts.some((start) => href.startsWith(start))) { diff --git a/bin/best-practice-dirs.cjs b/bin/best-practice-dirs.cjs index bbc95bbf7..d5f0bf8a7 100644 --- a/bin/best-practice-dirs.cjs +++ b/bin/best-practice-dirs.cjs @@ -3,7 +3,10 @@ const path = require('path'); const CONTENT_DIR = path.join(__dirname, '../content'); // Directory containing the best-practices -const BEST_PRACTICE_CONTENT_DIR = path.join(__dirname, '../src/data/best-practices'); +const BEST_PRACTICE_CONTENT_DIR = path.join( + __dirname, + '../src/data/best-practices' +); const bestPracticeId = process.argv[2]; const allowedBestPracticeId = fs.readdirSync(BEST_PRACTICE_CONTENT_DIR); @@ -28,7 +31,10 @@ if (!bestPracticeDirName) { process.exit(1); } -const bestPracticeDirPath = path.join(BEST_PRACTICE_CONTENT_DIR, bestPracticeDirName); +const bestPracticeDirPath = path.join( + BEST_PRACTICE_CONTENT_DIR, + bestPracticeDirName +); const bestPracticeContentDirPath = path.join( BEST_PRACTICE_CONTENT_DIR, bestPracticeDirName, @@ -37,7 +43,9 @@ const bestPracticeContentDirPath = path.join( // If best practice content already exists do not proceed as it would override the files if (fs.existsSync(bestPracticeContentDirPath)) { - console.error(`Best Practice content already exists @ ${bestPracticeContentDirPath}`); + console.error( + `Best Practice content already exists @ ${bestPracticeContentDirPath}` + ); process.exit(1); } @@ -51,7 +59,11 @@ function prepareDirTree(control, dirTree) { const controlName = control?.properties?.controlName || ''; // No directory for a group without control name - if (!controlName || controlName.startsWith('check:') || controlName.startsWith('ext_link:')) { + if ( + !controlName || + controlName.startsWith('check:') || + controlName.startsWith('ext_link:') + ) { return; } @@ -76,7 +88,10 @@ function prepareDirTree(control, dirTree) { return { dirTree }; } -const bestPractice = require(path.join(__dirname, `../public/jsons/best-practices/${bestPracticeId}`)); +const bestPractice = require(path.join( + __dirname, + `../public/jsons/best-practices/${bestPracticeId}` +)); const controls = bestPractice.mockup.controls.control; // Prepare the dir tree that we will be creating @@ -129,11 +144,7 @@ function createDirTree(parentDir, dirTree, filePaths = {}) { // For each of the directory names, create a // directory inside the given directory childrenDirNames.forEach((dirName) => { - createDirTree( - path.join(parentDir, dirName), - dirTree[dirName], - filePaths - ); + createDirTree(path.join(parentDir, dirName), dirTree[dirName], filePaths); }); return filePaths; @@ -141,4 +152,4 @@ function createDirTree(parentDir, dirTree, filePaths = {}) { // Create directories and get back the paths for created directories createDirTree(bestPracticeContentDirPath, dirTree); -console.log('Created best practice content directory structure'); \ No newline at end of file +console.log('Created best practice content directory structure'); diff --git a/bin/readme.md b/bin/readme.md index 73ea128c8..86cb552bb 100644 --- a/bin/readme.md +++ b/bin/readme.md @@ -1,4 +1,5 @@ ## CLI Tools + > A bunch of CLI scripts to make the development easier ## `roadmap-links.cjs` @@ -34,5 +35,3 @@ For the content skeleton to be generated, we should have proper grouping, and th - Assign the name to the groups. - Group names have the format of `[sort]-[slug]` e.g. `100-internet`. Each group name should start with a number starting from 100 which helps with sorting of the directories and the files. Groups at the same level have the sequential sorting information. - Each groups children have a separate group and have the name similar to `[sort]-[parent-slug]:[child-slug]` where sort refers to the sorting of the `child-slug` and not the parent. Also parent-slug does not need to have the sorting information as a part of slug e.g. if parent was `100-internet` the children would be `100-internet:how-does-the-internet-work`, `101-internet:what-is-http`, `102-internet:browsers`. - - diff --git a/bin/roadmap-content.cjs b/bin/roadmap-content.cjs index f756e012e..0b15053a6 100644 --- a/bin/roadmap-content.cjs +++ b/bin/roadmap-content.cjs @@ -95,7 +95,9 @@ async function run() { const roadmapJson = require(path.join(ROADMAP_JSON_DIR, `${roadmapId}.json`)); const groups = roadmapJson?.mockup?.controls?.control?.filter( - (control) => control.typeID === '__group__' && !control.properties?.controlName?.startsWith('ext_link') + (control) => + control.typeID === '__group__' && + !control.properties?.controlName?.startsWith('ext_link') ); if (!OPEN_AI_API_KEY) { @@ -106,8 +108,9 @@ async function run() { for (let group of groups) { const topicId = group?.properties?.controlName; - const topicTitle = group?.children?.controls?.control?.find((control) => control?.typeID === 'Label')?.properties - ?.text; + const topicTitle = group?.children?.controls?.control?.find( + (control) => control?.typeID === 'Label' + )?.properties?.text; const currTopicUrl = topicId.replace(/^\d+-/g, '/').replace(/:/g, '/'); const contentFilePath = topicUrlToPathMapping[currTopicUrl]; diff --git a/bin/roadmap-dirs.cjs b/bin/roadmap-dirs.cjs index 9a990d483..92490bc72 100644 --- a/bin/roadmap-dirs.cjs +++ b/bin/roadmap-dirs.cjs @@ -82,7 +82,10 @@ function prepareDirTree(control, dirTree, dirSortOrders) { return { dirTree, dirSortOrders }; } -const roadmap = require(path.join(__dirname, `../public/jsons/roadmaps/${roadmapId}`)); +const roadmap = require(path.join( + __dirname, + `../public/jsons/roadmaps/${roadmapId}` +)); const controls = roadmap.mockup.controls.control; // Prepare the dir tree that we will be creating and also calculate the sort orders diff --git a/bin/update-sponsors.cjs b/bin/update-sponsors.cjs index 2d687ee50..2919afbc8 100644 --- a/bin/update-sponsors.cjs +++ b/bin/update-sponsors.cjs @@ -27,15 +27,24 @@ function populatePageAds({ const isConfiguredActive = isActive.toLowerCase() === 'yes'; const currentDate = new Date(); - const isDateInRange = currentDate >= new Date(startDate) && currentDate <= new Date(endDate); + const isDateInRange = + currentDate >= new Date(startDate) && currentDate <= new Date(endDate); const shouldShowAd = isConfiguredActive && isDateInRange; - const urlPart = pageUrl.replace('https://roadmap.sh/', '').replace(/\?.+?$/, ''); + const urlPart = pageUrl + .replace('https://roadmap.sh/', '') + .replace(/\?.+?$/, ''); - const parentDir = urlPart.startsWith('best-practices/') ? 'best-practices' : 'roadmaps'; + const parentDir = urlPart.startsWith('best-practices/') + ? 'best-practices' + : 'roadmaps'; const pageId = urlPart.replace(`${parentDir}/`, ''); - const pageFilePath = path.join(__dirname, `../src/data/${parentDir}`, `${pageId}/${pageId}.md`); + const pageFilePath = path.join( + __dirname, + `../src/data/${parentDir}`, + `${pageId}/${pageId}.md` + ); if (!fs.existsSync(pageFilePath)) { console.error(`Page file not found: ${pageFilePath}`); @@ -48,7 +57,9 @@ function populatePageAds({ const frontMatterRegex = /---\n([\s\S]*?)\n---/; const existingFrontmatter = pageFileContent.match(frontMatterRegex)[1]; - const contentWithoutFrontmatter = pageFileContent.replace(frontMatterRegex, ``).trim(); + const contentWithoutFrontmatter = pageFileContent + .replace(frontMatterRegex, ``) + .trim(); let frontmatterObj = yaml.load(existingFrontmatter); delete frontmatterObj.sponsor; @@ -77,7 +88,11 @@ function populatePageAds({ frontmatterObj = Object.fromEntries(frontmatterValues); } - const newFrontmatter = yaml.dump(frontmatterObj, { lineWidth: 10000, forceQuotes: true, quotingType: '"' }); + const newFrontmatter = yaml.dump(frontmatterObj, { + lineWidth: 10000, + forceQuotes: true, + quotingType: '"', + }); const newContent = `---\n${newFrontmatter}---\n\n${contentWithoutFrontmatter}`; fs.writeFileSync(pageFilePath, newContent, 'utf8'); diff --git a/code_of_conduct.md b/code_of_conduct.md index 51b44888f..73f0f7e88 100644 --- a/code_of_conduct.md +++ b/code_of_conduct.md @@ -14,21 +14,21 @@ appearance, race, religion, or sexual identity and orientation. Examples of behavior that contributes to creating a positive environment include: -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members Examples of unacceptable behavior by participants include: -* The use of sexualized language or imagery and unwelcome sexual attention or +- The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a +- Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities diff --git a/package.json b/package.json index 4806cf153..8de868d41 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "start": "astro dev", "build": "astro build", "preview": "astro preview", + "format": "prettier --write .", "astro": "astro", "deploy": "NODE_DEBUG=gh-pages gh-pages -d dist -t", "compress:jsons": "node bin/compress-jsons.cjs", diff --git a/playwright.config.ts b/playwright.config.ts index 6b79ad7c7..4f4d780b0 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -100,7 +100,7 @@ const config: PlaywrightTestConfig = { /* Run your local dev server before starting the tests */ webServer: { command: 'npm run dev', - url: "http://localhost:3000", + url: 'http://localhost:3000', reuseExistingServer: !process.env.CI, }, }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b05efe606..3f5e79807 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,29 +43,43 @@ devDependencies: prettier-plugin-tailwindcss: 0.2.6_kb4gmvngxncp3puqxt3b6slppy packages: - /@ampproject/remapping/2.2.0: - resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==, + } + engines: { node: '>=6.0.0' } dependencies: '@jridgewell/gen-mapping': 0.1.1 '@jridgewell/trace-mapping': 0.3.17 dev: false /@astrojs/compiler/0.31.3: - resolution: {integrity: sha512-WbA05QH5xkdaJ3XtzDuYOjtqsip2InW5rk156sSdaHs5qN2NroUHbzWZthHJwmNAAjQSGXVIj+O6jQj81zzX/Q==} + resolution: + { + integrity: sha512-WbA05QH5xkdaJ3XtzDuYOjtqsip2InW5rk156sSdaHs5qN2NroUHbzWZthHJwmNAAjQSGXVIj+O6jQj81zzX/Q==, + } dev: false /@astrojs/compiler/1.1.0: - resolution: {integrity: sha512-C4kTwirys+HafufMqaxCbML2wqkGaXJM+5AekXh/v1IIOnMIdcEON9GBYsG6qa8aAmLhZ58aUZGPhzcA3Dx7Uw==} + resolution: + { + integrity: sha512-C4kTwirys+HafufMqaxCbML2wqkGaXJM+5AekXh/v1IIOnMIdcEON9GBYsG6qa8aAmLhZ58aUZGPhzcA3Dx7Uw==, + } dev: true /@astrojs/compiler/1.3.0: - resolution: {integrity: sha512-VxSj3gh/UTB/27rkRCT7SvyGjWtuxUO7Jf7QqDduch7j/gr/uA5P/Q5I/4zIIrZjy2yQAKyKLoox2QI2mM/BSA==} + resolution: + { + integrity: sha512-VxSj3gh/UTB/27rkRCT7SvyGjWtuxUO7Jf7QqDduch7j/gr/uA5P/Q5I/4zIIrZjy2yQAKyKLoox2QI2mM/BSA==, + } dev: false /@astrojs/language-server/0.28.3: - resolution: {integrity: sha512-fPovAX/X46eE2w03jNRMpQ7W9m2mAvNt4Ay65lD9wl1Z5vIQYxlg7Enp9qP225muTr4jSVB5QiLumFJmZMAaVA==} + resolution: + { + integrity: sha512-fPovAX/X46eE2w03jNRMpQ7W9m2mAvNt4Ay65lD9wl1Z5vIQYxlg7Enp9qP225muTr4jSVB5QiLumFJmZMAaVA==, + } hasBin: true dependencies: '@vscode/emmet-helper': 2.8.6 @@ -83,7 +97,10 @@ packages: dev: false /@astrojs/markdown-remark/2.1.2_astro@2.1.7: - resolution: {integrity: sha512-rYkmFEv2w7oEk6ZPgxHkhWzwcxSUGc1vJU0cbCu5sHF8iFNnc1cmMsjXWa5DrU5sCEf8VVYE1iFlbbnFzvHQJw==} + resolution: + { + integrity: sha512-rYkmFEv2w7oEk6ZPgxHkhWzwcxSUGc1vJU0cbCu5sHF8iFNnc1cmMsjXWa5DrU5sCEf8VVYE1iFlbbnFzvHQJw==, + } peerDependencies: astro: ^2.1.5 dependencies: @@ -106,21 +123,30 @@ packages: dev: false /@astrojs/prism/2.1.0: - resolution: {integrity: sha512-+II6nfIFGZ7iH0FunhRGcj/J1mCxjcHl85cZRuFePKLoIhFHJT3nC3myQnUw386hUaIn2W20McxxtAVf4leeRQ==} - engines: {node: '>=16.12.0'} + resolution: + { + integrity: sha512-+II6nfIFGZ7iH0FunhRGcj/J1mCxjcHl85cZRuFePKLoIhFHJT3nC3myQnUw386hUaIn2W20McxxtAVf4leeRQ==, + } + engines: { node: '>=16.12.0' } dependencies: prismjs: 1.29.0 dev: false /@astrojs/sitemap/1.2.1: - resolution: {integrity: sha512-nlKP1qc1ENZ61w+ep5RdsObjYWso4QdLGC5WyzssnKkgVDijHT61s/tHFfBWHhxqdjcw4x1V1um/eSQZPDTR3Q==} + resolution: + { + integrity: sha512-nlKP1qc1ENZ61w+ep5RdsObjYWso4QdLGC5WyzssnKkgVDijHT61s/tHFfBWHhxqdjcw4x1V1um/eSQZPDTR3Q==, + } dependencies: sitemap: 7.1.1 zod: 3.20.2 dev: false /@astrojs/tailwind/3.1.1_xwlinsvcxfu6nyuevlo4g7jv7y: - resolution: {integrity: sha512-Wx/ZtVnmtfqHWGVzvUEYZm8rufVKVgDIef0q6fzwUxoT1EpTTwBkTbpnzooogewMLOh2eTscasGe3Ih2HC1wVA==} + resolution: + { + integrity: sha512-Wx/ZtVnmtfqHWGVzvUEYZm8rufVKVgDIef0q6fzwUxoT1EpTTwBkTbpnzooogewMLOh2eTscasGe3Ih2HC1wVA==, + } peerDependencies: astro: ^2.1.3 tailwindcss: ^3.0.24 @@ -136,8 +162,11 @@ packages: dev: false /@astrojs/telemetry/2.1.0: - resolution: {integrity: sha512-P3gXNNOkRJM8zpnasNoi5kXp3LnFt0smlOSUXhkynfJpTJMIDrcMbKpNORN0OYbqpKt9JPdgRN7nsnGWpbH1ww==} - engines: {node: '>=16.12.0'} + resolution: + { + integrity: sha512-P3gXNNOkRJM8zpnasNoi5kXp3LnFt0smlOSUXhkynfJpTJMIDrcMbKpNORN0OYbqpKt9JPdgRN7nsnGWpbH1ww==, + } + engines: { node: '>=16.12.0' } dependencies: ci-info: 3.7.0 debug: 4.3.4 @@ -152,26 +181,38 @@ packages: dev: false /@astrojs/webapi/2.1.0: - resolution: {integrity: sha512-sbF44s/uU33jAdefzKzXZaENPeXR0sR3ptLs+1xp9xf5zIBhedH2AfaFB5qTEv9q5udUVoKxubZGT3G1nWs6rA==} + resolution: + { + integrity: sha512-sbF44s/uU33jAdefzKzXZaENPeXR0sR3ptLs+1xp9xf5zIBhedH2AfaFB5qTEv9q5udUVoKxubZGT3G1nWs6rA==, + } dependencies: undici: 5.20.0 dev: false /@babel/code-frame/7.18.6: - resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==, + } + engines: { node: '>=6.9.0' } dependencies: '@babel/highlight': 7.18.6 dev: false /@babel/compat-data/7.20.10: - resolution: {integrity: sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==, + } + engines: { node: '>=6.9.0' } dev: false /@babel/core/7.20.7: - resolution: {integrity: sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw==, + } + engines: { node: '>=6.9.0' } dependencies: '@ampproject/remapping': 2.2.0 '@babel/code-frame': 7.18.6 @@ -193,8 +234,11 @@ packages: dev: false /@babel/generator/7.20.7: - resolution: {integrity: sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==, + } + engines: { node: '>=6.9.0' } dependencies: '@babel/types': 7.20.7 '@jridgewell/gen-mapping': 0.3.2 @@ -202,15 +246,21 @@ packages: dev: false /@babel/helper-annotate-as-pure/7.18.6: - resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==, + } + engines: { node: '>=6.9.0' } dependencies: '@babel/types': 7.20.7 dev: false /@babel/helper-compilation-targets/7.20.7_@babel+core@7.20.7: - resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0 dependencies: @@ -223,35 +273,50 @@ packages: dev: false /@babel/helper-environment-visitor/7.18.9: - resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==, + } + engines: { node: '>=6.9.0' } dev: false /@babel/helper-function-name/7.19.0: - resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==, + } + engines: { node: '>=6.9.0' } dependencies: '@babel/template': 7.20.7 '@babel/types': 7.20.7 dev: false /@babel/helper-hoist-variables/7.18.6: - resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==, + } + engines: { node: '>=6.9.0' } dependencies: '@babel/types': 7.20.7 dev: false /@babel/helper-module-imports/7.18.6: - resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==, + } + engines: { node: '>=6.9.0' } dependencies: '@babel/types': 7.20.7 dev: false /@babel/helper-module-transforms/7.20.11: - resolution: {integrity: sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==, + } + engines: { node: '>=6.9.0' } dependencies: '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-module-imports': 7.18.6 @@ -266,42 +331,63 @@ packages: dev: false /@babel/helper-plugin-utils/7.20.2: - resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==, + } + engines: { node: '>=6.9.0' } dev: false /@babel/helper-simple-access/7.20.2: - resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==, + } + engines: { node: '>=6.9.0' } dependencies: '@babel/types': 7.20.7 dev: false /@babel/helper-split-export-declaration/7.18.6: - resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==, + } + engines: { node: '>=6.9.0' } dependencies: '@babel/types': 7.20.7 dev: false /@babel/helper-string-parser/7.19.4: - resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==, + } + engines: { node: '>=6.9.0' } dev: false /@babel/helper-validator-identifier/7.19.1: - resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==, + } + engines: { node: '>=6.9.0' } dev: false /@babel/helper-validator-option/7.18.6: - resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==, + } + engines: { node: '>=6.9.0' } dev: false /@babel/helpers/7.20.7: - resolution: {integrity: sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==, + } + engines: { node: '>=6.9.0' } dependencies: '@babel/template': 7.20.7 '@babel/traverse': 7.20.10 @@ -311,8 +397,11 @@ packages: dev: false /@babel/highlight/7.18.6: - resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==, + } + engines: { node: '>=6.9.0' } dependencies: '@babel/helper-validator-identifier': 7.19.1 chalk: 2.4.2 @@ -320,16 +409,22 @@ packages: dev: false /@babel/parser/7.20.7: - resolution: {integrity: sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==, + } + engines: { node: '>=6.0.0' } hasBin: true dependencies: '@babel/types': 7.20.7 dev: false /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.20.7: - resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 dependencies: @@ -338,8 +433,11 @@ packages: dev: false /@babel/plugin-transform-react-jsx/7.20.7_@babel+core@7.20.7: - resolution: {integrity: sha512-Tfq7qqD+tRj3EoDhY00nn2uP2hsRxgYGi5mLQ5TimKav0a9Lrpd4deE+fcLXU8zFYRjlKPHZhpCvfEA6qnBxqQ==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-Tfq7qqD+tRj3EoDhY00nn2uP2hsRxgYGi5mLQ5TimKav0a9Lrpd4deE+fcLXU8zFYRjlKPHZhpCvfEA6qnBxqQ==, + } + engines: { node: '>=6.9.0' } peerDependencies: '@babel/core': ^7.0.0-0 dependencies: @@ -352,8 +450,11 @@ packages: dev: false /@babel/template/7.20.7: - resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==, + } + engines: { node: '>=6.9.0' } dependencies: '@babel/code-frame': 7.18.6 '@babel/parser': 7.20.7 @@ -361,8 +462,11 @@ packages: dev: false /@babel/traverse/7.20.10: - resolution: {integrity: sha512-oSf1juCgymrSez8NI4A2sr4+uB/mFd9MXplYGPEBnfAuWmmyeVcHa6xLPiaRBcXkcb/28bgxmQLTVwFKE1yfsg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-oSf1juCgymrSez8NI4A2sr4+uB/mFd9MXplYGPEBnfAuWmmyeVcHa6xLPiaRBcXkcb/28bgxmQLTVwFKE1yfsg==, + } + engines: { node: '>=6.9.0' } dependencies: '@babel/code-frame': 7.18.6 '@babel/generator': 7.20.7 @@ -379,8 +483,11 @@ packages: dev: false /@babel/types/7.20.7: - resolution: {integrity: sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==, + } + engines: { node: '>=6.9.0' } dependencies: '@babel/helper-string-parser': 7.19.4 '@babel/helper-validator-identifier': 7.19.1 @@ -388,31 +495,46 @@ packages: dev: false /@colors/colors/1.5.0: - resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} - engines: {node: '>=0.1.90'} + resolution: + { + integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==, + } + engines: { node: '>=0.1.90' } requiresBuild: true dev: false optional: true /@emmetio/abbreviation/2.2.3: - resolution: {integrity: sha512-87pltuCPt99aL+y9xS6GPZ+Wmmyhll2WXH73gG/xpGcQ84DRnptBsI2r0BeIQ0EB/SQTOe2ANPqFqj3Rj5FOGA==} + resolution: + { + integrity: sha512-87pltuCPt99aL+y9xS6GPZ+Wmmyhll2WXH73gG/xpGcQ84DRnptBsI2r0BeIQ0EB/SQTOe2ANPqFqj3Rj5FOGA==, + } dependencies: '@emmetio/scanner': 1.0.0 dev: false /@emmetio/css-abbreviation/2.1.4: - resolution: {integrity: sha512-qk9L60Y+uRtM5CPbB0y+QNl/1XKE09mSO+AhhSauIfr2YOx/ta3NJw2d8RtCFxgzHeRqFRr8jgyzThbu+MZ4Uw==} + resolution: + { + integrity: sha512-qk9L60Y+uRtM5CPbB0y+QNl/1XKE09mSO+AhhSauIfr2YOx/ta3NJw2d8RtCFxgzHeRqFRr8jgyzThbu+MZ4Uw==, + } dependencies: '@emmetio/scanner': 1.0.0 dev: false /@emmetio/scanner/1.0.0: - resolution: {integrity: sha512-8HqW8EVqjnCmWXVpqAOZf+EGESdkR27odcMMMGefgKXtar00SoYNSryGv//TELI4T3QFsECo78p+0lmalk/CFA==} + resolution: + { + integrity: sha512-8HqW8EVqjnCmWXVpqAOZf+EGESdkR27odcMMMGefgKXtar00SoYNSryGv//TELI4T3QFsECo78p+0lmalk/CFA==, + } dev: false /@esbuild/android-arm/0.16.17: - resolution: {integrity: sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==, + } + engines: { node: '>=12' } cpu: [arm] os: [android] requiresBuild: true @@ -420,8 +542,11 @@ packages: optional: true /@esbuild/android-arm64/0.16.17: - resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==, + } + engines: { node: '>=12' } cpu: [arm64] os: [android] requiresBuild: true @@ -429,8 +554,11 @@ packages: optional: true /@esbuild/android-x64/0.16.17: - resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==, + } + engines: { node: '>=12' } cpu: [x64] os: [android] requiresBuild: true @@ -438,8 +566,11 @@ packages: optional: true /@esbuild/darwin-arm64/0.16.17: - resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==, + } + engines: { node: '>=12' } cpu: [arm64] os: [darwin] requiresBuild: true @@ -447,8 +578,11 @@ packages: optional: true /@esbuild/darwin-x64/0.16.17: - resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==, + } + engines: { node: '>=12' } cpu: [x64] os: [darwin] requiresBuild: true @@ -456,8 +590,11 @@ packages: optional: true /@esbuild/freebsd-arm64/0.16.17: - resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==, + } + engines: { node: '>=12' } cpu: [arm64] os: [freebsd] requiresBuild: true @@ -465,8 +602,11 @@ packages: optional: true /@esbuild/freebsd-x64/0.16.17: - resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==, + } + engines: { node: '>=12' } cpu: [x64] os: [freebsd] requiresBuild: true @@ -474,8 +614,11 @@ packages: optional: true /@esbuild/linux-arm/0.16.17: - resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==, + } + engines: { node: '>=12' } cpu: [arm] os: [linux] requiresBuild: true @@ -483,8 +626,11 @@ packages: optional: true /@esbuild/linux-arm64/0.16.17: - resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==, + } + engines: { node: '>=12' } cpu: [arm64] os: [linux] requiresBuild: true @@ -492,8 +638,11 @@ packages: optional: true /@esbuild/linux-ia32/0.16.17: - resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==, + } + engines: { node: '>=12' } cpu: [ia32] os: [linux] requiresBuild: true @@ -501,8 +650,11 @@ packages: optional: true /@esbuild/linux-loong64/0.16.17: - resolution: {integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==, + } + engines: { node: '>=12' } cpu: [loong64] os: [linux] requiresBuild: true @@ -510,8 +662,11 @@ packages: optional: true /@esbuild/linux-mips64el/0.16.17: - resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==, + } + engines: { node: '>=12' } cpu: [mips64el] os: [linux] requiresBuild: true @@ -519,8 +674,11 @@ packages: optional: true /@esbuild/linux-ppc64/0.16.17: - resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==, + } + engines: { node: '>=12' } cpu: [ppc64] os: [linux] requiresBuild: true @@ -528,8 +686,11 @@ packages: optional: true /@esbuild/linux-riscv64/0.16.17: - resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==, + } + engines: { node: '>=12' } cpu: [riscv64] os: [linux] requiresBuild: true @@ -537,8 +698,11 @@ packages: optional: true /@esbuild/linux-s390x/0.16.17: - resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==, + } + engines: { node: '>=12' } cpu: [s390x] os: [linux] requiresBuild: true @@ -546,8 +710,11 @@ packages: optional: true /@esbuild/linux-x64/0.16.17: - resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==, + } + engines: { node: '>=12' } cpu: [x64] os: [linux] requiresBuild: true @@ -555,8 +722,11 @@ packages: optional: true /@esbuild/netbsd-x64/0.16.17: - resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==, + } + engines: { node: '>=12' } cpu: [x64] os: [netbsd] requiresBuild: true @@ -564,8 +734,11 @@ packages: optional: true /@esbuild/openbsd-x64/0.16.17: - resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==, + } + engines: { node: '>=12' } cpu: [x64] os: [openbsd] requiresBuild: true @@ -573,8 +746,11 @@ packages: optional: true /@esbuild/sunos-x64/0.16.17: - resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==, + } + engines: { node: '>=12' } cpu: [x64] os: [sunos] requiresBuild: true @@ -582,8 +758,11 @@ packages: optional: true /@esbuild/win32-arm64/0.16.17: - resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==, + } + engines: { node: '>=12' } cpu: [arm64] os: [win32] requiresBuild: true @@ -591,8 +770,11 @@ packages: optional: true /@esbuild/win32-ia32/0.16.17: - resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==, + } + engines: { node: '>=12' } cpu: [ia32] os: [win32] requiresBuild: true @@ -600,8 +782,11 @@ packages: optional: true /@esbuild/win32-x64/0.16.17: - resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==, + } + engines: { node: '>=12' } cpu: [x64] os: [win32] requiresBuild: true @@ -609,20 +794,29 @@ packages: optional: true /@gar/promisify/1.1.3: - resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} + resolution: + { + integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==, + } dev: false /@jridgewell/gen-mapping/0.1.1: - resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==, + } + engines: { node: '>=6.0.0' } dependencies: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.14 dev: false /@jridgewell/gen-mapping/0.3.2: - resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==, + } + engines: { node: '>=6.0.0' } dependencies: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.14 @@ -630,73 +824,109 @@ packages: dev: false /@jridgewell/resolve-uri/3.1.0: - resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==, + } + engines: { node: '>=6.0.0' } dev: false /@jridgewell/set-array/1.1.2: - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} - engines: {node: '>=6.0.0'} + resolution: + { + integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==, + } + engines: { node: '>=6.0.0' } dev: false /@jridgewell/source-map/0.3.2: - resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==} + resolution: + { + integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==, + } dependencies: '@jridgewell/gen-mapping': 0.3.2 '@jridgewell/trace-mapping': 0.3.17 dev: false /@jridgewell/sourcemap-codec/1.4.14: - resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + resolution: + { + integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==, + } dev: false /@jridgewell/trace-mapping/0.3.17: - resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} + resolution: + { + integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==, + } dependencies: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 dev: false /@ljharb/has-package-exports-patterns/0.0.2: - resolution: {integrity: sha512-4/RWEeXDO6bocPONheFe6gX/oQdP/bEpv0oL4HqjPP5DCenBSt0mHgahppY49N0CpsaqffdwPq+TlX9CYOq2Dw==} + resolution: + { + integrity: sha512-4/RWEeXDO6bocPONheFe6gX/oQdP/bEpv0oL4HqjPP5DCenBSt0mHgahppY49N0CpsaqffdwPq+TlX9CYOq2Dw==, + } dev: false /@nodelib/fs.scandir/2.1.5: - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==, + } + engines: { node: '>= 8' } dependencies: '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 /@nodelib/fs.stat/2.0.5: - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, + } + engines: { node: '>= 8' } /@nodelib/fs.walk/1.2.8: - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, + } + engines: { node: '>= 8' } dependencies: '@nodelib/fs.scandir': 2.1.5 fastq: 1.14.0 /@npmcli/fs/2.1.2: - resolution: {integrity: sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + resolution: + { + integrity: sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } dependencies: '@gar/promisify': 1.1.3 semver: 7.3.8 dev: false /@npmcli/fs/3.1.0: - resolution: {integrity: sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: semver: 7.3.8 dev: false /@npmcli/git/4.0.3: - resolution: {integrity: sha512-8cXNkDIbnXPVbhXMmQ7/bklCAjtmPaXfI9aEM4iH+xSuEHINLMHhlfESvVwdqmHJRJkR48vNJTSUvoF6GRPSFA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-8cXNkDIbnXPVbhXMmQ7/bklCAjtmPaXfI9aEM4iH+xSuEHINLMHhlfESvVwdqmHJRJkR48vNJTSUvoF6GRPSFA==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: '@npmcli/promise-spawn': 6.0.2 lru-cache: 7.14.1 @@ -712,8 +942,11 @@ packages: dev: false /@npmcli/installed-package-contents/2.0.1: - resolution: {integrity: sha512-GIykAFdOVK31Q1/zAtT5MbxqQL2vyl9mvFJv+OGu01zxbhL3p0xc8gJjdNGX1mWmUT43aEKVO2L6V/2j4TOsAA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-GIykAFdOVK31Q1/zAtT5MbxqQL2vyl9mvFJv+OGu01zxbhL3p0xc8gJjdNGX1mWmUT43aEKVO2L6V/2j4TOsAA==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } hasBin: true dependencies: npm-bundled: 3.0.0 @@ -721,8 +954,11 @@ packages: dev: false /@npmcli/move-file/2.0.1: - resolution: {integrity: sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + resolution: + { + integrity: sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } deprecated: This functionality has been moved to @npmcli/fs dependencies: mkdirp: 1.0.4 @@ -730,20 +966,29 @@ packages: dev: false /@npmcli/node-gyp/3.0.0: - resolution: {integrity: sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dev: false /@npmcli/promise-spawn/6.0.2: - resolution: {integrity: sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: which: 3.0.0 dev: false /@npmcli/run-script/6.0.0: - resolution: {integrity: sha512-ql+AbRur1TeOdl1FY+RAwGW9fcr4ZwiVKabdvm93mujGREVuVLbdkXRJDrkTXSdCjaxYydr1wlA2v67jxWG5BQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-ql+AbRur1TeOdl1FY+RAwGW9fcr4ZwiVKabdvm93mujGREVuVLbdkXRJDrkTXSdCjaxYydr1wlA2v67jxWG5BQ==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: '@npmcli/node-gyp': 3.0.0 '@npmcli/promise-spawn': 6.0.2 @@ -756,8 +1001,11 @@ packages: dev: false /@pkgr/utils/2.3.1: - resolution: {integrity: sha512-wfzX8kc1PMyUILA+1Z/EqoE4UCXGy0iRGMhPwdfae1+f0OXlLqCk+By+aMzgJBzR9AzS4CDizioG6Ss1gvAFJw==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + resolution: + { + integrity: sha512-wfzX8kc1PMyUILA+1Z/EqoE4UCXGy0iRGMhPwdfae1+f0OXlLqCk+By+aMzgJBzR9AzS4CDizioG6Ss1gvAFJw==, + } + engines: { node: ^12.20.0 || ^14.18.0 || >=16.0.0 } dependencies: cross-spawn: 7.0.3 is-glob: 4.0.3 @@ -767,8 +1015,11 @@ packages: tslib: 2.4.1 /@playwright/test/1.32.1: - resolution: {integrity: sha512-FTwjCuhlm1qHUGf4hWjfr64UMJD/z0hXYbk+O387Ioe6WdyZQ+0TBDAc6P+pHjx2xCv1VYNgrKbYrNixFWy4Dg==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-FTwjCuhlm1qHUGf4hWjfr64UMJD/z0hXYbk+O387Ioe6WdyZQ+0TBDAc6P+pHjx2xCv1VYNgrKbYrNixFWy4Dg==, + } + engines: { node: '>=14' } hasBin: true dependencies: '@types/node': 17.0.45 @@ -778,41 +1029,59 @@ packages: dev: true /@pnpm/network.ca-file/1.0.2: - resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} - engines: {node: '>=12.22.0'} + resolution: + { + integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==, + } + engines: { node: '>=12.22.0' } dependencies: graceful-fs: 4.2.10 dev: false /@pnpm/npm-conf/1.0.5: - resolution: {integrity: sha512-hD8ml183638O3R6/Txrh0L8VzGOrFXgRtRDG4qQC4tONdZ5Z1M+tlUUDUvrjYdmK6G+JTBTeaCLMna11cXzi8A==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-hD8ml183638O3R6/Txrh0L8VzGOrFXgRtRDG4qQC4tONdZ5Z1M+tlUUDUvrjYdmK6G+JTBTeaCLMna11cXzi8A==, + } + engines: { node: '>=12' } dependencies: '@pnpm/network.ca-file': 1.0.2 config-chain: 1.1.13 dev: false /@proload/core/0.3.3: - resolution: {integrity: sha512-7dAFWsIK84C90AMl24+N/ProHKm4iw0akcnoKjRvbfHifJZBLhaDsDus1QJmhG12lXj4e/uB/8mB/0aduCW+NQ==} + resolution: + { + integrity: sha512-7dAFWsIK84C90AMl24+N/ProHKm4iw0akcnoKjRvbfHifJZBLhaDsDus1QJmhG12lXj4e/uB/8mB/0aduCW+NQ==, + } dependencies: deepmerge: 4.2.2 escalade: 3.1.1 dev: false /@sindresorhus/is/5.3.0: - resolution: {integrity: sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==} - engines: {node: '>=14.16'} + resolution: + { + integrity: sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==, + } + engines: { node: '>=14.16' } dev: false /@szmarczak/http-timer/5.0.1: - resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} - engines: {node: '>=14.16'} + resolution: + { + integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==, + } + engines: { node: '>=14.16' } dependencies: defer-to-connect: 2.0.1 dev: false /@tailwindcss/typography/0.5.9_tailwindcss@3.2.7: - resolution: {integrity: sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg==} + resolution: + { + integrity: sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg==, + } peerDependencies: tailwindcss: '>=3.0.0 || insiders' dependencies: @@ -824,17 +1093,26 @@ packages: dev: true /@tootallnate/once/2.0.0: - resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} - engines: {node: '>= 10'} + resolution: + { + integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==, + } + engines: { node: '>= 10' } dev: false /@trysound/sax/0.2.0: - resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} - engines: {node: '>=10.13.0'} + resolution: + { + integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==, + } + engines: { node: '>=10.13.0' } dev: false /@types/babel__core/7.1.20: - resolution: {integrity: sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==} + resolution: + { + integrity: sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==, + } dependencies: '@babel/parser': 7.20.7 '@babel/types': 7.20.7 @@ -844,107 +1122,170 @@ packages: dev: false /@types/babel__generator/7.6.4: - resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} + resolution: + { + integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==, + } dependencies: '@babel/types': 7.20.7 dev: false /@types/babel__template/7.4.1: - resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} + resolution: + { + integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==, + } dependencies: '@babel/parser': 7.20.7 '@babel/types': 7.20.7 dev: false /@types/babel__traverse/7.18.3: - resolution: {integrity: sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==} + resolution: + { + integrity: sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==, + } dependencies: '@babel/types': 7.20.7 dev: false /@types/css-tree/2.0.1: - resolution: {integrity: sha512-eeRN9rsZK/ZD5nmJCeZXxyTwq+gsvN1EljeCPEyXk+vLOAwsgpsrdXio4lPBzxAuhIKu3MK7QvZxWUw9xDX8Bg==} + resolution: + { + integrity: sha512-eeRN9rsZK/ZD5nmJCeZXxyTwq+gsvN1EljeCPEyXk+vLOAwsgpsrdXio4lPBzxAuhIKu3MK7QvZxWUw9xDX8Bg==, + } dev: false /@types/csso/5.0.0: - resolution: {integrity: sha512-EMrCTGpXRUsbFfZBzn2jcW6Sqg8kxWXkJcpvAGYSEzFqAJ2THDJSwiMeS2fPUw+0p6RQNT/n8F/skEc9hUBc0g==} + resolution: + { + integrity: sha512-EMrCTGpXRUsbFfZBzn2jcW6Sqg8kxWXkJcpvAGYSEzFqAJ2THDJSwiMeS2fPUw+0p6RQNT/n8F/skEc9hUBc0g==, + } dependencies: '@types/css-tree': 2.0.1 dev: false /@types/debug/4.1.7: - resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==} + resolution: + { + integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==, + } dependencies: '@types/ms': 0.7.31 dev: false /@types/hast/2.3.4: - resolution: {integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==} + resolution: + { + integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==, + } dependencies: '@types/unist': 2.0.6 dev: false /@types/html-minifier-terser/7.0.0: - resolution: {integrity: sha512-hw3bhStrg5e3FQT8qZKCJTrzt/UbEaunU1xRWJ+aNOTmeBMvE3S4Ml2HiiNnZgL8izu0LFVkHUoPFXL1s5QNpQ==} + resolution: + { + integrity: sha512-hw3bhStrg5e3FQT8qZKCJTrzt/UbEaunU1xRWJ+aNOTmeBMvE3S4Ml2HiiNnZgL8izu0LFVkHUoPFXL1s5QNpQ==, + } dev: false /@types/http-cache-semantics/4.0.1: - resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} + resolution: + { + integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==, + } dev: false /@types/json5/0.0.30: - resolution: {integrity: sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA==} + resolution: + { + integrity: sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA==, + } dev: false /@types/mdast/3.0.10: - resolution: {integrity: sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==} + resolution: + { + integrity: sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==, + } dependencies: '@types/unist': 2.0.6 dev: false /@types/ms/0.7.31: - resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} + resolution: + { + integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==, + } dev: false /@types/nlcst/1.0.0: - resolution: {integrity: sha512-3TGCfOcy8R8mMQ4CNSNOe3PG66HttvjcLzCoOpvXvDtfWOTi+uT/rxeOKm/qEwbM4SNe1O/PjdiBK2YcTjU4OQ==} + resolution: + { + integrity: sha512-3TGCfOcy8R8mMQ4CNSNOe3PG66HttvjcLzCoOpvXvDtfWOTi+uT/rxeOKm/qEwbM4SNe1O/PjdiBK2YcTjU4OQ==, + } dependencies: '@types/unist': 2.0.6 dev: false /@types/node/17.0.45: - resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} + resolution: + { + integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==, + } /@types/parse5/6.0.3: - resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==} + resolution: + { + integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==, + } dev: false /@types/resolve/1.20.2: - resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + resolution: + { + integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==, + } dev: false /@types/sax/1.2.4: - resolution: {integrity: sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==} + resolution: + { + integrity: sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==, + } dependencies: '@types/node': 17.0.45 dev: false /@types/sharp/0.31.1: - resolution: {integrity: sha512-5nWwamN9ZFHXaYEincMSuza8nNfOof8nmO+mcI+Agx1uMUk4/pQnNIcix+9rLPXzKrm1pS34+6WRDbDV0Jn7ag==} + resolution: + { + integrity: sha512-5nWwamN9ZFHXaYEincMSuza8nNfOof8nmO+mcI+Agx1uMUk4/pQnNIcix+9rLPXzKrm1pS34+6WRDbDV0Jn7ag==, + } dependencies: '@types/node': 17.0.45 dev: false /@types/unist/2.0.6: - resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} + resolution: + { + integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==, + } dev: false /@types/yargs-parser/21.0.0: - resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} + resolution: + { + integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==, + } dev: false /@vscode/emmet-helper/2.8.6: - resolution: {integrity: sha512-IIB8jbiKy37zN8bAIHx59YmnIelY78CGHtThnibD/d3tQOKRY83bYVi9blwmZVUZh6l9nfkYH3tvReaiNxY9EQ==} + resolution: + { + integrity: sha512-IIB8jbiKy37zN8bAIHx59YmnIelY78CGHtThnibD/d3tQOKRY83bYVi9blwmZVUZh6l9nfkYH3tvReaiNxY9EQ==, + } dependencies: emmet: 2.3.6 jsonc-parser: 2.3.1 @@ -954,38 +1295,59 @@ packages: dev: false /@vscode/l10n/0.0.10: - resolution: {integrity: sha512-E1OCmDcDWa0Ya7vtSjp/XfHFGqYJfh+YPC1RkATU71fTac+j1JjCcB3qwSzmlKAighx2WxhLlfhS0RwAN++PFQ==} + resolution: + { + integrity: sha512-E1OCmDcDWa0Ya7vtSjp/XfHFGqYJfh+YPC1RkATU71fTac+j1JjCcB3qwSzmlKAighx2WxhLlfhS0RwAN++PFQ==, + } dev: false /abbrev/1.1.1: - resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + resolution: + { + integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==, + } dev: false /acorn-node/1.8.2: - resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==} + resolution: + { + integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==, + } dependencies: acorn: 7.4.1 acorn-walk: 7.2.0 xtend: 4.0.2 /acorn-walk/7.2.0: - resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==, + } + engines: { node: '>=0.4.0' } /acorn/7.4.1: - resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==, + } + engines: { node: '>=0.4.0' } hasBin: true /acorn/8.8.1: - resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==, + } + engines: { node: '>=0.4.0' } hasBin: true dev: false /agent-base/6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} + resolution: + { + integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==, + } + engines: { node: '>= 6.0.0' } dependencies: debug: 4.3.4 transitivePeerDependencies: @@ -993,8 +1355,11 @@ packages: dev: false /agentkeepalive/4.2.1: - resolution: {integrity: sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==} - engines: {node: '>= 8.0.0'} + resolution: + { + integrity: sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==, + } + engines: { node: '>= 8.0.0' } dependencies: debug: 4.3.4 depd: 1.1.2 @@ -1004,102 +1369,156 @@ packages: dev: false /aggregate-error/3.1.0: - resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==, + } + engines: { node: '>=8' } dependencies: clean-stack: 2.2.0 indent-string: 4.0.0 dev: false /ansi-align/3.0.1: - resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + resolution: + { + integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==, + } dependencies: string-width: 4.2.3 dev: false /ansi-regex/5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, + } + engines: { node: '>=8' } dev: false /ansi-regex/6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==, + } + engines: { node: '>=12' } dev: false /ansi-styles/3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==, + } + engines: { node: '>=4' } dependencies: color-convert: 1.9.3 dev: false /ansi-styles/4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, + } + engines: { node: '>=8' } dependencies: color-convert: 2.0.1 dev: false /ansi-styles/6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==, + } + engines: { node: '>=12' } dev: false /anymatch/3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, + } + engines: { node: '>= 8' } dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 /aproba/2.0.0: - resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + resolution: + { + integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==, + } dev: false /are-we-there-yet/3.0.1: - resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + resolution: + { + integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } dependencies: delegates: 1.0.0 readable-stream: 3.6.0 dev: false /arg/5.0.2: - resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + resolution: + { + integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==, + } /argparse/1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + resolution: + { + integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, + } dependencies: sprintf-js: 1.0.3 dev: false /argparse/2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + resolution: + { + integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, + } /array-iterate/2.0.1: - resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} + resolution: + { + integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==, + } dev: false /array-union/1.0.2: - resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==, + } + engines: { node: '>=0.10.0' } dependencies: array-uniq: 1.0.3 dev: true /array-union/2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==, + } + engines: { node: '>=8' } dev: false /array-uniq/1.0.3: - resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==, + } + engines: { node: '>=0.10.0' } dev: true /astro-compress/1.1.35: - resolution: {integrity: sha512-K6BK+iMbejXeUS1eAjoQhRh4geEutFrGkgCkeTAthf1XeRzPrWvtNPA7RjJBXWR8aNJtjryxyW02z3pE+4RNow==} + resolution: + { + integrity: sha512-K6BK+iMbejXeUS1eAjoQhRh4geEutFrGkgCkeTAthf1XeRzPrWvtNPA7RjJBXWR8aNJtjryxyW02z3pE+4RNow==, + } dependencies: '@types/csso': 5.0.0 '@types/html-minifier-terser': 7.0.0 @@ -1113,8 +1532,11 @@ packages: dev: false /astro/2.1.7: - resolution: {integrity: sha512-Eaq8/mJTx+kbghfW5ZEJ8rKiEduo03Rn6R/fp/gJGpBSRm/0FiVxVsrpq5SV4kUPrttEi1zMEnEc2GP6JWfXeg==} - engines: {node: '>=16.12.0', npm: '>=6.14.0'} + resolution: + { + integrity: sha512-Eaq8/mJTx+kbghfW5ZEJ8rKiEduo03Rn6R/fp/gJGpBSRm/0FiVxVsrpq5SV4kUPrttEi1zMEnEc2GP6JWfXeg==, + } + engines: { node: '>=16.12.0', npm: '>=6.14.0' } hasBin: true peerDependencies: sharp: ^0.31.3 @@ -1186,16 +1608,25 @@ packages: dev: false /async/3.2.4: - resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} + resolution: + { + integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==, + } dev: true /asynckit/0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + resolution: + { + integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, + } dev: true /autoprefixer/10.4.13_postcss@8.4.21: - resolution: {integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==} - engines: {node: ^10 || ^12 || >=14} + resolution: + { + integrity: sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==, + } + engines: { node: ^10 || ^12 || >=14 } hasBin: true peerDependencies: postcss: ^8.1.0 @@ -1210,7 +1641,10 @@ packages: dev: false /axios/0.26.1: - resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==} + resolution: + { + integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==, + } dependencies: follow-redirects: 1.15.2 transitivePeerDependencies: @@ -1218,22 +1652,37 @@ packages: dev: true /bail/2.0.2: - resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + resolution: + { + integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==, + } dev: false /balanced-match/1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + resolution: + { + integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, + } /base64-js/1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + resolution: + { + integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==, + } dev: false /binary-extensions/2.2.0: - resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==, + } + engines: { node: '>=8' } /bl/4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + resolution: + { + integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==, + } dependencies: buffer: 5.7.1 inherits: 2.0.4 @@ -1241,7 +1690,10 @@ packages: dev: false /bl/5.1.0: - resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==} + resolution: + { + integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==, + } dependencies: buffer: 6.0.3 inherits: 2.0.4 @@ -1249,12 +1701,18 @@ packages: dev: false /boolbase/1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + resolution: + { + integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==, + } dev: false /boxen/6.2.1: - resolution: {integrity: sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } dependencies: ansi-align: 3.0.1 camelcase: 6.3.0 @@ -1267,8 +1725,11 @@ packages: dev: false /boxen/7.0.1: - resolution: {integrity: sha512-8k2eH6SRAK00NDl1iX5q17RJ8rfl53TajdYxE3ssMLehbg487dEVgsad4pIsZb/QqBgYWIl6JOauMTLGX2Kpkw==} - engines: {node: '>=14.16'} + resolution: + { + integrity: sha512-8k2eH6SRAK00NDl1iX5q17RJ8rfl53TajdYxE3ssMLehbg487dEVgsad4pIsZb/QqBgYWIl6JOauMTLGX2Kpkw==, + } + engines: { node: '>=14.16' } dependencies: ansi-align: 3.0.1 camelcase: 7.0.1 @@ -1281,26 +1742,38 @@ packages: dev: false /brace-expansion/1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + resolution: + { + integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==, + } dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 /brace-expansion/2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + resolution: + { + integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==, + } dependencies: balanced-match: 1.0.2 dev: false /braces/3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==, + } + engines: { node: '>=8' } dependencies: fill-range: 7.0.1 /browserslist/4.21.4: - resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + resolution: + { + integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==, + } + engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } hasBin: true dependencies: caniuse-lite: 1.0.30001441 @@ -1310,39 +1783,57 @@ packages: dev: false /buffer-from/1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + resolution: + { + integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==, + } dev: false /buffer/5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + resolution: + { + integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==, + } dependencies: base64-js: 1.5.1 ieee754: 1.2.1 dev: false /buffer/6.0.3: - resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + resolution: + { + integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==, + } dependencies: base64-js: 1.5.1 ieee754: 1.2.1 dev: false /builtins/5.0.1: - resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} + resolution: + { + integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==, + } dependencies: semver: 7.3.8 dev: false /busboy/1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} + resolution: + { + integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==, + } + engines: { node: '>=10.16.0' } dependencies: streamsearch: 1.1.0 dev: false /cacache/16.1.3: - resolution: {integrity: sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + resolution: + { + integrity: sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } dependencies: '@npmcli/fs': 2.1.2 '@npmcli/move-file': 2.0.1 @@ -1367,8 +1858,11 @@ packages: dev: false /cacache/17.0.4: - resolution: {integrity: sha512-Z/nL3gU+zTUjz5pCA5vVjYM8pmaw2kxM7JEiE0fv3w77Wj+sFbi70CrBruUWH0uNcEdvLDixFpgA2JM4F4DBjA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-Z/nL3gU+zTUjz5pCA5vVjYM8pmaw2kxM7JEiE0fv3w77Wj+sFbi70CrBruUWH0uNcEdvLDixFpgA2JM4F4DBjA==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: '@npmcli/fs': 3.1.0 fs-minipass: 3.0.0 @@ -1388,13 +1882,19 @@ packages: dev: false /cacheable-lookup/7.0.0: - resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} - engines: {node: '>=14.16'} + resolution: + { + integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==, + } + engines: { node: '>=14.16' } dev: false /cacheable-request/10.2.5: - resolution: {integrity: sha512-5RwYYCfzjNPsyJxb/QpaM0bfzx+kw5/YpDhZPm9oMIDntHFQ9YXeyV47ZvzlTE0XrrrbyO2UITJH4GF9eRLdXQ==} - engines: {node: '>=14.16'} + resolution: + { + integrity: sha512-5RwYYCfzjNPsyJxb/QpaM0bfzx+kw5/YpDhZPm9oMIDntHFQ9YXeyV47ZvzlTE0XrrrbyO2UITJH4GF9eRLdXQ==, + } + engines: { node: '>=14.16' } dependencies: '@types/http-cache-semantics': 4.0.1 get-stream: 6.0.1 @@ -1406,37 +1906,58 @@ packages: dev: false /camel-case/4.1.2: - resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} + resolution: + { + integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==, + } dependencies: pascal-case: 3.1.2 tslib: 2.4.1 dev: false /camelcase-css/2.0.1: - resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==, + } + engines: { node: '>= 6' } /camelcase/6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==, + } + engines: { node: '>=10' } dev: false /camelcase/7.0.1: - resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} - engines: {node: '>=14.16'} + resolution: + { + integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==, + } + engines: { node: '>=14.16' } dev: false /caniuse-lite/1.0.30001441: - resolution: {integrity: sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==} + resolution: + { + integrity: sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==, + } dev: false /ccount/2.0.1: - resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + resolution: + { + integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==, + } dev: false /chalk/2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==, + } + engines: { node: '>=4' } dependencies: ansi-styles: 3.2.1 escape-string-regexp: 1.0.5 @@ -1444,33 +1965,51 @@ packages: dev: false /chalk/4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, + } + engines: { node: '>=10' } dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 dev: false /chalk/5.2.0: - resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + resolution: + { + integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==, + } + engines: { node: ^12.17.0 || ^14.13 || >=16.0.0 } dev: false /character-entities-html4/2.1.0: - resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + resolution: + { + integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==, + } dev: false /character-entities-legacy/3.0.0: - resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + resolution: + { + integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==, + } dev: false /character-entities/2.0.2: - resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + resolution: + { + integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==, + } dev: false /chokidar/3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} - engines: {node: '>= 8.10.0'} + resolution: + { + integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==, + } + engines: { node: '>= 8.10.0' } dependencies: anymatch: 3.1.3 braces: 3.0.2 @@ -1483,51 +2022,78 @@ packages: fsevents: 2.3.2 /chownr/1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + resolution: + { + integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==, + } dev: false /chownr/2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==, + } + engines: { node: '>=10' } dev: false /ci-info/3.7.0: - resolution: {integrity: sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==, + } + engines: { node: '>=8' } dev: false /clean-css/5.2.0: - resolution: {integrity: sha512-2639sWGa43EMmG7fn8mdVuBSs6HuWaSor+ZPoFWzenBc6oN+td8YhTfghWXZ25G1NiiSvz8bOFBS7PdSbTiqEA==} - engines: {node: '>= 10.0'} + resolution: + { + integrity: sha512-2639sWGa43EMmG7fn8mdVuBSs6HuWaSor+ZPoFWzenBc6oN+td8YhTfghWXZ25G1NiiSvz8bOFBS7PdSbTiqEA==, + } + engines: { node: '>= 10.0' } dependencies: source-map: 0.6.1 dev: false /clean-stack/2.2.0: - resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==, + } + engines: { node: '>=6' } dev: false /cli-boxes/3.0.0: - resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==, + } + engines: { node: '>=10' } dev: false /cli-cursor/4.0.0: - resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } dependencies: restore-cursor: 4.0.0 dev: false /cli-spinners/2.7.0: - resolution: {integrity: sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==, + } + engines: { node: '>=6' } dev: false /cli-table3/0.6.3: - resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} - engines: {node: 10.* || >= 12.*} + resolution: + { + integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==, + } + engines: { node: 10.* || >= 12.* } dependencies: string-width: 4.2.3 optionalDependencies: @@ -1535,100 +2101,157 @@ packages: dev: false /clone/1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} + resolution: + { + integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==, + } + engines: { node: '>=0.8' } dev: false /color-convert/1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + resolution: + { + integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==, + } dependencies: color-name: 1.1.3 dev: false /color-convert/2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + resolution: + { + integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, + } + engines: { node: '>=7.0.0' } dependencies: color-name: 1.1.4 dev: false /color-name/1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + resolution: + { + integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==, + } dev: false /color-name/1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + resolution: + { + integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, + } /color-string/1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + resolution: + { + integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==, + } dependencies: color-name: 1.1.4 simple-swizzle: 0.2.2 dev: false /color-support/1.1.3: - resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + resolution: + { + integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==, + } hasBin: true dev: false /color/4.2.3: - resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} - engines: {node: '>=12.5.0'} + resolution: + { + integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==, + } + engines: { node: '>=12.5.0' } dependencies: color-convert: 2.0.1 color-string: 1.9.1 dev: false /combined-stream/1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, + } + engines: { node: '>= 0.8' } dependencies: delayed-stream: 1.0.0 dev: true /comma-separated-tokens/2.0.3: - resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + resolution: + { + integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==, + } dev: false /commander/10.0.0: - resolution: {integrity: sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA==, + } + engines: { node: '>=14' } dev: false /commander/2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + resolution: + { + integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==, + } /commander/7.2.0: - resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} - engines: {node: '>= 10'} + resolution: + { + integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==, + } + engines: { node: '>= 10' } dev: false /commander/9.4.1: - resolution: {integrity: sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==} - engines: {node: ^12.20.0 || >=14} + resolution: + { + integrity: sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==, + } + engines: { node: ^12.20.0 || >=14 } dev: false /common-ancestor-path/1.0.1: - resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} + resolution: + { + integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==, + } dev: false /commondir/1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + resolution: + { + integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==, + } dev: true /concat-map/0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + resolution: + { + integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, + } /config-chain/1.1.13: - resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + resolution: + { + integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==, + } dependencies: ini: 1.3.8 proto-list: 1.2.4 dev: false /configstore/6.0.0: - resolution: {integrity: sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==, + } + engines: { node: '>=12' } dependencies: dot-prop: 6.0.1 graceful-fs: 4.2.10 @@ -1638,35 +2261,53 @@ packages: dev: false /console-control-strings/1.1.0: - resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + resolution: + { + integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==, + } dev: false /convert-source-map/1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + resolution: + { + integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==, + } dev: false /cookie/0.5.0: - resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==, + } + engines: { node: '>= 0.6' } dev: false /cross-spawn/7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==, + } + engines: { node: '>= 8' } dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 /crypto-random-string/4.0.0: - resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==, + } + engines: { node: '>=12' } dependencies: type-fest: 1.4.0 dev: false /css-select/5.1.0: - resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + resolution: + { + integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==, + } dependencies: boolbase: 1.0.0 css-what: 6.1.0 @@ -1676,41 +2317,59 @@ packages: dev: false /css-tree/2.2.1: - resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + resolution: + { + integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==, + } + engines: { node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0' } dependencies: mdn-data: 2.0.28 source-map-js: 1.0.2 dev: false /css-tree/2.3.1: - resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + resolution: + { + integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==, + } + engines: { node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0 } dependencies: mdn-data: 2.0.30 source-map-js: 1.0.2 dev: false /css-what/6.1.0: - resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==, + } + engines: { node: '>= 6' } dev: false /cssesc/3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==, + } + engines: { node: '>=4' } hasBin: true /csso/5.0.5: - resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + resolution: + { + integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==, + } + engines: { node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0' } dependencies: css-tree: 2.2.1 dev: false /debug/4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} + resolution: + { + integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==, + } + engines: { node: '>=6.0' } peerDependencies: supports-color: '*' peerDependenciesMeta: @@ -1721,78 +2380,123 @@ packages: dev: false /decode-named-character-reference/1.0.2: - resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + resolution: + { + integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==, + } dependencies: character-entities: 2.0.2 dev: false /decompress-response/6.0.0: - resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==, + } + engines: { node: '>=10' } dependencies: mimic-response: 3.1.0 dev: false /deep-extend/0.6.0: - resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} - engines: {node: '>=4.0.0'} + resolution: + { + integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==, + } + engines: { node: '>=4.0.0' } dev: false /deepmerge-ts/4.3.0: - resolution: {integrity: sha512-if3ZYdkD2dClhnXR5reKtG98cwyaRT1NeugQoAPTTfsOpV9kqyeiBF9Qa5RHjemb3KzD5ulqygv6ED3t5j9eJw==} - engines: {node: '>=12.4.0'} + resolution: + { + integrity: sha512-if3ZYdkD2dClhnXR5reKtG98cwyaRT1NeugQoAPTTfsOpV9kqyeiBF9Qa5RHjemb3KzD5ulqygv6ED3t5j9eJw==, + } + engines: { node: '>=12.4.0' } dev: false /deepmerge/4.2.2: - resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==, + } + engines: { node: '>=0.10.0' } dev: false /defaults/1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + resolution: + { + integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==, + } dependencies: clone: 1.0.4 dev: false /defer-to-connect/2.0.1: - resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==, + } + engines: { node: '>=10' } dev: false /define-lazy-prop/2.0.0: - resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==, + } + engines: { node: '>=8' } /defined/1.0.1: - resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==} + resolution: + { + integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==, + } /delayed-stream/1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, + } + engines: { node: '>=0.4.0' } dev: true /delegates/1.0.0: - resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + resolution: + { + integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==, + } dev: false /depd/1.1.2: - resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==, + } + engines: { node: '>= 0.6' } dev: false /dequal/2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==, + } + engines: { node: '>=6' } dev: false /detect-libc/2.0.1: - resolution: {integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==, + } + engines: { node: '>=8' } dev: false /detective/5.2.1: - resolution: {integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==} - engines: {node: '>=0.8.0'} + resolution: + { + integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==, + } + engines: { node: '>=0.8.0' } hasBin: true dependencies: acorn-node: 1.8.2 @@ -1800,29 +2504,47 @@ packages: minimist: 1.2.7 /devalue/4.2.0: - resolution: {integrity: sha512-mbjoAaCL2qogBKgeFxFPOXAUsZchircF+B/79LD4sHH0+NHfYm8gZpQrskKDn5gENGt35+5OI1GUF7hLVnkPDw==} + resolution: + { + integrity: sha512-mbjoAaCL2qogBKgeFxFPOXAUsZchircF+B/79LD4sHH0+NHfYm8gZpQrskKDn5gENGt35+5OI1GUF7hLVnkPDw==, + } dev: false /didyoumean/1.2.2: - resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + resolution: + { + integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==, + } /diff/5.1.0: - resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} - engines: {node: '>=0.3.1'} + resolution: + { + integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==, + } + engines: { node: '>=0.3.1' } dev: false /dir-glob/3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==, + } + engines: { node: '>=8' } dependencies: path-type: 4.0.0 dev: false /dlv/1.1.3: - resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + resolution: + { + integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==, + } /dom-serializer/2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + resolution: + { + integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==, + } dependencies: domelementtype: 2.3.0 domhandler: 5.0.3 @@ -1830,18 +2552,27 @@ packages: dev: false /domelementtype/2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + resolution: + { + integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==, + } dev: false /domhandler/5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} + resolution: + { + integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==, + } + engines: { node: '>= 4' } dependencies: domelementtype: 2.3.0 dev: false /domutils/3.0.1: - resolution: {integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==} + resolution: + { + integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==, + } dependencies: dom-serializer: 2.0.0 domelementtype: 2.3.0 @@ -1849,53 +2580,83 @@ packages: dev: false /dot-case/3.0.4: - resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + resolution: + { + integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==, + } dependencies: no-case: 3.0.4 tslib: 2.4.1 dev: false /dot-prop/6.0.1: - resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==, + } + engines: { node: '>=10' } dependencies: is-obj: 2.0.0 dev: false /dset/3.1.2: - resolution: {integrity: sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q==, + } + engines: { node: '>=4' } dev: false /eastasianwidth/0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + resolution: + { + integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==, + } dev: false /electron-to-chromium/1.4.284: - resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} + resolution: + { + integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==, + } dev: false /email-addresses/5.0.0: - resolution: {integrity: sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==} + resolution: + { + integrity: sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==, + } dev: true /emmet/2.3.6: - resolution: {integrity: sha512-pLS4PBPDdxuUAmw7Me7+TcHbykTsBKN/S9XJbUOMFQrNv9MoshzyMFK/R57JBm94/6HSL4vHnDeEmxlC82NQ4A==} + resolution: + { + integrity: sha512-pLS4PBPDdxuUAmw7Me7+TcHbykTsBKN/S9XJbUOMFQrNv9MoshzyMFK/R57JBm94/6HSL4vHnDeEmxlC82NQ4A==, + } dependencies: '@emmetio/abbreviation': 2.2.3 '@emmetio/css-abbreviation': 2.1.4 dev: false /emoji-regex/8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + resolution: + { + integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, + } dev: false /emoji-regex/9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + resolution: + { + integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==, + } dev: false /encoding/0.1.13: - resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + resolution: + { + integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==, + } requiresBuild: true dependencies: iconv-lite: 0.6.3 @@ -1903,37 +2664,58 @@ packages: optional: true /end-of-stream/1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + resolution: + { + integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==, + } dependencies: once: 1.4.0 dev: false /entities/3.0.1: - resolution: {integrity: sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==} - engines: {node: '>=0.12'} + resolution: + { + integrity: sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==, + } + engines: { node: '>=0.12' } dev: true /entities/4.4.0: - resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} - engines: {node: '>=0.12'} + resolution: + { + integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==, + } + engines: { node: '>=0.12' } dev: false /env-paths/2.2.1: - resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==, + } + engines: { node: '>=6' } dev: false /err-code/2.0.3: - resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + resolution: + { + integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==, + } dev: false /es-module-lexer/1.1.0: - resolution: {integrity: sha512-fJg+1tiyEeS8figV+fPcPpm8WqJEflG3yPU0NOm5xMvrNkuiy7HzX/Ljng4Y0hAoiw4/3hQTCFYw+ub8+a2pRA==} + resolution: + { + integrity: sha512-fJg+1tiyEeS8figV+fPcPpm8WqJEflG3yPU0NOm5xMvrNkuiy7HzX/Ljng4Y0hAoiw4/3hQTCFYw+ub8+a2pRA==, + } dev: false /esbuild/0.16.17: - resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==, + } + engines: { node: '>=12' } hasBin: true requiresBuild: true optionalDependencies: @@ -1962,42 +2744,66 @@ packages: dev: false /escalade/3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==, + } + engines: { node: '>=6' } dev: false /escape-goat/4.0.0: - resolution: {integrity: sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==, + } + engines: { node: '>=12' } dev: false /escape-string-regexp/1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} + resolution: + { + integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==, + } + engines: { node: '>=0.8.0' } /escape-string-regexp/5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==, + } + engines: { node: '>=12' } dev: false /esprima/4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, + } + engines: { node: '>=4' } hasBin: true dev: false /estree-walker/3.0.1: - resolution: {integrity: sha512-woY0RUD87WzMBUiZLx8NsYr23N5BKsOMZHhu2hoNRVh6NXGfoiT1KOL8G3UHlJAnEDGmfa5ubNA/AacfG+Kb0g==} + resolution: + { + integrity: sha512-woY0RUD87WzMBUiZLx8NsYr23N5BKsOMZHhu2hoNRVh6NXGfoiT1KOL8G3UHlJAnEDGmfa5ubNA/AacfG+Kb0g==, + } dev: false /events/3.3.0: - resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} - engines: {node: '>=0.8.x'} + resolution: + { + integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==, + } + engines: { node: '>=0.8.x' } dev: false /execa/6.1.0: - resolution: {integrity: sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-QVWlX2e50heYJcCPG0iWtf8r0xjEYfz/OYLGDYH+IyjWezzPNxz63qNFOu0l4YftGWuizFVZHHs8PrLU5p2IDA==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } dependencies: cross-spawn: 7.0.3 get-stream: 6.0.1 @@ -2011,24 +2817,36 @@ packages: dev: false /expand-template/2.0.3: - resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==, + } + engines: { node: '>=6' } dev: false /extend-shallow/2.0.1: - resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==, + } + engines: { node: '>=0.10.0' } dependencies: is-extendable: 0.1.1 dev: false /extend/3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + resolution: + { + integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==, + } dev: false /fast-glob/3.2.12: - resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} - engines: {node: '>=8.6.0'} + resolution: + { + integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==, + } + engines: { node: '>=8.6.0' } dependencies: '@nodelib/fs.stat': 2.0.5 '@nodelib/fs.walk': 1.2.8 @@ -2037,22 +2855,34 @@ packages: micromatch: 4.0.5 /fast-memoize/2.5.2: - resolution: {integrity: sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==} + resolution: + { + integrity: sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==, + } dev: false /fastq/1.14.0: - resolution: {integrity: sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==} + resolution: + { + integrity: sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==, + } dependencies: reusify: 1.0.4 /filename-reserved-regex/2.0.0: - resolution: {integrity: sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==, + } + engines: { node: '>=4' } dev: true /filenamify/4.3.0: - resolution: {integrity: sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==, + } + engines: { node: '>=8' } dependencies: filename-reserved-regex: 2.0.0 strip-outer: 1.0.1 @@ -2060,21 +2890,30 @@ packages: dev: true /files-pipe/0.0.1: - resolution: {integrity: sha512-+U75QMGwmNi6S3cLJPCXtCWCUP3QTKCf6zwtW+7A+OS06PDbiX6MOPI3KE6XZZKLl0UYdiB3rimyFeqZDUdh1g==} + resolution: + { + integrity: sha512-+U75QMGwmNi6S3cLJPCXtCWCUP3QTKCf6zwtW+7A+OS06PDbiX6MOPI3KE6XZZKLl0UYdiB3rimyFeqZDUdh1g==, + } dependencies: deepmerge-ts: 4.3.0 fast-glob: 3.2.12 dev: false /fill-range/7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==, + } + engines: { node: '>=8' } dependencies: to-regex-range: 5.0.1 /find-cache-dir/3.3.2: - resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==, + } + engines: { node: '>=8' } dependencies: commondir: 1.0.1 make-dir: 3.1.0 @@ -2082,30 +2921,42 @@ packages: dev: true /find-up/4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==, + } + engines: { node: '>=8' } dependencies: locate-path: 5.0.0 path-exists: 4.0.0 /find-up/5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==, + } + engines: { node: '>=10' } dependencies: locate-path: 6.0.0 path-exists: 4.0.0 dev: false /find-yarn-workspace-root2/1.2.16: - resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} + resolution: + { + integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==, + } dependencies: micromatch: 4.0.5 pkg-dir: 4.2.0 dev: false /follow-redirects/1.15.2: - resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} - engines: {node: '>=4.0'} + resolution: + { + integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==, + } + engines: { node: '>=4.0' } peerDependencies: debug: '*' peerDependenciesMeta: @@ -2114,13 +2965,19 @@ packages: dev: true /form-data-encoder/2.1.4: - resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} - engines: {node: '>= 14.17'} + resolution: + { + integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==, + } + engines: { node: '>= 14.17' } dev: false /form-data/4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==, + } + engines: { node: '>= 6' } dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 @@ -2128,21 +2985,33 @@ packages: dev: true /fp-and-or/0.1.3: - resolution: {integrity: sha512-wJaE62fLaB3jCYvY2ZHjZvmKK2iiLiiehX38rz5QZxtdN8fVPJDeZUiVvJrHStdTc+23LHlyZuSEKgFc0pxi2g==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-wJaE62fLaB3jCYvY2ZHjZvmKK2iiLiiehX38rz5QZxtdN8fVPJDeZUiVvJrHStdTc+23LHlyZuSEKgFc0pxi2g==, + } + engines: { node: '>=10' } dev: false /fraction.js/4.2.0: - resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} + resolution: + { + integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==, + } dev: false /fs-constants/1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + resolution: + { + integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==, + } dev: false /fs-extra/8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} - engines: {node: '>=6 <7 || >=8'} + resolution: + { + integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==, + } + engines: { node: '>=6 <7 || >=8' } dependencies: graceful-fs: 4.2.10 jsonfile: 4.0.0 @@ -2150,35 +3019,53 @@ packages: dev: true /fs-minipass/2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==, + } + engines: { node: '>= 8' } dependencies: minipass: 3.3.6 dev: false /fs-minipass/3.0.0: - resolution: {integrity: sha512-EUojgQaSPy6sxcqcZgQv6TVF6jiKvurji3AxhAivs/Ep4O1UpS8TusaxpybfFHZ2skRhLqzk6WR8nqNYIMMDeA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-EUojgQaSPy6sxcqcZgQv6TVF6jiKvurji3AxhAivs/Ep4O1UpS8TusaxpybfFHZ2skRhLqzk6WR8nqNYIMMDeA==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: minipass: 4.0.0 dev: false /fs.realpath/1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + resolution: + { + integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==, + } /fsevents/2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + resolution: + { + integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } os: [darwin] requiresBuild: true optional: true /function-bind/1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + resolution: + { + integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==, + } /gauge/4.0.4: - resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + resolution: + { + integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } dependencies: aproba: 2.0.0 color-support: 1.1.3 @@ -2191,23 +3078,35 @@ packages: dev: false /gensync/1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} + resolution: + { + integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, + } + engines: { node: '>=6.9.0' } dev: false /get-stdin/8.0.0: - resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==, + } + engines: { node: '>=10' } dev: false /get-stream/6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==, + } + engines: { node: '>=10' } dev: false /gh-pages/5.0.0: - resolution: {integrity: sha512-Nqp1SjkPIB94Xw/3yYNTUL+G2dxlhjvv1zeN/4kMC1jfViTEqhtVz/Ba1zSXHuvXCN9ADNS1dN4r5/J/nZWEQQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Nqp1SjkPIB94Xw/3yYNTUL+G2dxlhjvv1zeN/4kMC1jfViTEqhtVz/Ba1zSXHuvXCN9ADNS1dN4r5/J/nZWEQQ==, + } + engines: { node: '>=10' } hasBin: true dependencies: async: 3.2.4 @@ -2220,31 +3119,49 @@ packages: dev: true /github-from-package/0.0.0: - resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + resolution: + { + integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==, + } dev: false /github-slugger/1.5.0: - resolution: {integrity: sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==} + resolution: + { + integrity: sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==, + } dev: false /github-slugger/2.0.0: - resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + resolution: + { + integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==, + } dev: false /glob-parent/5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, + } + engines: { node: '>= 6' } dependencies: is-glob: 4.0.3 /glob-parent/6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} + resolution: + { + integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==, + } + engines: { node: '>=10.13.0' } dependencies: is-glob: 4.0.3 /glob/7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + resolution: + { + integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==, + } dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 @@ -2254,8 +3171,11 @@ packages: path-is-absolute: 1.0.1 /glob/8.0.3: - resolution: {integrity: sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==, + } + engines: { node: '>=12' } dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 @@ -2265,8 +3185,11 @@ packages: dev: false /glob/9.3.2: - resolution: {integrity: sha512-BTv/JhKXFEHsErMte/AnfiSv8yYOLLiyH2lTg8vn02O21zWFgHPTfxtgn1QRe7NRgggUhC8hacR2Re94svHqeA==} - engines: {node: '>=16 || 14 >=14.17'} + resolution: + { + integrity: sha512-BTv/JhKXFEHsErMte/AnfiSv8yYOLLiyH2lTg8vn02O21zWFgHPTfxtgn1QRe7NRgggUhC8hacR2Re94svHqeA==, + } + engines: { node: '>=16 || 14 >=14.17' } dependencies: fs.realpath: 1.0.0 minimatch: 7.4.3 @@ -2275,23 +3198,35 @@ packages: dev: false /global-dirs/3.0.1: - resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==, + } + engines: { node: '>=10' } dependencies: ini: 2.0.0 dev: false /globals/11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==, + } + engines: { node: '>=4' } dev: false /globalyzer/0.1.0: - resolution: {integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==} + resolution: + { + integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==, + } /globby/11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==, + } + engines: { node: '>=10' } dependencies: array-union: 2.1.0 dir-glob: 3.0.1 @@ -2302,8 +3237,11 @@ packages: dev: false /globby/6.1.0: - resolution: {integrity: sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==, + } + engines: { node: '>=0.10.0' } dependencies: array-union: 1.0.2 glob: 7.2.3 @@ -2313,11 +3251,17 @@ packages: dev: true /globrex/0.1.2: - resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + resolution: + { + integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==, + } /got/12.5.3: - resolution: {integrity: sha512-8wKnb9MGU8IPGRIo+/ukTy9XLJBwDiCpIf5TVzQ9Cpol50eMTpBq2GAuDsuDIz7hTYmZgMgC1e9ydr6kSDWs3w==} - engines: {node: '>=14.16'} + resolution: + { + integrity: sha512-8wKnb9MGU8IPGRIo+/ukTy9XLJBwDiCpIf5TVzQ9Cpol50eMTpBq2GAuDsuDIz7hTYmZgMgC1e9ydr6kSDWs3w==, + } + engines: { node: '>=14.16' } dependencies: '@sindresorhus/is': 5.3.0 '@szmarczak/http-timer': 5.0.1 @@ -2333,11 +3277,17 @@ packages: dev: false /graceful-fs/4.2.10: - resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + resolution: + { + integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==, + } /gray-matter/4.0.3: - resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} - engines: {node: '>=6.0'} + resolution: + { + integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==, + } + engines: { node: '>=6.0' } dependencies: js-yaml: 3.14.1 kind-of: 6.0.3 @@ -2346,38 +3296,59 @@ packages: dev: false /has-flag/3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==, + } + engines: { node: '>=4' } dev: false /has-flag/4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, + } + engines: { node: '>=8' } dev: false /has-package-exports/1.3.0: - resolution: {integrity: sha512-e9OeXPQnmPhYoJ63lXC4wWe34TxEGZDZ3OQX9XRqp2VwsfLl3bQBy7VehLnd34g3ef8CmYlBLGqEMKXuz8YazQ==} + resolution: + { + integrity: sha512-e9OeXPQnmPhYoJ63lXC4wWe34TxEGZDZ3OQX9XRqp2VwsfLl3bQBy7VehLnd34g3ef8CmYlBLGqEMKXuz8YazQ==, + } dependencies: '@ljharb/has-package-exports-patterns': 0.0.2 dev: false /has-unicode/2.0.1: - resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + resolution: + { + integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==, + } dev: false /has-yarn/3.0.0: - resolution: {integrity: sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } dev: false /has/1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} + resolution: + { + integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==, + } + engines: { node: '>= 0.4.0' } dependencies: function-bind: 1.1.1 /hast-to-hyperscript/10.0.1: - resolution: {integrity: sha512-dhIVGoKCQVewFi+vz3Vt567E4ejMppS1haBRL6TEmeLeJVB1i/FJIIg/e6s1Bwn0g5qtYojHEKvyGA+OZuyifw==} + resolution: + { + integrity: sha512-dhIVGoKCQVewFi+vz3Vt567E4ejMppS1haBRL6TEmeLeJVB1i/FJIIg/e6s1Bwn0g5qtYojHEKvyGA+OZuyifw==, + } dependencies: '@types/unist': 2.0.6 comma-separated-tokens: 2.0.3 @@ -2389,7 +3360,10 @@ packages: dev: false /hast-util-from-parse5/7.1.0: - resolution: {integrity: sha512-m8yhANIAccpU4K6+121KpPP55sSl9/samzQSQGpb0mTExcNh2WlvjtMwSWFhg6uqD4Rr6Nfa8N6TMypQM51rzQ==} + resolution: + { + integrity: sha512-m8yhANIAccpU4K6+121KpPP55sSl9/samzQSQGpb0mTExcNh2WlvjtMwSWFhg6uqD4Rr6Nfa8N6TMypQM51rzQ==, + } dependencies: '@types/hast': 2.3.4 '@types/parse5': 6.0.3 @@ -2402,20 +3376,29 @@ packages: dev: false /hast-util-is-element/2.1.2: - resolution: {integrity: sha512-thjnlGAnwP8ef/GSO1Q8BfVk2gundnc2peGQqEg2kUt/IqesiGg/5mSwN2fE7nLzy61pg88NG6xV+UrGOrx9EA==} + resolution: + { + integrity: sha512-thjnlGAnwP8ef/GSO1Q8BfVk2gundnc2peGQqEg2kUt/IqesiGg/5mSwN2fE7nLzy61pg88NG6xV+UrGOrx9EA==, + } dependencies: '@types/hast': 2.3.4 '@types/unist': 2.0.6 dev: false /hast-util-parse-selector/3.1.0: - resolution: {integrity: sha512-AyjlI2pTAZEOeu7GeBPZhROx0RHBnydkQIXlhnFzDi0qfXTmGUWoCYZtomHbrdrheV4VFUlPcfJ6LMF5T6sQzg==} + resolution: + { + integrity: sha512-AyjlI2pTAZEOeu7GeBPZhROx0RHBnydkQIXlhnFzDi0qfXTmGUWoCYZtomHbrdrheV4VFUlPcfJ6LMF5T6sQzg==, + } dependencies: '@types/hast': 2.3.4 dev: false /hast-util-raw/7.2.3: - resolution: {integrity: sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==} + resolution: + { + integrity: sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==, + } dependencies: '@types/hast': 2.3.4 '@types/parse5': 6.0.3 @@ -2431,7 +3414,10 @@ packages: dev: false /hast-util-to-html/8.0.3: - resolution: {integrity: sha512-/D/E5ymdPYhHpPkuTHOUkSatxr4w1ZKrZsG0Zv/3C2SRVT0JFJG53VS45AMrBtYk0wp5A7ksEhiC8QaOZM95+A==} + resolution: + { + integrity: sha512-/D/E5ymdPYhHpPkuTHOUkSatxr4w1ZKrZsG0Zv/3C2SRVT0JFJG53VS45AMrBtYk0wp5A7ksEhiC8QaOZM95+A==, + } dependencies: '@types/hast': 2.3.4 ccount: 2.0.1 @@ -2446,7 +3432,10 @@ packages: dev: false /hast-util-to-parse5/7.0.0: - resolution: {integrity: sha512-YHiS6aTaZ3N0Q3nxaY/Tj98D6kM8QX5Q8xqgg8G45zR7PvWnPGPP0vcKCgb/moIydEJ/QWczVrX0JODCVeoV7A==} + resolution: + { + integrity: sha512-YHiS6aTaZ3N0Q3nxaY/Tj98D6kM8QX5Q8xqgg8G45zR7PvWnPGPP0vcKCgb/moIydEJ/QWczVrX0JODCVeoV7A==, + } dependencies: '@types/hast': 2.3.4 '@types/parse5': 6.0.3 @@ -2457,11 +3446,17 @@ packages: dev: false /hast-util-whitespace/2.0.0: - resolution: {integrity: sha512-Pkw+xBHuV6xFeJprJe2BBEoDV+AvQySaz3pPDRUs5PNZEMQjpXJJueqrpcHIXxnWTcAGi/UOCgVShlkY6kLoqg==} + resolution: + { + integrity: sha512-Pkw+xBHuV6xFeJprJe2BBEoDV+AvQySaz3pPDRUs5PNZEMQjpXJJueqrpcHIXxnWTcAGi/UOCgVShlkY6kLoqg==, + } dev: false /hastscript/7.1.0: - resolution: {integrity: sha512-uBjaTTLN0MkCZxY/R2fWUOcu7FRtUVzKRO5P/RAfgsu3yFiMB1JWCO4AjeVkgHxAira1f2UecHK5WfS9QurlWA==} + resolution: + { + integrity: sha512-uBjaTTLN0MkCZxY/R2fWUOcu7FRtUVzKRO5P/RAfgsu3yFiMB1JWCO4AjeVkgHxAira1f2UecHK5WfS9QurlWA==, + } dependencies: '@types/hast': 2.3.4 comma-separated-tokens: 2.0.3 @@ -2471,31 +3466,46 @@ packages: dev: false /he/1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + resolution: + { + integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==, + } hasBin: true dev: false /hosted-git-info/5.2.1: - resolution: {integrity: sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + resolution: + { + integrity: sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } dependencies: lru-cache: 7.14.1 dev: false /hosted-git-info/6.1.1: - resolution: {integrity: sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: lru-cache: 7.14.1 dev: false /html-escaper/3.0.3: - resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} + resolution: + { + integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==, + } dev: false /html-minifier-terser/7.1.0: - resolution: {integrity: sha512-BvPO2S7Ip0Q5qt+Y8j/27Vclj6uHC6av0TMoDn7/bJPhMWHI2UtR2e/zEgJn3/qYAmxumrGp9q4UHurL6mtW9Q==} - engines: {node: ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-BvPO2S7Ip0Q5qt+Y8j/27Vclj6uHC6av0TMoDn7/bJPhMWHI2UtR2e/zEgJn3/qYAmxumrGp9q4UHurL6mtW9Q==, + } + engines: { node: ^14.13.1 || >=16.0.0 } hasBin: true dependencies: camel-case: 4.1.2 @@ -2508,16 +3518,25 @@ packages: dev: false /html-void-elements/2.0.1: - resolution: {integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==} + resolution: + { + integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==, + } dev: false /http-cache-semantics/4.1.0: - resolution: {integrity: sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==} + resolution: + { + integrity: sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==, + } dev: false /http-proxy-agent/5.0.0: - resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==, + } + engines: { node: '>= 6' } dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 @@ -2527,16 +3546,22 @@ packages: dev: false /http2-wrapper/2.2.0: - resolution: {integrity: sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==} - engines: {node: '>=10.19.0'} + resolution: + { + integrity: sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==, + } + engines: { node: '>=10.19.0' } dependencies: quick-lru: 5.1.1 resolve-alpn: 1.2.1 dev: false /https-proxy-agent/5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==, + } + engines: { node: '>= 6' } dependencies: agent-base: 6.0.2 debug: 4.3.4 @@ -2545,236 +3570,377 @@ packages: dev: false /human-signals/3.0.1: - resolution: {integrity: sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==} - engines: {node: '>=12.20.0'} + resolution: + { + integrity: sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ==, + } + engines: { node: '>=12.20.0' } dev: false /humanize-ms/1.2.1: - resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + resolution: + { + integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==, + } dependencies: ms: 2.1.2 dev: false /iconv-lite/0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==, + } + engines: { node: '>=0.10.0' } dependencies: safer-buffer: 2.1.2 dev: false optional: true /ieee754/1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + resolution: + { + integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==, + } dev: false /ignore-walk/6.0.0: - resolution: {integrity: sha512-bTf9UWe/UP1yxG3QUrj/KOvEhTAUWPcv+WvbFZ28LcqznXabp7Xu6o9y1JEC18+oqODuS7VhTpekV5XvFwsxJg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-bTf9UWe/UP1yxG3QUrj/KOvEhTAUWPcv+WvbFZ28LcqznXabp7Xu6o9y1JEC18+oqODuS7VhTpekV5XvFwsxJg==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: minimatch: 5.1.2 dev: false /ignore/5.2.4: - resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} - engines: {node: '>= 4'} + resolution: + { + integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==, + } + engines: { node: '>= 4' } dev: false /import-lazy/4.0.0: - resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==, + } + engines: { node: '>=8' } dev: false /import-meta-resolve/2.2.0: - resolution: {integrity: sha512-CpPOtiCHxP9HdtDM5F45tNiAe66Cqlv3f5uHoJjt+KlaLrUh9/Wz9vepADZ78SlqEo62aDWZtj9ydMGXV+CPnw==} + resolution: + { + integrity: sha512-CpPOtiCHxP9HdtDM5F45tNiAe66Cqlv3f5uHoJjt+KlaLrUh9/Wz9vepADZ78SlqEo62aDWZtj9ydMGXV+CPnw==, + } dev: false /imurmurhash/0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} + resolution: + { + integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, + } + engines: { node: '>=0.8.19' } dev: false /indent-string/4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==, + } + engines: { node: '>=8' } dev: false /infer-owner/1.0.4: - resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} + resolution: + { + integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==, + } dev: false /inflight/1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + resolution: + { + integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==, + } dependencies: once: 1.4.0 wrappy: 1.0.2 /inherits/2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + resolution: + { + integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, + } /ini/1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + resolution: + { + integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==, + } dev: false /ini/2.0.0: - resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==, + } + engines: { node: '>=10' } dev: false /ini/4.0.0: - resolution: {integrity: sha512-t0ikzf5qkSFqRl1e6ejKBe+Tk2bsQd8ivEkcisyGXsku2t8NvXZ1Y3RRz5vxrDgOrTBOi13CvGsVoI5wVpd7xg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-t0ikzf5qkSFqRl1e6ejKBe+Tk2bsQd8ivEkcisyGXsku2t8NvXZ1Y3RRz5vxrDgOrTBOi13CvGsVoI5wVpd7xg==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dev: false /inline-style-parser/0.1.1: - resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} + resolution: + { + integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==, + } dev: false /ip/2.0.0: - resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} + resolution: + { + integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==, + } dev: false /is-absolute-url/4.0.1: - resolution: {integrity: sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } dev: false /is-arrayish/0.3.2: - resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + resolution: + { + integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==, + } dev: false /is-binary-path/2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==, + } + engines: { node: '>=8' } dependencies: binary-extensions: 2.2.0 /is-buffer/2.0.5: - resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==, + } + engines: { node: '>=4' } dev: false /is-ci/3.0.1: - resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + resolution: + { + integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==, + } hasBin: true dependencies: ci-info: 3.7.0 dev: false /is-core-module/2.11.0: - resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} + resolution: + { + integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==, + } dependencies: has: 1.0.3 /is-docker/2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==, + } + engines: { node: '>=8' } hasBin: true /is-docker/3.0.0: - resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } hasBin: true dev: false /is-extendable/0.1.1: - resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==, + } + engines: { node: '>=0.10.0' } dev: false /is-extglob/2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, + } + engines: { node: '>=0.10.0' } /is-fullwidth-code-point/3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, + } + engines: { node: '>=8' } dev: false /is-glob/4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, + } + engines: { node: '>=0.10.0' } dependencies: is-extglob: 2.1.1 /is-installed-globally/0.4.0: - resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==, + } + engines: { node: '>=10' } dependencies: global-dirs: 3.0.1 is-path-inside: 3.0.3 dev: false /is-interactive/2.0.0: - resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==, + } + engines: { node: '>=12' } dev: false /is-lambda/1.0.1: - resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + resolution: + { + integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==, + } dev: false /is-npm/6.0.0: - resolution: {integrity: sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } dev: false /is-number/7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} + resolution: + { + integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, + } + engines: { node: '>=0.12.0' } /is-obj/2.0.0: - resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==, + } + engines: { node: '>=8' } dev: false /is-path-inside/3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==, + } + engines: { node: '>=8' } dev: false /is-plain-obj/4.1.0: - resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==, + } + engines: { node: '>=12' } dev: false /is-stream/3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } dev: false /is-typedarray/1.0.0: - resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + resolution: + { + integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==, + } dev: false /is-unicode-supported/1.3.0: - resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==, + } + engines: { node: '>=12' } dev: false /is-wsl/2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==, + } + engines: { node: '>=8' } dependencies: is-docker: 2.2.1 /is-yarn-global/0.4.1: - resolution: {integrity: sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==, + } + engines: { node: '>=12' } dev: false /isexe/2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + resolution: + { + integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, + } /jju/1.4.0: - resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + resolution: + { + integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==, + } dev: false /js-tokens/4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + resolution: + { + integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, + } dev: false /js-yaml/3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + resolution: + { + integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==, + } hasBin: true dependencies: argparse: 1.0.10 @@ -2782,102 +3948,159 @@ packages: dev: false /js-yaml/4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + resolution: + { + integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==, + } hasBin: true dependencies: argparse: 2.0.1 /jsesc/2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==, + } + engines: { node: '>=4' } hasBin: true dev: false /json-buffer/3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + resolution: + { + integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==, + } dev: false /json-parse-even-better-errors/3.0.0: - resolution: {integrity: sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dev: false /json-parse-helpfulerror/1.0.3: - resolution: {integrity: sha512-XgP0FGR77+QhUxjXkwOMkC94k3WtqEBfcnjWqhRd82qTat4SWKRE+9kUnynz/shm3I4ea2+qISvTIeGTNU7kJg==} + resolution: + { + integrity: sha512-XgP0FGR77+QhUxjXkwOMkC94k3WtqEBfcnjWqhRd82qTat4SWKRE+9kUnynz/shm3I4ea2+qISvTIeGTNU7kJg==, + } dependencies: jju: 1.4.0 dev: false /json5/2.2.2: - resolution: {integrity: sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==, + } + engines: { node: '>=6' } hasBin: true dev: false /jsonc-parser/2.3.1: - resolution: {integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==} + resolution: + { + integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==, + } dev: false /jsonc-parser/3.2.0: - resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + resolution: + { + integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==, + } dev: false /jsonfile/4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + resolution: + { + integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==, + } optionalDependencies: graceful-fs: 4.2.10 dev: true /jsonlines/0.1.1: - resolution: {integrity: sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA==} + resolution: + { + integrity: sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA==, + } dev: false /jsonparse/1.3.1: - resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} - engines: {'0': node >= 0.2.0} + resolution: + { + integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==, + } + engines: { '0': node >= 0.2.0 } dev: false /keyv/4.5.2: - resolution: {integrity: sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==} + resolution: + { + integrity: sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==, + } dependencies: json-buffer: 3.0.1 dev: false /kind-of/6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==, + } + engines: { node: '>=0.10.0' } dev: false /kleur/3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==, + } + engines: { node: '>=6' } dev: false /kleur/4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==, + } + engines: { node: '>=6' } dev: false /latest-version/7.0.0: - resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} - engines: {node: '>=14.16'} + resolution: + { + integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==, + } + engines: { node: '>=14.16' } dependencies: package-json: 8.1.0 dev: false /lilconfig/2.0.6: - resolution: {integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==, + } + engines: { node: '>=10' } /linkify-it/4.0.1: - resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==} + resolution: + { + integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==, + } dependencies: uc.micro: 1.0.6 dev: true /load-yaml-file/0.2.0: - resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==, + } + engines: { node: '>=6' } dependencies: graceful-fs: 4.2.10 js-yaml: 3.14.1 @@ -2886,92 +4109,140 @@ packages: dev: false /locate-path/5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==, + } + engines: { node: '>=8' } dependencies: p-locate: 4.1.0 /locate-path/6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==, + } + engines: { node: '>=10' } dependencies: p-locate: 5.0.0 dev: false /lodash.castarray/4.4.0: - resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==} + resolution: + { + integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==, + } dev: true /lodash.isplainobject/4.0.6: - resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + resolution: + { + integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==, + } dev: true /lodash.merge/4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + resolution: + { + integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==, + } dev: true /lodash/4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + resolution: + { + integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==, + } dev: false /log-symbols/5.1.0: - resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==, + } + engines: { node: '>=12' } dependencies: chalk: 5.2.0 is-unicode-supported: 1.3.0 dev: false /longest-streak/3.1.0: - resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + resolution: + { + integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==, + } dev: false /lower-case/2.0.2: - resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + resolution: + { + integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==, + } dependencies: tslib: 2.4.1 dev: false /lowercase-keys/3.0.0: - resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } dev: false /lru-cache/5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + resolution: + { + integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, + } dependencies: yallist: 3.1.1 dev: false /lru-cache/6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==, + } + engines: { node: '>=10' } dependencies: yallist: 4.0.0 dev: false /lru-cache/7.14.1: - resolution: {integrity: sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-ysxwsnTKdAx96aTRdhDOCQfDgbHnt8SK0KY8SEjO0wHinhWOFTESbjVCMPbU1uGXg/ch4lifqx0wfjOawU2+WA==, + } + engines: { node: '>=12' } dev: false /magic-string/0.27.0: - resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==, + } + engines: { node: '>=12' } dependencies: '@jridgewell/sourcemap-codec': 1.4.14 dev: false /make-dir/3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==, + } + engines: { node: '>=8' } dependencies: semver: 6.3.0 dev: true /make-fetch-happen/10.2.1: - resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + resolution: + { + integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } dependencies: agentkeepalive: 4.2.1 cacache: 16.1.3 @@ -2995,8 +4266,11 @@ packages: dev: false /make-fetch-happen/11.0.2: - resolution: {integrity: sha512-5n/Pq41w/uZghpdlXAY5kIM85RgJThtTH/NYBRAZ9VUOBWV90USaQjwGrw76fZP3Lj5hl/VZjpVvOaRBMoL/2w==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-5n/Pq41w/uZghpdlXAY5kIM85RgJThtTH/NYBRAZ9VUOBWV90USaQjwGrw76fZP3Lj5hl/VZjpVvOaRBMoL/2w==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: agentkeepalive: 4.2.1 cacache: 17.0.4 @@ -3020,7 +4294,10 @@ packages: dev: false /markdown-it/13.0.1: - resolution: {integrity: sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==} + resolution: + { + integrity: sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==, + } hasBin: true dependencies: argparse: 2.0.1 @@ -3031,11 +4308,17 @@ packages: dev: true /markdown-table/3.0.3: - resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==} + resolution: + { + integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==, + } dev: false /mdast-util-definitions/5.1.1: - resolution: {integrity: sha512-rQ+Gv7mHttxHOBx2dkF4HWTg+EE+UR78ptQWDylzPKaQuVGdG4HIoY3SrS/pCp80nZ04greFvXbVFHT+uf0JVQ==} + resolution: + { + integrity: sha512-rQ+Gv7mHttxHOBx2dkF4HWTg+EE+UR78ptQWDylzPKaQuVGdG4HIoY3SrS/pCp80nZ04greFvXbVFHT+uf0JVQ==, + } dependencies: '@types/mdast': 3.0.10 '@types/unist': 2.0.6 @@ -3043,7 +4326,10 @@ packages: dev: false /mdast-util-find-and-replace/2.2.1: - resolution: {integrity: sha512-SobxkQXFAdd4b5WmEakmkVoh18icjQRxGy5OWTCzgsLRm1Fu/KCtwD1HIQSsmq5ZRjVH0Ehwg6/Fn3xIUk+nKw==} + resolution: + { + integrity: sha512-SobxkQXFAdd4b5WmEakmkVoh18icjQRxGy5OWTCzgsLRm1Fu/KCtwD1HIQSsmq5ZRjVH0Ehwg6/Fn3xIUk+nKw==, + } dependencies: escape-string-regexp: 5.0.0 unist-util-is: 5.1.1 @@ -3051,7 +4337,10 @@ packages: dev: false /mdast-util-from-markdown/1.2.0: - resolution: {integrity: sha512-iZJyyvKD1+K7QX1b5jXdE7Sc5dtoTry1vzV28UZZe8Z1xVnB/czKntJ7ZAkG0tANqRnBF6p3p7GpU1y19DTf2Q==} + resolution: + { + integrity: sha512-iZJyyvKD1+K7QX1b5jXdE7Sc5dtoTry1vzV28UZZe8Z1xVnB/czKntJ7ZAkG0tANqRnBF6p3p7GpU1y19DTf2Q==, + } dependencies: '@types/mdast': 3.0.10 '@types/unist': 2.0.6 @@ -3070,7 +4359,10 @@ packages: dev: false /mdast-util-gfm-autolink-literal/1.0.2: - resolution: {integrity: sha512-FzopkOd4xTTBeGXhXSBU0OCDDh5lUj2rd+HQqG92Ld+jL4lpUfgX2AT2OHAVP9aEeDKp7G92fuooSZcYJA3cRg==} + resolution: + { + integrity: sha512-FzopkOd4xTTBeGXhXSBU0OCDDh5lUj2rd+HQqG92Ld+jL4lpUfgX2AT2OHAVP9aEeDKp7G92fuooSZcYJA3cRg==, + } dependencies: '@types/mdast': 3.0.10 ccount: 2.0.1 @@ -3079,7 +4371,10 @@ packages: dev: false /mdast-util-gfm-footnote/1.0.1: - resolution: {integrity: sha512-p+PrYlkw9DeCRkTVw1duWqPRHX6Ywh2BNKJQcZbCwAuP/59B0Lk9kakuAd7KbQprVO4GzdW8eS5++A9PUSqIyw==} + resolution: + { + integrity: sha512-p+PrYlkw9DeCRkTVw1duWqPRHX6Ywh2BNKJQcZbCwAuP/59B0Lk9kakuAd7KbQprVO4GzdW8eS5++A9PUSqIyw==, + } dependencies: '@types/mdast': 3.0.10 mdast-util-to-markdown: 1.4.0 @@ -3087,14 +4382,20 @@ packages: dev: false /mdast-util-gfm-strikethrough/1.0.2: - resolution: {integrity: sha512-T/4DVHXcujH6jx1yqpcAYYwd+z5lAYMw4Ls6yhTfbMMtCt0PHY4gEfhW9+lKsLBtyhUGKRIzcUA2FATVqnvPDA==} + resolution: + { + integrity: sha512-T/4DVHXcujH6jx1yqpcAYYwd+z5lAYMw4Ls6yhTfbMMtCt0PHY4gEfhW9+lKsLBtyhUGKRIzcUA2FATVqnvPDA==, + } dependencies: '@types/mdast': 3.0.10 mdast-util-to-markdown: 1.4.0 dev: false /mdast-util-gfm-table/1.0.6: - resolution: {integrity: sha512-uHR+fqFq3IvB3Rd4+kzXW8dmpxUhvgCQZep6KdjsLK4O6meK5dYZEayLtIxNus1XO3gfjfcIFe8a7L0HZRGgag==} + resolution: + { + integrity: sha512-uHR+fqFq3IvB3Rd4+kzXW8dmpxUhvgCQZep6KdjsLK4O6meK5dYZEayLtIxNus1XO3gfjfcIFe8a7L0HZRGgag==, + } dependencies: '@types/mdast': 3.0.10 markdown-table: 3.0.3 @@ -3105,14 +4406,20 @@ packages: dev: false /mdast-util-gfm-task-list-item/1.0.1: - resolution: {integrity: sha512-KZ4KLmPdABXOsfnM6JHUIjxEvcx2ulk656Z/4Balw071/5qgnhz+H1uGtf2zIGnrnvDC8xR4Fj9uKbjAFGNIeA==} + resolution: + { + integrity: sha512-KZ4KLmPdABXOsfnM6JHUIjxEvcx2ulk656Z/4Balw071/5qgnhz+H1uGtf2zIGnrnvDC8xR4Fj9uKbjAFGNIeA==, + } dependencies: '@types/mdast': 3.0.10 mdast-util-to-markdown: 1.4.0 dev: false /mdast-util-gfm/2.0.1: - resolution: {integrity: sha512-42yHBbfWIFisaAfV1eixlabbsa6q7vHeSPY+cg+BBjX51M8xhgMacqH9g6TftB/9+YkcI0ooV4ncfrJslzm/RQ==} + resolution: + { + integrity: sha512-42yHBbfWIFisaAfV1eixlabbsa6q7vHeSPY+cg+BBjX51M8xhgMacqH9g6TftB/9+YkcI0ooV4ncfrJslzm/RQ==, + } dependencies: mdast-util-from-markdown: 1.2.0 mdast-util-gfm-autolink-literal: 1.0.2 @@ -3126,7 +4433,10 @@ packages: dev: false /mdast-util-to-hast/12.2.4: - resolution: {integrity: sha512-a21xoxSef1l8VhHxS1Dnyioz6grrJkoaCUgGzMD/7dWHvboYX3VW53esRUfB5tgTyz4Yos1n25SPcj35dJqmAg==} + resolution: + { + integrity: sha512-a21xoxSef1l8VhHxS1Dnyioz6grrJkoaCUgGzMD/7dWHvboYX3VW53esRUfB5tgTyz4Yos1n25SPcj35dJqmAg==, + } dependencies: '@types/hast': 2.3.4 '@types/mdast': 3.0.10 @@ -3140,7 +4450,10 @@ packages: dev: false /mdast-util-to-markdown/1.4.0: - resolution: {integrity: sha512-IjXARf/O8VGx/pc5SZ7syfydq1DYL9vd92orsG5U0b4GNCmAvXzu+n7sbzfIKrXwB0AVrYk3NV2kXl0AIi9LCA==} + resolution: + { + integrity: sha512-IjXARf/O8VGx/pc5SZ7syfydq1DYL9vd92orsG5U0b4GNCmAvXzu+n7sbzfIKrXwB0AVrYk3NV2kXl0AIi9LCA==, + } dependencies: '@types/mdast': 3.0.10 '@types/unist': 2.0.6 @@ -3152,31 +4465,52 @@ packages: dev: false /mdast-util-to-string/3.1.0: - resolution: {integrity: sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==} + resolution: + { + integrity: sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==, + } dev: false /mdn-data/2.0.28: - resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + resolution: + { + integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==, + } dev: false /mdn-data/2.0.30: - resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + resolution: + { + integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==, + } dev: false /mdurl/1.0.1: - resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} + resolution: + { + integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==, + } dev: true /merge-stream/2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + resolution: + { + integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, + } dev: false /merge2/1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, + } + engines: { node: '>= 8' } /micromark-core-commonmark/1.0.6: - resolution: {integrity: sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA==} + resolution: + { + integrity: sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA==, + } dependencies: decode-named-character-reference: 1.0.2 micromark-factory-destination: 1.0.0 @@ -3197,7 +4531,10 @@ packages: dev: false /micromark-extension-gfm-autolink-literal/1.0.3: - resolution: {integrity: sha512-i3dmvU0htawfWED8aHMMAzAVp/F0Z+0bPh3YrbTPPL1v4YAlCZpy5rBO5p0LPYiZo0zFVkoYh7vDU7yQSiCMjg==} + resolution: + { + integrity: sha512-i3dmvU0htawfWED8aHMMAzAVp/F0Z+0bPh3YrbTPPL1v4YAlCZpy5rBO5p0LPYiZo0zFVkoYh7vDU7yQSiCMjg==, + } dependencies: micromark-util-character: 1.1.0 micromark-util-sanitize-uri: 1.1.0 @@ -3207,7 +4544,10 @@ packages: dev: false /micromark-extension-gfm-footnote/1.0.4: - resolution: {integrity: sha512-E/fmPmDqLiMUP8mLJ8NbJWJ4bTw6tS+FEQS8CcuDtZpILuOb2kjLqPEeAePF1djXROHXChM/wPJw0iS4kHCcIg==} + resolution: + { + integrity: sha512-E/fmPmDqLiMUP8mLJ8NbJWJ4bTw6tS+FEQS8CcuDtZpILuOb2kjLqPEeAePF1djXROHXChM/wPJw0iS4kHCcIg==, + } dependencies: micromark-core-commonmark: 1.0.6 micromark-factory-space: 1.0.0 @@ -3220,7 +4560,10 @@ packages: dev: false /micromark-extension-gfm-strikethrough/1.0.4: - resolution: {integrity: sha512-/vjHU/lalmjZCT5xt7CcHVJGq8sYRm80z24qAKXzaHzem/xsDYb2yLL+NNVbYvmpLx3O7SYPuGL5pzusL9CLIQ==} + resolution: + { + integrity: sha512-/vjHU/lalmjZCT5xt7CcHVJGq8sYRm80z24qAKXzaHzem/xsDYb2yLL+NNVbYvmpLx3O7SYPuGL5pzusL9CLIQ==, + } dependencies: micromark-util-chunked: 1.0.0 micromark-util-classify-character: 1.0.0 @@ -3231,7 +4574,10 @@ packages: dev: false /micromark-extension-gfm-table/1.0.5: - resolution: {integrity: sha512-xAZ8J1X9W9K3JTJTUL7G6wSKhp2ZYHrFk5qJgY/4B33scJzE2kpfRL6oiw/veJTbt7jiM/1rngLlOKPWr1G+vg==} + resolution: + { + integrity: sha512-xAZ8J1X9W9K3JTJTUL7G6wSKhp2ZYHrFk5qJgY/4B33scJzE2kpfRL6oiw/veJTbt7jiM/1rngLlOKPWr1G+vg==, + } dependencies: micromark-factory-space: 1.0.0 micromark-util-character: 1.1.0 @@ -3241,13 +4587,19 @@ packages: dev: false /micromark-extension-gfm-tagfilter/1.0.1: - resolution: {integrity: sha512-Ty6psLAcAjboRa/UKUbbUcwjVAv5plxmpUTy2XC/3nJFL37eHej8jrHrRzkqcpipJliuBH30DTs7+3wqNcQUVA==} + resolution: + { + integrity: sha512-Ty6psLAcAjboRa/UKUbbUcwjVAv5plxmpUTy2XC/3nJFL37eHej8jrHrRzkqcpipJliuBH30DTs7+3wqNcQUVA==, + } dependencies: micromark-util-types: 1.0.2 dev: false /micromark-extension-gfm-task-list-item/1.0.3: - resolution: {integrity: sha512-PpysK2S1Q/5VXi72IIapbi/jliaiOFzv7THH4amwXeYXLq3l1uo8/2Be0Ac1rEwK20MQEsGH2ltAZLNY2KI/0Q==} + resolution: + { + integrity: sha512-PpysK2S1Q/5VXi72IIapbi/jliaiOFzv7THH4amwXeYXLq3l1uo8/2Be0Ac1rEwK20MQEsGH2ltAZLNY2KI/0Q==, + } dependencies: micromark-factory-space: 1.0.0 micromark-util-character: 1.1.0 @@ -3257,7 +4609,10 @@ packages: dev: false /micromark-extension-gfm/2.0.1: - resolution: {integrity: sha512-p2sGjajLa0iYiGQdT0oelahRYtMWvLjy8J9LOCxzIQsllMCGLbsLW+Nc+N4vi02jcRJvedVJ68cjelKIO6bpDA==} + resolution: + { + integrity: sha512-p2sGjajLa0iYiGQdT0oelahRYtMWvLjy8J9LOCxzIQsllMCGLbsLW+Nc+N4vi02jcRJvedVJ68cjelKIO6bpDA==, + } dependencies: micromark-extension-gfm-autolink-literal: 1.0.3 micromark-extension-gfm-footnote: 1.0.4 @@ -3270,7 +4625,10 @@ packages: dev: false /micromark-factory-destination/1.0.0: - resolution: {integrity: sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==} + resolution: + { + integrity: sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==, + } dependencies: micromark-util-character: 1.1.0 micromark-util-symbol: 1.0.1 @@ -3278,7 +4636,10 @@ packages: dev: false /micromark-factory-label/1.0.2: - resolution: {integrity: sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg==} + resolution: + { + integrity: sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg==, + } dependencies: micromark-util-character: 1.1.0 micromark-util-symbol: 1.0.1 @@ -3287,14 +4648,20 @@ packages: dev: false /micromark-factory-space/1.0.0: - resolution: {integrity: sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==} + resolution: + { + integrity: sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==, + } dependencies: micromark-util-character: 1.1.0 micromark-util-types: 1.0.2 dev: false /micromark-factory-title/1.0.2: - resolution: {integrity: sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A==} + resolution: + { + integrity: sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A==, + } dependencies: micromark-factory-space: 1.0.0 micromark-util-character: 1.1.0 @@ -3304,7 +4671,10 @@ packages: dev: false /micromark-factory-whitespace/1.0.0: - resolution: {integrity: sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==} + resolution: + { + integrity: sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==, + } dependencies: micromark-factory-space: 1.0.0 micromark-util-character: 1.1.0 @@ -3313,20 +4683,29 @@ packages: dev: false /micromark-util-character/1.1.0: - resolution: {integrity: sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg==} + resolution: + { + integrity: sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg==, + } dependencies: micromark-util-symbol: 1.0.1 micromark-util-types: 1.0.2 dev: false /micromark-util-chunked/1.0.0: - resolution: {integrity: sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==} + resolution: + { + integrity: sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==, + } dependencies: micromark-util-symbol: 1.0.1 dev: false /micromark-util-classify-character/1.0.0: - resolution: {integrity: sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==} + resolution: + { + integrity: sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==, + } dependencies: micromark-util-character: 1.1.0 micromark-util-symbol: 1.0.1 @@ -3334,20 +4713,29 @@ packages: dev: false /micromark-util-combine-extensions/1.0.0: - resolution: {integrity: sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==} + resolution: + { + integrity: sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==, + } dependencies: micromark-util-chunked: 1.0.0 micromark-util-types: 1.0.2 dev: false /micromark-util-decode-numeric-character-reference/1.0.0: - resolution: {integrity: sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==} + resolution: + { + integrity: sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==, + } dependencies: micromark-util-symbol: 1.0.1 dev: false /micromark-util-decode-string/1.0.2: - resolution: {integrity: sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q==} + resolution: + { + integrity: sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q==, + } dependencies: decode-named-character-reference: 1.0.2 micromark-util-character: 1.1.0 @@ -3356,27 +4744,42 @@ packages: dev: false /micromark-util-encode/1.0.1: - resolution: {integrity: sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA==} + resolution: + { + integrity: sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA==, + } dev: false /micromark-util-html-tag-name/1.1.0: - resolution: {integrity: sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA==} + resolution: + { + integrity: sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA==, + } dev: false /micromark-util-normalize-identifier/1.0.0: - resolution: {integrity: sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==} + resolution: + { + integrity: sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==, + } dependencies: micromark-util-symbol: 1.0.1 dev: false /micromark-util-resolve-all/1.0.0: - resolution: {integrity: sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==} + resolution: + { + integrity: sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==, + } dependencies: micromark-util-types: 1.0.2 dev: false /micromark-util-sanitize-uri/1.1.0: - resolution: {integrity: sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg==} + resolution: + { + integrity: sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg==, + } dependencies: micromark-util-character: 1.1.0 micromark-util-encode: 1.0.1 @@ -3384,7 +4787,10 @@ packages: dev: false /micromark-util-subtokenize/1.0.2: - resolution: {integrity: sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA==} + resolution: + { + integrity: sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA==, + } dependencies: micromark-util-chunked: 1.0.0 micromark-util-symbol: 1.0.1 @@ -3393,15 +4799,24 @@ packages: dev: false /micromark-util-symbol/1.0.1: - resolution: {integrity: sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ==} + resolution: + { + integrity: sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ==, + } dev: false /micromark-util-types/1.0.2: - resolution: {integrity: sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w==} + resolution: + { + integrity: sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w==, + } dev: false /micromark/3.1.0: - resolution: {integrity: sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==} + resolution: + { + integrity: sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==, + } dependencies: '@types/debug': 4.1.7 debug: 4.3.4 @@ -3425,89 +4840,134 @@ packages: dev: false /micromatch/4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} + resolution: + { + integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==, + } + engines: { node: '>=8.6' } dependencies: braces: 3.0.2 picomatch: 2.3.1 /mime-db/1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, + } + engines: { node: '>= 0.6' } dev: true /mime-types/2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, + } + engines: { node: '>= 0.6' } dependencies: mime-db: 1.52.0 dev: true /mime/3.0.0: - resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} - engines: {node: '>=10.0.0'} + resolution: + { + integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==, + } + engines: { node: '>=10.0.0' } hasBin: true dev: false /mimic-fn/2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, + } + engines: { node: '>=6' } dev: false /mimic-fn/4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==, + } + engines: { node: '>=12' } dev: false /mimic-response/3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==, + } + engines: { node: '>=10' } dev: false /mimic-response/4.0.0: - resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } dev: false /minimatch/3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + resolution: + { + integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, + } dependencies: brace-expansion: 1.1.11 /minimatch/5.1.2: - resolution: {integrity: sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==, + } + engines: { node: '>=10' } dependencies: brace-expansion: 2.0.1 dev: false /minimatch/6.2.0: - resolution: {integrity: sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg==, + } + engines: { node: '>=10' } dependencies: brace-expansion: 2.0.1 dev: false /minimatch/7.4.3: - resolution: {integrity: sha512-5UB4yYusDtkRPbRiy1cqZ1IpGNcJCGlEMG17RKzPddpyiPKoCdwohbED8g4QXT0ewCt8LTkQXuljsUfQ3FKM4A==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-5UB4yYusDtkRPbRiy1cqZ1IpGNcJCGlEMG17RKzPddpyiPKoCdwohbED8g4QXT0ewCt8LTkQXuljsUfQ3FKM4A==, + } + engines: { node: '>=10' } dependencies: brace-expansion: 2.0.1 dev: false /minimist/1.2.7: - resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} + resolution: + { + integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==, + } /minipass-collect/1.0.2: - resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==, + } + engines: { node: '>= 8' } dependencies: minipass: 3.3.6 dev: false /minipass-fetch/2.1.2: - resolution: {integrity: sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + resolution: + { + integrity: sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } dependencies: minipass: 3.3.6 minipass-sized: 1.0.3 @@ -3517,8 +4977,11 @@ packages: dev: false /minipass-fetch/3.0.1: - resolution: {integrity: sha512-t9/wowtf7DYkwz8cfMSt0rMwiyNIBXf5CKZ3S5ZMqRqMYT0oLTp0x1WorMI9WTwvaPg21r1JbFxJMum8JrLGfw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-t9/wowtf7DYkwz8cfMSt0rMwiyNIBXf5CKZ3S5ZMqRqMYT0oLTp0x1WorMI9WTwvaPg21r1JbFxJMum8JrLGfw==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: minipass: 4.2.5 minipass-sized: 1.0.3 @@ -3528,120 +4991,180 @@ packages: dev: false /minipass-flush/1.0.5: - resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==, + } + engines: { node: '>= 8' } dependencies: minipass: 3.3.6 dev: false /minipass-json-stream/1.0.1: - resolution: {integrity: sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==} + resolution: + { + integrity: sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==, + } dependencies: jsonparse: 1.3.1 minipass: 3.3.6 dev: false /minipass-pipeline/1.2.4: - resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==, + } + engines: { node: '>=8' } dependencies: minipass: 3.3.6 dev: false /minipass-sized/1.0.3: - resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==, + } + engines: { node: '>=8' } dependencies: minipass: 3.3.6 dev: false /minipass/3.3.6: - resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==, + } + engines: { node: '>=8' } dependencies: yallist: 4.0.0 dev: false /minipass/4.0.0: - resolution: {integrity: sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==, + } + engines: { node: '>=8' } dependencies: yallist: 4.0.0 dev: false /minipass/4.2.5: - resolution: {integrity: sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==, + } + engines: { node: '>=8' } dev: false /minizlib/2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==, + } + engines: { node: '>= 8' } dependencies: minipass: 3.3.6 yallist: 4.0.0 dev: false /mkdirp-classic/0.5.3: - resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + resolution: + { + integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==, + } dev: false /mkdirp/1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==, + } + engines: { node: '>=10' } hasBin: true dev: false /mri/1.2.0: - resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==, + } + engines: { node: '>=4' } dev: false /ms/2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + resolution: + { + integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, + } dev: false /nanoid/3.3.4: - resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + resolution: + { + integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==, + } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } hasBin: true /napi-build-utils/1.0.2: - resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} + resolution: + { + integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==, + } dev: false /negotiator/0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==, + } + engines: { node: '>= 0.6' } dev: false /nlcst-to-string/3.1.0: - resolution: {integrity: sha512-Y8HQWKw/zrHTCnu2zcFBN1dV6vN0NUG7s5fkEj380G8tF3R+vA2KG+tDl2QoHVQCTHGHVXwoni2RQkDSFQb1PA==} + resolution: + { + integrity: sha512-Y8HQWKw/zrHTCnu2zcFBN1dV6vN0NUG7s5fkEj380G8tF3R+vA2KG+tDl2QoHVQCTHGHVXwoni2RQkDSFQb1PA==, + } dependencies: '@types/nlcst': 1.0.0 dev: false /no-case/3.0.4: - resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + resolution: + { + integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==, + } dependencies: lower-case: 2.0.2 tslib: 2.4.1 dev: false /node-abi/3.30.0: - resolution: {integrity: sha512-qWO5l3SCqbwQavymOmtTVuCWZE23++S+rxyoHjXqUmPyzRcaoI4lA2gO55/drddGnedAyjA7sk76SfQ5lfUMnw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-qWO5l3SCqbwQavymOmtTVuCWZE23++S+rxyoHjXqUmPyzRcaoI4lA2gO55/drddGnedAyjA7sk76SfQ5lfUMnw==, + } + engines: { node: '>=10' } dependencies: semver: 7.3.8 dev: false /node-addon-api/5.0.0: - resolution: {integrity: sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==} + resolution: + { + integrity: sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==, + } dev: false /node-gyp/9.3.1: - resolution: {integrity: sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg==} - engines: {node: ^12.13 || ^14.13 || >=16} + resolution: + { + integrity: sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg==, + } + engines: { node: ^12.13 || ^14.13 || >=16 } hasBin: true dependencies: env-paths: 2.2.1 @@ -3660,27 +5183,39 @@ packages: dev: false /node-html-parser/6.1.5: - resolution: {integrity: sha512-fAaM511feX++/Chnhe475a0NHD8M7AxDInsqQpz6x63GRF7xYNdS8Vo5dKsIVPgsOvG7eioRRTZQnWBrhDHBSg==} + resolution: + { + integrity: sha512-fAaM511feX++/Chnhe475a0NHD8M7AxDInsqQpz6x63GRF7xYNdS8Vo5dKsIVPgsOvG7eioRRTZQnWBrhDHBSg==, + } dependencies: css-select: 5.1.0 he: 1.2.0 dev: false /node-releases/2.0.8: - resolution: {integrity: sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==} + resolution: + { + integrity: sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==, + } dev: false /nopt/6.0.0: - resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + resolution: + { + integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } hasBin: true dependencies: abbrev: 1.1.1 dev: false /normalize-package-data/5.0.0: - resolution: {integrity: sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: hosted-git-info: 6.1.1 is-core-module: 2.11.0 @@ -3689,29 +5224,44 @@ packages: dev: false /normalize-path/3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, + } + engines: { node: '>=0.10.0' } /normalize-range/0.1.2: - resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==, + } + engines: { node: '>=0.10.0' } dev: false /normalize-url/8.0.0: - resolution: {integrity: sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==} - engines: {node: '>=14.16'} + resolution: + { + integrity: sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==, + } + engines: { node: '>=14.16' } dev: false /npm-bundled/3.0.0: - resolution: {integrity: sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: npm-normalize-package-bin: 3.0.0 dev: false /npm-check-updates/16.8.0: - resolution: {integrity: sha512-2xpFtUPa2OyswC8kpIpxRqQcP/D0uqaBgfiOQAtvGlnDhmHr3QwR2gWjjWtS6xnNvgyyVly/4edY0Uu24c46ew==} - engines: {node: '>=14.14'} + resolution: + { + integrity: sha512-2xpFtUPa2OyswC8kpIpxRqQcP/D0uqaBgfiOQAtvGlnDhmHr3QwR2gWjjWtS6xnNvgyyVly/4edY0Uu24c46ew==, + } + engines: { node: '>=14.14' } hasBin: true dependencies: chalk: 5.2.0 @@ -3750,20 +5300,29 @@ packages: dev: false /npm-install-checks/6.0.0: - resolution: {integrity: sha512-SBU9oFglRVZnfElwAtF14NivyulDqF1VKqqwNsFW9HDcbHMAPHpRSsVFgKuwFGq/hVvWZExz62Th0kvxn/XE7Q==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-SBU9oFglRVZnfElwAtF14NivyulDqF1VKqqwNsFW9HDcbHMAPHpRSsVFgKuwFGq/hVvWZExz62Th0kvxn/XE7Q==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: semver: 7.3.8 dev: false /npm-normalize-package-bin/3.0.0: - resolution: {integrity: sha512-g+DPQSkusnk7HYXr75NtzkIP4+N81i3RPsGFidF3DzHd9MT9wWngmqoeg/fnHFz5MNdtG4w03s+QnhewSLTT2Q==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-g+DPQSkusnk7HYXr75NtzkIP4+N81i3RPsGFidF3DzHd9MT9wWngmqoeg/fnHFz5MNdtG4w03s+QnhewSLTT2Q==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dev: false /npm-package-arg/10.1.0: - resolution: {integrity: sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: hosted-git-info: 6.1.1 proc-log: 3.0.0 @@ -3772,15 +5331,21 @@ packages: dev: false /npm-packlist/7.0.4: - resolution: {integrity: sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: ignore-walk: 6.0.0 dev: false /npm-pick-manifest/8.0.1: - resolution: {integrity: sha512-mRtvlBjTsJvfCCdmPtiu2bdlx8d/KXtF7yNXNWe7G0Z36qWA9Ny5zXsI2PfBZEv7SXgoxTmNaTzGSbbzDZChoA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-mRtvlBjTsJvfCCdmPtiu2bdlx8d/KXtF7yNXNWe7G0Z36qWA9Ny5zXsI2PfBZEv7SXgoxTmNaTzGSbbzDZChoA==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: npm-install-checks: 6.0.0 npm-normalize-package-bin: 3.0.0 @@ -3789,8 +5354,11 @@ packages: dev: false /npm-registry-fetch/14.0.3: - resolution: {integrity: sha512-YaeRbVNpnWvsGOjX2wk5s85XJ7l1qQBGAp724h8e2CZFFhMSuw9enom7K1mWVUtvXO1uUSFIAPofQK0pPN0ZcA==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-YaeRbVNpnWvsGOjX2wk5s85XJ7l1qQBGAp724h8e2CZFFhMSuw9enom7K1mWVUtvXO1uUSFIAPofQK0pPN0ZcA==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: make-fetch-happen: 11.0.2 minipass: 4.0.0 @@ -3805,15 +5373,21 @@ packages: dev: false /npm-run-path/5.1.0: - resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } dependencies: path-key: 4.0.0 dev: false /npmlog/6.0.2: - resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + resolution: + { + integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } dependencies: are-we-there-yet: 3.0.1 console-control-strings: 1.1.0 @@ -3822,49 +5396,73 @@ packages: dev: false /nth-check/2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + resolution: + { + integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==, + } dependencies: boolbase: 1.0.0 dev: false /object-assign/4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==, + } + engines: { node: '>=0.10.0' } dev: true /object-hash/3.0.0: - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==, + } + engines: { node: '>= 6' } /once/1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + resolution: + { + integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, + } dependencies: wrappy: 1.0.2 /onetime/5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, + } + engines: { node: '>=6' } dependencies: mimic-fn: 2.1.0 dev: false /onetime/6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==, + } + engines: { node: '>=12' } dependencies: mimic-fn: 4.0.0 dev: false /open/8.4.0: - resolution: {integrity: sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==, + } + engines: { node: '>=12' } dependencies: define-lazy-prop: 2.0.0 is-docker: 2.2.1 is-wsl: 2.2.0 /openai/3.2.1: - resolution: {integrity: sha512-762C9BNlJPbjjlWZi4WYK9iM2tAVAv0uUp1UmI34vb0CN5T2mjB/qM6RYBmNKMh/dN9fC+bxqPwWJZUTWW052A==} + resolution: + { + integrity: sha512-762C9BNlJPbjjlWZi4WYK9iM2tAVAv0uUp1UmI34vb0CN5T2mjB/qM6RYBmNKMh/dN9fC+bxqPwWJZUTWW052A==, + } dependencies: axios: 0.26.1 form-data: 4.0.0 @@ -3873,8 +5471,11 @@ packages: dev: true /ora/6.1.2: - resolution: {integrity: sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } dependencies: bl: 5.1.0 chalk: 5.2.0 @@ -3888,50 +5489,74 @@ packages: dev: false /p-cancelable/3.0.0: - resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} - engines: {node: '>=12.20'} + resolution: + { + integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==, + } + engines: { node: '>=12.20' } dev: false /p-limit/2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==, + } + engines: { node: '>=6' } dependencies: p-try: 2.2.0 /p-limit/3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, + } + engines: { node: '>=10' } dependencies: yocto-queue: 0.1.0 dev: false /p-locate/4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==, + } + engines: { node: '>=8' } dependencies: p-limit: 2.3.0 /p-locate/5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==, + } + engines: { node: '>=10' } dependencies: p-limit: 3.1.0 dev: false /p-map/4.0.0: - resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==, + } + engines: { node: '>=10' } dependencies: aggregate-error: 3.1.0 dev: false /p-try/2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==, + } + engines: { node: '>=6' } /package-json/8.1.0: - resolution: {integrity: sha512-hySwcV8RAWeAfPsXb9/HGSPn8lwDnv6fabH+obUZKX169QknRkRhPxd1yMubpKDskLFATkl3jHpNtVtDPFA0Wg==} - engines: {node: '>=14.16'} + resolution: + { + integrity: sha512-hySwcV8RAWeAfPsXb9/HGSPn8lwDnv6fabH+obUZKX169QknRkRhPxd1yMubpKDskLFATkl3jHpNtVtDPFA0Wg==, + } + engines: { node: '>=14.16' } dependencies: got: 12.5.3 registry-auth-token: 5.0.1 @@ -3940,8 +5565,11 @@ packages: dev: false /pacote/15.1.1: - resolution: {integrity: sha512-eeqEe77QrA6auZxNHIp+1TzHQ0HBKf5V6c8zcaYZ134EJe1lCi+fjXATkNiEEfbG+e50nu02GLvUtmZcGOYabQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-eeqEe77QrA6auZxNHIp+1TzHQ0HBKf5V6c8zcaYZ134EJe1lCi+fjXATkNiEEfbG+e50nu02GLvUtmZcGOYabQ==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } hasBin: true dependencies: '@npmcli/git': 4.0.3 @@ -3968,20 +5596,29 @@ packages: dev: false /param-case/3.0.4: - resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + resolution: + { + integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==, + } dependencies: dot-case: 3.0.4 tslib: 2.4.1 dev: false /parse-github-url/1.0.2: - resolution: {integrity: sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==, + } + engines: { node: '>=0.10.0' } hasBin: true dev: false /parse-latin/5.0.1: - resolution: {integrity: sha512-b/K8ExXaWC9t34kKeDV8kGXBkXZ1HCSAZRYE7HR14eA1GlXX5L8iWhs8USJNhQU9q5ci413jCKF0gOyovvyRBg==} + resolution: + { + integrity: sha512-b/K8ExXaWC9t34kKeDV8kGXBkXZ1HCSAZRYE7HR14eA1GlXX5L8iWhs8USJNhQU9q5ci413jCKF0gOyovvyRBg==, + } dependencies: nlcst-to-string: 3.1.0 unist-util-modify-children: 3.1.0 @@ -3989,96 +5626,153 @@ packages: dev: false /parse5/6.0.1: - resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + resolution: + { + integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==, + } dev: false /pascal-case/3.1.2: - resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + resolution: + { + integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==, + } dependencies: no-case: 3.0.4 tslib: 2.4.1 dev: false /path-exists/4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, + } + engines: { node: '>=8' } /path-is-absolute/1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==, + } + engines: { node: '>=0.10.0' } /path-key/3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, + } + engines: { node: '>=8' } /path-key/4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==, + } + engines: { node: '>=12' } dev: false /path-parse/1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + resolution: + { + integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, + } /path-scurry/1.6.3: - resolution: {integrity: sha512-RAmB+n30SlN+HnNx6EbcpoDy9nwdpcGPnEKrJnu6GZoDWBdIjo1UQMVtW2ybtC7LC2oKLcMq8y5g8WnKLiod9g==} - engines: {node: '>=16 || 14 >=14.17'} + resolution: + { + integrity: sha512-RAmB+n30SlN+HnNx6EbcpoDy9nwdpcGPnEKrJnu6GZoDWBdIjo1UQMVtW2ybtC7LC2oKLcMq8y5g8WnKLiod9g==, + } + engines: { node: '>=16 || 14 >=14.17' } dependencies: lru-cache: 7.14.1 minipass: 4.2.5 dev: false /path-to-regexp/6.2.1: - resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} + resolution: + { + integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==, + } dev: false /path-type/4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==, + } + engines: { node: '>=8' } dev: false /picocolors/1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + resolution: + { + integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==, + } /picomatch/2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} + resolution: + { + integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, + } + engines: { node: '>=8.6' } /pify/2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==, + } + engines: { node: '>=0.10.0' } /pify/4.0.1: - resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==, + } + engines: { node: '>=6' } dev: false /pinkie-promise/2.0.1: - resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==, + } + engines: { node: '>=0.10.0' } dependencies: pinkie: 2.0.4 dev: true /pinkie/2.0.4: - resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==, + } + engines: { node: '>=0.10.0' } dev: true /pkg-dir/4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==, + } + engines: { node: '>=8' } dependencies: find-up: 4.1.0 /playwright-core/1.32.1: - resolution: {integrity: sha512-KZYUQC10mXD2Am1rGlidaalNGYk3LU1vZqqNk0gT4XPty1jOqgup8KDP8l2CUlqoNKhXM5IfGjWgW37xvGllBA==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-KZYUQC10mXD2Am1rGlidaalNGYk3LU1vZqqNk0gT4XPty1jOqgup8KDP8l2CUlqoNKhXM5IfGjWgW37xvGllBA==, + } + engines: { node: '>=14' } hasBin: true dev: true /postcss-import/14.1.0_postcss@8.4.21: - resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==} - engines: {node: '>=10.0.0'} + resolution: + { + integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==, + } + engines: { node: '>=10.0.0' } peerDependencies: postcss: ^8.0.0 dependencies: @@ -4088,8 +5782,11 @@ packages: resolve: 1.22.1 /postcss-js/4.0.0_postcss@8.4.21: - resolution: {integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==} - engines: {node: ^12 || ^14 || >= 16} + resolution: + { + integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==, + } + engines: { node: ^12 || ^14 || >= 16 } peerDependencies: postcss: ^8.3.3 dependencies: @@ -4097,8 +5794,11 @@ packages: postcss: 8.4.21 /postcss-load-config/3.1.4_postcss@8.4.21: - resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} - engines: {node: '>= 10'} + resolution: + { + integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==, + } + engines: { node: '>= 10' } peerDependencies: postcss: '>=8.0.9' ts-node: '>=9.0.0' @@ -4113,8 +5813,11 @@ packages: yaml: 1.10.2 /postcss-load-config/4.0.1_postcss@8.4.21: - resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==, + } + engines: { node: '>= 14' } peerDependencies: postcss: '>=8.0.9' ts-node: '>=9.0.0' @@ -4130,8 +5833,11 @@ packages: dev: false /postcss-nested/6.0.0_postcss@8.4.21: - resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==} - engines: {node: '>=12.0'} + resolution: + { + integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==, + } + engines: { node: '>=12.0' } peerDependencies: postcss: ^8.2.14 dependencies: @@ -4139,34 +5845,49 @@ packages: postcss-selector-parser: 6.0.11 /postcss-selector-parser/6.0.10: - resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==, + } + engines: { node: '>=4' } dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 dev: true /postcss-selector-parser/6.0.11: - resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==, + } + engines: { node: '>=4' } dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 /postcss-value-parser/4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + resolution: + { + integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==, + } /postcss/8.4.21: - resolution: {integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==} - engines: {node: ^10 || ^12 || >=14} + resolution: + { + integrity: sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==, + } + engines: { node: ^10 || ^12 || >=14 } dependencies: nanoid: 3.3.4 picocolors: 1.0.0 source-map-js: 1.0.2 /prebuild-install/7.1.1: - resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==, + } + engines: { node: '>=10' } hasBin: true dependencies: detect-libc: 2.0.1 @@ -4184,8 +5905,11 @@ packages: dev: false /preferred-pm/3.0.3: - resolution: {integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==, + } + engines: { node: '>=10' } dependencies: find-up: 5.0.0 find-yarn-workspace-root2: 1.2.16 @@ -4194,8 +5918,11 @@ packages: dev: false /prettier-plugin-astro/0.7.2: - resolution: {integrity: sha512-mmifnkG160BtC727gqoimoxnZT/dwr8ASxpoGGl6EHevhfblSOeu+pwH1LAm5Qu1MynizktztFujHHaijLCkww==} - engines: {node: ^14.15.0 || >=16.0.0, pnpm: '>=7.14.0'} + resolution: + { + integrity: sha512-mmifnkG160BtC727gqoimoxnZT/dwr8ASxpoGGl6EHevhfblSOeu+pwH1LAm5Qu1MynizktztFujHHaijLCkww==, + } + engines: { node: ^14.15.0 || >=16.0.0, pnpm: '>=7.14.0' } dependencies: '@astrojs/compiler': 0.31.3 prettier: 2.8.7 @@ -4204,8 +5931,11 @@ packages: dev: false /prettier-plugin-astro/0.8.0: - resolution: {integrity: sha512-kt9wk33J7HvFGwFaHb8piwy4zbUmabC8Nu+qCw493jhe96YkpjscqGBPy4nJ9TPy9pd7+kEx1zM81rp+MIdrXg==} - engines: {node: ^14.15.0 || >=16.0.0, pnpm: '>=7.14.0'} + resolution: + { + integrity: sha512-kt9wk33J7HvFGwFaHb8piwy4zbUmabC8Nu+qCw493jhe96YkpjscqGBPy4nJ9TPy9pd7+kEx1zM81rp+MIdrXg==, + } + engines: { node: ^14.15.0 || >=16.0.0, pnpm: '>=7.14.0' } dependencies: '@astrojs/compiler': 1.1.0 prettier: 2.8.7 @@ -4214,8 +5944,11 @@ packages: dev: true /prettier-plugin-tailwindcss/0.2.6_kb4gmvngxncp3puqxt3b6slppy: - resolution: {integrity: sha512-F+7XCl9RLF/LPrGdUMHWpsT6TM31JraonAUyE6eBmpqymFvDwyl0ETHsKFHP1NG+sEfv8bmKqnTxEbWQbHPlBA==} - engines: {node: '>=12.17.0'} + resolution: + { + integrity: sha512-F+7XCl9RLF/LPrGdUMHWpsT6TM31JraonAUyE6eBmpqymFvDwyl0ETHsKFHP1NG+sEfv8bmKqnTxEbWQbHPlBA==, + } + engines: { node: '>=12.17.0' } peerDependencies: '@ianvs/prettier-plugin-sort-imports': '*' '@prettier/plugin-php': '*' @@ -4270,27 +6003,42 @@ packages: dev: true /prettier/2.8.7: - resolution: {integrity: sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==} - engines: {node: '>=10.13.0'} + resolution: + { + integrity: sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==, + } + engines: { node: '>=10.13.0' } hasBin: true /prismjs/1.29.0: - resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==, + } + engines: { node: '>=6' } dev: false /proc-log/3.0.0: - resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dev: false /progress/2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==, + } + engines: { node: '>=0.4.0' } dev: false /promise-inflight/1.0.1: - resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} + resolution: + { + integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==, + } peerDependencies: bluebird: '*' peerDependenciesMeta: @@ -4299,60 +6047,90 @@ packages: dev: false /promise-retry/2.0.1: - resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==, + } + engines: { node: '>=10' } dependencies: err-code: 2.0.3 retry: 0.12.0 dev: false /prompts-ncu/2.5.1: - resolution: {integrity: sha512-Hdd7GgV7b76Yh9FP9HL1D9xqtJCJdVPpiM2vDtuoc8W1KfweJe15gutFYmxkq83ViFaagFM8K0UcPCQ/tZq8bA==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-Hdd7GgV7b76Yh9FP9HL1D9xqtJCJdVPpiM2vDtuoc8W1KfweJe15gutFYmxkq83ViFaagFM8K0UcPCQ/tZq8bA==, + } + engines: { node: '>= 6' } dependencies: kleur: 4.1.5 sisteransi: 1.0.5 dev: false /prompts/2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==, + } + engines: { node: '>= 6' } dependencies: kleur: 3.0.3 sisteransi: 1.0.5 dev: false /property-information/6.2.0: - resolution: {integrity: sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==} + resolution: + { + integrity: sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==, + } dev: false /proto-list/1.2.4: - resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + resolution: + { + integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==, + } dev: false /pump/3.0.0: - resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + resolution: + { + integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==, + } dependencies: end-of-stream: 1.4.4 once: 1.4.0 dev: false /pupa/3.1.0: - resolution: {integrity: sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==} - engines: {node: '>=12.20'} + resolution: + { + integrity: sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==, + } + engines: { node: '>=12.20' } dependencies: escape-goat: 4.0.0 dev: false /queue-microtask/1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + resolution: + { + integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, + } /quick-lru/5.1.1: - resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==, + } + engines: { node: '>=10' } /rc-config-loader/4.1.2: - resolution: {integrity: sha512-qKTnVWFl9OQYKATPzdfaZIbTxcHziQl92zYSxYC6umhOqyAsoj8H8Gq/+aFjAso68sBdjTz3A7omqeAkkF1MWg==} + resolution: + { + integrity: sha512-qKTnVWFl9OQYKATPzdfaZIbTxcHziQl92zYSxYC6umhOqyAsoj8H8Gq/+aFjAso68sBdjTz3A7omqeAkkF1MWg==, + } dependencies: debug: 4.3.4 js-yaml: 4.1.0 @@ -4363,7 +6141,10 @@ packages: dev: false /rc/1.2.8: - resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + resolution: + { + integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==, + } hasBin: true dependencies: deep-extend: 0.6.0 @@ -4373,21 +6154,30 @@ packages: dev: false /read-cache/1.0.0: - resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + resolution: + { + integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==, + } dependencies: pify: 2.3.0 /read-package-json-fast/3.0.2: - resolution: {integrity: sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: json-parse-even-better-errors: 3.0.0 npm-normalize-package-bin: 3.0.0 dev: false /read-package-json/6.0.0: - resolution: {integrity: sha512-b/9jxWJ8EwogJPpv99ma+QwtqB7FSl3+V6UXS7Aaay8/5VwMY50oIFooY1UKXMWpfNCM6T/PoGqa5GD1g9xf9w==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-b/9jxWJ8EwogJPpv99ma+QwtqB7FSl3+V6UXS7Aaay8/5VwMY50oIFooY1UKXMWpfNCM6T/PoGqa5GD1g9xf9w==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: glob: 8.0.3 json-parse-even-better-errors: 3.0.0 @@ -4396,8 +6186,11 @@ packages: dev: false /readable-stream/3.6.0: - resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==, + } + engines: { node: '>= 6' } dependencies: inherits: 2.0.4 string_decoder: 1.3.0 @@ -4405,27 +6198,39 @@ packages: dev: false /readdirp/3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} + resolution: + { + integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==, + } + engines: { node: '>=8.10.0' } dependencies: picomatch: 2.3.1 /registry-auth-token/5.0.1: - resolution: {integrity: sha512-UfxVOj8seK1yaIOiieV4FIP01vfBDLsY0H9sQzi9EbbUdJiuuBjJgLa1DpImXMNPnVkBD4eVxTEXcrZA6kfpJA==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-UfxVOj8seK1yaIOiieV4FIP01vfBDLsY0H9sQzi9EbbUdJiuuBjJgLa1DpImXMNPnVkBD4eVxTEXcrZA6kfpJA==, + } + engines: { node: '>=14' } dependencies: '@pnpm/npm-conf': 1.0.5 dev: false /registry-url/6.0.1: - resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==, + } + engines: { node: '>=12' } dependencies: rc: 1.2.8 dev: false /rehype-external-links/2.0.1: - resolution: {integrity: sha512-u2dNypma+ps12SJWlS23zvbqwNx0Hl24t0YHXSM/6FCZj/pqWETCO3WyyrvALv4JYvRtuPjhiv2Lpen15ESqbA==} + resolution: + { + integrity: sha512-u2dNypma+ps12SJWlS23zvbqwNx0Hl24t0YHXSM/6FCZj/pqWETCO3WyyrvALv4JYvRtuPjhiv2Lpen15ESqbA==, + } dependencies: '@types/hast': 2.3.4 extend: 3.0.2 @@ -4436,7 +6241,10 @@ packages: dev: false /rehype-parse/8.0.4: - resolution: {integrity: sha512-MJJKONunHjoTh4kc3dsM1v3C9kGrrxvA3U8PxZlP2SjH8RNUSrb+lF7Y0KVaUDnGH2QZ5vAn7ulkiajM9ifuqg==} + resolution: + { + integrity: sha512-MJJKONunHjoTh4kc3dsM1v3C9kGrrxvA3U8PxZlP2SjH8RNUSrb+lF7Y0KVaUDnGH2QZ5vAn7ulkiajM9ifuqg==, + } dependencies: '@types/hast': 2.3.4 hast-util-from-parse5: 7.1.0 @@ -4445,7 +6253,10 @@ packages: dev: false /rehype-raw/6.1.1: - resolution: {integrity: sha512-d6AKtisSRtDRX4aSPsJGTfnzrX2ZkHQLE5kiUuGOeEoLpbEulFF4hj0mLPbsa+7vmguDKOVVEQdHKDSwoaIDsQ==} + resolution: + { + integrity: sha512-d6AKtisSRtDRX4aSPsJGTfnzrX2ZkHQLE5kiUuGOeEoLpbEulFF4hj0mLPbsa+7vmguDKOVVEQdHKDSwoaIDsQ==, + } dependencies: '@types/hast': 2.3.4 hast-util-raw: 7.2.3 @@ -4453,7 +6264,10 @@ packages: dev: false /rehype-stringify/9.0.3: - resolution: {integrity: sha512-kWiZ1bgyWlgOxpqD5HnxShKAdXtb2IUljn3hQAhySeak6IOQPPt6DeGnsIh4ixm7yKJWzm8TXFuC/lPfcWHJqw==} + resolution: + { + integrity: sha512-kWiZ1bgyWlgOxpqD5HnxShKAdXtb2IUljn3hQAhySeak6IOQPPt6DeGnsIh4ixm7yKJWzm8TXFuC/lPfcWHJqw==, + } dependencies: '@types/hast': 2.3.4 hast-util-to-html: 8.0.3 @@ -4461,7 +6275,10 @@ packages: dev: false /rehype/12.0.1: - resolution: {integrity: sha512-ey6kAqwLM3X6QnMDILJthGvG1m1ULROS9NT4uG9IDCuv08SFyLlreSuvOa//DgEvbXx62DS6elGVqusWhRUbgw==} + resolution: + { + integrity: sha512-ey6kAqwLM3X6QnMDILJthGvG1m1ULROS9NT4uG9IDCuv08SFyLlreSuvOa//DgEvbXx62DS6elGVqusWhRUbgw==, + } dependencies: '@types/hast': 2.3.4 rehype-parse: 8.0.4 @@ -4470,12 +6287,18 @@ packages: dev: false /relateurl/0.2.7: - resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} - engines: {node: '>= 0.10'} + resolution: + { + integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==, + } + engines: { node: '>= 0.10' } dev: false /remark-gfm/3.0.1: - resolution: {integrity: sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==} + resolution: + { + integrity: sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==, + } dependencies: '@types/mdast': 3.0.10 mdast-util-gfm: 2.0.1 @@ -4486,7 +6309,10 @@ packages: dev: false /remark-parse/10.0.1: - resolution: {integrity: sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw==} + resolution: + { + integrity: sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw==, + } dependencies: '@types/mdast': 3.0.10 mdast-util-from-markdown: 1.2.0 @@ -4496,7 +6322,10 @@ packages: dev: false /remark-rehype/10.1.0: - resolution: {integrity: sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==} + resolution: + { + integrity: sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==, + } dependencies: '@types/hast': 2.3.4 '@types/mdast': 3.0.10 @@ -4505,8 +6334,11 @@ packages: dev: false /remark-smartypants/2.0.0: - resolution: {integrity: sha512-Rc0VDmr/yhnMQIz8n2ACYXlfw/P/XZev884QU1I5u+5DgJls32o97Vc1RbK3pfumLsJomS2yy8eT4Fxj/2MDVA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-Rc0VDmr/yhnMQIz8n2ACYXlfw/P/XZev884QU1I5u+5DgJls32o97Vc1RbK3pfumLsJomS2yy8eT4Fxj/2MDVA==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } dependencies: retext: 8.1.0 retext-smartypants: 5.2.0 @@ -4514,21 +6346,33 @@ packages: dev: false /remote-git-tags/3.0.0: - resolution: {integrity: sha512-C9hAO4eoEsX+OXA4rla66pXZQ+TLQ8T9dttgQj18yuKlPMTVkIkdYXvlMC55IuUsIkV6DpmQYi10JKFLaU+l7w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-C9hAO4eoEsX+OXA4rla66pXZQ+TLQ8T9dttgQj18yuKlPMTVkIkdYXvlMC55IuUsIkV6DpmQYi10JKFLaU+l7w==, + } + engines: { node: '>=8' } dev: false /require-from-string/2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==, + } + engines: { node: '>=0.10.0' } dev: false /resolve-alpn/1.2.1: - resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + resolution: + { + integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==, + } dev: false /resolve/1.22.1: - resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + resolution: + { + integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==, + } hasBin: true dependencies: is-core-module: 2.11.0 @@ -4536,22 +6380,31 @@ packages: supports-preserve-symlinks-flag: 1.0.0 /responselike/3.0.0: - resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} - engines: {node: '>=14.16'} + resolution: + { + integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==, + } + engines: { node: '>=14.16' } dependencies: lowercase-keys: 3.0.0 dev: false /restore-cursor/4.0.0: - resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } dependencies: onetime: 5.1.2 signal-exit: 3.0.7 dev: false /retext-latin/3.1.0: - resolution: {integrity: sha512-5MrD1tuebzO8ppsja5eEu+ZbBeUNCjoEarn70tkXOS7Bdsdf6tNahsv2bY0Z8VooFF6cw7/6S+d3yI/TMlMVVQ==} + resolution: + { + integrity: sha512-5MrD1tuebzO8ppsja5eEu+ZbBeUNCjoEarn70tkXOS7Bdsdf6tNahsv2bY0Z8VooFF6cw7/6S+d3yI/TMlMVVQ==, + } dependencies: '@types/nlcst': 1.0.0 parse-latin: 5.0.1 @@ -4560,7 +6413,10 @@ packages: dev: false /retext-smartypants/5.2.0: - resolution: {integrity: sha512-Do8oM+SsjrbzT2UNIKgheP0hgUQTDDQYyZaIY3kfq0pdFzoPk+ZClYJ+OERNXveog4xf1pZL4PfRxNoVL7a/jw==} + resolution: + { + integrity: sha512-Do8oM+SsjrbzT2UNIKgheP0hgUQTDDQYyZaIY3kfq0pdFzoPk+ZClYJ+OERNXveog4xf1pZL4PfRxNoVL7a/jw==, + } dependencies: '@types/nlcst': 1.0.0 nlcst-to-string: 3.1.0 @@ -4569,7 +6425,10 @@ packages: dev: false /retext-stringify/3.1.0: - resolution: {integrity: sha512-767TLOaoXFXyOnjx/EggXlb37ZD2u4P1n0GJqVdpipqACsQP+20W+BNpMYrlJkq7hxffnFk+jc6mAK9qrbuB8w==} + resolution: + { + integrity: sha512-767TLOaoXFXyOnjx/EggXlb37ZD2u4P1n0GJqVdpipqACsQP+20W+BNpMYrlJkq7hxffnFk+jc6mAK9qrbuB8w==, + } dependencies: '@types/nlcst': 1.0.0 nlcst-to-string: 3.1.0 @@ -4577,7 +6436,10 @@ packages: dev: false /retext/8.1.0: - resolution: {integrity: sha512-N9/Kq7YTn6ZpzfiGW45WfEGJqFf1IM1q8OsRa1CGzIebCJBNCANDRmOrholiDRGKo/We7ofKR4SEvcGAWEMD3Q==} + resolution: + { + integrity: sha512-N9/Kq7YTn6ZpzfiGW45WfEGJqFf1IM1q8OsRa1CGzIebCJBNCANDRmOrholiDRGKo/We7ofKR4SEvcGAWEMD3Q==, + } dependencies: '@types/nlcst': 1.0.0 retext-latin: 3.1.0 @@ -4586,116 +6448,179 @@ packages: dev: false /retry/0.12.0: - resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} - engines: {node: '>= 4'} + resolution: + { + integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==, + } + engines: { node: '>= 4' } dev: false /reusify/1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + resolution: + { + integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==, + } + engines: { iojs: '>=1.0.0', node: '>=0.10.0' } /rimraf/3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + resolution: + { + integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==, + } hasBin: true dependencies: glob: 7.2.3 dev: false /rimraf/4.4.1: - resolution: {integrity: sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==, + } + engines: { node: '>=14' } hasBin: true dependencies: glob: 9.3.2 dev: false /roadmap-renderer/1.0.4: - resolution: {integrity: sha512-TS9jDZu/CzTqxv7QWnMZHgB89WzgLpaExXKcBIWQEKtXm9g9E45t7gijZst9qtRQ2E2+iplAxQz/eMuttq4wAQ==} + resolution: + { + integrity: sha512-TS9jDZu/CzTqxv7QWnMZHgB89WzgLpaExXKcBIWQEKtXm9g9E45t7gijZst9qtRQ2E2+iplAxQz/eMuttq4wAQ==, + } dev: false /rollup/3.14.0: - resolution: {integrity: sha512-o23sdgCLcLSe3zIplT9nQ1+r97okuaiR+vmAPZPTDYB7/f3tgWIYNyiQveMsZwshBT0is4eGax/HH83Q7CG+/Q==} - engines: {node: '>=14.18.0', npm: '>=8.0.0'} + resolution: + { + integrity: sha512-o23sdgCLcLSe3zIplT9nQ1+r97okuaiR+vmAPZPTDYB7/f3tgWIYNyiQveMsZwshBT0is4eGax/HH83Q7CG+/Q==, + } + engines: { node: '>=14.18.0', npm: '>=8.0.0' } hasBin: true optionalDependencies: fsevents: 2.3.2 dev: false /run-parallel/1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + resolution: + { + integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, + } dependencies: queue-microtask: 1.2.3 /s.color/0.0.15: - resolution: {integrity: sha512-AUNrbEUHeKY8XsYr/DYpl+qk5+aM+DChopnWOPEzn8YKzOhv4l2zH6LzZms3tOZP3wwdOyc0RmTciyi46HLIuA==} + resolution: + { + integrity: sha512-AUNrbEUHeKY8XsYr/DYpl+qk5+aM+DChopnWOPEzn8YKzOhv4l2zH6LzZms3tOZP3wwdOyc0RmTciyi46HLIuA==, + } /sade/1.8.1: - resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==, + } + engines: { node: '>=6' } dependencies: mri: 1.2.0 dev: false /safe-buffer/5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + resolution: + { + integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==, + } dev: false /safer-buffer/2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + resolution: + { + integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==, + } dev: false optional: true /sass-formatter/0.7.5: - resolution: {integrity: sha512-NKFP8ddjhUYi6A/iD1cEtzkEs91U61kzqe3lY9SVNuvX7LGc88xnEN0mmsWL7Ol//YTi2GL/ol7b9XZ2+hgXuA==} + resolution: + { + integrity: sha512-NKFP8ddjhUYi6A/iD1cEtzkEs91U61kzqe3lY9SVNuvX7LGc88xnEN0mmsWL7Ol//YTi2GL/ol7b9XZ2+hgXuA==, + } dependencies: suf-log: 2.5.3 /sax/1.2.4: - resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} + resolution: + { + integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==, + } dev: false /section-matter/1.0.0: - resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==, + } + engines: { node: '>=4' } dependencies: extend-shallow: 2.0.1 kind-of: 6.0.3 dev: false /semver-diff/4.0.0: - resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==, + } + engines: { node: '>=12' } dependencies: semver: 7.3.8 dev: false /semver-utils/1.1.4: - resolution: {integrity: sha512-EjnoLE5OGmDAVV/8YDoN5KiajNadjzIp9BAHOhYeQHt7j0UWxjmgsx4YD48wp4Ue1Qogq38F1GNUJNqF1kKKxA==} + resolution: + { + integrity: sha512-EjnoLE5OGmDAVV/8YDoN5KiajNadjzIp9BAHOhYeQHt7j0UWxjmgsx4YD48wp4Ue1Qogq38F1GNUJNqF1kKKxA==, + } dev: false /semver/6.3.0: - resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + resolution: + { + integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==, + } hasBin: true /semver/7.3.8: - resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==, + } + engines: { node: '>=10' } hasBin: true dependencies: lru-cache: 6.0.0 dev: false /server-destroy/1.0.1: - resolution: {integrity: sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==} + resolution: + { + integrity: sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==, + } dev: false /set-blocking/2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + resolution: + { + integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==, + } dev: false /sharp/0.31.3: - resolution: {integrity: sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==} - engines: {node: '>=14.15.0'} + resolution: + { + integrity: sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==, + } + engines: { node: '>=14.15.0' } requiresBuild: true dependencies: color: 4.2.3 @@ -4709,17 +6634,26 @@ packages: dev: false /shebang-command/2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, + } + engines: { node: '>=8' } dependencies: shebang-regex: 3.0.0 /shebang-regex/3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, + } + engines: { node: '>=8' } /shiki/0.11.1: - resolution: {integrity: sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA==} + resolution: + { + integrity: sha512-EugY9VASFuDqOexOgXR18ZV+TbFrQHeCpEYaXamO+SZlsnT/2LxuLBX25GGtIrwaEVFXUAbUQ601SWE2rMwWHA==, + } dependencies: jsonc-parser: 3.2.0 vscode-oniguruma: 1.7.0 @@ -4727,12 +6661,18 @@ packages: dev: false /signal-exit/3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + resolution: + { + integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, + } dev: false /sigstore/1.0.0: - resolution: {integrity: sha512-e+qfbn/zf1+rCza/BhIA//Awmf0v1pa5HQS8Xk8iXrn9bgytytVLqYD0P7NSqZ6IELTgq+tcDvLPkQjNHyWLNg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-e+qfbn/zf1+rCza/BhIA//Awmf0v1pa5HQS8Xk8iXrn9bgytytVLqYD0P7NSqZ6IELTgq+tcDvLPkQjNHyWLNg==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } hasBin: true dependencies: make-fetch-happen: 11.0.2 @@ -4743,11 +6683,17 @@ packages: dev: false /simple-concat/1.0.1: - resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + resolution: + { + integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==, + } dev: false /simple-get/4.0.1: - resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + resolution: + { + integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==, + } dependencies: decompress-response: 6.0.0 once: 1.4.0 @@ -4755,18 +6701,27 @@ packages: dev: false /simple-swizzle/0.2.2: - resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + resolution: + { + integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==, + } dependencies: is-arrayish: 0.3.2 dev: false /sisteransi/1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + resolution: + { + integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==, + } dev: false /sitemap/7.1.1: - resolution: {integrity: sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==} - engines: {node: '>=12.0.0', npm: '>=5.6.0'} + resolution: + { + integrity: sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==, + } + engines: { node: '>=12.0.0', npm: '>=5.6.0' } hasBin: true dependencies: '@types/node': 17.0.45 @@ -4776,23 +6731,35 @@ packages: dev: false /slash/3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==, + } + engines: { node: '>=8' } dev: false /slash/4.0.0: - resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==, + } + engines: { node: '>=12' } dev: false /smart-buffer/4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + resolution: + { + integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==, + } + engines: { node: '>= 6.0.0', npm: '>= 3.0.0' } dev: false /socks-proxy-agent/7.0.0: - resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} - engines: {node: '>= 10'} + resolution: + { + integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==, + } + engines: { node: '>= 10' } dependencies: agent-base: 6.0.2 debug: 4.3.4 @@ -4802,93 +6769,141 @@ packages: dev: false /socks/2.7.1: - resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} - engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} + resolution: + { + integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==, + } + engines: { node: '>= 10.13.0', npm: '>= 3.0.0' } dependencies: ip: 2.0.0 smart-buffer: 4.2.0 dev: false /source-map-js/1.0.2: - resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==, + } + engines: { node: '>=0.10.0' } /source-map-support/0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + resolution: + { + integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==, + } dependencies: buffer-from: 1.1.2 source-map: 0.6.1 dev: false /source-map/0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, + } + engines: { node: '>=0.10.0' } dev: false /source-map/0.7.4: - resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==, + } + engines: { node: '>= 8' } dev: false /space-separated-tokens/2.0.2: - resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + resolution: + { + integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==, + } dev: false /spawn-please/2.0.1: - resolution: {integrity: sha512-W+cFbZR2q2mMTfjz5ZGvhBAiX+e/zczFCNlbS9mxiSdYswBXwUuBUT+a0urH+xZZa8f/bs0mXHyZsZHR9hKogA==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-W+cFbZR2q2mMTfjz5ZGvhBAiX+e/zczFCNlbS9mxiSdYswBXwUuBUT+a0urH+xZZa8f/bs0mXHyZsZHR9hKogA==, + } + engines: { node: '>=14' } dependencies: cross-spawn: 7.0.3 dev: false /spdx-correct/3.1.1: - resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} + resolution: + { + integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==, + } dependencies: spdx-expression-parse: 3.0.1 spdx-license-ids: 3.0.12 dev: false /spdx-exceptions/2.3.0: - resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + resolution: + { + integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==, + } dev: false /spdx-expression-parse/3.0.1: - resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + resolution: + { + integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==, + } dependencies: spdx-exceptions: 2.3.0 spdx-license-ids: 3.0.12 dev: false /spdx-license-ids/3.0.12: - resolution: {integrity: sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==} + resolution: + { + integrity: sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==, + } dev: false /sprintf-js/1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + resolution: + { + integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, + } dev: false /ssri/10.0.1: - resolution: {integrity: sha512-WVy6di9DlPOeBWEjMScpNipeSX2jIZBGEn5Uuo8Q7aIuFEuDX0pw8RxcOjlD1TWP4obi24ki7m/13+nFpcbXrw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-WVy6di9DlPOeBWEjMScpNipeSX2jIZBGEn5Uuo8Q7aIuFEuDX0pw8RxcOjlD1TWP4obi24ki7m/13+nFpcbXrw==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: minipass: 4.0.0 dev: false /ssri/9.0.1: - resolution: {integrity: sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + resolution: + { + integrity: sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } dependencies: minipass: 3.3.6 dev: false /streamsearch/1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} + resolution: + { + integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==, + } + engines: { node: '>=10.0.0' } dev: false /string-width/4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, + } + engines: { node: '>=8' } dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 @@ -4896,8 +6911,11 @@ packages: dev: false /string-width/5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==, + } + engines: { node: '>=12' } dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 @@ -4905,107 +6923,161 @@ packages: dev: false /string_decoder/1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + resolution: + { + integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==, + } dependencies: safe-buffer: 5.2.1 dev: false /stringify-entities/4.0.3: - resolution: {integrity: sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==} + resolution: + { + integrity: sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==, + } dependencies: character-entities-html4: 2.1.0 character-entities-legacy: 3.0.0 dev: false /strip-ansi/6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, + } + engines: { node: '>=8' } dependencies: ansi-regex: 5.0.1 dev: false /strip-ansi/7.0.1: - resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==, + } + engines: { node: '>=12' } dependencies: ansi-regex: 6.0.1 dev: false /strip-bom-string/1.0.0: - resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==, + } + engines: { node: '>=0.10.0' } dev: false /strip-bom/3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==, + } + engines: { node: '>=4' } dev: false /strip-bom/4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==, + } + engines: { node: '>=8' } dev: false /strip-final-newline/3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==, + } + engines: { node: '>=12' } dev: false /strip-json-comments/2.0.1: - resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==, + } + engines: { node: '>=0.10.0' } dev: false /strip-json-comments/5.0.0: - resolution: {integrity: sha512-V1LGY4UUo0jgwC+ELQ2BNWfPa17TIuwBLg+j1AA/9RPzKINl1lhxVEu2r+ZTTO8aetIsUzE5Qj6LMSBkoGYKKw==} - engines: {node: '>=14.16'} + resolution: + { + integrity: sha512-V1LGY4UUo0jgwC+ELQ2BNWfPa17TIuwBLg+j1AA/9RPzKINl1lhxVEu2r+ZTTO8aetIsUzE5Qj6LMSBkoGYKKw==, + } + engines: { node: '>=14.16' } dev: false /strip-outer/1.0.1: - resolution: {integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==, + } + engines: { node: '>=0.10.0' } dependencies: escape-string-regexp: 1.0.5 dev: true /style-to-object/0.3.0: - resolution: {integrity: sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==} + resolution: + { + integrity: sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==, + } dependencies: inline-style-parser: 0.1.1 dev: false /suf-log/2.5.3: - resolution: {integrity: sha512-KvC8OPjzdNOe+xQ4XWJV2whQA0aM1kGVczMQ8+dStAO6KfEB140JEVQ9dE76ONZ0/Ylf67ni4tILPJB41U0eow==} + resolution: + { + integrity: sha512-KvC8OPjzdNOe+xQ4XWJV2whQA0aM1kGVczMQ8+dStAO6KfEB140JEVQ9dE76ONZ0/Ylf67ni4tILPJB41U0eow==, + } dependencies: s.color: 0.0.15 /supports-color/5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==, + } + engines: { node: '>=4' } dependencies: has-flag: 3.0.0 dev: false /supports-color/7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, + } + engines: { node: '>=8' } dependencies: has-flag: 4.0.0 dev: false /supports-esm/1.0.0: - resolution: {integrity: sha512-96Am8CDqUaC0I2+C/swJ0yEvM8ZnGn4unoers/LSdE4umhX7mELzqyLzx3HnZAluq5PXIsGMKqa7NkqaeHMPcg==} + resolution: + { + integrity: sha512-96Am8CDqUaC0I2+C/swJ0yEvM8ZnGn4unoers/LSdE4umhX7mELzqyLzx3HnZAluq5PXIsGMKqa7NkqaeHMPcg==, + } dependencies: has-package-exports: 1.3.0 dev: false /supports-preserve-symlinks-flag/1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, + } + engines: { node: '>= 0.4' } /svgo/3.0.2: - resolution: {integrity: sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==} - engines: {node: '>=14.0.0'} + resolution: + { + integrity: sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==, + } + engines: { node: '>=14.0.0' } hasBin: true dependencies: '@trysound/sax': 0.2.0 @@ -5017,15 +7089,21 @@ packages: dev: false /synckit/0.8.4: - resolution: {integrity: sha512-Dn2ZkzMdSX827QbowGbU/4yjWuvNaCoScLLoMo/yKbu+P4GBR6cRGKZH27k6a9bRzdqcyd1DE96pQtQ6uNkmyw==} - engines: {node: ^14.18.0 || >=16.0.0} + resolution: + { + integrity: sha512-Dn2ZkzMdSX827QbowGbU/4yjWuvNaCoScLLoMo/yKbu+P4GBR6cRGKZH27k6a9bRzdqcyd1DE96pQtQ6uNkmyw==, + } + engines: { node: ^14.18.0 || >=16.0.0 } dependencies: '@pkgr/utils': 2.3.1 tslib: 2.4.1 /tailwindcss/3.2.7_postcss@8.4.21: - resolution: {integrity: sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==} - engines: {node: '>=12.13.0'} + resolution: + { + integrity: sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==, + } + engines: { node: '>=12.13.0' } hasBin: true peerDependencies: postcss: ^8.0.9 @@ -5057,7 +7135,10 @@ packages: - ts-node /tar-fs/2.1.1: - resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} + resolution: + { + integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==, + } dependencies: chownr: 1.1.4 mkdirp-classic: 0.5.3 @@ -5066,8 +7147,11 @@ packages: dev: false /tar-stream/2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==, + } + engines: { node: '>=6' } dependencies: bl: 4.1.0 end-of-stream: 1.4.4 @@ -5077,8 +7161,11 @@ packages: dev: false /tar/6.1.13: - resolution: {integrity: sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==, + } + engines: { node: '>=10' } dependencies: chownr: 2.0.0 fs-minipass: 2.1.0 @@ -5089,8 +7176,11 @@ packages: dev: false /terser/5.16.5: - resolution: {integrity: sha512-qcwfg4+RZa3YvlFh0qjifnzBHjKGNbtDo9yivMqMFDy9Q6FSaQWSB/j1xKhsoUFJIqDOM3TsN6D5xbrMrFcHbg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-qcwfg4+RZa3YvlFh0qjifnzBHjKGNbtDo9yivMqMFDy9Q6FSaQWSB/j1xKhsoUFJIqDOM3TsN6D5xbrMrFcHbg==, + } + engines: { node: '>=10' } hasBin: true dependencies: '@jridgewell/source-map': 0.3.2 @@ -5100,39 +7190,60 @@ packages: dev: false /tiny-glob/0.2.9: - resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} + resolution: + { + integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==, + } dependencies: globalyzer: 0.1.0 globrex: 0.1.2 /to-fast-properties/2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==, + } + engines: { node: '>=4' } dev: false /to-regex-range/5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + resolution: + { + integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, + } + engines: { node: '>=8.0' } dependencies: is-number: 7.0.0 /trim-lines/3.0.1: - resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + resolution: + { + integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==, + } dev: false /trim-repeated/1.0.0: - resolution: {integrity: sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==, + } + engines: { node: '>=0.10.0' } dependencies: escape-string-regexp: 1.0.5 dev: true /trough/2.1.0: - resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} + resolution: + { + integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==, + } dev: false /tsconfig-resolver/3.0.1: - resolution: {integrity: sha512-ZHqlstlQF449v8glscGRXzL6l2dZvASPCdXJRWG4gHEZlUVx2Jtmr+a2zeVG4LCsKhDXKRj5R3h0C/98UcVAQg==} + resolution: + { + integrity: sha512-ZHqlstlQF449v8glscGRXzL6l2dZvASPCdXJRWG4gHEZlUVx2Jtmr+a2zeVG4LCsKhDXKRj5R3h0C/98UcVAQg==, + } dependencies: '@types/json5': 0.0.30 '@types/resolve': 1.20.2 @@ -5143,11 +7254,17 @@ packages: dev: false /tslib/2.4.1: - resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} + resolution: + { + integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==, + } /tuf-js/1.0.0: - resolution: {integrity: sha512-1dxsQwESDzACJjTdYHQ4wJ1f/of7jALWKfJEHSBWUQB/5UTJUx9SW6GHXp4mZ1KvdBRJCpGjssoPFGi4hvw8/A==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-1dxsQwESDzACJjTdYHQ4wJ1f/of7jALWKfJEHSBWUQB/5UTJUx9SW6GHXp4mZ1KvdBRJCpGjssoPFGi4hvw8/A==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: make-fetch-happen: 11.0.2 minimatch: 6.2.0 @@ -5157,55 +7274,85 @@ packages: dev: false /tunnel-agent/0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + resolution: + { + integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==, + } dependencies: safe-buffer: 5.2.1 dev: false /type-fest/0.13.1: - resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==, + } + engines: { node: '>=10' } dev: false /type-fest/1.4.0: - resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==, + } + engines: { node: '>=10' } dev: false /type-fest/2.19.0: - resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} - engines: {node: '>=12.20'} + resolution: + { + integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==, + } + engines: { node: '>=12.20' } dev: false /typedarray-to-buffer/3.1.5: - resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + resolution: + { + integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==, + } dependencies: is-typedarray: 1.0.0 dev: false /typescript/4.9.4: - resolution: {integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==} - engines: {node: '>=4.2.0'} + resolution: + { + integrity: sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==, + } + engines: { node: '>=4.2.0' } hasBin: true dev: false /uc.micro/1.0.6: - resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} + resolution: + { + integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==, + } dev: true /undici/5.20.0: - resolution: {integrity: sha512-J3j60dYzuo6Eevbawwp1sdg16k5Tf768bxYK4TUJRH7cBM4kFCbf3mOnM/0E3vQYXvpxITbbWmBafaDbxLDz3g==} - engines: {node: '>=12.18'} + resolution: + { + integrity: sha512-J3j60dYzuo6Eevbawwp1sdg16k5Tf768bxYK4TUJRH7cBM4kFCbf3mOnM/0E3vQYXvpxITbbWmBafaDbxLDz3g==, + } + engines: { node: '>=12.18' } dependencies: busboy: 1.6.0 dev: false /unherit/3.0.1: - resolution: {integrity: sha512-akOOQ/Yln8a2sgcLj4U0Jmx0R5jpIg2IUyRrWOzmEbjBtGzBdHtSeFKgoEcoH4KYIG/Pb8GQ/BwtYm0GCq1Sqg==} + resolution: + { + integrity: sha512-akOOQ/Yln8a2sgcLj4U0Jmx0R5jpIg2IUyRrWOzmEbjBtGzBdHtSeFKgoEcoH4KYIG/Pb8GQ/BwtYm0GCq1Sqg==, + } dev: false /unified/10.1.2: - resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} + resolution: + { + integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==, + } dependencies: '@types/unist': 2.0.6 bail: 2.0.2 @@ -5217,88 +7364,130 @@ packages: dev: false /unique-filename/2.0.1: - resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + resolution: + { + integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } dependencies: unique-slug: 3.0.0 dev: false /unique-filename/3.0.0: - resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: unique-slug: 4.0.0 dev: false /unique-slug/3.0.0: - resolution: {integrity: sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + resolution: + { + integrity: sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==, + } + engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } dependencies: imurmurhash: 0.1.4 dev: false /unique-slug/4.0.0: - resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: imurmurhash: 0.1.4 dev: false /unique-string/3.0.0: - resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==, + } + engines: { node: '>=12' } dependencies: crypto-random-string: 4.0.0 dev: false /unist-builder/3.0.0: - resolution: {integrity: sha512-GFxmfEAa0vi9i5sd0R2kcrI9ks0r82NasRq5QHh2ysGngrc6GiqD5CDf1FjPenY4vApmFASBIIlk/jj5J5YbmQ==} + resolution: + { + integrity: sha512-GFxmfEAa0vi9i5sd0R2kcrI9ks0r82NasRq5QHh2ysGngrc6GiqD5CDf1FjPenY4vApmFASBIIlk/jj5J5YbmQ==, + } dependencies: '@types/unist': 2.0.6 dev: false /unist-util-generated/2.0.0: - resolution: {integrity: sha512-TiWE6DVtVe7Ye2QxOVW9kqybs6cZexNwTwSMVgkfjEReqy/xwGpAXb99OxktoWwmL+Z+Epb0Dn8/GNDYP1wnUw==} + resolution: + { + integrity: sha512-TiWE6DVtVe7Ye2QxOVW9kqybs6cZexNwTwSMVgkfjEReqy/xwGpAXb99OxktoWwmL+Z+Epb0Dn8/GNDYP1wnUw==, + } dev: false /unist-util-is/5.1.1: - resolution: {integrity: sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==} + resolution: + { + integrity: sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==, + } dev: false /unist-util-modify-children/3.1.0: - resolution: {integrity: sha512-L0UizdncPZ1NIwpmkwFdLo2NaK2Eb5LU/vaQ7lZGkAaOBZfsHp+8T/gVWPVmmMO1hj6gc+XeMoytut8jr7fdyA==} + resolution: + { + integrity: sha512-L0UizdncPZ1NIwpmkwFdLo2NaK2Eb5LU/vaQ7lZGkAaOBZfsHp+8T/gVWPVmmMO1hj6gc+XeMoytut8jr7fdyA==, + } dependencies: '@types/unist': 2.0.6 array-iterate: 2.0.1 dev: false /unist-util-position/4.0.3: - resolution: {integrity: sha512-p/5EMGIa1qwbXjA+QgcBXaPWjSnZfQ2Sc3yBEEfgPwsEmJd8Qh+DSk3LGnmOM4S1bY2C0AjmMnB8RuEYxpPwXQ==} + resolution: + { + integrity: sha512-p/5EMGIa1qwbXjA+QgcBXaPWjSnZfQ2Sc3yBEEfgPwsEmJd8Qh+DSk3LGnmOM4S1bY2C0AjmMnB8RuEYxpPwXQ==, + } dependencies: '@types/unist': 2.0.6 dev: false /unist-util-stringify-position/3.0.2: - resolution: {integrity: sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==} + resolution: + { + integrity: sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==, + } dependencies: '@types/unist': 2.0.6 dev: false /unist-util-visit-children/2.0.1: - resolution: {integrity: sha512-2cEU3dhV1hMfO9ajwb8rJsDedMfsahsm6fCfR8LxDR/w7KcB5lzHQ9dBTQIXsWGNWBFH5MPmaFP3Xh0dWLqClQ==} + resolution: + { + integrity: sha512-2cEU3dhV1hMfO9ajwb8rJsDedMfsahsm6fCfR8LxDR/w7KcB5lzHQ9dBTQIXsWGNWBFH5MPmaFP3Xh0dWLqClQ==, + } dependencies: '@types/unist': 2.0.6 dev: false /unist-util-visit-parents/5.1.1: - resolution: {integrity: sha512-gks4baapT/kNRaWxuGkl5BIhoanZo7sC/cUT/JToSRNL1dYoXRFl75d++NkjYk4TAu2uv2Px+l8guMajogeuiw==} + resolution: + { + integrity: sha512-gks4baapT/kNRaWxuGkl5BIhoanZo7sC/cUT/JToSRNL1dYoXRFl75d++NkjYk4TAu2uv2Px+l8guMajogeuiw==, + } dependencies: '@types/unist': 2.0.6 unist-util-is: 5.1.1 dev: false /unist-util-visit/4.1.1: - resolution: {integrity: sha512-n9KN3WV9k4h1DxYR1LoajgN93wpEi/7ZplVe02IoB4gH5ctI1AaF2670BLHQYbwj+pY83gFtyeySFiyMHJklrg==} + resolution: + { + integrity: sha512-n9KN3WV9k4h1DxYR1LoajgN93wpEi/7ZplVe02IoB4gH5ctI1AaF2670BLHQYbwj+pY83gFtyeySFiyMHJklrg==, + } dependencies: '@types/unist': 2.0.6 unist-util-is: 5.1.1 @@ -5306,17 +7495,26 @@ packages: dev: false /universalify/0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} + resolution: + { + integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==, + } + engines: { node: '>= 4.0.0' } dev: true /untildify/4.0.0: - resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==, + } + engines: { node: '>=8' } dev: false /update-browserslist-db/1.0.10_browserslist@4.21.4: - resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} + resolution: + { + integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==, + } hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -5327,8 +7525,11 @@ packages: dev: false /update-notifier/6.0.2: - resolution: {integrity: sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==} - engines: {node: '>=14.16'} + resolution: + { + integrity: sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==, + } + engines: { node: '>=14.16' } dependencies: boxen: 7.0.1 chalk: 5.2.0 @@ -5347,11 +7548,17 @@ packages: dev: false /util-deprecate/1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + resolution: + { + integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==, + } /uvu/0.5.6: - resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==, + } + engines: { node: '>=8' } hasBin: true dependencies: dequal: 2.0.3 @@ -5361,35 +7568,50 @@ packages: dev: false /validate-npm-package-license/3.0.4: - resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + resolution: + { + integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==, + } dependencies: spdx-correct: 3.1.1 spdx-expression-parse: 3.0.1 dev: false /validate-npm-package-name/5.0.0: - resolution: {integrity: sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } dependencies: builtins: 5.0.1 dev: false /vfile-location/4.0.1: - resolution: {integrity: sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==} + resolution: + { + integrity: sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==, + } dependencies: '@types/unist': 2.0.6 vfile: 5.3.6 dev: false /vfile-message/3.1.3: - resolution: {integrity: sha512-0yaU+rj2gKAyEk12ffdSbBfjnnj+b1zqTBv3OQCTn8yEB02bsPizwdBPrLJjHnK+cU9EMMcUnNv938XcZIkmdA==} + resolution: + { + integrity: sha512-0yaU+rj2gKAyEk12ffdSbBfjnnj+b1zqTBv3OQCTn8yEB02bsPizwdBPrLJjHnK+cU9EMMcUnNv938XcZIkmdA==, + } dependencies: '@types/unist': 2.0.6 unist-util-stringify-position: 3.0.2 dev: false /vfile/5.3.6: - resolution: {integrity: sha512-ADBsmerdGBs2WYckrLBEmuETSPyTD4TuLxTrw0DvjirxW1ra4ZwkbzG8ndsv3Q57smvHxo677MHaQrY9yxH8cA==} + resolution: + { + integrity: sha512-ADBsmerdGBs2WYckrLBEmuETSPyTD4TuLxTrw0DvjirxW1ra4ZwkbzG8ndsv3Q57smvHxo677MHaQrY9yxH8cA==, + } dependencies: '@types/unist': 2.0.6 is-buffer: 2.0.5 @@ -5398,8 +7620,11 @@ packages: dev: false /vite/4.1.4: - resolution: {integrity: sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==} - engines: {node: ^14.18.0 || >=16.0.0} + resolution: + { + integrity: sha512-3knk/HsbSTKEin43zHu7jTwYWv81f8kgAL99G5NWBcA1LKvtvcVAC4JjBH1arBunO9kQka+1oGbrMKOjk4ZrBg==, + } + engines: { node: ^14.18.0 || >=16.0.0 } hasBin: true peerDependencies: '@types/node': '>= 14' @@ -5431,7 +7656,10 @@ packages: dev: false /vitefu/0.2.4_vite@4.1.4: - resolution: {integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==} + resolution: + { + integrity: sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==, + } peerDependencies: vite: ^3.0.0 || ^4.0.0 peerDependenciesMeta: @@ -5442,7 +7670,10 @@ packages: dev: false /vscode-css-languageservice/6.2.1: - resolution: {integrity: sha512-FMaMjB2LQdkHjTCP2CWh2S94xuGsxSc8xr0H9nAACVd/iUDyZLoKFjwoB+mA3v0rpCH2U5vVCVwxyULy61CgqA==} + resolution: + { + integrity: sha512-FMaMjB2LQdkHjTCP2CWh2S94xuGsxSc8xr0H9nAACVd/iUDyZLoKFjwoB+mA3v0rpCH2U5vVCVwxyULy61CgqA==, + } dependencies: '@vscode/l10n': 0.0.10 vscode-languageserver-textdocument: 1.0.8 @@ -5451,7 +7682,10 @@ packages: dev: false /vscode-html-languageservice/5.0.3: - resolution: {integrity: sha512-6rfrtcHhXDMXmC5pR2WXrx02HiNCzQDynOBMn+53zLxr2hvZrDzoc0QgC0FaFGfcglf7GeOsfhkWvJBFC/a70g==} + resolution: + { + integrity: sha512-6rfrtcHhXDMXmC5pR2WXrx02HiNCzQDynOBMn+53zLxr2hvZrDzoc0QgC0FaFGfcglf7GeOsfhkWvJBFC/a70g==, + } dependencies: '@vscode/l10n': 0.0.10 vscode-languageserver-textdocument: 1.0.8 @@ -5460,102 +7694,156 @@ packages: dev: false /vscode-jsonrpc/8.0.2: - resolution: {integrity: sha512-RY7HwI/ydoC1Wwg4gJ3y6LpU9FJRZAUnTYMXthqhFXXu77ErDd/xkREpGuk4MyYkk4a+XDWAMqe0S3KkelYQEQ==} - engines: {node: '>=14.0.0'} + resolution: + { + integrity: sha512-RY7HwI/ydoC1Wwg4gJ3y6LpU9FJRZAUnTYMXthqhFXXu77ErDd/xkREpGuk4MyYkk4a+XDWAMqe0S3KkelYQEQ==, + } + engines: { node: '>=14.0.0' } dev: false /vscode-languageserver-protocol/3.17.2: - resolution: {integrity: sha512-8kYisQ3z/SQ2kyjlNeQxbkkTNmVFoQCqkmGrzLH6A9ecPlgTbp3wDTnUNqaUxYr4vlAcloxx8zwy7G5WdguYNg==} + resolution: + { + integrity: sha512-8kYisQ3z/SQ2kyjlNeQxbkkTNmVFoQCqkmGrzLH6A9ecPlgTbp3wDTnUNqaUxYr4vlAcloxx8zwy7G5WdguYNg==, + } dependencies: vscode-jsonrpc: 8.0.2 vscode-languageserver-types: 3.17.2 dev: false /vscode-languageserver-textdocument/1.0.8: - resolution: {integrity: sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q==} + resolution: + { + integrity: sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q==, + } dev: false /vscode-languageserver-types/3.17.2: - resolution: {integrity: sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA==} + resolution: + { + integrity: sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA==, + } dev: false /vscode-languageserver/8.0.2: - resolution: {integrity: sha512-bpEt2ggPxKzsAOZlXmCJ50bV7VrxwCS5BI4+egUmure/oI/t4OlFzi/YNtVvY24A2UDOZAgwFGgnZPwqSJubkA==} + resolution: + { + integrity: sha512-bpEt2ggPxKzsAOZlXmCJ50bV7VrxwCS5BI4+egUmure/oI/t4OlFzi/YNtVvY24A2UDOZAgwFGgnZPwqSJubkA==, + } hasBin: true dependencies: vscode-languageserver-protocol: 3.17.2 dev: false /vscode-oniguruma/1.7.0: - resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} + resolution: + { + integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==, + } dev: false /vscode-textmate/6.0.0: - resolution: {integrity: sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==} + resolution: + { + integrity: sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==, + } dev: false /vscode-uri/2.1.2: - resolution: {integrity: sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==} + resolution: + { + integrity: sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==, + } dev: false /vscode-uri/3.0.7: - resolution: {integrity: sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA==} + resolution: + { + integrity: sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA==, + } dev: false /wcwidth/1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + resolution: + { + integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==, + } dependencies: defaults: 1.0.4 dev: false /web-namespaces/2.0.1: - resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + resolution: + { + integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==, + } dev: false /which-pm-runs/1.1.0: - resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==, + } + engines: { node: '>=4' } dev: false /which-pm/2.0.0: - resolution: {integrity: sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==} - engines: {node: '>=8.15'} + resolution: + { + integrity: sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==, + } + engines: { node: '>=8.15' } dependencies: load-yaml-file: 0.2.0 path-exists: 4.0.0 dev: false /which/2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, + } + engines: { node: '>= 8' } hasBin: true dependencies: isexe: 2.0.0 /which/3.0.0: - resolution: {integrity: sha512-nla//68K9NU6yRiwDY/Q8aU6siKlSs64aEC7+IV56QoAuyQT2ovsJcgGYGyqMOmI/CGN1BOR6mM5EN0FBO+zyQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-nla//68K9NU6yRiwDY/Q8aU6siKlSs64aEC7+IV56QoAuyQT2ovsJcgGYGyqMOmI/CGN1BOR6mM5EN0FBO+zyQ==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } hasBin: true dependencies: isexe: 2.0.0 dev: false /wide-align/1.1.5: - resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + resolution: + { + integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==, + } dependencies: string-width: 4.2.3 dev: false /widest-line/4.0.1: - resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==, + } + engines: { node: '>=12' } dependencies: string-width: 5.1.2 dev: false /wrap-ansi/8.0.1: - resolution: {integrity: sha512-QFF+ufAqhoYHvoHdajT/Po7KoXVBPXS2bgjIam5isfWJPfIOnQZ50JtUiVvCv/sjgacf3yRrt2ZKUZ/V4itN4g==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-QFF+ufAqhoYHvoHdajT/Po7KoXVBPXS2bgjIam5isfWJPfIOnQZ50JtUiVvCv/sjgacf3yRrt2ZKUZ/V4itN4g==, + } + engines: { node: '>=12' } dependencies: ansi-styles: 6.2.1 string-width: 5.1.2 @@ -5563,10 +7851,16 @@ packages: dev: false /wrappy/1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + resolution: + { + integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, + } /write-file-atomic/3.0.3: - resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + resolution: + { + integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==, + } dependencies: imurmurhash: 0.1.4 is-typedarray: 1.0.0 @@ -5575,45 +7869,75 @@ packages: dev: false /xdg-basedir/5.1.0: - resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==, + } + engines: { node: '>=12' } dev: false /xtend/4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} + resolution: + { + integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==, + } + engines: { node: '>=0.4' } /yallist/3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + resolution: + { + integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, + } dev: false /yallist/4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + resolution: + { + integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==, + } dev: false /yaml/1.10.2: - resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==, + } + engines: { node: '>= 6' } /yaml/2.2.1: - resolution: {integrity: sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==, + } + engines: { node: '>= 14' } dev: false /yargs-parser/21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, + } + engines: { node: '>=12' } dev: false /yocto-queue/0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, + } + engines: { node: '>=10' } dev: false /zod/3.20.2: - resolution: {integrity: sha512-1MzNQdAvO+54H+EaK5YpyEy0T+Ejo/7YLHS93G3RnYWh5gaotGHwGeN/ZO687qEDU2y4CdStQYXVHIgrUl5UVQ==} + resolution: + { + integrity: sha512-1MzNQdAvO+54H+EaK5YpyEy0T+Ejo/7YLHS93G3RnYWh5gaotGHwGeN/ZO687qEDU2y4CdStQYXVHIgrUl5UVQ==, + } dev: false /zwitch/2.0.4: - resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + resolution: + { + integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==, + } dev: false diff --git a/sitemap.mjs b/sitemap.mjs index 41dcd1802..1a522e2bc 100644 --- a/sitemap.mjs +++ b/sitemap.mjs @@ -27,8 +27,13 @@ export async function serializeSitemap(item) { 'https://roadmap.sh/best-practices', 'https://roadmap.sh/guides', 'https://roadmap.sh/videos', - ...(await getRoadmapIds()).flatMap((id) => [`https://roadmap.sh/${id}`, `https://roadmap.sh/${id}/topics`]), - ...(await getBestPracticesIds()).map((id) => `https://roadmap.sh/best-practices/${id}`), + ...(await getRoadmapIds()).flatMap((id) => [ + `https://roadmap.sh/${id}`, + `https://roadmap.sh/${id}/topics`, + ]), + ...(await getBestPracticesIds()).map( + (id) => `https://roadmap.sh/best-practices/${id}` + ), ]; // Roadmaps and other high priority pages @@ -44,7 +49,10 @@ export async function serializeSitemap(item) { } // Guide and video pages - if (item.url.startsWith('https://roadmap.sh/guides') || item.url.startsWith('https://roadmap.sh/videos')) { + if ( + item.url.startsWith('https://roadmap.sh/guides') || + item.url.startsWith('https://roadmap.sh/videos') + ) { return { ...item, // @ts-ignore diff --git a/src/components/TopicOverlay/topic.js b/src/components/TopicOverlay/topic.js index bdb1663bc..1f2c625d9 100644 --- a/src/components/TopicOverlay/topic.js +++ b/src/components/TopicOverlay/topic.js @@ -15,9 +15,12 @@ export class Topic { this.activeTopicId = null; this.handleRoadmapTopicClick = this.handleRoadmapTopicClick.bind(this); - this.handleBestPracticeTopicClick = this.handleBestPracticeTopicClick.bind(this); - this.handleBestPracticeTopicToggle = this.handleBestPracticeTopicToggle.bind(this); - this.handleBestPracticeTopicPending = this.handleBestPracticeTopicPending.bind(this); + this.handleBestPracticeTopicClick = + this.handleBestPracticeTopicClick.bind(this); + this.handleBestPracticeTopicToggle = + this.handleBestPracticeTopicToggle.bind(this); + this.handleBestPracticeTopicPending = + this.handleBestPracticeTopicPending.bind(this); this.close = this.close.bind(this); this.resetDOM = this.resetDOM.bind(this); @@ -178,7 +181,10 @@ export class Topic { this.resetDOM(); - const topicUrl = `/best-practices/${bestPracticeId}/${topicId.replaceAll(':', '/')}`; + const topicUrl = `/best-practices/${bestPracticeId}/${topicId.replaceAll( + ':', + '/' + )}`; this.renderTopicFromUrl(topicUrl).then(() => null); } @@ -210,24 +216,30 @@ export class Topic { const matchingElements = []; // Elements having sort order in the beginning of the group id - document.querySelectorAll(`[data-group-id$="-${topicId}"]`).forEach((element) => { - const foundGroupId = element?.dataset?.groupId || ''; - const validGroupRegex = new RegExp(`^\\d+-${topicId}$`); - - if (validGroupRegex.test(foundGroupId)) { - matchingElements.push(element); - } - }); + document + .querySelectorAll(`[data-group-id$="-${topicId}"]`) + .forEach((element) => { + const foundGroupId = element?.dataset?.groupId || ''; + const validGroupRegex = new RegExp(`^\\d+-${topicId}$`); + + if (validGroupRegex.test(foundGroupId)) { + matchingElements.push(element); + } + }); // Elements with exact match of the topic id - document.querySelectorAll(`[data-group-id="${topicId}"]`).forEach((element) => { - matchingElements.push(element); - }); + document + .querySelectorAll(`[data-group-id="${topicId}"]`) + .forEach((element) => { + matchingElements.push(element); + }); // Matching "check:XXXX" box of the topic - document.querySelectorAll(`[data-group-id="check:${topicId}"]`).forEach((element) => { - matchingElements.push(element); - }); + document + .querySelectorAll(`[data-group-id="check:${topicId}"]`) + .forEach((element) => { + matchingElements.push(element); + }); return matchingElements; } @@ -258,29 +270,44 @@ export class Topic { return; } - const isClickedDone = e.target.id === this.markTopicDoneId || e.target.closest(`#${this.markTopicDoneId}`); + const isClickedDone = + e.target.id === this.markTopicDoneId || + e.target.closest(`#${this.markTopicDoneId}`); if (isClickedDone) { this.markAsDone(this.activeTopicId); this.close(); } - const isClickedPending = e.target.id === this.markTopicPendingId || e.target.closest(`#${this.markTopicPendingId}`); + const isClickedPending = + e.target.id === this.markTopicPendingId || + e.target.closest(`#${this.markTopicPendingId}`); if (isClickedPending) { this.markAsPending(this.activeTopicId); this.close(); } - const isClickedClose = e.target.id === this.closeTopicId || e.target.closest(`#${this.closeTopicId}`); + const isClickedClose = + e.target.id === this.closeTopicId || + e.target.closest(`#${this.closeTopicId}`); if (isClickedClose) { this.close(); } } init() { - window.addEventListener('best-practice.topic.click', this.handleBestPracticeTopicClick); - window.addEventListener('best-practice.topic.toggle', this.handleBestPracticeTopicToggle); - - window.addEventListener('roadmap.topic.click', this.handleRoadmapTopicClick); + window.addEventListener( + 'best-practice.topic.click', + this.handleBestPracticeTopicClick + ); + window.addEventListener( + 'best-practice.topic.toggle', + this.handleBestPracticeTopicToggle + ); + + window.addEventListener( + 'roadmap.topic.click', + this.handleRoadmapTopicClick + ); window.addEventListener('click', this.handleOverlayClick); window.addEventListener('contextmenu', this.rightClickListener); diff --git a/src/data/best-practices/api-security/api-security.md b/src/data/best-practices/api-security/api-security.md index fade3dc3b..8de036744 100644 --- a/src/data/best-practices/api-security/api-security.md +++ b/src/data/best-practices/api-security/api-security.md @@ -1,37 +1,36 @@ --- -jsonUrl: "/jsons/best-practices/api-security.json" -pdfUrl: "/pdfs/best-practices/api-security.pdf" +jsonUrl: '/jsons/best-practices/api-security.json' +pdfUrl: '/pdfs/best-practices/api-security.pdf' order: 2 -briefTitle: "API Security" -briefDescription: "API Security Best Practices" +briefTitle: 'API Security' +briefDescription: 'API Security Best Practices' isNew: true isUpcoming: false -title: "API Security Best Practices" -description: "Detailed list of best practices to make your APIs secure" +title: 'API Security Best Practices' +description: 'Detailed list of best practices to make your APIs secure' dimensions: width: 968 height: 1543.39 sponsor: - url: "https://www.getambassador.io/products/edge-stack-api-gateway?utm_source=roadmap-sh&utm_medium=edge-stack-page&utm_campaign=new-account" - title: "Featured Product" - imageUrl: "https://i.imgur.com/e5fdI0q.png" - description: "Get your Kubernetes API Gateway up and running in 5 minutes with Ambassador Edge Stack!" + url: 'https://www.getambassador.io/products/edge-stack-api-gateway?utm_source=roadmap-sh&utm_medium=edge-stack-page&utm_campaign=new-account' + title: 'Featured Product' + imageUrl: 'https://i.imgur.com/e5fdI0q.png' + description: 'Get your Kubernetes API Gateway up and running in 5 minutes with Ambassador Edge Stack!' event: - category: "SponsorClick" - action: "Ambassador Redirect" - label: "API Security / Ambassador Link" + category: 'SponsorClick' + action: 'Ambassador Redirect' + label: 'API Security / Ambassador Link' schema: - headline: "API Security Best Practices" - description: "Detailed list of best practices to make your APIs secure. Each best practice carries further details and how to implement that best practice." - imageUrl: "https://roadmap.sh/best-practices/api-security.png" - datePublished: "2023-02-21" - dateModified: "2023-02-21" + headline: 'API Security Best Practices' + description: 'Detailed list of best practices to make your APIs secure. Each best practice carries further details and how to implement that best practice.' + imageUrl: 'https://roadmap.sh/best-practices/api-security.png' + datePublished: '2023-02-21' + dateModified: '2023-02-21' seo: - title: "API Security Best Practices" - description: "Detailed list of best practices to make your APIs secure. Each best practice carries further details and how to implement that best practice." + title: 'API Security Best Practices' + description: 'Detailed list of best practices to make your APIs secure. Each best practice carries further details and how to implement that best practice.' keywords: - - "API Security" - - "API Security Best Practices" - - "API Security Checklist" + - 'API Security' + - 'API Security Best Practices' + - 'API Security Checklist' --- - diff --git a/src/data/best-practices/api-security/content/api-gateway.md b/src/data/best-practices/api-security/content/api-gateway.md index 514003072..32512b8c8 100644 --- a/src/data/best-practices/api-security/content/api-gateway.md +++ b/src/data/best-practices/api-security/content/api-gateway.md @@ -12,4 +12,4 @@ An API gateway can make your APIs more secure by providing a centralized point o - Logging and monitoring: An API gateway can provide centralized logging and monitoring of API traffic, helping to identify and respond to security threats and other issues. -- Integration with security tools: An API gateway can be integrated with security tools such as WAFs, SIEMs, and other security tools to provide additional layers of protection. \ No newline at end of file +- Integration with security tools: An API gateway can be integrated with security tools such as WAFs, SIEMs, and other security tools to provide additional layers of protection. diff --git a/src/data/best-practices/api-security/content/authentication-mechanisms.md b/src/data/best-practices/api-security/content/authentication-mechanisms.md index b66be0340..e31eedee3 100644 --- a/src/data/best-practices/api-security/content/authentication-mechanisms.md +++ b/src/data/best-practices/api-security/content/authentication-mechanisms.md @@ -12,4 +12,4 @@ Here are some examples of established authentication mechanisms that you can use - Password hashing algorithms: Password hashing algorithms like bcrypt and scrypt are widely used to securely store and protect user passwords. These algorithms ensure that even if an attacker gains access to the password database, they will not be able to easily recover the passwords. -- Two-factor authentication (2FA): 2FA is an authentication mechanism that requires users to provide two forms of identification to access their accounts. This typically involves something the user knows (like a password) and something the user has (like a mobile device or security key). Many services and applications now offer 2FA as an additional security measure. \ No newline at end of file +- Two-factor authentication (2FA): 2FA is an authentication mechanism that requires users to provide two forms of identification to access their accounts. This typically involves something the user knows (like a password) and something the user has (like a mobile device or security key). Many services and applications now offer 2FA as an additional security measure. diff --git a/src/data/best-practices/api-security/content/authorization-header.md b/src/data/best-practices/api-security/content/authorization-header.md index f88d07f13..e5fa9ca25 100644 --- a/src/data/best-practices/api-security/content/authorization-header.md +++ b/src/data/best-practices/api-security/content/authorization-header.md @@ -6,4 +6,4 @@ Sending tokens in the query or body parameters is generally not recommended beca Additionally, sending tokens in query or body parameters can make them more vulnerable to cross-site request forgery (CSRF) attacks. In a CSRF attack, an attacker can trick a user into submitting a request that includes their authentication token, which the attacker can then use to impersonate the user and gain access to their account. -By contrast, using the `Authorization` header to send tokens helps to ensure that the tokens are not logged or cached by intermediary systems, and it can also help to protect against CSRF attacks by allowing the server to validate the token before processing the request. \ No newline at end of file +By contrast, using the `Authorization` header to send tokens helps to ensure that the tokens are not logged or cached by intermediary systems, and it can also help to protect against CSRF attacks by allowing the server to validate the token before processing the request. diff --git a/src/data/best-practices/api-security/content/avoid-http-blocking.md b/src/data/best-practices/api-security/content/avoid-http-blocking.md index d321d62b5..31fcb940e 100644 --- a/src/data/best-practices/api-security/content/avoid-http-blocking.md +++ b/src/data/best-practices/api-security/content/avoid-http-blocking.md @@ -2,4 +2,4 @@ > Avoid HTTP blocking if you are using huge amount of data by moving the HTTP heavy operations to background jobs or asynchronous tasks. -HTTP blocking is a common issue in web applications. It occurs when the application is unable to process incoming HTTP requests due to a large number of requests or a large amount of data. This can lead to the application becoming unresponsive and the server crashing. This can be prevented by moving HTTP heavy operations to background jobs or asynchronous tasks. You can use a message queue to queue the requests and process them in the background. This will allow the application to continue processing other requests while the heavy operations are being processed in the background. \ No newline at end of file +HTTP blocking is a common issue in web applications. It occurs when the application is unable to process incoming HTTP requests due to a large number of requests or a large amount of data. This can lead to the application becoming unresponsive and the server crashing. This can be prevented by moving HTTP heavy operations to background jobs or asynchronous tasks. You can use a message queue to queue the requests and process them in the background. This will allow the application to continue processing other requests while the heavy operations are being processed in the background. diff --git a/src/data/best-practices/api-security/content/avoid-logging-sensitive-data.md b/src/data/best-practices/api-security/content/avoid-logging-sensitive-data.md index 011804a91..1348740cf 100644 --- a/src/data/best-practices/api-security/content/avoid-logging-sensitive-data.md +++ b/src/data/best-practices/api-security/content/avoid-logging-sensitive-data.md @@ -2,4 +2,4 @@ > Ensure that you aren't logging any sensitive data. -Make sure that you are not logging any sensitive data such as passwords, credit card numbers, or personal information. This is because logging sensitive data can expose it to attackers, allowing them to gain unauthorized access to your system or data. Additionally, logging sensitive data can violate data privacy laws and regulations, exposing you to legal liability. \ No newline at end of file +Make sure that you are not logging any sensitive data such as passwords, credit card numbers, or personal information. This is because logging sensitive data can expose it to attackers, allowing them to gain unauthorized access to your system or data. Additionally, logging sensitive data can violate data privacy laws and regulations, exposing you to legal liability. diff --git a/src/data/best-practices/api-security/content/avoid-personal-id-urls.md b/src/data/best-practices/api-security/content/avoid-personal-id-urls.md index b488dedac..c9247cb98 100644 --- a/src/data/best-practices/api-security/content/avoid-personal-id-urls.md +++ b/src/data/best-practices/api-security/content/avoid-personal-id-urls.md @@ -2,4 +2,4 @@ > Avoid user’s personal ID in the resource URLs e.g. users/242/orders - User's own resource ID should be avoided. Use `/me/orders` instead of `/user/654321/orders`. This will help avoid the risk of exposing the user’s personal ID that can be used for further attacks. \ No newline at end of file +User's own resource ID should be avoided. Use `/me/orders` instead of `/user/654321/orders`. This will help avoid the risk of exposing the user’s personal ID that can be used for further attacks. diff --git a/src/data/best-practices/api-security/content/avoid-sensitive-data.md b/src/data/best-practices/api-security/content/avoid-sensitive-data.md index 979554e31..e9ddbf01d 100644 --- a/src/data/best-practices/api-security/content/avoid-sensitive-data.md +++ b/src/data/best-practices/api-security/content/avoid-sensitive-data.md @@ -2,4 +2,4 @@ > Only return the data that is needed for the client to function. -Returning only the data that is needed for the client to function is an important best practice for API security. This is because limiting the amount of data that is returned reduces the amount of sensitive information that is exposed. By only returning the necessary data, you can help prevent security vulnerabilities such as data leakage, injection attacks, and other types of attacks that rely on exposing too much information. Additionally, reducing the amount of data returned can improve the performance of your API by reducing the amount of data that needs to be processed and transmitted. \ No newline at end of file +Returning only the data that is needed for the client to function is an important best practice for API security. This is because limiting the amount of data that is returned reduces the amount of sensitive information that is exposed. By only returning the necessary data, you can help prevent security vulnerabilities such as data leakage, injection attacks, and other types of attacks that rely on exposing too much information. Additionally, reducing the amount of data returned can improve the performance of your API by reducing the amount of data that needs to be processed and transmitted. diff --git a/src/data/best-practices/api-security/content/cdn-for-file-uploads.md b/src/data/best-practices/api-security/content/cdn-for-file-uploads.md index 337b5da13..340b8934e 100644 --- a/src/data/best-practices/api-security/content/cdn-for-file-uploads.md +++ b/src/data/best-practices/api-security/content/cdn-for-file-uploads.md @@ -2,4 +2,4 @@ > Use CDN for file uploads -Using a Content Delivery Network (CDN) for file uploads can make an API more secure by offloading the file upload traffic from the API server and reducing the risk of DDoS attacks. \ No newline at end of file +Using a Content Delivery Network (CDN) for file uploads can make an API more secure by offloading the file upload traffic from the API server and reducing the risk of DDoS attacks. diff --git a/src/data/best-practices/api-security/content/centralized-logins.md b/src/data/best-practices/api-security/content/centralized-logins.md index f35d1c6d1..4dd009bce 100644 --- a/src/data/best-practices/api-security/content/centralized-logins.md +++ b/src/data/best-practices/api-security/content/centralized-logins.md @@ -10,4 +10,4 @@ Using centralized logins for all services and components is important for severa - Centralized logins make it easier to enforce security policies across different services and components, ensuring that only authorized users can access sensitive data or perform certain actions. -To use centralized logins, you need to set up a single sign-on (SSO) system that enables users to authenticate once and then access multiple services without having to provide credentials again. This can be done using protocols like OAuth or SAML, which enable secure authentication and authorization across different applications and services. Once set up, you can use centralized logging tools like ELK stack, Splunk, or Graylog to collect logs from different services and components and analyze them in one place. This enables you to quickly identify and respond to security threats or anomalies. \ No newline at end of file +To use centralized logins, you need to set up a single sign-on (SSO) system that enables users to authenticate once and then access multiple services without having to provide credentials again. This can be done using protocols like OAuth or SAML, which enable secure authentication and authorization across different applications and services. Once set up, you can use centralized logging tools like ELK stack, Splunk, or Graylog to collect logs from different services and components and analyze them in one place. This enables you to quickly identify and respond to security threats or anomalies. diff --git a/src/data/best-practices/api-security/content/check-dependencies.md b/src/data/best-practices/api-security/content/check-dependencies.md index 843d7921c..7df20a5a7 100644 --- a/src/data/best-practices/api-security/content/check-dependencies.md +++ b/src/data/best-practices/api-security/content/check-dependencies.md @@ -4,4 +4,4 @@ Vulnerabilities in third-party libraries and components can be exploited by attackers to gain access to your system or data. These vulnerabilities can be introduced through outdated or insecure dependencies that have not been updated with the latest security patches. -By regularly checking for vulnerabilities and keeping your dependencies up to date, you can ensure that your API is not susceptible to known security risks. This can be done by using automated tools or services that scan your codebase and provide reports on any vulnerabilities found in your dependencies. By addressing these vulnerabilities promptly, you can reduce the risk of your API being compromised by attackers. \ No newline at end of file +By regularly checking for vulnerabilities and keeping your dependencies up to date, you can ensure that your API is not susceptible to known security risks. This can be done by using automated tools or services that scan your codebase and provide reports on any vulnerabilities found in your dependencies. By addressing these vulnerabilities promptly, you can reduce the risk of your API being compromised by attackers. diff --git a/src/data/best-practices/api-security/content/code-review-process.md b/src/data/best-practices/api-security/content/code-review-process.md index d6a3bb681..f96c8854d 100644 --- a/src/data/best-practices/api-security/content/code-review-process.md +++ b/src/data/best-practices/api-security/content/code-review-process.md @@ -2,4 +2,4 @@ > Use a code review process and disregard self-approval. -Having a good code review process allows for additional sets of eyes to review the code and identify potential security issues or vulnerabilities. A code review process involves other team members reviewing the code to ensure it follows best practices and is secure. Disregarding self-approval means that the developer who wrote the code should not be the only one responsible for approving it for release. This helps to catch potential mistakes or oversights before the code is deployed, reducing the risk of security breaches or other issues. \ No newline at end of file +Having a good code review process allows for additional sets of eyes to review the code and identify potential security issues or vulnerabilities. A code review process involves other team members reviewing the code to ensure it follows best practices and is secure. Disregarding self-approval means that the developer who wrote the code should not be the only one responsible for approving it for release. This helps to catch potential mistakes or oversights before the code is deployed, reducing the risk of security breaches or other issues. diff --git a/src/data/best-practices/api-security/content/csp-header.md b/src/data/best-practices/api-security/content/csp-header.md index 9ff536c6c..3f8399f1e 100644 --- a/src/data/best-practices/api-security/content/csp-header.md +++ b/src/data/best-practices/api-security/content/csp-header.md @@ -2,4 +2,4 @@ > Send `Content-Security-Policy: default-src 'none'` header. -Sending the `Content-Security-Policy: default-src 'none'` header is a security best practice that helps prevent cross-site scripting (XSS) attacks. This header tells the browser to not allow any resources to be loaded from external sources, such as scripts, stylesheets, or images. It only allows resources that are explicitly whitelisted in the CSP header, such as scripts or stylesheets hosted on your own domain. This can help prevent malicious actors from injecting code into your web pages via XSS attacks, as the browser will not execute any scripts or load any resources that are not explicitly allowed by the CSP policy. \ No newline at end of file +Sending the `Content-Security-Policy: default-src 'none'` header is a security best practice that helps prevent cross-site scripting (XSS) attacks. This header tells the browser to not allow any resources to be loaded from external sources, such as scripts, stylesheets, or images. It only allows resources that are explicitly whitelisted in the CSP header, such as scripts or stylesheets hosted on your own domain. This can help prevent malicious actors from injecting code into your web pages via XSS attacks, as the browser will not execute any scripts or load any resources that are not explicitly allowed by the CSP policy. diff --git a/src/data/best-practices/api-security/content/debug-mode-off.md b/src/data/best-practices/api-security/content/debug-mode-off.md index 421e0100e..951798d1d 100644 --- a/src/data/best-practices/api-security/content/debug-mode-off.md +++ b/src/data/best-practices/api-security/content/debug-mode-off.md @@ -2,4 +2,4 @@ > Make sure to turn the debug mode off in production -Debug mode is a feature that is used to help developers debug their code. It is not meant to be used in production. It can expose sensitive information about the application and the server it is running on. Make sure to turn debug mode off in production. \ No newline at end of file +Debug mode is a feature that is used to help developers debug their code. It is not meant to be used in production. It can expose sensitive information about the application and the server it is running on. Make sure to turn debug mode off in production. diff --git a/src/data/best-practices/api-security/content/directory-listings.md b/src/data/best-practices/api-security/content/directory-listings.md index e9e41bec5..d29a8fad4 100644 --- a/src/data/best-practices/api-security/content/directory-listings.md +++ b/src/data/best-practices/api-security/content/directory-listings.md @@ -4,4 +4,4 @@ Directory listings are a feature of web servers that allow users to view the contents of a directory on a server. By default, web servers often have directory listings enabled, which means that anyone who has access to the server can see all the files and directories in a given folder. -Turning off directory listings is important for API security because it prevents attackers from gaining access to sensitive files and directories on the server. If directory listings are enabled and an attacker gains access to the server, they can easily view and download any files that are not properly protected. By disabling directory listings, you can ensure that only authorized users can access the files and directories on the server. \ No newline at end of file +Turning off directory listings is important for API security because it prevents attackers from gaining access to sensitive files and directories on the server. If directory listings are enabled and an attacker gains access to the server, they can easily view and download any files that are not properly protected. By disabling directory listings, you can ensure that only authorized users can access the files and directories on the server. diff --git a/src/data/best-practices/api-security/content/disable-entity-expansion.md b/src/data/best-practices/api-security/content/disable-entity-expansion.md index 25db7d24b..af8655072 100644 --- a/src/data/best-practices/api-security/content/disable-entity-expansion.md +++ b/src/data/best-practices/api-security/content/disable-entity-expansion.md @@ -2,4 +2,4 @@ > Disable entity expansion if using XML, YML or any other language -Disabling entity expansion is important when using XML, YAML, or any other language that allows entities because it helps prevent XXE (XML External Entity) or YAML tag injection attacks. In these attacks, attacker normally injects some sort of custom code in the input to perform attacks against the application.. By disabling entity expansion, the input cannot be manipulated in this way, reducing the risk of such attacks. \ No newline at end of file +Disabling entity expansion is important when using XML, YAML, or any other language that allows entities because it helps prevent XXE (XML External Entity) or YAML tag injection attacks. In these attacks, attacker normally injects some sort of custom code in the input to perform attacks against the application.. By disabling entity expansion, the input cannot be manipulated in this way, reducing the risk of such attacks. diff --git a/src/data/best-practices/api-security/content/disable-entity-parsing-xml.md b/src/data/best-practices/api-security/content/disable-entity-parsing-xml.md index 3b1ea9507..061ce4f14 100644 --- a/src/data/best-practices/api-security/content/disable-entity-parsing-xml.md +++ b/src/data/best-practices/api-security/content/disable-entity-parsing-xml.md @@ -4,4 +4,4 @@ If the XML parser is vulnerable to XXE attacks, the attacker can use this vulnerability to read files on the server, perform SSRF attacks, and more. This can lead to the disclosure of sensitive information, denial of service, and other attacks. -XXE (XML External Entity) attack is a type of attack that targets applications that parse XML input from untrusted sources. In this attack, an attacker injects a malicious XML payload. This payload can contain external entities that the attacker can use to retrieve sensitive data, execute remote code, or launch denial of service attacks. XXE attacks can be prevented by disabling external entity processing or by validating and sanitizing the XML input before parsing it. \ No newline at end of file +XXE (XML External Entity) attack is a type of attack that targets applications that parse XML input from untrusted sources. In this attack, an attacker injects a malicious XML payload. This payload can contain external entities that the attacker can use to retrieve sensitive data, execute remote code, or launch denial of service attacks. XXE attacks can be prevented by disabling external entity processing or by validating and sanitizing the XML input before parsing it. diff --git a/src/data/best-practices/api-security/content/endpoint-authentication.md b/src/data/best-practices/api-security/content/endpoint-authentication.md index 4a0c53460..e94cf1f73 100644 --- a/src/data/best-practices/api-security/content/endpoint-authentication.md +++ b/src/data/best-practices/api-security/content/endpoint-authentication.md @@ -1,6 +1,6 @@ # Endpoint Authentication > Check if all the protected endpoints are behind authentication -to avoid broken authentication process +> to avoid broken authentication process -By identifying and fixing broken authentication workflows, the API can prevent attacks such as brute force attacks, credential stuffing, session hijacking, and other authentication-related attacks. This can help ensure that the system is secure and that sensitive data is protected. \ No newline at end of file +By identifying and fixing broken authentication workflows, the API can prevent attacks such as brute force attacks, credential stuffing, session hijacking, and other authentication-related attacks. This can help ensure that the system is secure and that sensitive data is protected. diff --git a/src/data/best-practices/api-security/content/force-content-type.md b/src/data/best-practices/api-security/content/force-content-type.md index 60949eb1d..a130c7b81 100644 --- a/src/data/best-practices/api-security/content/force-content-type.md +++ b/src/data/best-practices/api-security/content/force-content-type.md @@ -2,4 +2,4 @@ > Always force the `Content-Type` header to be set to relevant MIME type. -Forcing the content-type for API security is important because it ensures that the client and server are communicating in a mutually agreed-upon format for the data being transmitted. This can prevent attacks such as content spoofing or injection, where an attacker tries to trick the server into processing malicious content by pretending that it is of a different content type. By forcing the content-type to a specific format, the server can validate that the data it is receiving is legitimate and safe to process. Additionally, forcing the content-type can help prevent certain types of parsing errors that could be exploited by attackers. \ No newline at end of file +Forcing the content-type for API security is important because it ensures that the client and server are communicating in a mutually agreed-upon format for the data being transmitted. This can prevent attacks such as content spoofing or injection, where an attacker tries to trick the server into processing malicious content by pretending that it is of a different content type. By forcing the content-type to a specific format, the server can validate that the data it is receiving is legitimate and safe to process. Additionally, forcing the content-type can help prevent certain types of parsing errors that could be exploited by attackers. diff --git a/src/data/best-practices/api-security/content/good-jwt-secret.md b/src/data/best-practices/api-security/content/good-jwt-secret.md index 61f09100d..ad92ac3bb 100644 --- a/src/data/best-practices/api-security/content/good-jwt-secret.md +++ b/src/data/best-practices/api-security/content/good-jwt-secret.md @@ -2,4 +2,4 @@ > You should have a good JWT secret to protect against token tempering as well as avoiding brute force attacks. -A strong secret key should be randomly generated, long, and complex, and should be stored securely and rotated periodically. \ No newline at end of file +A strong secret key should be randomly generated, long, and complex, and should be stored securely and rotated periodically. diff --git a/src/data/best-practices/api-security/content/hsts-header.md b/src/data/best-practices/api-security/content/hsts-header.md index 4dff63b6b..913ecd9be 100644 --- a/src/data/best-practices/api-security/content/hsts-header.md +++ b/src/data/best-practices/api-security/content/hsts-header.md @@ -6,4 +6,4 @@ SSL strip is a type of attack where an attacker intercepts traffic between a cli In an SSL strip attack, the attacker sets up a man-in-the-middle (MITM) position between the client and the server. When the client initiates a connection with the server, the attacker intercepts the SSL/TLS traffic and removes or replaces the HTTPS links with HTTP links. This can trick the user into thinking they are using a secure connection when in fact, they are not. The attacker can then monitor and manipulate the data transmitted between the client and server. -HSTS header is a security header that instructs browsers to only access the site over HTTPS. This header is used to prevent SSL Strip attacks. It is a good practice to use HSTS header with SSL. \ No newline at end of file +HSTS header is a security header that instructs browsers to only access the site over HTTPS. This header is used to prevent SSL Strip attacks. It is a good practice to use HSTS header with SSL. diff --git a/src/data/best-practices/api-security/content/index.md b/src/data/best-practices/api-security/content/index.md index 4e768b56d..792d60054 100644 --- a/src/data/best-practices/api-security/content/index.md +++ b/src/data/best-practices/api-security/content/index.md @@ -1 +1 @@ -# \ No newline at end of file +# diff --git a/src/data/best-practices/api-security/content/jwt-algorithm.md b/src/data/best-practices/api-security/content/jwt-algorithm.md index c843790a8..e9202c555 100644 --- a/src/data/best-practices/api-security/content/jwt-algorithm.md +++ b/src/data/best-practices/api-security/content/jwt-algorithm.md @@ -2,4 +2,4 @@ > Do not extract the algorithm from the header, use backend. -Extracting the algorithm from the header of a JWT token can pose a security risk, as an attacker could modify the algorithm and potentially gain unauthorized access. It is therefore recommended to verify the algorithm on the backend rather than extracting it from the header. This can help ensure that the algorithm used to sign and verify the token is secure and has not been tampered with. \ No newline at end of file +Extracting the algorithm from the header of a JWT token can pose a security risk, as an attacker could modify the algorithm and potentially gain unauthorized access. It is therefore recommended to verify the algorithm on the backend rather than extracting it from the header. This can help ensure that the algorithm used to sign and verify the token is secure and has not been tampered with. diff --git a/src/data/best-practices/api-security/content/jwt-payload.md b/src/data/best-practices/api-security/content/jwt-payload.md index bb660816f..24546acab 100644 --- a/src/data/best-practices/api-security/content/jwt-payload.md +++ b/src/data/best-practices/api-security/content/jwt-payload.md @@ -2,4 +2,4 @@ > Avoid storing sensitive data in JWT payload -Storing sensitive data in a JWT token payload can increase the risk of data breaches and other security incidents. If an attacker is able to obtain or tamper with the token, they could potentially access the sensitive data stored in the payload. \ No newline at end of file +Storing sensitive data in a JWT token payload can increase the risk of data breaches and other security incidents. If an attacker is able to obtain or tamper with the token, they could potentially access the sensitive data stored in the payload. diff --git a/src/data/best-practices/api-security/content/monitor-everything.md b/src/data/best-practices/api-security/content/monitor-everything.md index 2bd3ef2b0..99a34dc92 100644 --- a/src/data/best-practices/api-security/content/monitor-everything.md +++ b/src/data/best-practices/api-security/content/monitor-everything.md @@ -4,4 +4,4 @@ Using agents to monitor all requests, responses, and errors allows for real-time monitoring and detection of any abnormal activity or potential attacks. These agents can be configured to track metrics such as response times, error rates, and usage patterns, which can help identify any anomalies that could be indicative of an attack. By monitoring all requests and responses, the agents can provide visibility into the behavior of the API, which can help identify any potential security vulnerabilities or weaknesses. Additionally, agents can be used to log and analyze all data flowing through the API, which can be useful for debugging and auditing purposes. -To use agents for monitoring, a dedicated monitoring solution can be deployed alongside the API. This solution can be configured to capture data from all requests and responses, and analyze the data for any anomalies or issues. Agents can be implemented using various monitoring tools and technologies such as agents for application performance monitoring (APM), log monitoring, and network monitoring. The agents should be configured to provide real-time alerts to security teams if any suspicious activity is detected, allowing for immediate action to be taken. \ No newline at end of file +To use agents for monitoring, a dedicated monitoring solution can be deployed alongside the API. This solution can be configured to capture data from all requests and responses, and analyze the data for any anomalies or issues. Agents can be implemented using various monitoring tools and technologies such as agents for application performance monitoring (APM), log monitoring, and network monitoring. The agents should be configured to provide real-time alerts to security teams if any suspicious activity is detected, allowing for immediate action to be taken. diff --git a/src/data/best-practices/api-security/content/no-sniff-header.md b/src/data/best-practices/api-security/content/no-sniff-header.md index 1fbe4c5b6..8b29e6d32 100644 --- a/src/data/best-practices/api-security/content/no-sniff-header.md +++ b/src/data/best-practices/api-security/content/no-sniff-header.md @@ -4,4 +4,4 @@ You should send the `X-Content-Type-Options: nosniff` header to prevent [MIME type sniffing attacks](https://www.keycdn.com/support/what-is-mime-sniffing) on your web application. This header tells the browser not to override the response content type even if it's not the expected type. For example, if an attacker manages to upload an HTML file with a disguised extension like .jpg, the server may still send the correct content type header for the HTML file. However, some browsers may ignore this header and try to "sniff" the content type based on the actual contents of the file, leading to a potential cross-site scripting (XSS) attack. -By sending the `X-Content-Type-Options: nosniff` header, you tell the browser to always trust the provided content type and not try to sniff the content type. This helps to mitigate the risk of attackers exploiting content type mismatches to deliver malicious content to unsuspecting users. \ No newline at end of file +By sending the `X-Content-Type-Options: nosniff` header, you tell the browser to always trust the provided content type and not try to sniff the content type. This helps to mitigate the risk of attackers exploiting content type mismatches to deliver malicious content to unsuspecting users. diff --git a/src/data/best-practices/api-security/content/non-executable-stacks.md b/src/data/best-practices/api-security/content/non-executable-stacks.md index 33088fcfa..88affd10b 100644 --- a/src/data/best-practices/api-security/content/non-executable-stacks.md +++ b/src/data/best-practices/api-security/content/non-executable-stacks.md @@ -4,4 +4,4 @@ A stack usually refers to the call stack or execution stack. It is a data structure used by the computer program to manage and keep track of the sequence of function calls, local variables, and other related data during the execution of the program. -A non-executable stack is a security mechanism that prevents malicious code from being executed by preventing the stack memory from being executed as code. This helps to prevent attacks such as buffer overflow attacks, where an attacker tries to overwrite the return address on the stack to redirect the program to execute malicious code. By using non-executable stacks, the program can keep the stack separate from executable code and help prevent these types of attacks. \ No newline at end of file +A non-executable stack is a security mechanism that prevents malicious code from being executed by preventing the stack memory from being executed as code. This helps to prevent attacks such as buffer overflow attacks, where an attacker tries to overwrite the return address on the stack to redirect the program to execute malicious code. By using non-executable stacks, the program can keep the stack separate from executable code and help prevent these types of attacks. diff --git a/src/data/best-practices/api-security/content/oauth-redirect-ui.md b/src/data/best-practices/api-security/content/oauth-redirect-ui.md index 9e35ea303..0705e20d3 100644 --- a/src/data/best-practices/api-security/content/oauth-redirect-ui.md +++ b/src/data/best-practices/api-security/content/oauth-redirect-ui.md @@ -6,4 +6,4 @@ In OAuth, `redirect_uri` is a parameter that specifies the URI (Uniform Resource It is important to validate the `redirect_uri` on the server-side to prevent attacks such as open redirection attacks. In an open redirection attack, an attacker can modify the `redirect_uri` parameter to redirect the user to a malicious website. By validating the `redirect_uri` on the server-side, you can ensure that the redirect URI is a valid and authorized URI for the client application. -Validating the `redirect_uri` on the server-side can also prevent other types of attacks such as phishing attacks or cross-site request forgery (CSRF) attacks. By verifying that the `redirect_uri` matches a predefined list of authorized URIs, you can ensure that the user is redirected to a trusted site after authentication is complete. \ No newline at end of file +Validating the `redirect_uri` on the server-side can also prevent other types of attacks such as phishing attacks or cross-site request forgery (CSRF) attacks. By verifying that the `redirect_uri` matches a predefined list of authorized URIs, you can ensure that the user is redirected to a trusted site after authentication is complete. diff --git a/src/data/best-practices/api-security/content/only-server-side-encryption.md b/src/data/best-practices/api-security/content/only-server-side-encryption.md index d17b63091..6b5ddbb57 100644 --- a/src/data/best-practices/api-security/content/only-server-side-encryption.md +++ b/src/data/best-practices/api-security/content/only-server-side-encryption.md @@ -2,4 +2,4 @@ > Use server-side encryption instead of client-side encryption -Client-side encryption is not recommended because client side codebase can be easily reverse engineered which can lead to the exposure of encryption algorithms. \ No newline at end of file +Client-side encryption is not recommended because client side codebase can be easily reverse engineered which can lead to the exposure of encryption algorithms. diff --git a/src/data/best-practices/api-security/content/prefer-uuid.md b/src/data/best-practices/api-security/content/prefer-uuid.md index 6f1ed4da4..af1ee81eb 100644 --- a/src/data/best-practices/api-security/content/prefer-uuid.md +++ b/src/data/best-practices/api-security/content/prefer-uuid.md @@ -2,4 +2,4 @@ > Use UUIDs instead of auto-incrementing integers. UUIDs are globally unique, and are not sequential. They are also more difficult to guess than sequential integers. -Use of UUIDs over auto-incrementing IDs prevents attackers from guessing or iterating through resource IDs. UUIDs are randomly generated and contain 128 bits of entropy, making it practically impossible for attackers to guess them. In contrast, autoincrementing IDs can be easily predicted or iterated through, allowing attackers to access or manipulate resources they shouldn't have access to. Additionally, using UUIDs can help prevent information disclosure by hiding the order of resource creation or access. \ No newline at end of file +Use of UUIDs over auto-incrementing IDs prevents attackers from guessing or iterating through resource IDs. UUIDs are randomly generated and contain 128 bits of entropy, making it practically impossible for attackers to guess them. In contrast, autoincrementing IDs can be easily predicted or iterated through, allowing attackers to access or manipulate resources they shouldn't have access to. Additionally, using UUIDs can help prevent information disclosure by hiding the order of resource creation or access. diff --git a/src/data/best-practices/api-security/content/proper-http-methods.md b/src/data/best-practices/api-security/content/proper-http-methods.md index e0f99f351..d3027927d 100644 --- a/src/data/best-practices/api-security/content/proper-http-methods.md +++ b/src/data/best-practices/api-security/content/proper-http-methods.md @@ -1,5 +1,3 @@ # Proper HTTP Methods Use the proper HTTP method according to the operation: `GET (read)`, `POST (create)`, `PUT/PATCH (replace/update)`, and `DELETE (to delete a record)`, and respond with `405 Method Not Allowed` if the requested method isn't appropriate for the requested resource. - - diff --git a/src/data/best-practices/api-security/content/proper-response-code.md b/src/data/best-practices/api-security/content/proper-response-code.md index fa1ee405c..3e5980376 100644 --- a/src/data/best-practices/api-security/content/proper-response-code.md +++ b/src/data/best-practices/api-security/content/proper-response-code.md @@ -1,10 +1,11 @@ # Proper Response Code > Return the proper status code according to the operation completed. e.g. +> > - `200 OK` > - `400 Bad Request` > - `401 Unauthorized` > - `405 Method Not Allowed` > - ...etc. -Returning the proper status code according to the operation completed is important for API security because it allows the client to understand the outcome of their request and take appropriate actions. For example, if the server returns a 401 Unauthorized status code, the client knows that their authentication credentials are incorrect and can prompt the user to re-enter their login details. On the other hand, if the server returns a 200 OK status code even though the request failed, the client may not realize there was an issue and could potentially execute malicious actions or display incorrect data. Providing accurate status codes can help prevent security vulnerabilities and improve the overall reliability and usability of the API. \ No newline at end of file +Returning the proper status code according to the operation completed is important for API security because it allows the client to understand the outcome of their request and take appropriate actions. For example, if the server returns a 401 Unauthorized status code, the client knows that their authentication credentials are incorrect and can prompt the user to re-enter their login details. On the other hand, if the server returns a 200 OK status code even though the request failed, the client may not realize there was an issue and could potentially execute malicious actions or display incorrect data. Providing accurate status codes can help prevent security vulnerabilities and improve the overall reliability and usability of the API. diff --git a/src/data/best-practices/api-security/content/recommended-resources.md b/src/data/best-practices/api-security/content/recommended-resources.md index 7a6274b1f..0f1f6dd9b 100644 --- a/src/data/best-practices/api-security/content/recommended-resources.md +++ b/src/data/best-practices/api-security/content/recommended-resources.md @@ -5,4 +5,4 @@ Have a look at the following resources for more information on API security: - [Collection of Resources for Building APIs](https://github.com/yosriady/awesome-api-devtools) - [CS253: Web Security](https://www.youtube.com/watch?v=5JJrJGZ_LjM&list=PL1y1iaEtjSYiiSGVlL1cHsXN_kvJOOhu-) - [Securing Web Applications](https://www.youtube.com/watch?v=WlmKwIe9z1Q) -- [MIT 6.858: Computer Systems Security](https://www.youtube.com/watch?v=GqmQg-cszw4&list=PLUl4u3cNGP62K2DjQLRxDNRi0z2IRWnNh) \ No newline at end of file +- [MIT 6.858: Computer Systems Security](https://www.youtube.com/watch?v=GqmQg-cszw4&list=PLUl4u3cNGP62K2DjQLRxDNRi0z2IRWnNh) diff --git a/src/data/best-practices/api-security/content/remove-fingerprint-header.md b/src/data/best-practices/api-security/content/remove-fingerprint-header.md index 7ee9f6801..2d40c51e5 100644 --- a/src/data/best-practices/api-security/content/remove-fingerprint-header.md +++ b/src/data/best-practices/api-security/content/remove-fingerprint-header.md @@ -2,4 +2,4 @@ > Remove fingerprinting headers (i.e. x-powered-by etc) from the HTTP request. -Fingerprinting headers can be used to identify the web server and its version. This information can be used by attackers to identify vulnerabilities in the web server and exploit them. \ No newline at end of file +Fingerprinting headers can be used to identify the web server and its version. This information can be used by attackers to identify vulnerabilities in the web server and exploit them. diff --git a/src/data/best-practices/api-security/content/restrict-private-apis.md b/src/data/best-practices/api-security/content/restrict-private-apis.md index ada767013..33bce3e16 100644 --- a/src/data/best-practices/api-security/content/restrict-private-apis.md +++ b/src/data/best-practices/api-security/content/restrict-private-apis.md @@ -3,4 +3,3 @@ > Private APIs should only be accessible from safe listed IPs Private APIs should only be accessible from safe-listed IPs to ensure that only authorized users or systems can access the API. By restricting access to specific IP addresses, you can prevent unauthorized access from external networks or malicious actors. This can help to protect sensitive data and prevent attacks such as DDoS or brute-force attacks. Additionally, restricting access to safe-listed IPs can help to ensure the reliability and performance of the API by preventing excessive traffic from unauthorized sources. - diff --git a/src/data/best-practices/api-security/content/rollback-deployments.md b/src/data/best-practices/api-security/content/rollback-deployments.md index 6237b7c3e..ddc4b24d8 100644 --- a/src/data/best-practices/api-security/content/rollback-deployments.md +++ b/src/data/best-practices/api-security/content/rollback-deployments.md @@ -2,4 +2,4 @@ > Design a rollback solution for deployments. -Sometimes deploying a new version of the API can introduce unexpected bugs or issues that were not caught during testing. In such cases, rolling back to the previous version of the API can help to mitigate the impact of the issue and restore the service to a functional state. A well-designed rollback solution can help reduce downtime and minimize the impact on users. \ No newline at end of file +Sometimes deploying a new version of the API can introduce unexpected bugs or issues that were not caught during testing. In such cases, rolling back to the previous version of the API can help to mitigate the impact of the issue and restore the service to a functional state. A well-designed rollback solution can help reduce downtime and minimize the impact on users. diff --git a/src/data/best-practices/api-security/content/run-security-analysis.md b/src/data/best-practices/api-security/content/run-security-analysis.md index 81e909291..fa3f00d0b 100644 --- a/src/data/best-practices/api-security/content/run-security-analysis.md +++ b/src/data/best-practices/api-security/content/run-security-analysis.md @@ -2,4 +2,4 @@ > Continuously run security analysis on your code. -Continuous security analysis helps identify and address security vulnerabilities in the codebase before they can be exploited by attackers. It involves using automated tools and manual techniques to scan code for potential weaknesses, such as insecure coding practices, configuration errors, and outdated dependencies. By identifying and fixing vulnerabilities early in the development cycle, the risk of a security breach or data loss can be significantly reduced, improving the overall security posture of the system. \ No newline at end of file +Continuous security analysis helps identify and address security vulnerabilities in the codebase before they can be exploited by attackers. It involves using automated tools and manual techniques to scan code for potential weaknesses, such as insecure coding practices, configuration errors, and outdated dependencies. By identifying and fixing vulnerabilities early in the development cycle, the risk of a security breach or data loss can be significantly reduced, improving the overall security posture of the system. diff --git a/src/data/best-practices/api-security/content/sensitive-data-encryption.md b/src/data/best-practices/api-security/content/sensitive-data-encryption.md index 14abd1b71..48a1949b9 100644 --- a/src/data/best-practices/api-security/content/sensitive-data-encryption.md +++ b/src/data/best-practices/api-security/content/sensitive-data-encryption.md @@ -4,4 +4,4 @@ Encryption is a process of converting plain text data into a cipher text that can only be deciphered by someone who has the decryption key. This makes it difficult for attackers to access sensitive data, even if they are able to intercept it or gain unauthorized access to it. -To encrypt sensitive data, you can use encryption algorithms such as `AES` or `RSA`, along with a strong key management system to ensure that keys are securely stored and managed. Additionally, you can implement other security measures such as access controls, firewalls, and intrusion detection systems to further protect sensitive data. \ No newline at end of file +To encrypt sensitive data, you can use encryption algorithms such as `AES` or `RSA`, along with a strong key management system to ensure that keys are securely stored and managed. Additionally, you can implement other security measures such as access controls, firewalls, and intrusion detection systems to further protect sensitive data. diff --git a/src/data/best-practices/api-security/content/set-alerts.md b/src/data/best-practices/api-security/content/set-alerts.md index f2a244359..17a5377a6 100644 --- a/src/data/best-practices/api-security/content/set-alerts.md +++ b/src/data/best-practices/api-security/content/set-alerts.md @@ -2,4 +2,4 @@ > Use alerts for SMS, Slack, Email, Kibana, Cloudwatch, etc. -Using alerts for various communication channels such as SMS, Slack, Email, Kibana, Cloudwatch, etc. can help you quickly respond to any issues or anomalies in your system. These alerts can be set up to notify you in real-time if a particular event or condition occurs, allowing you to take proactive measures to prevent downtime, data loss, or security breaches. Additionally, alerts can provide valuable insights into system performance and user behavior, allowing you to make informed decisions about your API's design and implementation. \ No newline at end of file +Using alerts for various communication channels such as SMS, Slack, Email, Kibana, Cloudwatch, etc. can help you quickly respond to any issues or anomalies in your system. These alerts can be set up to notify you in real-time if a particular event or condition occurs, allowing you to take proactive measures to prevent downtime, data loss, or security breaches. Additionally, alerts can provide valuable insights into system performance and user behavior, allowing you to make informed decisions about your API's design and implementation. diff --git a/src/data/best-practices/api-security/content/throttle-requests.md b/src/data/best-practices/api-security/content/throttle-requests.md index 36459124a..51c3cfbbd 100644 --- a/src/data/best-practices/api-security/content/throttle-requests.md +++ b/src/data/best-practices/api-security/content/throttle-requests.md @@ -2,6 +2,6 @@ > Limit requests (throttling) to avoid DDoS / Brute Force attacks. -Limiting requests through throttling is important to prevent DDoS attacks and brute force attacks. DDoS attacks overwhelm the server with too many requests, while brute force attacks try to guess user credentials through multiple login attempts. +Limiting requests through throttling is important to prevent DDoS attacks and brute force attacks. DDoS attacks overwhelm the server with too many requests, while brute force attacks try to guess user credentials through multiple login attempts. -Throttling limits the number of requests that can be sent within a certain time period, making it harder for attackers to carry out these types of attacks. This can protect the system from being overwhelmed and can prevent attackers from gaining unauthorized access. \ No newline at end of file +Throttling limits the number of requests that can be sent within a certain time period, making it harder for attackers to carry out these types of attacks. This can protect the system from being overwhelmed and can prevent attackers from gaining unauthorized access. diff --git a/src/data/best-practices/api-security/content/token-expiry.md b/src/data/best-practices/api-security/content/token-expiry.md index 4a45d2a60..352389785 100644 --- a/src/data/best-practices/api-security/content/token-expiry.md +++ b/src/data/best-practices/api-security/content/token-expiry.md @@ -2,4 +2,4 @@ > Token expiry should be set to a reasonable time to reduce the window of vulnerability, limit the impact of token theft, and improve overall security. -Setting a short token expiration time (TTL, RTTL) is important for security purposes, as it reduces the window of vulnerability, limits the impact of token theft, and improves overall security. However, the expiration time should be balanced with usability, as setting it too short may inconvenience users and reduce productivity. \ No newline at end of file +Setting a short token expiration time (TTL, RTTL) is important for security purposes, as it reduces the window of vulnerability, limits the impact of token theft, and improves overall security. However, the expiration time should be balanced with usability, as setting it too short may inconvenience users and reduce productivity. diff --git a/src/data/best-practices/api-security/content/unit-integration-tests.md b/src/data/best-practices/api-security/content/unit-integration-tests.md index 191cc0fa8..2652ee316 100644 --- a/src/data/best-practices/api-security/content/unit-integration-tests.md +++ b/src/data/best-practices/api-security/content/unit-integration-tests.md @@ -2,4 +2,4 @@ > Audit your design and implementation with unit/integration tests coverage. -Unit and integration testing can help identify vulnerabilities in the API code and design, such as input validation errors, authentication and authorization flaws, and other security-related issues. By performing comprehensive testing, developers can ensure that the API works as intended and that it is secure against common attacks such as injection attacks, cross-site scripting, and other exploits. Adequate testing can also help identify and resolve performance bottlenecks, improve scalability and reliability, and ensure the overall quality of the API. \ No newline at end of file +Unit and integration testing can help identify vulnerabilities in the API code and design, such as input validation errors, authentication and authorization flaws, and other security-related issues. By performing comprehensive testing, developers can ensure that the API works as intended and that it is secure against common attacks such as injection attacks, cross-site scripting, and other exploits. Adequate testing can also help identify and resolve performance bottlenecks, improve scalability and reliability, and ensure the overall quality of the API. diff --git a/src/data/best-practices/api-security/content/use-https.md b/src/data/best-practices/api-security/content/use-https.md index 96e5f92ba..ce66602c5 100644 --- a/src/data/best-practices/api-security/content/use-https.md +++ b/src/data/best-practices/api-security/content/use-https.md @@ -5,4 +5,3 @@ Ensure that your API server uses HTTPS instead of HTTP. HTTPS is a secure protocol that encrypts data in transit, making it difficult for attackers to intercept and read sensitive information. To implement HTTPS, you need to obtain an SSL/TLS certificate and configure your server to use HTTPS. HTTPS uses ciphers to encrypt data in transit. It is important to choose secure ciphers that are resistant to attacks and offer strong encryption. Some common secure ciphers include AES, ChaCha20, and ECDHE for key exchange. Make sure to disable weak and outdated ciphers, such as RC4 and TLS 1.0/1.1, which are vulnerable to attacks. - diff --git a/src/data/best-practices/api-security/content/use-ids-ips-system.md b/src/data/best-practices/api-security/content/use-ids-ips-system.md index 68c78d3d2..5e2e320e2 100644 --- a/src/data/best-practices/api-security/content/use-ids-ips-system.md +++ b/src/data/best-practices/api-security/content/use-ids-ips-system.md @@ -2,4 +2,4 @@ > Use IDS and/or IPS systems to detect and block attacks. -Intrusion detection systems (IDS) and intrusion prevention systems (IPS) can be used to detect and block attacks. These systems can be configured to monitor all incoming and outgoing traffic, and detect any suspicious activity. If any suspicious activity is detected, the systems can be configured to block the traffic, preventing the attack from succeeding. IDS and IPS systems can be implemented using various tools and technologies such as network intrusion detection systems (NIDS), host-based intrusion detection systems (HIDS), and network intrusion prevention systems (NIPS). These systems can be deployed alongside the API, and configured to monitor all incoming and outgoing traffic. The systems can be configured to provide real-time alerts to security teams if any suspicious activity is detected, allowing for immediate action to be taken. \ No newline at end of file +Intrusion detection systems (IDS) and intrusion prevention systems (IPS) can be used to detect and block attacks. These systems can be configured to monitor all incoming and outgoing traffic, and detect any suspicious activity. If any suspicious activity is detected, the systems can be configured to block the traffic, preventing the attack from succeeding. IDS and IPS systems can be implemented using various tools and technologies such as network intrusion detection systems (NIDS), host-based intrusion detection systems (HIDS), and network intrusion prevention systems (NIPS). These systems can be deployed alongside the API, and configured to monitor all incoming and outgoing traffic. The systems can be configured to provide real-time alerts to security teams if any suspicious activity is detected, allowing for immediate action to be taken. diff --git a/src/data/best-practices/api-security/content/use-standard-authentication.md b/src/data/best-practices/api-security/content/use-standard-authentication.md index fa7b039fe..e9b61a2a8 100644 --- a/src/data/best-practices/api-security/content/use-standard-authentication.md +++ b/src/data/best-practices/api-security/content/use-standard-authentication.md @@ -14,4 +14,4 @@ There are several reasons why basic authentication should be avoided and replace - No support for multi-factor authentication: Basic authentication does not support multi-factor authentication (MFA), which is a critical security feature that provides an additional layer of protection against unauthorized access. -In contrast, other authentication techniques such as OAuth, OpenID Connect, and SAML provide more secure and robust methods for authentication. These methods typically use encrypted protocols to protect the user's credentials, provide mechanisms for verifying the integrity of the data, and support MFA. As a result, they are much more secure and reliable than basic authentication and should be used whenever possible. \ No newline at end of file +In contrast, other authentication techniques such as OAuth, OpenID Connect, and SAML provide more secure and robust methods for authentication. These methods typically use encrypted protocols to protect the user's credentials, provide mechanisms for verifying the integrity of the data, and support MFA. As a result, they are much more secure and reliable than basic authentication and should be used whenever possible. diff --git a/src/data/best-practices/api-security/content/validate-content-type.md b/src/data/best-practices/api-security/content/validate-content-type.md index 54d744863..d98296bc8 100644 --- a/src/data/best-practices/api-security/content/validate-content-type.md +++ b/src/data/best-practices/api-security/content/validate-content-type.md @@ -3,4 +3,3 @@ > Validate `content-type` on request headers to prevent XSS attacks Validating the `Content-Type` header on the request can help to make APIs more secure by ensuring that the request data is in the expected format and reducing the risk of attacks such as injection attacks or cross-site scripting (XSS). - diff --git a/src/data/best-practices/api-security/content/validate-user-input.md b/src/data/best-practices/api-security/content/validate-user-input.md index b3df39ab8..e3d1594bf 100644 --- a/src/data/best-practices/api-security/content/validate-user-input.md +++ b/src/data/best-practices/api-security/content/validate-user-input.md @@ -2,4 +2,4 @@ > Validate user input to avoid common vulnerabilities -User input is a common source of vulnerabilities in web applications. This is because user input is often not properly validated, sanitized, or escaped before being used in a web application. This can allow an attacker to manipulate the input and execute malicious code or cause the application to behave unexpectedly. \ No newline at end of file +User input is a common source of vulnerabilities in web applications. This is because user input is often not properly validated, sanitized, or escaped before being used in a web application. This can allow an attacker to manipulate the input and execute malicious code or cause the application to behave unexpectedly. diff --git a/src/data/best-practices/api-security/content/x-frame-options-deny.md b/src/data/best-practices/api-security/content/x-frame-options-deny.md index 2d24d7144..bf6e7450b 100644 --- a/src/data/best-practices/api-security/content/x-frame-options-deny.md +++ b/src/data/best-practices/api-security/content/x-frame-options-deny.md @@ -2,4 +2,4 @@ > Send `X-Frame-Options: deny` header. -The `X-Frame-Options` header prevents the page from being displayed in an iframe, which is commonly used in clickjacking attacks. By setting the value of this header to `deny`, you are telling the browser not to display the page in any iframe. This helps prevent the page from being embedded within an attacker's website and reduces the risk of clickjacking attacks. \ No newline at end of file +The `X-Frame-Options` header prevents the page from being displayed in an iframe, which is commonly used in clickjacking attacks. By setting the value of this header to `deny`, you are telling the browser not to display the page in any iframe. This helps prevent the page from being embedded within an attacker's website and reduces the risk of clickjacking attacks. diff --git a/src/data/best-practices/aws/content/alerts-as-notifications.md b/src/data/best-practices/aws/content/alerts-as-notifications.md index a9b43a036..7de2db596 100644 --- a/src/data/best-practices/aws/content/alerts-as-notifications.md +++ b/src/data/best-practices/aws/content/alerts-as-notifications.md @@ -2,4 +2,4 @@ > Get your alerts to become notifications. -If you've set everyting up correctly, your health checks should automatically destroy bad instances and spawn new ones. There's usually no action to take when getting a CloudWatch alert, as everything should be automated. If you're getting alerts where manual intervention is required, do a post-mortem and figure out if there's a way you can automate the action in future. The last time I had an actionable alert from CloudWatch was about a year ago, and it's extremely awesome not to be woken up at 4am for ops alerts any more. \ No newline at end of file +If you've set everyting up correctly, your health checks should automatically destroy bad instances and spawn new ones. There's usually no action to take when getting a CloudWatch alert, as everything should be automated. If you're getting alerts where manual intervention is required, do a post-mortem and figure out if there's a way you can automate the action in future. The last time I had an actionable alert from CloudWatch was about a year ago, and it's extremely awesome not to be woken up at 4am for ops alerts any more. diff --git a/src/data/best-practices/aws/content/app-changes-for-aws.md b/src/data/best-practices/aws/content/app-changes-for-aws.md index 6b02edb7d..5dbeebf5d 100644 --- a/src/data/best-practices/aws/content/app-changes-for-aws.md +++ b/src/data/best-practices/aws/content/app-changes-for-aws.md @@ -1,3 +1,3 @@ # App Changes for AWS -While a lot of applications can probably just be deployed to an EC2 instance and work well, if you're coming from a physical environment, you may need to re-architect your application in order to accomodate changes. Don't just think you can copy the files over and be done with it. \ No newline at end of file +While a lot of applications can probably just be deployed to an EC2 instance and work well, if you're coming from a physical environment, you may need to re-architect your application in order to accomodate changes. Don't just think you can copy the files over and be done with it. diff --git a/src/data/best-practices/aws/content/automate-everything.md b/src/data/best-practices/aws/content/automate-everything.md index 4c7cd962f..6184de2ab 100644 --- a/src/data/best-practices/aws/content/automate-everything.md +++ b/src/data/best-practices/aws/content/automate-everything.md @@ -1,3 +1,3 @@ # Automate Everything -This is more of general operations advice than AWS specific, but everything needs to be automated. Recovery, deployment, failover, etc. Package and OS updates should be managed by something, whether it's just a bash script, or Chef/Puppet, etc. You shouldn't have to care about this stuff. As mentioned in a different tip, you should also make sure to disable SSH access, as this will pretty quickly highlight any part of your process that isn't automated. Remember the key phrase from the earlier tip, if you have to SSH into your servers, then your automation has failed. \ No newline at end of file +This is more of general operations advice than AWS specific, but everything needs to be automated. Recovery, deployment, failover, etc. Package and OS updates should be managed by something, whether it's just a bash script, or Chef/Puppet, etc. You shouldn't have to care about this stuff. As mentioned in a different tip, you should also make sure to disable SSH access, as this will pretty quickly highlight any part of your process that isn't automated. Remember the key phrase from the earlier tip, if you have to SSH into your servers, then your automation has failed. diff --git a/src/data/best-practices/aws/content/avoid-fs-mounts.md b/src/data/best-practices/aws/content/avoid-fs-mounts.md index 9ef9fe4d5..9cbd409da 100644 --- a/src/data/best-practices/aws/content/avoid-fs-mounts.md +++ b/src/data/best-practices/aws/content/avoid-fs-mounts.md @@ -2,4 +2,4 @@ > Avoid filesystem mounts (FUSE, etc). -I've found them to be about as reliable as a large government department when used in critical applications. Use the SDK instead. \ No newline at end of file +I've found them to be about as reliable as a large government department when used in critical applications. Use the SDK instead. diff --git a/src/data/best-practices/aws/content/avoid-multiple-scaling-triggers.md b/src/data/best-practices/aws/content/avoid-multiple-scaling-triggers.md index d55c8a5e7..748c8d496 100644 --- a/src/data/best-practices/aws/content/avoid-multiple-scaling-triggers.md +++ b/src/data/best-practices/aws/content/avoid-multiple-scaling-triggers.md @@ -2,4 +2,4 @@ > Don't use multiple scaling triggers on the same group. -If you have multiple CloudWatch alarms which trigger scaling actions for the same auto-scaling group, it might not work as you initially expect it to. For example, let's say you add a trigger to scale up when CPU usage gets too high, or when the inbound network traffic gets high, and your scale down actions are the opposite. You might get an increase in CPU usage, but your inbound network is fine. So the high CPU trigger causes a scale-up action, but the low inbound traffic alarm immediately triggers a scale-down action. Depending on how you've set your cooldown period, this can cause quite a problem as they'll just fight against each other. If you want multiple triggers, you can use multiple auto-scaling groups. \ No newline at end of file +If you have multiple CloudWatch alarms which trigger scaling actions for the same auto-scaling group, it might not work as you initially expect it to. For example, let's say you add a trigger to scale up when CPU usage gets too high, or when the inbound network traffic gets high, and your scale down actions are the opposite. You might get an increase in CPU usage, but your inbound network is fine. So the high CPU trigger causes a scale-up action, but the low inbound traffic alarm immediately triggers a scale-down action. Depending on how you've set your cooldown period, this can cause quite a problem as they'll just fight against each other. If you want multiple triggers, you can use multiple auto-scaling groups. diff --git a/src/data/best-practices/aws/content/avoid-server-eips.md b/src/data/best-practices/aws/content/avoid-server-eips.md index df1705a5d..ce466c54b 100644 --- a/src/data/best-practices/aws/content/avoid-server-eips.md +++ b/src/data/best-practices/aws/content/avoid-server-eips.md @@ -2,4 +2,4 @@ > Don't give servers static/elastic IPs. -For a typical web application, you should put things behind a load balancer, and balance them between AZs. There are a few cases where Elastic IPs will probably need to be used, but in order to make best use of auto-scaling you'll want to use a load balancer instad of giving every instance their own unique IP. \ No newline at end of file +For a typical web application, you should put things behind a load balancer, and balance them between AZs. There are a few cases where Elastic IPs will probably need to be used, but in order to make best use of auto-scaling you'll want to use a load balancer instad of giving every instance their own unique IP. diff --git a/src/data/best-practices/aws/content/aws-right-choice.md b/src/data/best-practices/aws/content/aws-right-choice.md index 6d209ca2b..0de608ee5 100644 --- a/src/data/best-practices/aws/content/aws-right-choice.md +++ b/src/data/best-practices/aws/content/aws-right-choice.md @@ -2,4 +2,4 @@ > Make sure AWS is right for your workload. -You should make sure that using AWS is correct for your particular workload. If you have a steady load and 24/7 servers, it's possible there are cheaper providers you can use, or it might even be cheaper to use dedicated hardware of your own. One of the big benefits of AWS is the ability to scale up and down rapidly in response to load, but not everyone needs that feature. As when purchasing anything, you should shop around a bit first to make sure you're getting the best deal for what you need \ No newline at end of file +You should make sure that using AWS is correct for your particular workload. If you have a steady load and 24/7 servers, it's possible there are cheaper providers you can use, or it might even be cheaper to use dedicated hardware of your own. One of the big benefits of AWS is the ability to scale up and down rapidly in response to load, but not everyone needs that feature. As when purchasing anything, you should shop around a bit first to make sure you're getting the best deal for what you need diff --git a/src/data/best-practices/aws/content/beware-aws-limits.md b/src/data/best-practices/aws/content/beware-aws-limits.md index eb2850eaa..f8e32077b 100644 --- a/src/data/best-practices/aws/content/beware-aws-limits.md +++ b/src/data/best-practices/aws/content/beware-aws-limits.md @@ -2,4 +2,4 @@ > Be aware of AWS service limits before you deploy. -Various service limits are enforced which aren't highlighted until you're actually trying to deploy your application and get the error notification. These limits can easily be increased by making a request to AWS support, however that can involve a significant turn around time (as low as a few minutes, up to a few days, based on past experience), during which you won't be able to finish deploying. A few days before deploying, you should consult the service limits page to see if you think you're going to exceed any of them, and make your support request ahead of time. You will need to make a separate request to each department where you need a limit increased. It's also worth pointing out that some limits are global, while others are per-region. \ No newline at end of file +Various service limits are enforced which aren't highlighted until you're actually trying to deploy your application and get the error notification. These limits can easily be increased by making a request to AWS support, however that can involve a significant turn around time (as low as a few minutes, up to a few days, based on past experience), during which you won't be able to finish deploying. A few days before deploying, you should consult the service limits page to see if you think you're going to exceed any of them, and make your support request ahead of time. You will need to make a separate request to each department where you need a limit increased. It's also worth pointing out that some limits are global, while others are per-region. diff --git a/src/data/best-practices/aws/content/billing-alerts.md b/src/data/best-practices/aws/content/billing-alerts.md index e4a35c51a..765b90b17 100644 --- a/src/data/best-practices/aws/content/billing-alerts.md +++ b/src/data/best-practices/aws/content/billing-alerts.md @@ -2,4 +2,4 @@ > Set up granular billing alerts. -You should always have at least one billing alert set up, but that will only tell you on a monthly basis once you've exceeded your allowance. If you want to catch runaway billing early, you need a more fine grained approach. The way I do it is to set up an alert for my expected usage each week. So the first week's alert for say $1,000, the second for $2,000, third for $3,000, etc. If the week-2 alarm goes off before the 14th/15th of the month, then I know something is probably going wrong. For even more fine-grained control, you can set this up for each individual service, that way you instantly know which service is causing the problem. This could be useful if your usage on one service is quite steady month-to-month, but another is more erratic. Have the indidividual weekly alerts for the steady one, but just an overall one for the more erratic one. If everything is steady, then this is probably overkill, as looking at CloudWatch will quickly tell you which service is the one causing the problem. \ No newline at end of file +You should always have at least one billing alert set up, but that will only tell you on a monthly basis once you've exceeded your allowance. If you want to catch runaway billing early, you need a more fine grained approach. The way I do it is to set up an alert for my expected usage each week. So the first week's alert for say $1,000, the second for $2,000, third for $3,000, etc. If the week-2 alarm goes off before the 14th/15th of the month, then I know something is probably going wrong. For even more fine-grained control, you can set this up for each individual service, that way you instantly know which service is causing the problem. This could be useful if your usage on one service is quite steady month-to-month, but another is more erratic. Have the indidividual weekly alerts for the steady one, but just an overall one for the more erratic one. If everything is steady, then this is probably overkill, as looking at CloudWatch will quickly tell you which service is the one causing the problem. diff --git a/src/data/best-practices/aws/content/bucket-names-ssl.md b/src/data/best-practices/aws/content/bucket-names-ssl.md index 717f87063..935ccaf9e 100644 --- a/src/data/best-practices/aws/content/bucket-names-ssl.md +++ b/src/data/best-practices/aws/content/bucket-names-ssl.md @@ -2,4 +2,4 @@ > Use "-" instead of "." in bucket names for SSL. -If you ever want to use your bucket over SSL, using a "." will cause you to get certificate mismatch errors. You can't change bucket names once you've created them, so you'd have to copy everything to a new bucket. \ No newline at end of file +If you ever want to use your bucket over SSL, using a "." will cause you to get certificate mismatch errors. You can't change bucket names once you've created them, so you'd have to copy everything to a new bucket. diff --git a/src/data/best-practices/aws/content/cloudtrail.md b/src/data/best-practices/aws/content/cloudtrail.md index 35de80671..cf23efdcb 100644 --- a/src/data/best-practices/aws/content/cloudtrail.md +++ b/src/data/best-practices/aws/content/cloudtrail.md @@ -2,4 +2,4 @@ > Use CloudTrail to keep an audit log. -CloudTrail will log any action performed via the APIs or web console into an S3 bucket. Set up the bucket with versioning to be sure no one can modify your logs, and you then have a complete audit trail of all changes in your account. You hope that you will never need to use this, but it's well worth having for when you do. \ No newline at end of file +CloudTrail will log any action performed via the APIs or web console into an S3 bucket. Set up the bucket with versioning to be sure no one can modify your logs, and you then have a complete audit trail of all changes in your account. You hope that you will never need to use this, but it's well worth having for when you do. diff --git a/src/data/best-practices/aws/content/cloudwatch-cli-tools.md b/src/data/best-practices/aws/content/cloudwatch-cli-tools.md index 0730df6d0..6105de5f8 100644 --- a/src/data/best-practices/aws/content/cloudwatch-cli-tools.md +++ b/src/data/best-practices/aws/content/cloudwatch-cli-tools.md @@ -2,4 +2,4 @@ > Use the CLI tools. -It can become extremely tedious to create alarms using the web console, especially if you're setting up a lot of similar alarms, as there's no ability to "clone" an existing alarm while making a minor change elsewhere. Scripting this using the CLI tools can save you lots of time. \ No newline at end of file +It can become extremely tedious to create alarms using the web console, especially if you're setting up a lot of similar alarms, as there's no ability to "clone" an existing alarm while making a minor change elsewhere. Scripting this using the CLI tools can save you lots of time. diff --git a/src/data/best-practices/aws/content/cloudwatch-detailed-monitoring.md b/src/data/best-practices/aws/content/cloudwatch-detailed-monitoring.md index 1e81abad8..ac3c30778 100644 --- a/src/data/best-practices/aws/content/cloudwatch-detailed-monitoring.md +++ b/src/data/best-practices/aws/content/cloudwatch-detailed-monitoring.md @@ -2,4 +2,4 @@ > Use detailed monitoring. -It's ~$3.50 per instance/month, and well worth the extra cost for the extra detail. 1 minute granularity is much better than 5 minute. You can have cases where a problem is hidden in the 5 minute breakdown, but shows itself quite clearly in the 1 minute graphs. This may not be useful for everyone, but it's made investigating some issues much easier for me. \ No newline at end of file +It's ~$3.50 per instance/month, and well worth the extra cost for the extra detail. 1 minute granularity is much better than 5 minute. You can have cases where a problem is hidden in the 5 minute breakdown, but shows itself quite clearly in the 1 minute graphs. This may not be useful for everyone, but it's made investigating some issues much easier for me. diff --git a/src/data/best-practices/aws/content/cloudwatch-free-metrics.md b/src/data/best-practices/aws/content/cloudwatch-free-metrics.md index 5d29d89fd..b1404b09a 100644 --- a/src/data/best-practices/aws/content/cloudwatch-free-metrics.md +++ b/src/data/best-practices/aws/content/cloudwatch-free-metrics.md @@ -2,4 +2,4 @@ > Use the free metrics. -CloudWatch monitors all sorts of things for free (bandwidth, CPU usage, etc.), and you get up to 2 weeks of historical data. This saves you having to use your own tools to monitor you systems. If you need longer than 2 weeks, unfortunately you'll need to use a third-party or custom built monitoring solution. \ No newline at end of file +CloudWatch monitors all sorts of things for free (bandwidth, CPU usage, etc.), and you get up to 2 weeks of historical data. This saves you having to use your own tools to monitor you systems. If you need longer than 2 weeks, unfortunately you'll need to use a third-party or custom built monitoring solution. diff --git a/src/data/best-practices/aws/content/configured-azs-only.md b/src/data/best-practices/aws/content/configured-azs-only.md index eade6f027..3828cf53a 100644 --- a/src/data/best-practices/aws/content/configured-azs-only.md +++ b/src/data/best-practices/aws/content/configured-azs-only.md @@ -2,4 +2,4 @@ > Only use the availability zones (AZs) your ELB is configured for. -If you add your scaling group to multiple AZs, make sure your ELB is configured to use all of those AZs, otherwise your capacity will scale up, and the load balancer won't be able to see them. \ No newline at end of file +If you add your scaling group to multiple AZs, make sure your ELB is configured to use all of those AZs, otherwise your capacity will scale up, and the load balancer won't be able to see them. diff --git a/src/data/best-practices/aws/content/disable-ssh-access.md b/src/data/best-practices/aws/content/disable-ssh-access.md index 21d916854..01843ae84 100644 --- a/src/data/best-practices/aws/content/disable-ssh-access.md +++ b/src/data/best-practices/aws/content/disable-ssh-access.md @@ -4,4 +4,4 @@ This sounds crazy, I know, but port 22 should be disallowed for everyone in your security group. If there's one thing you take away from this post, this should be it: **If you have to SSH into your servers, then your automation has failed**. Disabling it at the firewall level (rather than on the servers themselves) will help the transition to this frame of thinking, as it will highlight any areas you need to automate, while still letting you easily re-instate access to solve immediate issues. It's incredibly freeing to know that you never need to SSH into an instance. This is both the most frightening and yet most useful thing I've learned. -Disabling inbound SSH has just been a way for me to stop myself cheating with automation (Oh, I'll just SSH in and fix this one thing). I can still re-enable it in the security group if I need to actively debug something on an instance, since sometimes there really is no other way to debug certain issues. It also depends on your application; If your application relies on you being able to push things to a server via SSH, then disabling it might be a bad idea. Blocking inbound SSH worked for me, and forced me to get my automation into a decent state, but it might not be for everyone. \ No newline at end of file +Disabling inbound SSH has just been a way for me to stop myself cheating with automation (Oh, I'll just SSH in and fix this one thing). I can still re-enable it in the security group if I need to actively debug something on an instance, since sometimes there really is no other way to debug certain issues. It also depends on your application; If your application relies on you being able to push things to a server via SSH, then disabling it might be a bad idea. Blocking inbound SSH worked for me, and forced me to get my automation into a decent state, but it might not be for everyone. diff --git a/src/data/best-practices/aws/content/ec2-roles.md b/src/data/best-practices/aws/content/ec2-roles.md index 8f64fcd5b..d2c845ea6 100644 --- a/src/data/best-practices/aws/content/ec2-roles.md +++ b/src/data/best-practices/aws/content/ec2-roles.md @@ -2,4 +2,4 @@ > Use EC2 roles, do not give applications an IAM account. -If your application has AWS credentials baked into it, you're "doing it wrong". One of the reasons it's important to use the AWS SDK for your language is that you can really easily use EC2 IAM roles. The idea of a role is that you specify the permissions a certain role should get, then assign that role to an EC2 instance. Whenever you use the AWS SDK on that instance, you don't specify any credentials. Instead, the SDK will retrieve temporary credentials which have the permissions of the role you set up. This is all handled transparently as far as you're concerned. It's secure, and extremely useful. \ No newline at end of file +If your application has AWS credentials baked into it, you're "doing it wrong". One of the reasons it's important to use the AWS SDK for your language is that you can really easily use EC2 IAM roles. The idea of a role is that you specify the permissions a certain role should get, then assign that role to an EC2 instance. Whenever you use the AWS SDK on that instance, you don't specify any credentials. Instead, the SDK will retrieve temporary credentials which have the permissions of the role you set up. This is all handled transparently as far as you're concerned. It's secure, and extremely useful. diff --git a/src/data/best-practices/aws/content/failover-event-subscription.md b/src/data/best-practices/aws/content/failover-event-subscription.md index eebe771a2..8a3f31521 100644 --- a/src/data/best-practices/aws/content/failover-event-subscription.md +++ b/src/data/best-practices/aws/content/failover-event-subscription.md @@ -2,4 +2,4 @@ > Set up event subscriptions for failover. -If you're using a Multi-AZ setup, this is one of those things you might not think about which ends up being incredibly useful when you do need it. \ No newline at end of file +If you're using a Multi-AZ setup, this is one of those things you might not think about which ends up being incredibly useful when you do need it. diff --git a/src/data/best-practices/aws/content/group-permissions.md b/src/data/best-practices/aws/content/group-permissions.md index 57b69ad00..8091b1127 100644 --- a/src/data/best-practices/aws/content/group-permissions.md +++ b/src/data/best-practices/aws/content/group-permissions.md @@ -2,4 +2,4 @@ > Assign permissions to groups, not users. -Managing users can be a pain, if you're using Active Directory, or some other external authentication mechanism which you've integrated with IAM, then this probably won't matter as much (or maybe it matters more). But I've found it much easier to manage permissions by assigning them only to groups, rather than to individual users. It's much easier to rein in permissions and get an overall view of the system than going through each individual user to see what permissions have been assigned. \ No newline at end of file +Managing users can be a pain, if you're using Active Directory, or some other external authentication mechanism which you've integrated with IAM, then this probably won't matter as much (or maybe it matters more). But I've found it much easier to manage permissions by assigning them only to groups, rather than to individual users. It's much easier to rein in permissions and get an overall view of the system than going through each individual user to see what permissions have been assigned. diff --git a/src/data/best-practices/aws/content/index.md b/src/data/best-practices/aws/content/index.md index 4e768b56d..792d60054 100644 --- a/src/data/best-practices/aws/content/index.md +++ b/src/data/best-practices/aws/content/index.md @@ -1 +1 @@ -# \ No newline at end of file +# diff --git a/src/data/best-practices/aws/content/key-management-strategy.md b/src/data/best-practices/aws/content/key-management-strategy.md index d263fd1db..55cf570ee 100644 --- a/src/data/best-practices/aws/content/key-management-strategy.md +++ b/src/data/best-practices/aws/content/key-management-strategy.md @@ -2,4 +2,4 @@ > Decide on a key-management strategy from the start. -Are you going to have one key-pair per group of instances, or are you going to have one key-pair you use for your entire account? It's easy to modify your authorized-keys file with a bootstrap script of course, but you need to decide if you want to manage multiple key-pairs or not, as things will get complicated later on if you try to change your mind. \ No newline at end of file +Are you going to have one key-pair per group of instances, or are you going to have one key-pair you use for your entire account? It's easy to modify your authorized-keys file with a bootstrap script of course, but you need to decide if you want to manage multiple key-pairs or not, as things will get complicated later on if you try to change your mind. diff --git a/src/data/best-practices/aws/content/multi-factor-auth-iam.md b/src/data/best-practices/aws/content/multi-factor-auth-iam.md index 599b63873..f579120f9 100644 --- a/src/data/best-practices/aws/content/multi-factor-auth-iam.md +++ b/src/data/best-practices/aws/content/multi-factor-auth-iam.md @@ -2,4 +2,4 @@ > IAM users can have multi-factor authentication, use it! -Enable MFA for your IAM users to add an extra layer of security. Your master account should most definitely have this, but it's also worth enabling it for normal IAM users too. \ No newline at end of file +Enable MFA for your IAM users to add an extra layer of security. Your master account should most definitely have this, but it's also worth enabling it for normal IAM users too. diff --git a/src/data/best-practices/aws/content/pre-warm-elb.md b/src/data/best-practices/aws/content/pre-warm-elb.md index 53459b446..879eaa1b1 100644 --- a/src/data/best-practices/aws/content/pre-warm-elb.md +++ b/src/data/best-practices/aws/content/pre-warm-elb.md @@ -2,5 +2,4 @@ > Pre-warm your ELBs if you're expecting heavy traffic. - It takes time for your ELB to scale up capacity. If you know you're going to have a large traffic spike (selling tickets, big event, etc), you need to "warm up" your ELB in advance. You can inject a load of traffic, and it will cause ELB to scale up and not choke when you actually get the traffic, however AWS suggest you contact them instead to prewarm your load balancer. (Source: [Best Practices in Evaluating Elastic Load Balancing](https://aws.amazon.com/articles/best-practices-in-evaluating-elastic-load-balancing/#pre-warming)). Alternatively you can install your own load balancer software on an EC2 instance and use that instead (HAProxy, etc). diff --git a/src/data/best-practices/aws/content/redundant-across-azs.md b/src/data/best-practices/aws/content/redundant-across-azs.md index 98a20eaca..9096d0637 100644 --- a/src/data/best-practices/aws/content/redundant-across-azs.md +++ b/src/data/best-practices/aws/content/redundant-across-azs.md @@ -2,4 +2,4 @@ > Always be redundant across availability zones (AZs). -AZs can have outages, it's happened in the past that certain things in an AZ have gone down. Spreading your application into multiple AZs is as simple as adding a new AZ to your load balancer and starting an instance in that AZ. You should spread your load over two AZs at the very least! If you can afford it, being redundant across regions can also be well worth it, but this generally has a more complex set up cost and isn't always necessary. You can now copy AMIs between regions, and you can set up your Route53 records to balance traffic between regions, but you can't use a single ELB across regions. \ No newline at end of file +AZs can have outages, it's happened in the past that certain things in an AZ have gone down. Spreading your application into multiple AZs is as simple as adding a new AZ to your load balancer and starting an instance in that AZ. You should spread your load over two AZs at the very least! If you can afford it, being redundant across regions can also be well worth it, but this generally has a more complex set up cost and isn't always necessary. You can now copy AMIs between regions, and you can set up your Route53 records to balance traffic between regions, but you can't use a single ELB across regions. diff --git a/src/data/best-practices/aws/content/release-eips.md b/src/data/best-practices/aws/content/release-eips.md index 8ead2cdac..1c1e6f9c2 100644 --- a/src/data/best-practices/aws/content/release-eips.md +++ b/src/data/best-practices/aws/content/release-eips.md @@ -2,4 +2,4 @@ > Don't keep unassociated Elastic IPs. -You get charged for any Elastic IPs you have created but not associated with an instance, so make sure you don't keep them around once you're done with them. \ No newline at end of file +You get charged for any Elastic IPs you have created but not associated with an instance, so make sure you don't keep them around once you're done with them. diff --git a/src/data/best-practices/aws/content/reserved-instances.md b/src/data/best-practices/aws/content/reserved-instances.md index b6951ffe1..2606b8b7d 100644 --- a/src/data/best-practices/aws/content/reserved-instances.md +++ b/src/data/best-practices/aws/content/reserved-instances.md @@ -2,4 +2,4 @@ > Use reserved instances to save big $$$. -Reserving an instance is just putting some money upfront in order to get a lower hourly rate. It ends up being a lot cheaper than an on-demand instance would cost. So if you know you're going to be keeping an instance around for 1 or 3 years, it's well worth reserving them. Reserved instances are a purely logical concept in AWS, you don't assign a specific instance to be reserved, but rather just specify the type and size, and any instances that match the criteria will get the lower price. \ No newline at end of file +Reserving an instance is just putting some money upfront in order to get a lower hourly rate. It ends up being a lot cheaper than an on-demand instance would cost. So if you know you're going to be keeping an instance around for 1 or 3 years, it's well worth reserving them. Reserved instances are a purely logical concept in AWS, you don't assign a specific instance to be reserved, but rather just specify the type and size, and any instances that match the criteria will get the lower price. diff --git a/src/data/best-practices/aws/content/s3-hive-results.md b/src/data/best-practices/aws/content/s3-hive-results.md index 720a2566c..0e0ec61a4 100644 --- a/src/data/best-practices/aws/content/s3-hive-results.md +++ b/src/data/best-practices/aws/content/s3-hive-results.md @@ -2,4 +2,4 @@ > Specify a directory on S3 for Hive results. -If you use Hive to output results to S3, you must specify a directory in the bucket, not the root of the bucket, otherwise you'll get a rather unhelpful NullPointerException with no real explanation as to why. \ No newline at end of file +If you use Hive to output results to S3, you must specify a directory in the bucket, not the root of the bucket, otherwise you'll get a rather unhelpful NullPointerException with no real explanation as to why. diff --git a/src/data/best-practices/aws/content/scale-down-events.md b/src/data/best-practices/aws/content/scale-down-events.md index 91b0e1313..6d3cd56d2 100644 --- a/src/data/best-practices/aws/content/scale-down-events.md +++ b/src/data/best-practices/aws/content/scale-down-events.md @@ -2,4 +2,4 @@ > Scale down on INSUFFICIENT_DATA as well as ALARM. -For your scale-down action, make sure to trigger a scale-down event when there's no metric data, as well as when your trigger goes off. For example, if you have an app which usually has very low traffic, but experiences occasional spikes, you want to be sure that it scales down once the spike is over and the traffic stops. If there's no traffic, you'll get `INSUFFIFIENT_DATA` instead of `ALARM` for your low traffic threshold and it won't trigger a scale-down action. \ No newline at end of file +For your scale-down action, make sure to trigger a scale-down event when there's no metric data, as well as when your trigger goes off. For example, if you have an app which usually has very low traffic, but experiences occasional spikes, you want to be sure that it scales down once the spike is over and the traffic stops. If there's no traffic, you'll get `INSUFFIFIENT_DATA` instead of `ALARM` for your low traffic threshold and it won't trigger a scale-down action. diff --git a/src/data/best-practices/aws/content/scale-horizontally.md b/src/data/best-practices/aws/content/scale-horizontally.md index 1b1b51ff4..a9e4788c8 100644 --- a/src/data/best-practices/aws/content/scale-horizontally.md +++ b/src/data/best-practices/aws/content/scale-horizontally.md @@ -1,3 +1,3 @@ # Scale Horizontally -I've found that using lots of smaller machines is generally more reliable than using a smaller number of larger machines. You need to balance this though, as trying to run your application from 100 t1.micro instances probably isn't going to work very well. Breaking your application into lots of smaller instances means you'll be more resiliant to failure in one of the machines. If you're just running from two massive compute cluster machines, and one goes down, things are going to get bad. \ No newline at end of file +I've found that using lots of smaller machines is generally more reliable than using a smaller number of larger machines. You need to balance this though, as trying to run your application from 100 t1.micro instances probably isn't going to work very well. Breaking your application into lots of smaller instances means you'll be more resiliant to failure in one of the machines. If you're just running from two massive compute cluster machines, and one goes down, things are going to get bad. diff --git a/src/data/best-practices/aws/content/security-audit.md b/src/data/best-practices/aws/content/security-audit.md index b80572e25..4163ee0b2 100644 --- a/src/data/best-practices/aws/content/security-audit.md +++ b/src/data/best-practices/aws/content/security-audit.md @@ -3,5 +3,3 @@ > Set up automated security auditing. It's important to keep track of changes in your infrastructure's security settings. One way to do this is to first set up a security auditer role ([JSON template](https://gist.github.com/bigsnarfdude/d0758b4fd335085623be)), which will give anyone assigned that role read-only access to any security related settings on your account. You can then use this rather [fantastic Python script](https://gist.github.com/jlevy/cce1b44fc24f94599d0a4b3e613cc15d), which will go over all the items in your account and produce a canonical output showing your configuration. You set up a cronjob somewhere to run this script, and compare its output to the output from the previous run. Any differences will show you exactly what has been changed in your security configuration. It's useful to set this up and just have it email you the diff of any changes. (Source: Intrusion Detection in the Cloud - [Presentation](http://awsmedia.s3.amazonaws.com/SEC402.pdf)) - - diff --git a/src/data/best-practices/aws/content/tag-everything.md b/src/data/best-practices/aws/content/tag-everything.md index d5c4942d5..e26458857 100644 --- a/src/data/best-practices/aws/content/tag-everything.md +++ b/src/data/best-practices/aws/content/tag-everything.md @@ -1,3 +1,3 @@ # Tag Everything -Pretty much everything can be given tags, use them! They're great for organising things, make it easier to search and group things up. You can also use them to trigger certain behaviour on your instances, for example a tag of env=debug could put your application into debug mode when it deploys, etc. \ No newline at end of file +Pretty much everything can be given tags, use them! They're great for organising things, make it easier to search and group things up. You can also use them to trigger certain behaviour on your instances, for example a tag of env=debug could put your application into debug mode when it deploys, etc. diff --git a/src/data/best-practices/aws/content/terminate-ssl.md b/src/data/best-practices/aws/content/terminate-ssl.md index ee40773d6..7e38e4263 100644 --- a/src/data/best-practices/aws/content/terminate-ssl.md +++ b/src/data/best-practices/aws/content/terminate-ssl.md @@ -2,4 +2,4 @@ > Terminate SSL on the load balancer. -You'll need to add your SSL certificate information to the ELB, but this will take the overhead of SSL termination away from your servers which can speed things up. Additionally, if you upload your SSL certificate, you can pass through the HTTPS traffic and the load balancer will add some extra headers to your request (x-forwarded-for, etc), which are useful if you want to know who the end user is. If you just forward TCP, then those headers aren't added and you lose the information. \ No newline at end of file +You'll need to add your SSL certificate information to the ELB, but this will take the overhead of SSL termination away from your servers which can speed things up. Additionally, if you upload your SSL certificate, you can pass through the HTTPS traffic and the load balancer will add some extra headers to your request (x-forwarded-for, etc), which are useful if you want to know who the end user is. If you just forward TCP, then those headers aren't added and you lose the information. diff --git a/src/data/best-practices/aws/content/termination-protection.md b/src/data/best-practices/aws/content/termination-protection.md index c4331e6ab..8c1eea872 100644 --- a/src/data/best-practices/aws/content/termination-protection.md +++ b/src/data/best-practices/aws/content/termination-protection.md @@ -2,4 +2,4 @@ > Use termination protection for non-auto-scaling instances. -If you have any instances which are one-off things that aren't under auto-scaling, then you should probably enable termination protection, to stop anyone from accidentally deleting the instance. I've had it happen, it sucks, learn from my mistake! \ No newline at end of file +If you have any instances which are one-off things that aren't under auto-scaling, then you should probably enable termination protection, to stop anyone from accidentally deleting the instance. I've had it happen, it sucks, learn from my mistake! diff --git a/src/data/best-practices/aws/content/tools-for-logs.md b/src/data/best-practices/aws/content/tools-for-logs.md index 2219ec053..c979717c0 100644 --- a/src/data/best-practices/aws/content/tools-for-logs.md +++ b/src/data/best-practices/aws/content/tools-for-logs.md @@ -2,4 +2,4 @@ > Have tools to view application logs. -You should have an admin tool, syslog viewer, or something that allows you to view current real-time log info without needing to SSH into a running instance. If you have centralised logging (which you really should), then you just want to be sure you can read the logs there without needing to use SSH. Needing to SSH into a running application instance to view logs is going to become problematic. \ No newline at end of file +You should have an admin tool, syslog viewer, or something that allows you to view current real-time log info without needing to SSH into a running instance. If you have centralised logging (which you really should), then you just want to be sure you can read the logs there without needing to use SSH. Needing to SSH into a running application instance to view logs is going to become problematic. diff --git a/src/data/best-practices/aws/content/use-alias-records.md b/src/data/best-practices/aws/content/use-alias-records.md index 8dd5bb4ae..2fc151368 100644 --- a/src/data/best-practices/aws/content/use-alias-records.md +++ b/src/data/best-practices/aws/content/use-alias-records.md @@ -2,4 +2,4 @@ > Use ALIAS records. -An ALIAS record will link your record set to a particular AWS resource directly (i.e. you can map a domain to an S3 bucket), but the key is that you don't get charged for any ALIAS lookups. So whereas a CNAME entry would cost you money, an ALIAS record won't. Also, unlike a CNAME, you can use an ALIAS on your zone apex. You can read more about this on [the AWS page for creating alias resource record sets](http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/CreatingAliasRRSets.html). \ No newline at end of file +An ALIAS record will link your record set to a particular AWS resource directly (i.e. you can map a domain to an S3 bucket), but the key is that you don't get charged for any ALIAS lookups. So whereas a CNAME entry would cost you money, an ALIAS record won't. Also, unlike a CNAME, you can use an ALIAS on your zone apex. You can read more about this on [the AWS page for creating alias resource record sets](http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/CreatingAliasRRSets.html). diff --git a/src/data/best-practices/aws/content/use-iam-acount.md b/src/data/best-practices/aws/content/use-iam-acount.md index 5274407aa..2e7e4a97a 100644 --- a/src/data/best-practices/aws/content/use-iam-acount.md +++ b/src/data/best-practices/aws/content/use-iam-acount.md @@ -5,4 +5,3 @@ Usually you'll have an "operations account" for a service, and your entire ops team will have the password. With AWS, you definitely don't want to do that. Everyone gets an IAM user with just the permissions they need (least privilege). An IAM user can control everything in the infrastructure. At the time of writing, the only thing an IAM user can't access are some parts of the billing pages. If you want to protect your account even more, make sure to [enable multi-factor authentication](http://aws.amazon.com/iam/details/mfa/) for everyone (you can use Google Authenticator). I've heard of some users who give the MFA token to two people, and the password to two others, so to perform any action on the master account, two of the users need to agree. This is overkill for my case, but worth mentioning in case someone else wants to do it. - diff --git a/src/data/best-practices/aws/content/use-iam-roles.md b/src/data/best-practices/aws/content/use-iam-roles.md index 0c833cd92..3ee1aa93d 100644 --- a/src/data/best-practices/aws/content/use-iam-roles.md +++ b/src/data/best-practices/aws/content/use-iam-roles.md @@ -1,3 +1,3 @@ # Use IAM Roles -Don't create users for application, always use IAM roles if you can. They simplify everything, and keeps things secure. Having application users just creates a point of failure (what if someone accidentally deletes the API key?) and it becomes a pain to manage. \ No newline at end of file +Don't create users for application, always use IAM roles if you can. They simplify everything, and keeps things secure. Having application users just creates a point of failure (what if someone accidentally deletes the API key?) and it becomes a pain to manage. diff --git a/src/data/best-practices/frontend-performance/content/analyse-stylesheets-complexity.md b/src/data/best-practices/frontend-performance/content/analyse-stylesheets-complexity.md index 73da37bdc..e650d1a02 100644 --- a/src/data/best-practices/frontend-performance/content/analyse-stylesheets-complexity.md +++ b/src/data/best-practices/frontend-performance/content/analyse-stylesheets-complexity.md @@ -9,4 +9,4 @@ Your CSS should be organized, using a CSS preprocessor can help you with that. S - [TestMyCSS | Optimize and Check CSS Performance](http://www.testmycss.com/) - [CSS Stats](https://cssstats.com/) - [macbre/analyze-css: CSS selectors complexity and performance analyzer](https://github.com/macbre/analyze-css) -- [Project Wallace](https://www.projectwallace.com/) is like CSS Stats but stores stats over time so you can track your changes \ No newline at end of file +- [Project Wallace](https://www.projectwallace.com/) is like CSS Stats but stores stats over time so you can track your changes diff --git a/src/data/best-practices/frontend-performance/content/analyze-js-for-perf-issues.md b/src/data/best-practices/frontend-performance/content/analyze-js-for-perf-issues.md index 7e8dc583d..71d3831ad 100644 --- a/src/data/best-practices/frontend-performance/content/analyze-js-for-perf-issues.md +++ b/src/data/best-practices/frontend-performance/content/analyze-js-for-perf-issues.md @@ -10,4 +10,4 @@ Use the Timeline tool in the Chrome Developer Tool to evaluate scripts events an - [JavaScript Profiling With The Chrome Developer Tools](https://www.smashingmagazine.com/2012/06/javascript-profiling-chrome-developer-tools/) - [How to Record Heap Snapshots | Tools for Web Developers](https://developers.google.com/web/tools/chrome-devtools/memory-problems/heap-snapshots) - [Chapter 22 - Profiling the Frontend - Blackfire](https://blackfire.io/docs/book/22-frontend-profiling) -- [30 Tips To Improve Javascript Performance](http://www.monitis.com/blog/30-tips-to-improve-javascript-performance/) \ No newline at end of file +- [30 Tips To Improve Javascript Performance](http://www.monitis.com/blog/30-tips-to-improve-javascript-performance/) diff --git a/src/data/best-practices/frontend-performance/content/avoid-404-files.md b/src/data/best-practices/frontend-performance/content/avoid-404-files.md index d7288b901..cab0cd43d 100644 --- a/src/data/best-practices/frontend-performance/content/avoid-404-files.md +++ b/src/data/best-practices/frontend-performance/content/avoid-404-files.md @@ -4,4 +4,4 @@ 404 request can slow down the performance of your website and negatively impact the user experience. Additionally, they can also cause search engines to crawl and index non-existent pages, which can negatively impact your search engine rankings. To avoid 404 requests, ensure that all links on your website are valid and that any broken links are fixed promptly. -- [How to avoid Bad Requests?](https://varvy.com/pagespeed/avoid-bad-requests.html) \ No newline at end of file +- [How to avoid Bad Requests?](https://varvy.com/pagespeed/avoid-bad-requests.html) diff --git a/src/data/best-practices/frontend-performance/content/avoid-base64-images.md b/src/data/best-practices/frontend-performance/content/avoid-base64-images.md index 131f0c328..e3615a55b 100644 --- a/src/data/best-practices/frontend-performance/content/avoid-base64-images.md +++ b/src/data/best-practices/frontend-performance/content/avoid-base64-images.md @@ -17,4 +17,4 @@ Instead of using Base64 encoded images, it is generally recommended to use binar - [Base64 Encoding & Performance, Part 1 and 2 by Harry Roberts](https://csswizardry.com/2017/02/base64-encoding-and-performance/) - [A closer look at Base64 image performance – The Page Not Found Blog](http://www.andygup.net/a-closer-look-at-base64-image-performance/) - [When to base64 encode images (and when not to) | David Calhoun](https://www.davidbcalhoun.com/2011/when-to-base64-encode-images-and-when-not-to/) -- [Base64 encoding images for faster pages | Performance and seo factors](https://varvy.com/pagespeed/base64-images.html) \ No newline at end of file +- [Base64 encoding images for faster pages | Performance and seo factors](https://varvy.com/pagespeed/base64-images.html) diff --git a/src/data/best-practices/frontend-performance/content/avoid-inline-css.md b/src/data/best-practices/frontend-performance/content/avoid-inline-css.md index 1c771701e..04f70c4dc 100644 --- a/src/data/best-practices/frontend-performance/content/avoid-inline-css.md +++ b/src/data/best-practices/frontend-performance/content/avoid-inline-css.md @@ -6,4 +6,4 @@ One of the first reason it's because it's a good practice to separate content fr Always use external stylesheets or embed CSS in your `
` (and follow the others CSS performance rules) -- [Observe CSS Best Practices: Avoid CSS Inline Styles](https://www.lifewire.com/avoid-inline-styles-for-css-3466846) \ No newline at end of file +- [Observe CSS Best Practices: Avoid CSS Inline Styles](https://www.lifewire.com/avoid-inline-styles-for-css-3466846) diff --git a/src/data/best-practices/frontend-performance/content/avoid-multiple-inline-js-snippets.md b/src/data/best-practices/frontend-performance/content/avoid-multiple-inline-js-snippets.md index f9af78b27..6cab70eb3 100644 --- a/src/data/best-practices/frontend-performance/content/avoid-multiple-inline-js-snippets.md +++ b/src/data/best-practices/frontend-performance/content/avoid-multiple-inline-js-snippets.md @@ -6,4 +6,4 @@ Placing JavaScript embedded code directly in your `` can slow down your pa Ensure that all your files are loaded using `async` or `defer` and decide wisely the code that you will need to inject in your ``. -- [11 Tips to Optimize JavaScript and Improve Website Loading Speeds](https://www.upwork.com/hiring/development/11-tips-to-optimize-javascript-and-improve-website-loading-speeds/) \ No newline at end of file +- [11 Tips to Optimize JavaScript and Improve Website Loading Speeds](https://www.upwork.com/hiring/development/11-tips-to-optimize-javascript-and-improve-website-loading-speeds/) diff --git a/src/data/best-practices/frontend-performance/content/check-dependency-size.md b/src/data/best-practices/frontend-performance/content/check-dependency-size.md index 935238f54..04048350f 100644 --- a/src/data/best-practices/frontend-performance/content/check-dependency-size.md +++ b/src/data/best-practices/frontend-performance/content/check-dependency-size.md @@ -9,4 +9,4 @@ Always compare and choose the best and lighter library for your needs. You can a - [ai/size-limit: Prevent JS libraries bloat](https://github.com/ai/size-limit) - [webpack-bundle-analyzer - npm](https://www.npmjs.com/package/webpack-bundle-analyzer) - [js-dependency-viewer - npm](https://www.npmjs.com/package/js-dependency-viewer) -- [Size Limit: Make the Web lighter](https://evilmartians.com/chronicles/size-limit-make-the-web-lighter) \ No newline at end of file +- [Size Limit: Make the Web lighter](https://evilmartians.com/chronicles/size-limit-make-the-web-lighter) diff --git a/src/data/best-practices/frontend-performance/content/choose-image-format-approprietly.md b/src/data/best-practices/frontend-performance/content/choose-image-format-approprietly.md index 28b7b4c68..c9a5e9c8e 100644 --- a/src/data/best-practices/frontend-performance/content/choose-image-format-approprietly.md +++ b/src/data/best-practices/frontend-performance/content/choose-image-format-approprietly.md @@ -9,4 +9,4 @@ Use [Lighthouse](https://developers.google.com/web/tools/lighthouse/) to identif - [Serve Images in Next-Gen Formats](https://developers.google.com/web/tools/lighthouse/audits/webp) - [What Is the Right Image Format for Your Website?](https://www.sitepoint.com/what-is-the-right-image-format-for-your-website/) - [PNG8 - The Clear Winner](https://www.sitepoint.com/png8-the-clear-winner/) -- [8-bit vs 16-bit - What Color Depth You Should Use And Why It Matters](https://www.diyphotography.net/8-bit-vs-16-bit-color-depth-use-matters/) \ No newline at end of file +- [8-bit vs 16-bit - What Color Depth You Should Use And Why It Matters](https://www.diyphotography.net/8-bit-vs-16-bit-color-depth-use-matters/) diff --git a/src/data/best-practices/frontend-performance/content/chrome-dev-tools.md b/src/data/best-practices/frontend-performance/content/chrome-dev-tools.md index 14cae7cd9..d8b13092e 100644 --- a/src/data/best-practices/frontend-performance/content/chrome-dev-tools.md +++ b/src/data/best-practices/frontend-performance/content/chrome-dev-tools.md @@ -12,4 +12,4 @@ Some of the benefits of using Chrome DevTools include: Chrome DevTools are a powerful and essential tool for web developers, as it helps to improve debugging, testing, and optimization of the web application. -- [Chrome DevTools Docs](https://developer.chrome.com/docs/devtools/) \ No newline at end of file +- [Chrome DevTools Docs](https://developer.chrome.com/docs/devtools/) diff --git a/src/data/best-practices/frontend-performance/content/compress-your-images.md b/src/data/best-practices/frontend-performance/content/compress-your-images.md index 13dab8236..4c16f94d5 100644 --- a/src/data/best-practices/frontend-performance/content/compress-your-images.md +++ b/src/data/best-practices/frontend-performance/content/compress-your-images.md @@ -16,4 +16,4 @@ Optimized images load faster in your browser and consume less data. - [Compressor.io](https://compressor.io/compress) - [Cloudinary - Image Analysis Tool](https://webspeedtest.cloudinary.com) - [ImageEngine - Image Webpage Loading Test](https://demo.imgeng.in) -- [SVGOMG - Optimize SVG vector graphics files](https://jakearchibald.github.io/svgomg/) \ No newline at end of file +- [SVGOMG - Optimize SVG vector graphics files](https://jakearchibald.github.io/svgomg/) diff --git a/src/data/best-practices/frontend-performance/content/concatenate-css-single-file.md b/src/data/best-practices/frontend-performance/content/concatenate-css-single-file.md index f9242736f..40a06542f 100644 --- a/src/data/best-practices/frontend-performance/content/concatenate-css-single-file.md +++ b/src/data/best-practices/frontend-performance/content/concatenate-css-single-file.md @@ -8,4 +8,4 @@ If you are still using HTTP/1, you may need to still concatenate your files, it' - Ensure, of course, that concatenation does not break your project - [HTTP: Optimizing Application Delivery - High Performance Browser Networking (O'Reilly)](https://hpbn.co/optimizing-application-delivery/#optimizing-for-http2) -- [Performance Best Practices in the HTTP/2 Era](https://deliciousbrains.com/performance-best-practices-http2/) \ No newline at end of file +- [Performance Best Practices in the HTTP/2 Era](https://deliciousbrains.com/performance-best-practices-http2/) diff --git a/src/data/best-practices/frontend-performance/content/cookie-size-less-4096-bytes.md b/src/data/best-practices/frontend-performance/content/cookie-size-less-4096-bytes.md index 74e4b1612..7fb272bd5 100644 --- a/src/data/best-practices/frontend-performance/content/cookie-size-less-4096-bytes.md +++ b/src/data/best-practices/frontend-performance/content/cookie-size-less-4096-bytes.md @@ -8,4 +8,4 @@ Cookies are exchanged in the HTTP headers between web servers and browsers. It's - [Cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies) - [Browser Cookie Limits](http://browsercookielimits.squawky.net/) - [Website Performance: Cookies Don't Taste So Good - Monitis Blog](http://www.monitis.com/blog/website-performance-cookies-dont-taste-so-good/) -- [Google's Web Performance Best Practices #3: Minimize Request Overhead - GlobalDots Blog](https://www.globaldots.com/googles-web-performance-best-practices-3-minimize-request-overhead/) \ No newline at end of file +- [Google's Web Performance Best Practices #3: Minimize Request Overhead - GlobalDots Blog](https://www.globaldots.com/googles-web-performance-best-practices-3-minimize-request-overhead/) diff --git a/src/data/best-practices/frontend-performance/content/enable-compression.md b/src/data/best-practices/frontend-performance/content/enable-compression.md index 09fe33751..657b81a7e 100644 --- a/src/data/best-practices/frontend-performance/content/enable-compression.md +++ b/src/data/best-practices/frontend-performance/content/enable-compression.md @@ -4,4 +4,4 @@ Use a compression method such as Gzip or Brotli to reduce the size of your JavaS - [Check GZIP compression](https://checkgzipcompression.com/) - [Check Brotli Compression](https://tools.keycdn.com/brotli-test) -- [Can I use... Brotli](https://caniuse.com/#feat=brotli) \ No newline at end of file +- [Can I use... Brotli](https://caniuse.com/#feat=brotli) diff --git a/src/data/best-practices/frontend-performance/content/framework-guides.md b/src/data/best-practices/frontend-performance/content/framework-guides.md index 07befb4aa..791738c25 100644 --- a/src/data/best-practices/frontend-performance/content/framework-guides.md +++ b/src/data/best-practices/frontend-performance/content/framework-guides.md @@ -15,4 +15,4 @@ These guides are intended to help you optimize your application for performance ## Vue -- [Vue - Useful Links|Style Guide and Performance](https://learn-vuejs.github.io/vue-patterns/useful-links/) \ No newline at end of file +- [Vue - Useful Links|Style Guide and Performance](https://learn-vuejs.github.io/vue-patterns/useful-links/) diff --git a/src/data/best-practices/frontend-performance/content/index.md b/src/data/best-practices/frontend-performance/content/index.md index 4e768b56d..792d60054 100644 --- a/src/data/best-practices/frontend-performance/content/index.md +++ b/src/data/best-practices/frontend-performance/content/index.md @@ -1 +1 @@ -# \ No newline at end of file +# diff --git a/src/data/best-practices/frontend-performance/content/inline-critical-css.md b/src/data/best-practices/frontend-performance/content/inline-critical-css.md index eacdcc7e0..a08da39a0 100644 --- a/src/data/best-practices/frontend-performance/content/inline-critical-css.md +++ b/src/data/best-practices/frontend-performance/content/inline-critical-css.md @@ -10,4 +10,4 @@ Generate the CSS critical with online tools or using a plugin like the one that - [Critical by Addy Osmani on GitHub](https://github.com/addyosmani/critical) automates this. - [Inlining critical CSS for better web performance | Go Make Things](https://gomakethings.com/inlining-critical-css-for-better-web-performance/) - [Critical Path CSS Generator - Prioritize above the fold content :: SiteLocity](https://www.sitelocity.com/critical-path-css-generator) -- [Reduce the size of the above-the-fold content](https://developers.google.com/speed/docs/insights/PrioritizeVisibleContent) \ No newline at end of file +- [Reduce the size of the above-the-fold content](https://developers.google.com/speed/docs/insights/PrioritizeVisibleContent) diff --git a/src/data/best-practices/frontend-performance/content/keep-cookie-count-below-20.md b/src/data/best-practices/frontend-performance/content/keep-cookie-count-below-20.md index 74e4b1612..7fb272bd5 100644 --- a/src/data/best-practices/frontend-performance/content/keep-cookie-count-below-20.md +++ b/src/data/best-practices/frontend-performance/content/keep-cookie-count-below-20.md @@ -8,4 +8,4 @@ Cookies are exchanged in the HTTP headers between web servers and browsers. It's - [Cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies) - [Browser Cookie Limits](http://browsercookielimits.squawky.net/) - [Website Performance: Cookies Don't Taste So Good - Monitis Blog](http://www.monitis.com/blog/website-performance-cookies-dont-taste-so-good/) -- [Google's Web Performance Best Practices #3: Minimize Request Overhead - GlobalDots Blog](https://www.globaldots.com/googles-web-performance-best-practices-3-minimize-request-overhead/) \ No newline at end of file +- [Google's Web Performance Best Practices #3: Minimize Request Overhead - GlobalDots Blog](https://www.globaldots.com/googles-web-performance-best-practices-3-minimize-request-overhead/) diff --git a/src/data/best-practices/frontend-performance/content/keep-dependencies-up-to-date.md b/src/data/best-practices/frontend-performance/content/keep-dependencies-up-to-date.md index 0a03b4201..ac64230ee 100644 --- a/src/data/best-practices/frontend-performance/content/keep-dependencies-up-to-date.md +++ b/src/data/best-practices/frontend-performance/content/keep-dependencies-up-to-date.md @@ -6,5 +6,4 @@ Most of the time, new versions come with optimization and security fix. You shou If your project use NPM packages, [npm-check](https://www.npmjs.com/package/npm-check) is a pretty interesting library to upgrade / update your libraries. [Greenkeeper](https://greenkeeper.io/) can automatically look for your dependencies and suggest an update every time a new version is out. - -- [Vanilla JavaScript for building powerful web applications](https://plainjs.com/) \ No newline at end of file +- [Vanilla JavaScript for building powerful web applications](https://plainjs.com/) diff --git a/src/data/best-practices/frontend-performance/content/keep-ttfb-less-1-3s.md b/src/data/best-practices/frontend-performance/content/keep-ttfb-less-1-3s.md index f3faaa627..d6cef058f 100644 --- a/src/data/best-practices/frontend-performance/content/keep-ttfb-less-1-3s.md +++ b/src/data/best-practices/frontend-performance/content/keep-ttfb-less-1-3s.md @@ -5,4 +5,4 @@ Reduce as much as you can the time your browser waits before receiving data. - [What is Waiting (TTFB) in DevTools, and what to do about it](https://scaleyourcode.com/blog/article/27) - [Monitoring your servers with free tools is easy](https://scaleyourcode.com/blog/article/7) - [Time to First Byte (TTFB)](https://varvy.com/pagespeed/ttfb.html) -- [Global latency testing tool](https://latency.apex.sh) \ No newline at end of file +- [Global latency testing tool](https://latency.apex.sh) diff --git a/src/data/best-practices/frontend-performance/content/keep-web-font-under-300k.md b/src/data/best-practices/frontend-performance/content/keep-web-font-under-300k.md index b6e0727df..5cf7dba39 100644 --- a/src/data/best-practices/frontend-performance/content/keep-web-font-under-300k.md +++ b/src/data/best-practices/frontend-performance/content/keep-web-font-under-300k.md @@ -4,4 +4,4 @@ Web fonts are a great way to add style to your website. However, they can also b Webfont sizes shouldn't exceed 300kb (all variants included) and are optimized for performance. -- [Font Bytes - Page Weight](https://httparchive.org/reports/page-weight#bytesFont) \ No newline at end of file +- [Font Bytes - Page Weight](https://httparchive.org/reports/page-weight#bytesFont) diff --git a/src/data/best-practices/frontend-performance/content/load-offscreen-images-lazily.md b/src/data/best-practices/frontend-performance/content/load-offscreen-images-lazily.md index 74a9756d9..b36afcf03 100644 --- a/src/data/best-practices/frontend-performance/content/load-offscreen-images-lazily.md +++ b/src/data/best-practices/frontend-performance/content/load-offscreen-images-lazily.md @@ -11,5 +11,5 @@ It will improve the response time of the current page and then avoid loading unn - [verlok/lazyload: GitHub](https://github.com/verlok/lazyload) - [aFarkas/lazysizes: GitHub](https://github.com/aFarkas/lazysizes/) - [mfranzke/loading-attribute-polyfill: GitHub](https://github.com/mfranzke/loading-attribute-polyfill/) -- [Lazy Loading Images and Video | Web Fundamentals | Google Developers](https://developers.google.com/web/fundamentals/performance/lazy-loading-guidance/images-and-video/) +- [Lazy Loading Images and Video | Web Fundamentals | Google Developers](https://developers.google.com/web/fundamentals/performance/lazy-loading-guidance/images-and-video/) - [5 Brilliant Ways to Lazy Load Images For Faster Page Loads - Dynamic Drive Blog](http://blog.dynamicdrive.com/5-brilliant-ways-to-lazy-load-images-for-faster-page-loads/) diff --git a/src/data/best-practices/frontend-performance/content/make-css-files-non-blocking.md b/src/data/best-practices/frontend-performance/content/make-css-files-non-blocking.md index 5369f9e47..b78ef546b 100644 --- a/src/data/best-practices/frontend-performance/content/make-css-files-non-blocking.md +++ b/src/data/best-practices/frontend-performance/content/make-css-files-non-blocking.md @@ -9,4 +9,4 @@ You need to add the `rel` attribute with the preload value and add `as="style"` - [loadCSS by filament group](https://github.com/filamentgroup/loadCSS) - [Example of preload CSS using loadCSS](https://gist.github.com/thedaviddias/c24763b82b9991e53928e66a0bafc9bf) - [Preloading content with rel="preload"](https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content) -- [Preload: What Is It Good For? — Smashing Magazine](https://www.smashingmagazine.com/2016/02/preload-what-is-it-good-for/) \ No newline at end of file +- [Preload: What Is It Good For? — Smashing Magazine](https://www.smashingmagazine.com/2016/02/preload-what-is-it-good-for/) diff --git a/src/data/best-practices/frontend-performance/content/minify-css.md b/src/data/best-practices/frontend-performance/content/minify-css.md index 785239334..8c2538a31 100644 --- a/src/data/best-practices/frontend-performance/content/minify-css.md +++ b/src/data/best-practices/frontend-performance/content/minify-css.md @@ -9,4 +9,4 @@ Use tools to minify your files automatically before or during your build or your - [cssnano: A modular minifier based on the PostCSS ecosystem. - cssnano](https://cssnano.co/) - [CSS Minfier](https://goonlinetools.com/css-minifier/) - [@neutrinojs/style-minify - npm](https://www.npmjs.com/package/@neutrinojs/style-minify) -- [Online CSS Compressor](http://refresh-sf.com) \ No newline at end of file +- [Online CSS Compressor](http://refresh-sf.com) diff --git a/src/data/best-practices/frontend-performance/content/minify-html.md b/src/data/best-practices/frontend-performance/content/minify-html.md index 19ce1d08c..b5066c89a 100644 --- a/src/data/best-practices/frontend-performance/content/minify-html.md +++ b/src/data/best-practices/frontend-performance/content/minify-html.md @@ -1,4 +1,5 @@ # Minify HTML + > The HTML code is minified, comments, white spaces and new lines are removed from production files. Removing all unnecessary spaces, comments and attributes will reduce the size of your HTML and speed up your site's page load times and obviously lighten the download for your user. @@ -7,4 +8,4 @@ Most of the frameworks have plugins to facilitate the minification of the webpag - [HTML minifier | Minify Code](http://minifycode.com/html-minifier/) - [Online HTML Compressor](http://refresh-sf.com) -- [Experimenting with HTML minifier — Perfection Kills](http://perfectionkills.com/experimenting-with-html-minifier/#use_short_doctype) \ No newline at end of file +- [Experimenting with HTML minifier — Perfection Kills](http://perfectionkills.com/experimenting-with-html-minifier/#use_short_doctype) diff --git a/src/data/best-practices/frontend-performance/content/minify-your-javascript.md b/src/data/best-practices/frontend-performance/content/minify-your-javascript.md index 4ba984119..e1c750946 100644 --- a/src/data/best-practices/frontend-performance/content/minify-your-javascript.md +++ b/src/data/best-practices/frontend-performance/content/minify-your-javascript.md @@ -9,4 +9,4 @@ Use the tools suggested below to minify your files automatically before or durin - [terser - JavaScript parser, mangler and compressor toolkit for ES6+](https://github.com/terser/terser) - [uglify-js - npm](https://www.npmjs.com/package/uglify-js) - [Online JavaScript Compressor](http://refresh-sf.com) -- [Short read: How is HTTP/2 different? Should we still minify and concatenate?](https://scaleyourcode.com/blog/article/28) \ No newline at end of file +- [Short read: How is HTTP/2 different? Should we still minify and concatenate?](https://scaleyourcode.com/blog/article/28) diff --git a/src/data/best-practices/frontend-performance/content/minimize-http-requests.md b/src/data/best-practices/frontend-performance/content/minimize-http-requests.md index de3aa7f35..51deaa5ba 100644 --- a/src/data/best-practices/frontend-performance/content/minimize-http-requests.md +++ b/src/data/best-practices/frontend-performance/content/minimize-http-requests.md @@ -3,4 +3,4 @@ > Always ensure that every file requested are essential for your website or application. - [Combine external CSS](https://varvy.com/pagespeed/combine-external-css.html) -- [Combine external JavaScript](https://varvy.com/pagespeed/combine-external-javascript.html) \ No newline at end of file +- [Combine external JavaScript](https://varvy.com/pagespeed/combine-external-javascript.html) diff --git a/src/data/best-practices/frontend-performance/content/minimize-iframe-count.md b/src/data/best-practices/frontend-performance/content/minimize-iframe-count.md index d1e726945..32125f548 100644 --- a/src/data/best-practices/frontend-performance/content/minimize-iframe-count.md +++ b/src/data/best-practices/frontend-performance/content/minimize-iframe-count.md @@ -1,3 +1,3 @@ # Avoid iframes -Use iframes only if you don't have any other technical possibility. Try to avoid iframes as much as you can. Iframes are not only bad for performance, but also for accessibility and usability. Iframes are also not indexed by search engines. \ No newline at end of file +Use iframes only if you don't have any other technical possibility. Try to avoid iframes as much as you can. Iframes are not only bad for performance, but also for accessibility and usability. Iframes are also not indexed by search engines. diff --git a/src/data/best-practices/frontend-performance/content/page-load-time-below-3s.md b/src/data/best-practices/frontend-performance/content/page-load-time-below-3s.md index 8f3de0c13..23959bef0 100644 --- a/src/data/best-practices/frontend-performance/content/page-load-time-below-3s.md +++ b/src/data/best-practices/frontend-performance/content/page-load-time-below-3s.md @@ -1,4 +1,5 @@ # Page Load Time + > Reduce as much as possible your page load times to quickly deliver your content to your users. Faster your website or app is, less you have probability of bounce increases, in other terms you have less chances to lose your user or future client. Enough researches on the subject prove that point. @@ -7,4 +8,4 @@ Use online tools like [Page Speed Insights](https://developers.google.com/speed/ - [Compare your mobile site speed](https://www.thinkwithgoogle.com/feature/mobile/) - [Test Your Mobile Website Speed and Performance - Think With Google](https://testmysite.thinkwithgoogle.com/intl/en-us) -- [Average Page Load Times for 2018 - How does yours compare? - MachMetrics Speed Blog](https://www.machmetrics.com/speed-blog/average-page-load-times-websites-2018/) \ No newline at end of file +- [Average Page Load Times for 2018 - How does yours compare? - MachMetrics Speed Blog](https://www.machmetrics.com/speed-blog/average-page-load-times-websites-2018/) diff --git a/src/data/best-practices/frontend-performance/content/page-speed-insights.md b/src/data/best-practices/frontend-performance/content/page-speed-insights.md index 5b3fbd219..9079c25af 100644 --- a/src/data/best-practices/frontend-performance/content/page-speed-insights.md +++ b/src/data/best-practices/frontend-performance/content/page-speed-insights.md @@ -1,5 +1,5 @@ # Page Speed Insights -Page Speed Insights is a free tool from Google that analyzes the performance of a web page and provides suggestions for improvements. +Page Speed Insights is a free tool from Google that analyzes the performance of a web page and provides suggestions for improvements. -- [Page Speed Insights](https://pagespeed.web.dev/) \ No newline at end of file +- [Page Speed Insights](https://pagespeed.web.dev/) diff --git a/src/data/best-practices/frontend-performance/content/page-weight-below-1500.md b/src/data/best-practices/frontend-performance/content/page-weight-below-1500.md index 5b17d15d4..36852101e 100644 --- a/src/data/best-practices/frontend-performance/content/page-weight-below-1500.md +++ b/src/data/best-practices/frontend-performance/content/page-weight-below-1500.md @@ -8,4 +8,4 @@ All the listed best practices in this list will help you to reduce as much as po - [Page Weight](https://httparchive.org/reports/page-weight#bytesTotal) - [What Does My Site Cost?](https://whatdoesmysitecost.com/) -- [web - Measure full page size in Chrome DevTools - Stack Overflow](https://stackoverflow.com/questions/38239980/measure-full-page-size-in-chrome-devtools) \ No newline at end of file +- [web - Measure full page size in Chrome DevTools - Stack Overflow](https://stackoverflow.com/questions/38239980/measure-full-page-size-in-chrome-devtools) diff --git a/src/data/best-practices/frontend-performance/content/pre-load-urls-where-possible.md b/src/data/best-practices/frontend-performance/content/pre-load-urls-where-possible.md index 621aa6e25..037255375 100644 --- a/src/data/best-practices/frontend-performance/content/pre-load-urls-where-possible.md +++ b/src/data/best-practices/frontend-performance/content/pre-load-urls-where-possible.md @@ -6,4 +6,4 @@ Prefetching allows a browser to silently fetch the necessary resources needed to - [What Is Prefetching and Why Use It](https://www.keycdn.com/support/prefetching) - [Prefetching, preloading, prebrowsing](https://css-tricks.com/prefetching-preloading-prebrowsing/) -- [What is Preload, Prefetch, and Preconnect](https://www.keycdn.com/blog/resource-hints) \ No newline at end of file +- [What is Preload, Prefetch, and Preconnect](https://www.keycdn.com/blog/resource-hints) diff --git a/src/data/best-practices/frontend-performance/content/prefer-vector-images.md b/src/data/best-practices/frontend-performance/content/prefer-vector-images.md index a0349e0c6..76ec6595f 100644 --- a/src/data/best-practices/frontend-performance/content/prefer-vector-images.md +++ b/src/data/best-practices/frontend-performance/content/prefer-vector-images.md @@ -2,4 +2,4 @@ > Prefer using vector image rather than bitmap images (when possible). -Vector images (SVG) tend to be smaller than images and SVG's are responsive and scale perfectly. These images can be animated and modified by CSS. \ No newline at end of file +Vector images (SVG) tend to be smaller than images and SVG's are responsive and scale perfectly. These images can be animated and modified by CSS. diff --git a/src/data/best-practices/frontend-performance/content/prevent-flash-text.md b/src/data/best-practices/frontend-performance/content/prevent-flash-text.md index a81aab89c..bec37d7b0 100644 --- a/src/data/best-practices/frontend-performance/content/prevent-flash-text.md +++ b/src/data/best-practices/frontend-performance/content/prevent-flash-text.md @@ -3,4 +3,4 @@ > Avoid transparent text until the Webfont is loaded - [`font-display` for the Masses](https://css-tricks.com/font-display-masses/) -- [CSS font-display: The Future of Font Rendering on the Web](https://www.sitepoint.com/css-font-display-future-font-rendering-web/) \ No newline at end of file +- [CSS font-display: The Future of Font Rendering on the Web](https://www.sitepoint.com/css-font-display-future-font-rendering-web/) diff --git a/src/data/best-practices/frontend-performance/content/recommended-guides.md b/src/data/best-practices/frontend-performance/content/recommended-guides.md index 702c278bb..62cbea482 100644 --- a/src/data/best-practices/frontend-performance/content/recommended-guides.md +++ b/src/data/best-practices/frontend-performance/content/recommended-guides.md @@ -2,89 +2,89 @@ > Optimize the critical rendering path: -* [Critical CSS? Not So Fast!](https://csswizardry.com/2022/09/critical-css-not-so-fast/) -* [Priority Hints - What Your Browser Doesn’t Know (Yet)](https://www.etsy.com/codeascraft/priority-hints-what-your-browser-doesnt-know-yet) -* [Optimizing resource loading with Priority Hints](https://web.dev/priority-hints/) -* [Chrome Resource Priorities and Scheduling](https://docs.google.com/document/d/1bCDuq9H1ih9iNjgzyAL0gpwNFiEP4TZS-YLRp_RuMlc/edit?usp=sharing) -* [How To Optimize CSS for Peak Site Performance](https://kinsta.com/blog/optimize-css/) -* [Eliminate render blocking CSS to improve start render time](https://www.jeffreyknox.dev/blog/eliminate-render-blocking-css-to-improve-start-render-time/) -* [Small Bundles, Fast Pages: What To Do With Too Much JavaScript](https://calibreapp.com/blog/bundle-size-optimization) -* [How to Eliminate Render-Blocking Resources: a Deep Dive](https://sia.codes/posts/render-blocking-resources/) -* [The Critical Request: How to Prioritise Requests to Improve Speed](https://calibreapp.com/blog/critical-request) -* [How to Improve CSS Performance](https://calibreapp.com/blog/css-performance) -* [The Simplest Way to Load CSS Asynchronously](https://www.filamentgroup.com/lab/load-css-simpler/) -* [CSS audit](https://css-tricks.com/a-quick-css-audit-and-general-notes-about-design-systems/) -* [Measuring the Critical Rendering Path](https://developers.google.com/web/fundamentals/performance/critical-rendering-path/measure-crp) -* [Inlining or Caching? Both Please!](https://www.filamentgroup.com/lab/inlining-cache.html) -* [CSS and Network Performance](https://csswizardry.com/2018/11/css-and-network-performance/) -* [Analyzing Critical Rendering Path Performance](https://developers.google.com/web/fundamentals/performance/critical-rendering-path/analyzing-crp) -* [Front-End Performance Checklist](https://github.com/thedaviddias/Front-End-Performance-Checklist) -* [The PRPL Pattern](https://developers.google.com/web/fundamentals/performance/prpl-pattern/) -* [Now You See Me: How To Defer, Lazy-Load And Act With IntersectionObserver](https://www.smashingmagazine.com/2018/01/deferring-lazy-loading-intersection-observer-api/) -* [Optimising the front end for the browser](https://hackernoon.com/optimising-the-front-end-for-the-browser-f2f51a29c572) -* [Prefer DEFER Over ASYNC](https://calendar.perfplanet.com/2016/prefer-defer-over-async/) -* [A comprehensive guide to font loading strategies](https://www.zachleat.com/web/comprehensive-webfonts/) -* [Understanding the critical rendering path, rendering pages in 1 second](https://medium.com/@luisvieira_gmr/understanding-the-critical-rendering-path-rendering-pages-in-1-second-735c6e45b47a) -* [More Weight Doesn’t Mean More Wait](https://www.filamentgroup.com/lab/weight-wait.html) +- [Critical CSS? Not So Fast!](https://csswizardry.com/2022/09/critical-css-not-so-fast/) +- [Priority Hints - What Your Browser Doesn’t Know (Yet)](https://www.etsy.com/codeascraft/priority-hints-what-your-browser-doesnt-know-yet) +- [Optimizing resource loading with Priority Hints](https://web.dev/priority-hints/) +- [Chrome Resource Priorities and Scheduling](https://docs.google.com/document/d/1bCDuq9H1ih9iNjgzyAL0gpwNFiEP4TZS-YLRp_RuMlc/edit?usp=sharing) +- [How To Optimize CSS for Peak Site Performance](https://kinsta.com/blog/optimize-css/) +- [Eliminate render blocking CSS to improve start render time](https://www.jeffreyknox.dev/blog/eliminate-render-blocking-css-to-improve-start-render-time/) +- [Small Bundles, Fast Pages: What To Do With Too Much JavaScript](https://calibreapp.com/blog/bundle-size-optimization) +- [How to Eliminate Render-Blocking Resources: a Deep Dive](https://sia.codes/posts/render-blocking-resources/) +- [The Critical Request: How to Prioritise Requests to Improve Speed](https://calibreapp.com/blog/critical-request) +- [How to Improve CSS Performance](https://calibreapp.com/blog/css-performance) +- [The Simplest Way to Load CSS Asynchronously](https://www.filamentgroup.com/lab/load-css-simpler/) +- [CSS audit](https://css-tricks.com/a-quick-css-audit-and-general-notes-about-design-systems/) +- [Measuring the Critical Rendering Path](https://developers.google.com/web/fundamentals/performance/critical-rendering-path/measure-crp) +- [Inlining or Caching? Both Please!](https://www.filamentgroup.com/lab/inlining-cache.html) +- [CSS and Network Performance](https://csswizardry.com/2018/11/css-and-network-performance/) +- [Analyzing Critical Rendering Path Performance](https://developers.google.com/web/fundamentals/performance/critical-rendering-path/analyzing-crp) +- [Front-End Performance Checklist](https://github.com/thedaviddias/Front-End-Performance-Checklist) +- [The PRPL Pattern](https://developers.google.com/web/fundamentals/performance/prpl-pattern/) +- [Now You See Me: How To Defer, Lazy-Load And Act With IntersectionObserver](https://www.smashingmagazine.com/2018/01/deferring-lazy-loading-intersection-observer-api/) +- [Optimising the front end for the browser](https://hackernoon.com/optimising-the-front-end-for-the-browser-f2f51a29c572) +- [Prefer DEFER Over ASYNC](https://calendar.perfplanet.com/2016/prefer-defer-over-async/) +- [A comprehensive guide to font loading strategies](https://www.zachleat.com/web/comprehensive-webfonts/) +- [Understanding the critical rendering path, rendering pages in 1 second](https://medium.com/@luisvieira_gmr/understanding-the-critical-rendering-path-rendering-pages-in-1-second-735c6e45b47a) +- [More Weight Doesn’t Mean More Wait](https://www.filamentgroup.com/lab/weight-wait.html) > JavaScript Rendering Performance -* [Five Data-Loading Patterns To Boost Web Performance](https://www.smashingmagazine.com/2022/09/data-loading-patterns-improve-frontend-performance/) -* [Optimize long tasks](https://web.dev/optimize-long-tasks/) -* [The impact of removing jQuery on our web performance](https://insidegovuk.blog.gov.uk/2022/08/15/the-impact-of-removing-jquery-on-our-web-performance/) -* [Profiling & Optimizing the runtime performance with the DevTools Performance tab](iamtk.co/profiling-and-optimizing-the-runtime-performance-with-the-devtools-performance-tab) -* [Don't fight the browser preload scanner](https://web.dev/preload-scanner/) -* [The Web Performance impact of jQuery](https://twitter.com/TheRealNooshu/status/1509487050122276864) -* [Have Single-Page Apps Ruined the Web? | Transitional Apps](https://www.youtube.com/watch?v=860d8usGC0o) -* [Improve how you architect webapps](https://www.patterns.dev/) -* [Nuxt SSR Optimizing Tips](https://vueschool.io/articles/vuejs-tutorials/nuxt-ssr-optimizing-tips/, Filip Rakowski -* [GPU accelerated JavaScript](https://gpu.rocks/#/) -* [Introducing Partytown 🎉: Run Third-Party Scripts From a Web Worker](https://dev.to/adamdbradley/introducing-partytown-run-third-party-scripts-from-a-web-worker-2cnp) -* [Astro: Astro is a fresh but familiar approach to building websites. Astro combines decades of proven performance best practices with the DX improvements of the component-oriented era. Use your favorite JavaScript framework and automatically ship the bare-minimum amount of JavaScript—by default.](https://docs.astro.build/getting-started/) -* [Minimising Layout and Layout thrashing for 60 FPS](https://www.charistheo.io/blog/2021/09/dom-reflow-and-layout-thrashing/) -* [Does shadow DOM improve style performance?](https://nolanlawson.com/2021/08/15/does-shadow-dom-improve-style-performance/) -* [Debugging memory leaks - HTTP 203](https://www.youtube.com/watch?v=YDU_3WdfkxA) -* [Explore JavaScript Dependencies With Lighthouse Treemap](https://sia.codes/posts/lighthouse-treemap/) -* [The real cost of Javascript dependencies (and the state of JS package quality)](https://medium.com/voodoo-engineering/the-real-cost-of-javascript-dependencies-and-the-state-of-js-package-quality-a8dacd74c0ec) -* [The State Of Web Workers In 2021](https://www.smashingmagazine.com/2021/06/web-workers-2021/) -* [Techniques for developing high-performance animations](https://web.dev/animations/) -* [Building a Faster Web Experience with the postTask Scheduler](https://medium.com/airbnb-engineering/building-a-faster-web-experience-with-the-posttask-scheduler-276b83454e91), Callie (Airbnb Engineering & Data Science) -* [Don’t attach tooltips to document.body – Learn how the browser works – Debug forced reflow](https://atfzl.com/don-t-attach-tooltips-to-document-body) -* [How to Create and Fix Memory Leaks With Chrome DevTools](https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658) -* [JavaScript performance beyond bundle size](https://nolanlawson.com/2021/02/23/javascript-performance-beyond-bundle-size/) -* [The Import On Interaction Pattern](https://addyosmani.com/blog/import-on-interaction/) -* [The “Live DOM” Is Not “Slow”, “Bad”, Or “Wrong”. Web Developers Are.](https://levelup.gitconnected.com/the-live-dom-is-not-slow-bad-or-wrong-web-developers-are-2bf86c3b9e2e) -* [Prevent layout shifts with CSS grid stacks](https://www.hsablonniere.com/prevent-layout-shifts-with-css-grid-stacks--qcj5jo/) -* [content-visibility: the new CSS property that boosts your rendering performance](https://web.dev/content-visibility/) -* [Preact vs React - Updating React at Etsy](https://github.com/mq2thez/blog/blob/main/upgrade-react-etsy/preact-vs-react.md) -* [The Cost of Javascript Frameworks](https://timkadlec.com/remembers/2020-04-21-the-cost-of-javascript-frameworks/) -* [Fixing memory leaks in web applications](https://nolanlawson.com/2020/02/19/fixing-memory-leaks-in-web-applications/) -* [How to load polyfills only when needed](https://3perf.com/blog/polyfills/) -* [Responsible JavaScript: Part III - Third parties](https://alistapart.com/article/responsible-javascript-part-3/) -* [The cost of JavaScript in 2019](https://v8.dev/blog/cost-of-javascript-2019) -* [When should you be using Web Workers?](https://dassur.ma/things/when-workers/) -* [Responsible Javascript: Part II - Code Bundle](https://alistapart.com/article/responsible-javascript-part-2/) -* [Faster script loading with BinaryAST?](https://blog.cloudflare.com/binary-ast/) -* [Svelte 3: Rethinking reactivity](https://svelte.dev/blog/svelte-3-rethinking-reactivity) -* [Responsible Javascript: Part I - Web platform over frameworks](https://alistapart.com/article/responsible-javascript-part-1/) -* [JavaScript Loading Priorities in Chrome](https://addyosmani.com/blog/script-priorities/) -* [Idle Until Urgent](https://philipwalton.com/articles/idle-until-urgent/) -* [Browser painting and considerations for web performance](https://css-tricks.com/browser-painting-and-considerations-for-web-performance/) -* [The Cost Of JavaScript In 2018](https://medium.com/@addyosmani/the-cost-of-javascript-in-2018-7d8950fbb5d4) ([Video](https://www.youtube.com/watch?v=i5R7giitymk)) -* [Examining Web Worker Performance](https://www.loxodrome.io/post/web-worker-performance/) -* [Front-End Performance Checklist](https://github.com/thedaviddias/Front-End-Performance-Checklist) -* [jankfree](http://jankfree.org/) -* [What forces layout/reflow?](https://gist.github.com/paulirish/5d52fb081b3570c81e3a) -* [Using requestIdleCallback](https://developers.google.com/web/updates/2015/08/using-requestidlecallback) -* [Optimize Javascript Execution](https://developers.google.com/web/fundamentals/performance/rendering/optimize-javascript-execution) -* [Why Web Developers Need to Care about Interactivity](https://philipwalton.com/articles/why-web-developers-need-to-care-about-interactivity/) -* [Improving Performance with the Paint Timing API](https://www.sitepen.com/blog/2017/10/06/improving-performance-with-the-paint-timing-api) -* [Deploying ES2015+ Code in Production Today](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/) -* [Performant Web Animations and Interactions: Achieving 60 FPS](https://blog.algolia.com/performant-web-animations/) -* [JavaScript Start-up Performance](https://medium.com/reloading/javascript-start-up-performance-69200f43b201) -* [Performant Parallaxing](https://developers.google.com/web/updates/2016/12/performant-parallaxing) -* [The Anatomy of a Frame](https://aerotwist.com/blog/the-anatomy-of-a-frame/) -* [The future of loading CSS](https://jakearchibald.com/2016/link-in-body/) -* [4 Types of Memory Leaks in JavaScript and How to Get Rid Of Them](https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/) -* [The cost of frameworks](https://aerotwist.com/blog/the-cost-of-frameworks/) -* [FLIP Your Animations](https://aerotwist.com/blog/flip-your-animations/) +- [Five Data-Loading Patterns To Boost Web Performance](https://www.smashingmagazine.com/2022/09/data-loading-patterns-improve-frontend-performance/) +- [Optimize long tasks](https://web.dev/optimize-long-tasks/) +- [The impact of removing jQuery on our web performance](https://insidegovuk.blog.gov.uk/2022/08/15/the-impact-of-removing-jquery-on-our-web-performance/) +- [Profiling & Optimizing the runtime performance with the DevTools Performance tab](iamtk.co/profiling-and-optimizing-the-runtime-performance-with-the-devtools-performance-tab) +- [Don't fight the browser preload scanner](https://web.dev/preload-scanner/) +- [The Web Performance impact of jQuery](https://twitter.com/TheRealNooshu/status/1509487050122276864) +- [Have Single-Page Apps Ruined the Web? | Transitional Apps](https://www.youtube.com/watch?v=860d8usGC0o) +- [Improve how you architect webapps](https://www.patterns.dev/) +- [Nuxt SSR Optimizing Tips](https://vueschool.io/articles/vuejs-tutorials/nuxt-ssr-optimizing-tips/, Filip Rakowski +- [GPU accelerated JavaScript](https://gpu.rocks/#/) +- [Introducing Partytown 🎉: Run Third-Party Scripts From a Web Worker](https://dev.to/adamdbradley/introducing-partytown-run-third-party-scripts-from-a-web-worker-2cnp) +- [Astro: Astro is a fresh but familiar approach to building websites. Astro combines decades of proven performance best practices with the DX improvements of the component-oriented era. Use your favorite JavaScript framework and automatically ship the bare-minimum amount of JavaScript—by default.](https://docs.astro.build/getting-started/) +- [Minimising Layout and Layout thrashing for 60 FPS](https://www.charistheo.io/blog/2021/09/dom-reflow-and-layout-thrashing/) +- [Does shadow DOM improve style performance?](https://nolanlawson.com/2021/08/15/does-shadow-dom-improve-style-performance/) +- [Debugging memory leaks - HTTP 203](https://www.youtube.com/watch?v=YDU_3WdfkxA) +- [Explore JavaScript Dependencies With Lighthouse Treemap](https://sia.codes/posts/lighthouse-treemap/) +- [The real cost of Javascript dependencies (and the state of JS package quality)](https://medium.com/voodoo-engineering/the-real-cost-of-javascript-dependencies-and-the-state-of-js-package-quality-a8dacd74c0ec) +- [The State Of Web Workers In 2021](https://www.smashingmagazine.com/2021/06/web-workers-2021/) +- [Techniques for developing high-performance animations](https://web.dev/animations/) +- [Building a Faster Web Experience with the postTask Scheduler](https://medium.com/airbnb-engineering/building-a-faster-web-experience-with-the-posttask-scheduler-276b83454e91), Callie (Airbnb Engineering & Data Science) +- [Don’t attach tooltips to document.body – Learn how the browser works – Debug forced reflow](https://atfzl.com/don-t-attach-tooltips-to-document-body) +- [How to Create and Fix Memory Leaks With Chrome DevTools](https://betterprogramming.pub/build-me-an-angular-app-with-memory-leaks-please-36302184e658) +- [JavaScript performance beyond bundle size](https://nolanlawson.com/2021/02/23/javascript-performance-beyond-bundle-size/) +- [The Import On Interaction Pattern](https://addyosmani.com/blog/import-on-interaction/) +- [The “Live DOM” Is Not “Slow”, “Bad”, Or “Wrong”. Web Developers Are.](https://levelup.gitconnected.com/the-live-dom-is-not-slow-bad-or-wrong-web-developers-are-2bf86c3b9e2e) +- [Prevent layout shifts with CSS grid stacks](https://www.hsablonniere.com/prevent-layout-shifts-with-css-grid-stacks--qcj5jo/) +- [content-visibility: the new CSS property that boosts your rendering performance](https://web.dev/content-visibility/) +- [Preact vs React - Updating React at Etsy](https://github.com/mq2thez/blog/blob/main/upgrade-react-etsy/preact-vs-react.md) +- [The Cost of Javascript Frameworks](https://timkadlec.com/remembers/2020-04-21-the-cost-of-javascript-frameworks/) +- [Fixing memory leaks in web applications](https://nolanlawson.com/2020/02/19/fixing-memory-leaks-in-web-applications/) +- [How to load polyfills only when needed](https://3perf.com/blog/polyfills/) +- [Responsible JavaScript: Part III - Third parties](https://alistapart.com/article/responsible-javascript-part-3/) +- [The cost of JavaScript in 2019](https://v8.dev/blog/cost-of-javascript-2019) +- [When should you be using Web Workers?](https://dassur.ma/things/when-workers/) +- [Responsible Javascript: Part II - Code Bundle](https://alistapart.com/article/responsible-javascript-part-2/) +- [Faster script loading with BinaryAST?](https://blog.cloudflare.com/binary-ast/) +- [Svelte 3: Rethinking reactivity](https://svelte.dev/blog/svelte-3-rethinking-reactivity) +- [Responsible Javascript: Part I - Web platform over frameworks](https://alistapart.com/article/responsible-javascript-part-1/) +- [JavaScript Loading Priorities in Chrome](https://addyosmani.com/blog/script-priorities/) +- [Idle Until Urgent](https://philipwalton.com/articles/idle-until-urgent/) +- [Browser painting and considerations for web performance](https://css-tricks.com/browser-painting-and-considerations-for-web-performance/) +- [The Cost Of JavaScript In 2018](https://medium.com/@addyosmani/the-cost-of-javascript-in-2018-7d8950fbb5d4) ([Video](https://www.youtube.com/watch?v=i5R7giitymk)) +- [Examining Web Worker Performance](https://www.loxodrome.io/post/web-worker-performance/) +- [Front-End Performance Checklist](https://github.com/thedaviddias/Front-End-Performance-Checklist) +- [jankfree](http://jankfree.org/) +- [What forces layout/reflow?](https://gist.github.com/paulirish/5d52fb081b3570c81e3a) +- [Using requestIdleCallback](https://developers.google.com/web/updates/2015/08/using-requestidlecallback) +- [Optimize Javascript Execution](https://developers.google.com/web/fundamentals/performance/rendering/optimize-javascript-execution) +- [Why Web Developers Need to Care about Interactivity](https://philipwalton.com/articles/why-web-developers-need-to-care-about-interactivity/) +- [Improving Performance with the Paint Timing API](https://www.sitepen.com/blog/2017/10/06/improving-performance-with-the-paint-timing-api) +- [Deploying ES2015+ Code in Production Today](https://philipwalton.com/articles/deploying-es2015-code-in-production-today/) +- [Performant Web Animations and Interactions: Achieving 60 FPS](https://blog.algolia.com/performant-web-animations/) +- [JavaScript Start-up Performance](https://medium.com/reloading/javascript-start-up-performance-69200f43b201) +- [Performant Parallaxing](https://developers.google.com/web/updates/2016/12/performant-parallaxing) +- [The Anatomy of a Frame](https://aerotwist.com/blog/the-anatomy-of-a-frame/) +- [The future of loading CSS](https://jakearchibald.com/2016/link-in-body/) +- [4 Types of Memory Leaks in JavaScript and How to Get Rid Of Them](https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/) +- [The cost of frameworks](https://aerotwist.com/blog/the-cost-of-frameworks/) +- [FLIP Your Animations](https://aerotwist.com/blog/flip-your-animations/) diff --git a/src/data/best-practices/frontend-performance/content/remove-unused-css.md b/src/data/best-practices/frontend-performance/content/remove-unused-css.md index 51e88d3da..f08677a69 100644 --- a/src/data/best-practices/frontend-performance/content/remove-unused-css.md +++ b/src/data/best-practices/frontend-performance/content/remove-unused-css.md @@ -7,4 +7,4 @@ Always check if the framework CSS you want to use don't already has a reset / no - [UnCSS Online](https://uncss-online.com/) - [PurifyCSS](https://github.com/purifycss/purifycss) - [PurgeCSS](https://github.com/FullHuman/purgecss) -- [Chrome DevTools Coverage](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage) \ No newline at end of file +- [Chrome DevTools Coverage](https://developers.google.com/web/updates/2017/04/devtools-release-notes#coverage) diff --git a/src/data/best-practices/frontend-performance/content/serve-exact-size-images.md b/src/data/best-practices/frontend-performance/content/serve-exact-size-images.md index 3c4d38f80..88e17e12e 100644 --- a/src/data/best-practices/frontend-performance/content/serve-exact-size-images.md +++ b/src/data/best-practices/frontend-performance/content/serve-exact-size-images.md @@ -7,4 +7,4 @@ Small devices don't need images bigger than their viewport. It's recommended to - Create different image sizes for the devices you want to target - Use `srcset` and `picture` to deliver multiple variants of each image. -- [Responsive images - Learn web development | MDN](https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images) \ No newline at end of file +- [Responsive images - Learn web development | MDN](https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images) diff --git a/src/data/best-practices/frontend-performance/content/set-width-height-images.md b/src/data/best-practices/frontend-performance/content/set-width-height-images.md index 665f81445..2c5aded25 100644 --- a/src/data/best-practices/frontend-performance/content/set-width-height-images.md +++ b/src/data/best-practices/frontend-performance/content/set-width-height-images.md @@ -2,4 +2,4 @@ > Set width and height attributes on `` if the final rendered image size is known. -If height and width are set, the space required for the image is reserved when the page is loaded. However, without these attributes, the browser does not know the size of the image, and cannot reserve the appropriate space to it. The effect will be that the page layout will change during loading (while the images load). \ No newline at end of file +If height and width are set, the space required for the image is reserved when the page is loaded. However, without these attributes, the browser does not know the size of the image, and cannot reserve the appropriate space to it. The effect will be that the page layout will change during loading (while the images load). diff --git a/src/data/best-practices/frontend-performance/content/squoosh-ap.md b/src/data/best-practices/frontend-performance/content/squoosh-ap.md index 090f2eadc..312c059fc 100644 --- a/src/data/best-practices/frontend-performance/content/squoosh-ap.md +++ b/src/data/best-practices/frontend-performance/content/squoosh-ap.md @@ -2,4 +2,4 @@ Squoosh.app is a web app that allows you to compress images using a variety of codecs. It is built by Google Chrome team and is open source. -- [Squoosh.app](https://squoosh.app/) \ No newline at end of file +- [Squoosh.app](https://squoosh.app/) diff --git a/src/data/best-practices/frontend-performance/content/use-cdn.md b/src/data/best-practices/frontend-performance/content/use-cdn.md index 1964eeda9..8442885ea 100644 --- a/src/data/best-practices/frontend-performance/content/use-cdn.md +++ b/src/data/best-practices/frontend-performance/content/use-cdn.md @@ -2,5 +2,5 @@ Use a CDN to serve your static assets. This will reduce the load on your server and improve the performance of your site. - - [10 Tips to Optimize CDN Performance - CDN Planet](https://www.cdnplanet.com/blog/10-tips-optimize-cdn-performance/) - - [HTTP Caching | Web Fundamentals | Google Developers](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching) \ No newline at end of file +- [10 Tips to Optimize CDN Performance - CDN Planet](https://www.cdnplanet.com/blog/10-tips-optimize-cdn-performance/) +- [HTTP Caching | Web Fundamentals | Google Developers](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching) diff --git a/src/data/best-practices/frontend-performance/content/use-http-cache-headers.md b/src/data/best-practices/frontend-performance/content/use-http-cache-headers.md index 8de08e409..5f494b397 100644 --- a/src/data/best-practices/frontend-performance/content/use-http-cache-headers.md +++ b/src/data/best-practices/frontend-performance/content/use-http-cache-headers.md @@ -2,4 +2,4 @@ Set HTTP headers to avoid expensive number of roundtrips between your browser and the server. -- [Using cache-control for browser caching](https://varvy.com/pagespeed/cache-control.html) \ No newline at end of file +- [Using cache-control for browser caching](https://varvy.com/pagespeed/cache-control.html) diff --git a/src/data/best-practices/frontend-performance/content/use-https-on-your-website.md b/src/data/best-practices/frontend-performance/content/use-https-on-your-website.md index 83b935a29..8ebdc58e2 100644 --- a/src/data/best-practices/frontend-performance/content/use-https-on-your-website.md +++ b/src/data/best-practices/frontend-performance/content/use-https-on-your-website.md @@ -6,4 +6,4 @@ HTTPS is not only for ecommerce websites, but for all websites that are exchangi - [Enabling HTTPS Without Sacrificing Your Web Performance - Moz](https://moz.com/blog/enabling-https-without-sacrificing-web-performance) - [How HTTPS Affects Website Performance](https://wp-rocket.me/blog/https-affects-website-performance/) - [HTTP versus HTTPS versus HTTP2 - The real story | Tune The Web](https://www.tunetheweb.com/blog/http-versus-https-versus-http2/) -- [HTTP vs HTTPS — Test them both yourself](https://www.httpvshttps.com/) \ No newline at end of file +- [HTTP vs HTTPS — Test them both yourself](https://www.httpvshttps.com/) diff --git a/src/data/best-practices/frontend-performance/content/use-non-blocking-javascript.md b/src/data/best-practices/frontend-performance/content/use-non-blocking-javascript.md index a24df202f..1b64a5883 100644 --- a/src/data/best-practices/frontend-performance/content/use-non-blocking-javascript.md +++ b/src/data/best-practices/frontend-performance/content/use-non-blocking-javascript.md @@ -15,6 +15,5 @@ JavaScript blocks the normal parsing of the HTML document, so when the parser re - Add `async` (if the script don't rely on other scripts) or `defer` (if the script relies upon or relied upon by an async script) as an attribute to your script tag. - If you have small scripts, maybe use inline script place above async scripts. - - [Remove Render-Blocking JavaScript](https://developers.google.com/speed/docs/insights/BlockingJS) -- [Defer loading JavaScript](https://varvy.com/pagespeed/defer-loading-javascript.html) \ No newline at end of file +- [Defer loading JavaScript](https://varvy.com/pagespeed/defer-loading-javascript.html) diff --git a/src/data/best-practices/frontend-performance/content/use-preconnect-to-load-fonts.md b/src/data/best-practices/frontend-performance/content/use-preconnect-to-load-fonts.md index 848ea9b9a..5eb9e0e9b 100644 --- a/src/data/best-practices/frontend-performance/content/use-preconnect-to-load-fonts.md +++ b/src/data/best-practices/frontend-performance/content/use-preconnect-to-load-fonts.md @@ -1,7 +1,7 @@ # Preconnect on Fonts ```html - + ``` When you arrived on a website, your device needs to find out where your site lives and which server it needs to connect with. Your browser had to contact a DNS server and wait for the lookup complete before fetching the resource (fonts, CSS files...). Prefetches and preconnects allow the browser to lookup the DNS information and start establishing a TCP connection to the server hosting the font file. This provides a performance boost because by the time the browser gets around to parsing the css file with the font information and discovering it needs to request a font file from the server, it will already have pre-resolved the DNS information and have an open connection to the server ready in its connection pool. @@ -14,4 +14,4 @@ When you arrived on a website, your device needs to find out where your site liv - [Make Your Site Faster with Preconnect Hints | Viget](https://www.viget.com/articles/make-your-site-faster-with-preconnect-hints/) - [Ultimate Guide to Browser Hints: Preload, Prefetch, and Preconnect - MachMetrics Speed Blog](https://www.machmetrics.com/speed-blog/guide-to-browser-hints-preload-preconnect-prefetch/) - [A Comprehensive Guide to Font Loading Strategies—zachleat.com](https://www.zachleat.com/web/comprehensive-webfonts/#font-face) -- [typekit/webfontloader: Web Font Loader gives you added control when using linked fonts via @font-face.](https://github.com/typekit/webfontloader) \ No newline at end of file +- [typekit/webfontloader: Web Font Loader gives you added control when using linked fonts via @font-face.](https://github.com/typekit/webfontloader) diff --git a/src/data/best-practices/frontend-performance/content/use-same-protocol.md b/src/data/best-practices/frontend-performance/content/use-same-protocol.md index bd5bea11d..abff2ecf8 100644 --- a/src/data/best-practices/frontend-performance/content/use-same-protocol.md +++ b/src/data/best-practices/frontend-performance/content/use-same-protocol.md @@ -1,3 +1,3 @@ # Use same Protocol -Avoid having your website serving files coming from source using HTTP on your website which is using HTTPS for example. If your website is using HTTPS, external files should come from the same protocol. \ No newline at end of file +Avoid having your website serving files coming from source using HTTP on your website which is using HTTPS for example. If your website is using HTTPS, external files should come from the same protocol. diff --git a/src/data/best-practices/frontend-performance/content/use-service-workers-for-caching.md b/src/data/best-practices/frontend-performance/content/use-service-workers-for-caching.md index b5e81dd1f..e237f8c78 100644 --- a/src/data/best-practices/frontend-performance/content/use-service-workers-for-caching.md +++ b/src/data/best-practices/frontend-performance/content/use-service-workers-for-caching.md @@ -2,7 +2,7 @@ You are using Service Workers in your PWA to cache data or execute possible heavy tasks without impacting the user experience of your application. -- [Service Workers: an Introduction | Web Fundamentals | Google Developers](https://developers.google.com/web/fundamentals/primers/service-workers/) -- [Measuring the Real-world Performance Impact of Service Workers | Web | Google Developers](https://developers.google.com/web/showcase/2016/service-worker-perf) +- [Service Workers: an Introduction | Web Fundamentals | Google Developers](https://developers.google.com/web/fundamentals/primers/service-workers/) +- [Measuring the Real-world Performance Impact of Service Workers | Web | Google Developers](https://developers.google.com/web/showcase/2016/service-worker-perf) - [What Are Service Workers and How They Help Improve Performance](https://www.keycdn.com/blog/service-workers/) -- [How does a service worker work? - YouTube](https://www.youtube.com/watch?v=__xAtWgfzvc) \ No newline at end of file +- [How does a service worker work? - YouTube](https://www.youtube.com/watch?v=__xAtWgfzvc) diff --git a/src/data/best-practices/frontend-performance/content/use-woff2-font-format.md b/src/data/best-practices/frontend-performance/content/use-woff2-font-format.md index 77a901e24..290736ade 100644 --- a/src/data/best-practices/frontend-performance/content/use-woff2-font-format.md +++ b/src/data/best-practices/frontend-performance/content/use-woff2-font-format.md @@ -8,4 +8,4 @@ Check before buying your new font that the provider gives you the WOFF2 format. - [Create Your Own @font-face Kits » Font Squirrel](https://www.fontsquirrel.com/tools/webfont-generator) - [IcoMoon App - Icon Font, SVG, PDF & PNG Generator](https://icomoon.io/app/) - [Using @font-face | CSS-Tricks](https://css-tricks.com/snippets/css/using-font-face/?ref=frontendchecklist) -- [Can I use... WOFF2](https://caniuse.com/#feat=woff2) \ No newline at end of file +- [Can I use... WOFF2](https://caniuse.com/#feat=woff2) diff --git a/src/data/best-practices/frontend-performance/content/web-page-test.md b/src/data/best-practices/frontend-performance/content/web-page-test.md index 3108d5d7c..e0c745050 100644 --- a/src/data/best-practices/frontend-performance/content/web-page-test.md +++ b/src/data/best-practices/frontend-performance/content/web-page-test.md @@ -1,3 +1,3 @@ # webpagetest.org -Webpagetest.org is a website performance testing tool that allows users to test the load time and performance of web pages. It provides a wealth of information about the page load, including load time, Speed Index, and filmstrip view of the page load, as well as a breakdown of the page components and their load times. It also allows for testing from multiple locations and browsers. The test results can be shared and compared with others. It is widely used by developers, marketers, and website owners to improve the performance and user experience of their websites. \ No newline at end of file +Webpagetest.org is a website performance testing tool that allows users to test the load time and performance of web pages. It provides a wealth of information about the page load, including load time, Speed Index, and filmstrip view of the page load, as well as a breakdown of the page components and their load times. It also allows for testing from multiple locations and browsers. The test results can be shared and compared with others. It is widely used by developers, marketers, and website owners to improve the performance and user experience of their websites. diff --git a/src/data/best-practices/frontend-performance/frontend-performance.md b/src/data/best-practices/frontend-performance/frontend-performance.md index b53d4178d..dfe17ccfc 100644 --- a/src/data/best-practices/frontend-performance/frontend-performance.md +++ b/src/data/best-practices/frontend-performance/frontend-performance.md @@ -1,29 +1,29 @@ --- -jsonUrl: "/jsons/best-practices/frontend-performance.json" -pdfUrl: "/pdfs/best-practices/frontend-performance.pdf" +jsonUrl: '/jsons/best-practices/frontend-performance.json' +pdfUrl: '/pdfs/best-practices/frontend-performance.pdf' order: 1 -briefTitle: "Frontend Performance" -briefDescription: "Frontend Performance Best Practices" +briefTitle: 'Frontend Performance' +briefDescription: 'Frontend Performance Best Practices' isNew: true isUpcoming: false -title: "Frontend Performance Best Practices" -description: "Detailed list of best practices to improve your frontend performance" +title: 'Frontend Performance Best Practices' +description: 'Detailed list of best practices to improve your frontend performance' dimensions: width: 968 height: 1270.89 schema: - headline: "Frontend Performance Best Practices" - description: "Detailed list of best practices to improve the frontend performance of your website. Each best practice carries further details and how to implement that best practice." - imageUrl: "https://roadmap.sh/best-practices/frontend-performance.png" - datePublished: "2023-01-23" - dateModified: "2023-01-23" + headline: 'Frontend Performance Best Practices' + description: 'Detailed list of best practices to improve the frontend performance of your website. Each best practice carries further details and how to implement that best practice.' + imageUrl: 'https://roadmap.sh/best-practices/frontend-performance.png' + datePublished: '2023-01-23' + dateModified: '2023-01-23' seo: - title: "Frontend Performance Best Practices" - description: "Detailed list of best practices to improve the frontend performance of your website. Each best practice carries further details and how to implement that best practice." + title: 'Frontend Performance Best Practices' + description: 'Detailed list of best practices to improve the frontend performance of your website. Each best practice carries further details and how to implement that best practice.' keywords: - - "frontend performance" - - "frontend performance best practices" - - "frontend performance checklist" - - "frontend checklist" - - "make performant frontends" ---- \ No newline at end of file + - 'frontend performance' + - 'frontend performance best practices' + - 'frontend performance checklist' + - 'frontend checklist' + - 'make performant frontends' +--- diff --git a/src/data/guides/asymptotic-notation.md b/src/data/guides/asymptotic-notation.md index 70efe8b49..50df513d5 100644 --- a/src/data/guides/asymptotic-notation.md +++ b/src/data/guides/asymptotic-notation.md @@ -1,26 +1,25 @@ --- -title: "Asymptotic Notation" -description: "Learn the basics of measuring the time and space complexity of algorithms" +title: 'Asymptotic Notation' +description: 'Learn the basics of measuring the time and space complexity of algorithms' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "Asymptotic Notation - roadmap.sh" - description: "Learn the basics of measuring the time and space complexity of algorithms" + title: 'Asymptotic Notation - roadmap.sh' + description: 'Learn the basics of measuring the time and space complexity of algorithms' isNew: false -type: "visual" +type: 'visual' date: 2021-04-03 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "visual-guide" - - "guide-sitemap" + - 'guide' + - 'visual-guide' + - 'guide-sitemap' --- Asymptotic notation is the standard way of measuring the time and space that an algorithm will consume as the input grows. In one of my last guides, I covered "Big-O notation" and a lot of you asked for a similar one for Asymptotic notation. You can find the [previous guide here](/guides/big-o-notation). [![Asymptotic Notation](/guides/asymptotic-notation.png)](/guides/asymptotic-notation.png) - diff --git a/src/data/guides/avoid-render-blocking-javascript-with-async-defer.md b/src/data/guides/avoid-render-blocking-javascript-with-async-defer.md index 941675b41..2111c473c 100644 --- a/src/data/guides/avoid-render-blocking-javascript-with-async-defer.md +++ b/src/data/guides/avoid-render-blocking-javascript-with-async-defer.md @@ -1,24 +1,23 @@ --- -title: "Async and Defer Script Loading" -description: "Learn how to avoid render blocking JavaScript using async and defer scripts." +title: 'Async and Defer Script Loading' +description: 'Learn how to avoid render blocking JavaScript using async and defer scripts.' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "Async and Defer Script Loading - roadmap.sh" - description: "Learn how to avoid render blocking JavaScript using async and defer scripts." + title: 'Async and Defer Script Loading - roadmap.sh' + description: 'Learn how to avoid render blocking JavaScript using async and defer scripts.' isNew: false -type: "visual" +type: 'visual' date: 2021-09-10 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "visual-guide" - - "guide-sitemap" + - 'guide' + - 'visual-guide' + - 'guide-sitemap' --- [![Avoid Render Blocking with Async and Defer](/guides/avoid-render-blocking-javascript-with-async-defer.png)](/guides/avoid-render-blocking-javascript-with-async-defer.png) - diff --git a/src/data/guides/basic-authentication.md b/src/data/guides/basic-authentication.md index 23a1a926b..4d0a8eb8d 100644 --- a/src/data/guides/basic-authentication.md +++ b/src/data/guides/basic-authentication.md @@ -1,24 +1,23 @@ --- -title: "Basic Authentication" -description: "Understand what is basic authentication and how it is implemented" +title: 'Basic Authentication' +description: 'Understand what is basic authentication and how it is implemented' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "Basic Authentication - roadmap.sh" - description: "Understand what is basic authentication and how it is implemented" + title: 'Basic Authentication - roadmap.sh' + description: 'Understand what is basic authentication and how it is implemented' isNew: false -type: "visual" +type: 'visual' date: 2021-05-19 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "visual-guide" - - "guide-sitemap" + - 'guide' + - 'visual-guide' + - 'guide-sitemap' --- [![Basic Authentication](/guides/basic-authentication.png)](/guides/basic-authentication.png) - diff --git a/src/data/guides/basics-of-authentication.md b/src/data/guides/basics-of-authentication.md index 244dcff81..4ac970c3a 100644 --- a/src/data/guides/basics-of-authentication.md +++ b/src/data/guides/basics-of-authentication.md @@ -1,23 +1,23 @@ --- -title: "Basics of Authentication" -description: "Learn the basics of Authentication and Authorization" +title: 'Basics of Authentication' +description: 'Learn the basics of Authentication and Authorization' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "Basics of Authentication - roadmap.sh" - description: "Learn the basics of Authentication and Authorization" + title: 'Basics of Authentication - roadmap.sh' + description: 'Learn the basics of Authentication and Authorization' isNew: false -type: "textual" +type: 'textual' date: 2022-09-21 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "textual-guide" - - "guide-sitemap" + - 'guide' + - 'textual-guide' + - 'guide-sitemap' --- Our last video series was about data structures. We looked at the most common data structures, their use cases, pros and cons, and the different operations you could perform on each data structure. @@ -79,6 +79,7 @@ Two-factor authentication is similar to multifactor authentication. The only dif Next we have the difference between authentication and authorization. This comes up a lot in the interviews, and beginners often confuse them. ### What is Authentication + Authentication is the process of verifying the identity. For example, when you enter your credentials at a login screen, the application here identifies you through your credentials. So this is what the authentication is, the process of verifying the identity. In case of an authentication failure, for example, if you enter an invalid username and password, the HTTP response code is "Unauthorized" 401. diff --git a/src/data/guides/big-o-notation.md b/src/data/guides/big-o-notation.md index 00078e4c6..32062ae7b 100644 --- a/src/data/guides/big-o-notation.md +++ b/src/data/guides/big-o-notation.md @@ -1,26 +1,25 @@ --- -title: "Big-O Notation" -description: "Easy to understand explanation of Big-O notation without any fancy terms" +title: 'Big-O Notation' +description: 'Easy to understand explanation of Big-O notation without any fancy terms' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "Big-O Notation - roadmap.sh" - description: "Easy to understand explanation of Big-O notation without any fancy terms" + title: 'Big-O Notation - roadmap.sh' + description: 'Easy to understand explanation of Big-O notation without any fancy terms' isNew: false -type: "visual" +type: 'visual' date: 2021-03-15 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "visual-guide" - - "guide-sitemap" + - 'guide' + - 'visual-guide' + - 'guide-sitemap' --- -Big-O notation is the mathematical notation that helps analyse the algorithms to get an idea about how they might perform as the input grows. The image below explains Big-O in a simple way without using any fancy terminology. +Big-O notation is the mathematical notation that helps analyse the algorithms to get an idea about how they might perform as the input grows. The image below explains Big-O in a simple way without using any fancy terminology. [![Big-O Notation](/guides/big-o-notation.png)](/guides/big-o-notation.png) - diff --git a/src/data/guides/character-encodings.md b/src/data/guides/character-encodings.md index 3142e2b36..6769955ad 100644 --- a/src/data/guides/character-encodings.md +++ b/src/data/guides/character-encodings.md @@ -1,24 +1,23 @@ --- -title: "Character Encodings" -description: "Covers the basics of character encodings and explains ASCII vs Unicode" +title: 'Character Encodings' +description: 'Covers the basics of character encodings and explains ASCII vs Unicode' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "Character Encodings - roadmap.sh" - description: "Covers the basics of character encodings and explains ASCII vs Unicode" + title: 'Character Encodings - roadmap.sh' + description: 'Covers the basics of character encodings and explains ASCII vs Unicode' isNew: false -type: "visual" +type: 'visual' date: 2021-05-14 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "visual-guide" - - "guide-sitemap" + - 'guide' + - 'visual-guide' + - 'guide-sitemap' --- [![Character Encodings](/guides/character-encodings.png)](/guides/character-encodings.png) - diff --git a/src/data/guides/ci-cd.md b/src/data/guides/ci-cd.md index 6fe17bfd1..f150b1ac3 100644 --- a/src/data/guides/ci-cd.md +++ b/src/data/guides/ci-cd.md @@ -1,26 +1,25 @@ --- -title: "What is CI and CD?" -description: "Learn the basics of CI/CD and how to implement that with GitHub Actions." +title: 'What is CI and CD?' +description: 'Learn the basics of CI/CD and how to implement that with GitHub Actions.' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "What is CI and CD? - roadmap.sh" - description: "Learn the basics of CI/CD and how to implement that with GitHub Actions." + title: 'What is CI and CD? - roadmap.sh' + description: 'Learn the basics of CI/CD and how to implement that with GitHub Actions.' isNew: false -type: "visual" +type: 'visual' date: 2021-07-09 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "visual-guide" - - "guide-sitemap" + - 'guide' + - 'visual-guide' + - 'guide-sitemap' --- The image below details the differences between the continuous integration and continuous delivery. Also, here is the [accompanying video on implementing that with GitHub actions](https://www.youtube.com/watch?v=nyKZTKQS_EQ). [![CI vs CD](/guides/ci-cd.png)](/guides/ci-cd.png) - diff --git a/src/data/guides/consistency-patterns-in-distributed-systems.md b/src/data/guides/consistency-patterns-in-distributed-systems.md index aa88144df..c3b04a2ab 100644 --- a/src/data/guides/consistency-patterns-in-distributed-systems.md +++ b/src/data/guides/consistency-patterns-in-distributed-systems.md @@ -1,24 +1,24 @@ --- -title: "Consistency Patterns" -description: "Everything you need to know about Week, Strong and Eventual Consistency" +title: 'Consistency Patterns' +description: 'Everything you need to know about Week, Strong and Eventual Consistency' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "Consistency Patterns - roadmap.sh" - description: "Everything you need to know about Week, Strong and Eventual Consistency" + title: 'Consistency Patterns - roadmap.sh' + description: 'Everything you need to know about Week, Strong and Eventual Consistency' isNew: true -canonicalUrl: "https://cs.fyi/guide/consistency-patterns-week-strong-eventual/" -type: "textual" +canonicalUrl: 'https://cs.fyi/guide/consistency-patterns-week-strong-eventual/' +type: 'textual' date: 2023-01-18 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "visual-guide" - - "guide-sitemap" + - 'guide' + - 'visual-guide' + - 'guide-sitemap' --- Before we talk about the Consistency Patterns, we should know what a distributed system is. Simply put, a distributed system is a system that consists of more than one components, and each component is responsible for one part of the application. @@ -39,11 +39,11 @@ When working with distributed systems, we need to think about managing the data ## Consistency Patterns -Consistency patterns refer to the ways in which data is stored and managed in a distributed system and how that data is made available to users and applications. There are three main types of consistency patterns: +Consistency patterns refer to the ways in which data is stored and managed in a distributed system and how that data is made available to users and applications. There are three main types of consistency patterns: -* Strong consistency -* Weak consistency -* Eventual Consistency +- Strong consistency +- Weak consistency +- Eventual Consistency Each of these patterns has its own advantages and disadvantages, and the choice of which pattern to use will depend on the specific requirements of the application or system. @@ -51,7 +51,7 @@ Each of these patterns has its own advantages and disadvantages, and the choice > After an update is made to the data, it will be immediately visible to any subsequent read operations. The data is replicated in a synchronous manner, ensuring that all copies of the data are updated at the same time. -In a strong consistency system, any updates to some data are immediately propagated to all locations. This ensures that all locations have the same version of the data, but it also means that the system is not highly available and has high latency. +In a strong consistency system, any updates to some data are immediately propagated to all locations. This ensures that all locations have the same version of the data, but it also means that the system is not highly available and has high latency. An example of strong consistency is a financial system where users can transfer money between accounts. The system is designed for **high data integrity**, so the data is stored in a single location and updates to that data are immediately propagated to all other locations. This ensures that all users and applications are working with the same, accurate data. For instance, when a user initiates a transfer of funds from one account to another, the system immediately updates the balance of both accounts and all other system components are immediately aware of the change. This ensures that all users can see the updated balance of both accounts and prevents any discrepancies. diff --git a/src/data/guides/design-patterns-for-humans.md b/src/data/guides/design-patterns-for-humans.md index 2e2cbd2c7..61529f909 100644 --- a/src/data/guides/design-patterns-for-humans.md +++ b/src/data/guides/design-patterns-for-humans.md @@ -1,23 +1,23 @@ --- -title: "Design Patterns for Humans" -description: "A language agnostic, ultra-simplified explanation to design patterns" +title: 'Design Patterns for Humans' +description: 'A language agnostic, ultra-simplified explanation to design patterns' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "Design Patterns for Humans - roadmap.sh" - description: "A language agnostic, ultra-simplified explanation to design patterns" + title: 'Design Patterns for Humans - roadmap.sh' + description: 'A language agnostic, ultra-simplified explanation to design patterns' isNew: false -type: "textual" +type: 'textual' date: 2019-01-23 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "textual-guide" - - "guide-sitemap" + - 'guide' + - 'textual-guide' + - 'guide-sitemap' --- Design patterns are solutions to recurring problems; **guidelines on how to tackle certain problems**. They are not classes, packages or libraries that you can plug into your application and wait for the magic to happen. These are, rather, guidelines on how to tackle certain problems in certain situations. @@ -33,7 +33,7 @@ Wikipedia describes them as Developers, mostly beginners, make the mistake of over-thinking and forcing the design patterns which results in a horrible un-maintainable mess. The rule of thumb is to keep the codebase as simple as possible, once you start developing, you will start to see the patterns repeating in the codebase in which case you can go ahead and implement the relevant design patterns. - Design patterns are not a silver bullet to all your problems. -- Do not try to force them; bad things are supposed to happen, if done so. +- Do not try to force them; bad things are supposed to happen, if done so. - Keep in mind that design patterns are solutions **to** problems, not solutions **finding** problems; so don't overthink. - If used in a correct place in a correct manner, they can prove to be a savior; or else they can result in a horrible mess of a code. @@ -43,41 +43,47 @@ Developers, mostly beginners, make the mistake of over-thinking and forcing the This guide is about Gang of Four (GoF) design patterns, which refers to the four authors of [the book which introduced these design patterns](https://en.wikipedia.org/wiki/Design_Patterns). There are three types of design patterns: -* [Creational](#creational-design-patterns) -* [Structural](#structural-design-patterns) -* [Behavioral](#behavioral-design-patterns) +- [Creational](#creational-design-patterns) +- [Structural](#structural-design-patterns) +- [Behavioral](#behavioral-design-patterns) ## Creational Design Patterns In plain words + > Creational patterns are focused towards how to instantiate an object or group of related objects. Wikipedia says + > In software engineering, creational design patterns are design patterns that deal with object creation mechanisms, trying to create objects in a manner suitable to the situation. The basic form of object creation could result in design problems or added complexity to the design. Creational design patterns solve this problem by somehow controlling this object creation. There are 6 types of Creational patterns - * [Simple Factory](#-simple-factory) - * [Factory Method](#-factory-method) - * [Abstract Factory](#-abstract-factory) - * [Builder](#-builder) - * [Prototype](#-prototype) - * [Singleton](#-singleton) +- [Simple Factory](#-simple-factory) +- [Factory Method](#-factory-method) +- [Abstract Factory](#-abstract-factory) +- [Builder](#-builder) +- [Prototype](#-prototype) +- [Singleton](#-singleton) + +## 🏠 Simple Factory -🏠 Simple Factory --------------- Real world example + > Consider, you are building a house and you need doors. You can either put on your carpenter clothes, bring some wood, glue, nails and all the tools required to build the door and start building it in your house or you can simply call the factory and get the built door delivered to you so that you don't need to learn anything about the door making or to deal with the mess that comes with making it. In plain words + > Simple factory simply generates an instance for client without exposing any instantiation logic to the client Wikipedia says + > In object-oriented programming (OOP), a factory is an object for creating other objects – formally a factory is a function or method that returns objects of a varying prototype or class from some method call, which is assumed to be "new". **Programmatic Example** First of all we have a door interface and the implementation + ```php interface Door { @@ -107,7 +113,9 @@ class WoodenDoor implements Door } } ``` + Then we have our door factory that makes the door and returns it + ```php class DoorFactory { @@ -117,7 +125,9 @@ class DoorFactory } } ``` + And then it can be used as + ```php // Make me a door of 100x200 $door = DoorFactory::makeDoor(100, 200); @@ -133,19 +143,21 @@ $door2 = DoorFactory::makeDoor(50, 100); When creating an object is not just a few assignments and involves some logic, it makes sense to put it in a dedicated factory instead of repeating the same code everywhere. -🏭 Factory Method --------------- +## 🏭 Factory Method Real world example + > Consider the case of a hiring manager. It is impossible for one person to interview for each of the positions. Based on the job opening, she has to decide and delegate the interview steps to different people. In plain words + > It provides a way to delegate the instantiation logic to child classes. Wikipedia says + > In class-based programming, the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor. - **Programmatic Example** +**Programmatic Example** Taking our hiring manager example above. First of all we have an interviewer interface and some implementations for it @@ -189,7 +201,9 @@ abstract class HiringManager } ``` + Now any child can extend it and provide the required interviewer + ```php class DevelopmentManager extends HiringManager { @@ -207,6 +221,7 @@ class MarketingManager extends HiringManager } } ``` + and then it can be used as ```php @@ -221,16 +236,18 @@ $marketingManager->takeInterview(); // Output: Asking about community building. Useful when there is some generic processing in a class but the required sub-class is dynamically decided at runtime. Or putting it in other words, when the client doesn't know what exact sub-class it might need. -🔨 Abstract Factory ----------------- +## 🔨 Abstract Factory Real world example + > Extending our door example from Simple Factory. Based on your needs you might get a wooden door from a wooden door shop, iron door from an iron shop or a PVC door from the relevant shop. Plus you might need a guy with different kind of specialities to fit the door, for example a carpenter for wooden door, welder for iron door etc. As you can see there is a dependency between the doors now, wooden door needs carpenter, iron door needs a welder etc. In plain words + > A factory of factories; a factory that groups the individual but related/dependent factories together without specifying their concrete classes. Wikipedia says + > The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes **Programmatic Example** @@ -259,6 +276,7 @@ class IronDoor implements Door } } ``` + Then we have some fitting experts for each door type ```php @@ -285,6 +303,7 @@ class Carpenter implements DoorFittingExpert ``` Now we have our abstract factory that would let us make family of related objects i.e. wooden door factory would create a wooden door and wooden door fitting expert and iron door factory would create an iron door and iron door fitting expert + ```php interface DoorFactory { @@ -320,7 +339,9 @@ class IronDoorFactory implements DoorFactory } } ``` + And then it can be used as + ```php $woodenFactory = new WoodenDoorFactory(); @@ -340,20 +361,24 @@ $door->getDescription(); // Output: I am an iron door $expert->getDescription(); // Output: I can only fit iron doors ``` -As you can see the wooden door factory has encapsulated the `carpenter` and the `wooden door` also iron door factory has encapsulated the `iron door` and `welder`. And thus it had helped us make sure that for each of the created door, we do not get a wrong fitting expert. +As you can see the wooden door factory has encapsulated the `carpenter` and the `wooden door` also iron door factory has encapsulated the `iron door` and `welder`. And thus it had helped us make sure that for each of the created door, we do not get a wrong fitting expert. **When to use?** When there are interrelated dependencies with not-that-simple creation logic involved ## 👷 Builder + Real world example -> Imagine you are at Hardee's and you order a specific deal, lets say, "Big Hardee" and they hand it over to you without *any questions*; this is the example of simple factory. But there are cases when the creation logic might involve more steps. For example you want a customized Subway deal, you have several options in how your burger is made e.g what bread do you want? what types of sauces would you like? What cheese would you want? etc. In such cases builder pattern comes to the rescue. + +> Imagine you are at Hardee's and you order a specific deal, lets say, "Big Hardee" and they hand it over to you without _any questions_; this is the example of simple factory. But there are cases when the creation logic might involve more steps. For example you want a customized Subway deal, you have several options in how your burger is made e.g what bread do you want? what types of sauces would you like? What cheese would you want? etc. In such cases builder pattern comes to the rescue. In plain words + > Allows you to create different flavors of an object while avoiding constructor pollution. Useful when there could be several flavors of an object. Or when there are a lot of steps involved in creation of an object. Wikipedia says + > The builder pattern is an object creation software design pattern with the intentions of finding a solution to the telescoping constructor anti-pattern. Having said that let me add a bit about what telescoping constructor anti-pattern is. At one point or the other we have all seen a constructor like below: @@ -438,6 +463,7 @@ class BurgerBuilder } } ``` + And then it can be used as: ```php @@ -452,15 +478,18 @@ $burger = (new BurgerBuilder(14)) When there could be several flavors of an object and to avoid the constructor telescoping. The key difference from the factory pattern is that; factory pattern is to be used when the creation is a one step process while builder pattern is to be used when the creation is a multi step process. -🐑 Prototype ------------- +## 🐑 Prototype + Real world example + > Remember dolly? The sheep that was cloned! Lets not get into the details but the key point here is that it is all about cloning In plain words + > Create object based on an existing object through cloning. Wikipedia says + > The prototype pattern is a creational design pattern in software development. It is used when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects. In short, it allows you to create a copy of an existing object and modify it to your needs, instead of going through the trouble of creating an object from scratch and setting it up. @@ -502,7 +531,9 @@ class Sheep } } ``` + Then it can be cloned like below + ```php $original = new Sheep('Jolly'); echo $original->getName(); // Jolly @@ -521,15 +552,18 @@ Also you could use the magic method `__clone` to modify the cloning behavior. When an object is required that is similar to existing object or when the creation would be expensive as compared to cloning. -💍 Singleton ------------- +## 💍 Singleton + Real world example + > There can only be one president of a country at a time. The same president has to be brought to action, whenever duty calls. President here is singleton. In plain words + > Ensures that only one object of a particular class is ever created. Wikipedia says + > In software engineering, the singleton pattern is a software design pattern that restricts the instantiation of a class to one object. This is useful when exactly one object is needed to coordinate actions across the system. Singleton pattern is actually considered an anti-pattern and overuse of it should be avoided. It is not necessarily bad and could have some valid use-cases but should be used with caution because it introduces a global state in your application and change to it in one place could affect in the other areas and it could become pretty difficult to debug. The other bad thing about them is it makes your code tightly coupled plus mocking the singleton could be difficult. @@ -537,6 +571,7 @@ Singleton pattern is actually considered an anti-pattern and overuse of it shoul **Programmatic Example** To create a singleton, make the constructor private, disable cloning, disable extension and create a static variable to house the instance + ```php final class President { @@ -567,7 +602,9 @@ final class President } } ``` + Then in order to use + ```php $president1 = President::getInstance(); $president2 = President::getInstance(); @@ -576,33 +613,39 @@ var_dump($president1 === $president2); // true ``` ## Structural Design Patterns + In plain words + > Structural patterns are mostly concerned with object composition or in other words how the entities can use each other. Or yet another explanation would be, they help in answering "How to build a software component?" Wikipedia says + > In software engineering, structural design patterns are design patterns that ease the design by identifying a simple way to realize relationships between entities. There are 7 types of structural patterns - * [Adapter](#-adapter) - * [Bridge](#-bridge) - * [Composite](#-composite) - * [Decorator](#-decorator) - * [Facade](#-facade) - * [Flyweight](#-flyweight) - * [Proxy](#-proxy) +- [Adapter](#-adapter) +- [Bridge](#-bridge) +- [Composite](#-composite) +- [Decorator](#-decorator) +- [Facade](#-facade) +- [Flyweight](#-flyweight) +- [Proxy](#-proxy) + +## 🔌 Adapter -🔌 Adapter -------- Real world example + > Consider that you have some pictures in your memory card and you need to transfer them to your computer. In order to transfer them you need some kind of adapter that is compatible with your computer ports so that you can attach memory card to your computer. In this case card reader is an adapter. > Another example would be the famous power adapter; a three legged plug can't be connected to a two pronged outlet, it needs to use a power adapter that makes it compatible with the two pronged outlet. > Yet another example would be a translator translating words spoken by one person to another In plain words + > Adapter pattern lets you wrap an otherwise incompatible object in an adapter to make it compatible with another class. Wikipedia says + > In software engineering, the adapter pattern is a software design pattern that allows the interface of an existing class to be used as another interface. It is often used to make existing classes work with others without modifying their source code. **Programmatic Example** @@ -631,7 +674,9 @@ class AsianLion implements Lion } } ``` + And hunter expects any implementation of `Lion` interface to hunt. + ```php class Hunter { @@ -669,6 +714,7 @@ class WildDogAdapter implements Lion } } ``` + And now the `WildDog` can be used in our game using `WildDogAdapter`. ```php @@ -679,17 +725,20 @@ $hunter = new Hunter(); $hunter->hunt($wildDogAdapter); ``` -🚡 Bridge ------- +## 🚡 Bridge + Real world example + > Consider you have a website with different pages and you are supposed to allow the user to change the theme. What would you do? Create multiple copies of each of the pages for each of the themes or would you just create separate theme and load them based on the user's preferences? Bridge pattern allows you to do the second i.e. ![With and without the bridge pattern](https://cloud.githubusercontent.com/assets/11269635/23065293/33b7aea0-f515-11e6-983f-98823c9845ee.png) In Plain Words + > Bridge pattern is about preferring composition over inheritance. Implementation details are pushed from a hierarchy to another object with a separate hierarchy. Wikipedia says + > The bridge pattern is a design pattern used in software engineering that is meant to "decouple an abstraction from its implementation so that the two can vary independently" **Programmatic Example** @@ -733,7 +782,9 @@ class Careers implements WebPage } } ``` + And the separate theme hierarchy + ```php interface Theme @@ -763,7 +814,9 @@ class AquaTheme implements Theme } } ``` + And both the hierarchies + ```php $darkTheme = new DarkTheme(); @@ -777,12 +830,15 @@ echo $careers->getContent(); // "Careers page in Dark Black"; ## 🌿 Composite Real world example + > Every organization is composed of employees. Each of the employees has the same features i.e. has a salary, has some responsibilities, may or may not report to someone, may or may not have some subordinates etc. In plain words + > Composite pattern lets clients treat the individual objects in a uniform manner. Wikipedia says + > In software engineering, the composite pattern is a partitioning design pattern. The composite pattern describes that a group of objects is to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects and compositions uniformly. **Programmatic Example** @@ -804,7 +860,7 @@ class Developer implements Employee protected $salary; protected $name; protected $roles; - + public function __construct(string $name, float $salary) { $this->name = $name; @@ -906,17 +962,18 @@ $organization->addEmployee($jane); echo "Net salaries: " . $organization->getNetSalaries(); // Net Salaries: 27000 ``` -☕ Decorator -------------- +## ☕ Decorator Real world example > Imagine you run a car service shop offering multiple services. Now how do you calculate the bill to be charged? You pick one service and dynamically keep adding to it the prices for the provided services till you get the final cost. Here each type of service is a decorator. In plain words + > Decorator pattern lets you dynamically change the behavior of an object at run time by wrapping them in an object of a decorator class. Wikipedia says + > In object-oriented programming, the decorator pattern is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class. The decorator pattern is often useful for adhering to the Single Responsibility Principle, as it allows functionality to be divided between classes with unique areas of concern. **Programmatic Example** @@ -943,7 +1000,9 @@ class SimpleCoffee implements Coffee } } ``` + We want to make the code extensible to allow options to modify it if required. Lets make some add-ons (decorators) + ```php class MilkCoffee implements Coffee { @@ -1026,16 +1085,18 @@ echo $someCoffee->getCost(); // 20 echo $someCoffee->getDescription(); // Simple Coffee, milk, whip, vanilla ``` -📦 Facade ----------------- +## 📦 Facade Real world example + > How do you turn on the computer? "Hit the power button" you say! That is what you believe because you are using a simple interface that computer provides on the outside, internally it has to do a lot of stuff to make it happen. This simple interface to the complex subsystem is a facade. In plain words + > Facade pattern provides a simplified interface to a complex subsystem. Wikipedia says + > A facade is an object that provides a simplified interface to a larger body of code, such as a class library. **Programmatic Example** @@ -1081,7 +1142,9 @@ class Computer } } ``` + Here we have the facade + ```php class ComputerFacade { @@ -1108,23 +1171,27 @@ class ComputerFacade } } ``` + Now to use the facade + ```php $computer = new ComputerFacade(new Computer()); $computer->turnOn(); // Ouch! Beep beep! Loading.. Ready to be used! $computer->turnOff(); // Bup bup buzzz! Haah! Zzzzz ``` -🍃 Flyweight ---------- +## 🍃 Flyweight Real world example + > Did you ever have fresh tea from some stall? They often make more than one cup that you demanded and save the rest for any other customer so to save the resources e.g. gas etc. Flyweight pattern is all about that i.e. sharing. In plain words + > It is used to minimize memory usage or computational expenses by sharing as much as possible with similar objects. Wikipedia says + > In computer programming, flyweight is a software design pattern. A flyweight is an object that minimizes memory use by sharing as much data as possible with other similar objects; it is a way to use objects in large numbers when a simple repeated representation would use an unacceptable amount of memory. **Programmatic example** @@ -1180,6 +1247,7 @@ class TeaShop } } ``` + And it can be used as below ```php @@ -1197,13 +1265,17 @@ $shop->serve(); ``` ## 🎱 Proxy + Real world example + > Have you ever used an access card to go through a door? There are multiple options to open that door i.e. it can be opened either using access card or by pressing a button that bypasses the security. The door's main functionality is to open but there is a proxy added on top of it to add some functionality. Let me better explain it using the code example below. In plain words + > Using the proxy pattern, a class represents the functionality of another class. Wikipedia says + > A proxy, in its most general form, is a class functioning as an interface to something else. A proxy is a wrapper or agent object that is being called by the client to access the real serving object behind the scenes. Use of the proxy can simply be forwarding to the real object, or can provide additional logic. In the proxy extra functionality can be provided, for example caching when operations on the real object are resource intensive, or checking preconditions before operations on the real object are invoked. **Programmatic Example** @@ -1230,7 +1302,9 @@ class LabDoor implements Door } } ``` + Then we have a proxy to secure any doors that we want + ```php class SecuredDoor { @@ -1261,7 +1335,9 @@ class SecuredDoor } } ``` + And here is how it can be used + ```php $door = new SecuredDoor(new LabDoor()); $door->open('invalid'); // Big no! It ain't possible. @@ -1269,38 +1345,44 @@ $door->open('invalid'); // Big no! It ain't possible. $door->open('$ecr@t'); // Opening lab door $door->close(); // Closing lab door ``` + Yet another example would be some sort of data-mapper implementation. For example, I recently made an ODM (Object Data Mapper) for MongoDB using this pattern where I wrote a proxy around mongo classes while utilizing the magic method `__call()`. All the method calls were proxied to the original mongo class and result retrieved was returned as it is but in case of `find` or `findOne` data was mapped to the required class objects and the object was returned instead of `Cursor`. ## Behavioral Design Patterns In plain words + > It is concerned with assignment of responsibilities between the objects. What makes them different from structural patterns is they don't just specify the structure but also outline the patterns for message passing/communication between them. Or in other words, they assist in answering "How to run a behavior in software component?" Wikipedia says + > In software engineering, behavioral design patterns are design patterns that identify common communication patterns between objects and realize these patterns. By doing so, these patterns increase flexibility in carrying out this communication. There are 10 types of behavioral design patterns -* [Chain of Responsibility](#-chain-of-responsibility) -* [Command](#-command) -* [Iterator](#-iterator) -* [Mediator](#-mediator) -* [Memento](#-memento) -* [Observer](#-observer) -* [Visitor](#-visitor) -* [Strategy](#-strategy) -* [State](#-state) -* [Template Method](#-template-method) +- [Chain of Responsibility](#-chain-of-responsibility) +- [Command](#-command) +- [Iterator](#-iterator) +- [Mediator](#-mediator) +- [Memento](#-memento) +- [Observer](#-observer) +- [Visitor](#-visitor) +- [Strategy](#-strategy) +- [State](#-state) +- [Template Method](#-template-method) ## 🔗 Chain of Responsibility Real world example + > For example, you have three payment methods (`A`, `B` and `C`) setup in your account; each having a different amount in it. `A` has 100 USD, `B` has 300 USD and `C` having 1000 USD and the preference for payments is chosen as `A` then `B` then `C`. You try to purchase something that is worth 210 USD. Using Chain of Responsibility, first of all account `A` will be checked if it can make the purchase, if yes purchase will be made and the chain will be broken. If not, request will move forward to account `B` checking for amount if yes chain will be broken otherwise the request will keep forwarding till it finds the suitable handler. Here `A`, `B` and `C` are links of the chain and the whole phenomenon is Chain of Responsibility. In plain words + > It helps building a chain of objects. Request enters from one end and keeps going from object to object till it finds the suitable handler. Wikipedia says + > In object-oriented design, the chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. **Programmatic Example** @@ -1394,22 +1476,25 @@ $bank->pay(259); // Paid 259 using Bitcoin! ``` -👮 Command -------- +## 👮 Command Real world example + > A generic example would be you ordering food at a restaurant. You (i.e. `Client`) ask the waiter (i.e. `Invoker`) to bring some food (i.e. `Command`) and waiter simply forwards the request to Chef (i.e. `Receiver`) who has the knowledge of what and how to cook. > Another example would be you (i.e. `Client`) switching on (i.e. `Command`) the television (i.e. `Receiver`) using a remote control (`Invoker`). In plain words + > Allows you to encapsulate actions in objects. The key idea behind this pattern is to provide the means to decouple client from receiver. Wikipedia says + > In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to encapsulate all information needed to perform an action or trigger an event at a later time. This information includes the method name, the object that owns the method and values for the method parameters. **Programmatic Example** First of all we have the receiver that has the implementation of every action that could be performed + ```php // Receiver class Bulb @@ -1425,7 +1510,9 @@ class Bulb } } ``` + then we have an interface that each of the commands are going to implement and then we have a set of commands + ```php interface Command { @@ -1485,7 +1572,9 @@ class TurnOff implements Command } } ``` + Then we have an `Invoker` with whom the client will interact to process any commands + ```php // Invoker class RemoteControl @@ -1496,7 +1585,9 @@ class RemoteControl } } ``` + Finally let's see how we can use it in our client + ```php $bulb = new Bulb(); @@ -1510,16 +1601,18 @@ $remote->submit($turnOff); // Darkness! Command pattern can also be used to implement a transaction based system. Where you keep maintaining the history of commands as soon as you execute them. If the final command is successfully executed, all good otherwise just iterate through the history and keep executing the `undo` on all the executed commands. -➿ Iterator --------- +## ➿ Iterator Real world example -> An old radio set will be a good example of iterator, where user could start at some channel and then use next or previous buttons to go through the respective channels. Or take an example of MP3 player or a TV set where you could press the next and previous buttons to go through the consecutive channels or in other words they all provide an interface to iterate through the respective channels, songs or radio stations. + +> An old radio set will be a good example of iterator, where user could start at some channel and then use next or previous buttons to go through the respective channels. Or take an example of MP3 player or a TV set where you could press the next and previous buttons to go through the consecutive channels or in other words they all provide an interface to iterate through the respective channels, songs or radio stations. In plain words + > It presents a way to access the elements of an object without exposing the underlying presentation. Wikipedia says + > In object-oriented programming, the iterator pattern is a design pattern in which an iterator is used to traverse a container and access the container's elements. The iterator pattern decouples algorithms from containers; in some cases, algorithms are necessarily container-specific and thus cannot be decoupled. **Programmatic example** @@ -1542,6 +1635,7 @@ class RadioStation } } ``` + Then we have our iterator ```php @@ -1600,7 +1694,9 @@ class StationList implements Countable, Iterator } } ``` + And then it can be used as + ```php $stationList = new StationList(); @@ -1616,16 +1712,18 @@ foreach($stationList as $station) { $stationList->removeStation(new RadioStation(89)); // Will remove station 89 ``` -👽 Mediator --------- +## 👽 Mediator Real world example + > A general example would be when you talk to someone on your mobile phone, there is a network provider sitting between you and them and your conversation goes through it instead of being directly sent. In this case network provider is mediator. In plain words + > Mediator pattern adds a third party object (called mediator) to control the interaction between two objects (called colleagues). It helps reduce the coupling between the classes communicating with each other. Because now they don't need to have the knowledge of each other's implementation. Wikipedia says + > In software engineering, the mediator pattern defines an object that encapsulates how a set of objects interact. This pattern is considered to be a behavioral pattern due to the way it can alter the program's running behavior. **Programmatic Example** @@ -1635,7 +1733,7 @@ Here is the simplest example of a chat room (i.e. mediator) with users (i.e. col First of all, we have the mediator i.e. the chat room ```php -interface ChatRoomMediator +interface ChatRoomMediator { public function showMessage(User $user, string $message); } @@ -1654,6 +1752,7 @@ class ChatRoom implements ChatRoomMediator ``` Then we have our users i.e. colleagues + ```php class User { protected $name; @@ -1673,7 +1772,9 @@ class User { } } ``` + And the usage + ```php $mediator = new ChatRoom(); @@ -1688,15 +1789,18 @@ $jane->send('Hey!'); // Feb 14, 10:58 [Jane]: Hey! ``` -💾 Memento -------- +## 💾 Memento + Real world example + > Take the example of calculator (i.e. originator), where whenever you perform some calculation the last calculation is saved in memory (i.e. memento) so that you can get back to it and maybe get it restored using some action buttons (i.e. caretaker). In plain words + > Memento pattern is about capturing and storing the current state of an object in a manner that it can be restored later on in a smooth manner. Wikipedia says + > The memento pattern is a software design pattern that provides the ability to restore an object to its previous state (undo via rollback). Usually useful when you need to provide some sort of undo functionality. @@ -1777,20 +1881,24 @@ $editor->restore($saved); $editor->getContent(); // This is the first sentence. This is second. ``` -😎 Observer --------- +## 😎 Observer + Real world example -> A good example would be the job seekers where they subscribe to some job posting site and they are notified whenever there is a matching job opportunity. + +> A good example would be the job seekers where they subscribe to some job posting site and they are notified whenever there is a matching job opportunity. In plain words + > Defines a dependency between objects so that whenever an object changes its state, all its dependents are notified. Wikipedia says + > The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. **Programmatic example** Translating our example from above. First of all we have job seekers that need to be notified for a job posting + ```php class JobPost { @@ -1823,7 +1931,9 @@ class JobSeeker implements Observer } } ``` + Then we have our job postings to which the job seekers will subscribe + ```php class EmploymentAgency implements Observable { @@ -1847,7 +1957,9 @@ class EmploymentAgency implements Observable } } ``` + Then it can be used as + ```php // Create subscribers $johnDoe = new JobSeeker('John Doe'); @@ -1866,15 +1978,18 @@ $jobPostings->addJob(new JobPost('Software Engineer')); // Hi Jane Doe! New job posted: Software Engineer ``` -🏃 Visitor -------- +## 🏃 Visitor + Real world example + > Consider someone visiting Dubai. They just need a way (i.e. visa) to enter Dubai. After arrival, they can come and visit any place in Dubai on their own without having to ask for permission or to do some leg work in order to visit any place here; just let them know of a place and they can visit it. Visitor pattern lets you do just that, it helps you add places to visit so that they can visit as much as they can without having to do any legwork. In plain words + > Visitor pattern lets you add further operations to objects without having to modify them. Wikipedia says + > In object-oriented programming and software engineering, the visitor design pattern is a way of separating an algorithm from an object structure on which it operates. A practical result of this separation is the ability to add new operations to existing object structures without modifying those structures. It is one way to follow the open/closed principle. **Programmatic example** @@ -1896,7 +2011,9 @@ interface AnimalOperation public function visitDolphin(Dolphin $dolphin); } ``` + Then we have our implementations for the animals + ```php class Monkey implements Animal { @@ -1937,7 +2054,9 @@ class Dolphin implements Animal } } ``` + Let's implement our visitor + ```php class Speak implements AnimalOperation { @@ -1959,6 +2078,7 @@ class Speak implements AnimalOperation ``` And then it can be used as + ```php $monkey = new Monkey(); $lion = new Lion(); @@ -1966,10 +2086,11 @@ $dolphin = new Dolphin(); $speak = new Speak(); -$monkey->accept($speak); // Ooh oo aa aa! +$monkey->accept($speak); // Ooh oo aa aa! $lion->accept($speak); // Roaaar! $dolphin->accept($speak); // Tuut tutt tuutt! ``` + We could have done this simply by having an inheritance hierarchy for the animals but then we would have to modify the animals whenever we would have to add new actions to animals. But now we will not have to change them. For example, let's say we are asked to add the jump behavior to the animals, we can simply add that by creating a new visitor i.e. ```php @@ -1991,7 +2112,9 @@ class Jump implements AnimalOperation } } ``` + And for the usage + ```php $jump = new Jump(); @@ -2005,16 +2128,18 @@ $dolphin->accept($speak); // Tuut tutt tuutt! $dolphin->accept($jump); // Walked on water a little and disappeared ``` -💡 Strategy --------- +## 💡 Strategy Real world example + > Consider the example of sorting, we implemented bubble sort but the data started to grow and bubble sort started getting very slow. In order to tackle this we implemented Quick sort. But now although the quick sort algorithm was doing better for large datasets, it was very slow for smaller datasets. In order to handle this we implemented a strategy where for small datasets, bubble sort will be used and for larger, quick sort. In plain words + > Strategy pattern allows you to switch the algorithm or strategy based upon the situation. Wikipedia says + > In computer programming, the strategy pattern (also known as the policy pattern) is a behavioural software design pattern that enables an algorithm's behavior to be selected at runtime. **Programmatic example** @@ -2051,6 +2176,7 @@ class QuickSortStrategy implements SortStrategy ``` And then we have our client that is going to use any strategy + ```php class Sorter { @@ -2067,7 +2193,9 @@ class Sorter } } ``` + And it can be used as + ```php $dataset = [1, 5, 4, 3, 2, 8]; @@ -2078,15 +2206,18 @@ $sorter = new Sorter(new QuickSortStrategy()); $sorter->sort($dataset); // Output : Sorting using quick sort ``` -💢 State ------ +## 💢 State + Real world example -> Imagine you are using some drawing application, you choose the paint brush to draw. Now the brush changes its behavior based on the selected color i.e. if you have chosen red color it will draw in red, if blue then it will be in blue etc. + +> Imagine you are using some drawing application, you choose the paint brush to draw. Now the brush changes its behavior based on the selected color i.e. if you have chosen red color it will draw in red, if blue then it will be in blue etc. In plain words + > It lets you change the behavior of a class when the state changes. Wikipedia says + > The state pattern is a behavioral software design pattern that implements a state machine in an object-oriented way. With the state pattern, a state machine is implemented by implementing each individual state as a derived class of the state pattern interface, and implementing state transitions by invoking methods defined by the pattern's superclass. > The state pattern can be interpreted as a strategy pattern which is able to switch the current strategy through invocations of methods defined in the pattern's interface. @@ -2126,7 +2257,9 @@ class DefaultText implements WritingState } } ``` + Then we have our editor + ```php class TextEditor { @@ -2148,7 +2281,9 @@ class TextEditor } } ``` + And then it can be used as + ```php $editor = new TextEditor(new DefaultText()); @@ -2172,11 +2307,12 @@ $editor->type('Fifth line'); // fifth line ``` -📒 Template Method ---------------- +## 📒 Template Method Real world example + > Suppose we are getting some house built. The steps for building might look like +> > - Prepare the base of house > - Build the walls > - Add roof @@ -2185,9 +2321,11 @@ Real world example > The order of these steps could never be changed i.e. you can't build the roof before building the walls etc but each of the steps could be modified for example walls can be made of wood or polyester or stone. In plain words + > Template method defines the skeleton of how a certain algorithm could be performed, but defers the implementation of those steps to the children classes. Wikipedia says + > In software engineering, the template method pattern is a behavioral design pattern that defines the program skeleton of an algorithm in an operation, deferring some steps to subclasses. It lets one redefine certain steps of an algorithm without changing the algorithm's structure. **Programmatic Example** @@ -2195,6 +2333,7 @@ Wikipedia says Imagine we have a build tool that helps us test, lint, build, generate build reports (i.e. code coverage reports, linting report etc) and deploy our app on the test server. First of all we have our base class that specifies the skeleton for the build algorithm + ```php abstract class Builder { @@ -2264,6 +2403,7 @@ class IosBuilder extends Builder } } ``` + And then it can be used as ```php diff --git a/src/data/guides/dhcp-in-one-picture.md b/src/data/guides/dhcp-in-one-picture.md index 1920c0451..7ae3e6825 100644 --- a/src/data/guides/dhcp-in-one-picture.md +++ b/src/data/guides/dhcp-in-one-picture.md @@ -1,24 +1,23 @@ --- -title: "DHCP in One Picture" -description: "Here is what happens when a new device joins the network." +title: 'DHCP in One Picture' +description: 'Here is what happens when a new device joins the network.' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "DHCP in One Picture - roadmap.sh" - description: "Here is what happens when a new device joins the network." + title: 'DHCP in One Picture - roadmap.sh' + description: 'Here is what happens when a new device joins the network.' isNew: false -type: "visual" +type: 'visual' date: 2021-04-28 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "visual-guide" - - "guide-sitemap" + - 'guide' + - 'visual-guide' + - 'guide-sitemap' --- [![DHCP in One Picture](/guides/dhcp.png)](/guides/dhcp.png) - diff --git a/src/data/guides/dns-in-one-picture.md b/src/data/guides/dns-in-one-picture.md index 8655df8c6..c4049b6a0 100644 --- a/src/data/guides/dns-in-one-picture.md +++ b/src/data/guides/dns-in-one-picture.md @@ -1,23 +1,23 @@ --- -title: "DNS in One Picture" -description: "Quick illustrative guide on how a website is found on the internet." +title: 'DNS in One Picture' +description: 'Quick illustrative guide on how a website is found on the internet.' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "DNS in One Picture - roadmap.sh" - description: "Quick illustrative guide on how a website is found on the internet." + title: 'DNS in One Picture - roadmap.sh' + description: 'Quick illustrative guide on how a website is found on the internet.' isNew: false -type: "visual" +type: 'visual' date: 2018-12-04 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "visual-guide" - - "guide-sitemap" + - 'guide' + - 'visual-guide' + - 'guide-sitemap' --- DNS or Domain Name System is one of the fundamental blocks of the internet. As a developer, you should have at-least the basic understanding of how it works. This article is a brief introduction to what is DNS and how it works. diff --git a/src/data/guides/history-of-javascript.md b/src/data/guides/history-of-javascript.md index f523579bc..988b074f0 100644 --- a/src/data/guides/history-of-javascript.md +++ b/src/data/guides/history-of-javascript.md @@ -1,63 +1,72 @@ --- -title: "Brief History of JavaScript" -description: "How JavaScript was introduced and evolved over the years" +title: 'Brief History of JavaScript' +description: 'How JavaScript was introduced and evolved over the years' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "Brief History of JavaScript - roadmap.sh" - description: "How JavaScript was introduced and evolved over the years" + title: 'Brief History of JavaScript - roadmap.sh' + description: 'How JavaScript was introduced and evolved over the years' isNew: false -type: "textual" +type: 'textual' date: 2017-10-28 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "textual-guide" - - "guide-sitemap" + - 'guide' + - 'textual-guide' + - 'guide-sitemap' --- -Around 10 years ago, Jeff Atwood (the founder of stackoverflow) made a case that JavaScript is going to be the future and he coined the “Atwood Law” which states that *Any application that can be written in JavaScript will eventually be written in JavaScript*. Fast-forward to today, 10 years later, if you look at it it rings truer than ever. JavaScript is continuing to gain more and more adoption. +Around 10 years ago, Jeff Atwood (the founder of stackoverflow) made a case that JavaScript is going to be the future and he coined the “Atwood Law” which states that _Any application that can be written in JavaScript will eventually be written in JavaScript_. Fast-forward to today, 10 years later, if you look at it it rings truer than ever. JavaScript is continuing to gain more and more adoption. ### JavaScript is announced -JavaScript was initially created by [Brendan Eich](https://twitter.com/BrendanEich) of NetScape and was first announced in a press release by Netscape in 1995. It has a bizarre history of naming; initially it was named `Mocha` by the creator, which was later renamed to `LiveScript`. In 1996, about a year later after the release, NetScape decided to rename it to be `JavaScript` with hopes of capitalizing on the Java community (although JavaScript did not have any relationship with Java) and released Netscape 2.0 with the official support of JavaScript. + +JavaScript was initially created by [Brendan Eich](https://twitter.com/BrendanEich) of NetScape and was first announced in a press release by Netscape in 1995. It has a bizarre history of naming; initially it was named `Mocha` by the creator, which was later renamed to `LiveScript`. In 1996, about a year later after the release, NetScape decided to rename it to be `JavaScript` with hopes of capitalizing on the Java community (although JavaScript did not have any relationship with Java) and released Netscape 2.0 with the official support of JavaScript. ### ES1, ES2 and ES3 + In 1996, Netscape decided to submit it to [ECMA International](https://en.wikipedia.org/wiki/Ecma_International) with the hopes of getting it standardized. First edition of the standard specification was released in 1997 and the language was standardized. After the initial release, `ECMAScript` was continued to be worked upon and in no-time two more versions were released ECMAScript 2 in 1998 and ECMAScript 3 in 1999. ### Decade of Silence and ES4 + After the release of ES3 in 1999, there was a complete silence for a decade and no changes were made to the official standard. There was some work on the fourth edition in the initial days; some of the features that were being discussed included classes, modules, static typings, destructuring etc. It was being targeted to be released by 2008 but was abandoned due to political differences concerning language complexity. However, the vendors kept introducing the extensions to the language and the developers were left scratching their heads — adding polyfills to battle compatibility issues between different browsers. ### From silence to ES5 + Google, Microsoft, Yahoo and other disputers of ES4 came together and decided to work on a less ambitious update to ES3 tentatively named ES3.1. But the teams were still fighting about what to include from ES4 and what not. Finally, in 2009 ES5 was released mainly focusing on fixing the compatibility and security issues etc. But there wasn’t much of a splash in the water — it took ages for the vendors to incorporate the standards and many developers were still using ES3 without being aware of the “modern” standards. ### Release of ES6 — ECMAScript 2015 + After a few years of the release of ES5, things started to change, TC39 (the committee under ECMA international responsible for ECMAScript standardization) kept working on the next version of ECMAScript (ES6) which was originally named ES Harmony, before being eventually released with the name ES2015. ES2015 adds significant features and syntactic sugar to allow writing complex applications. Some of the features that ES6 has to offer, include Classes, Modules, Arrows, Enhanced object literals, Template strings, Destructuring, Default param values + rest + spread, Let and Const, Iterators + for..of, Generators, Maps + Sets, Proxies, Symbols, Promises, math + number + string + array + object APIs [etc](http://es6-features.org/#Constants) Browser support for ES6 is still scarce but everything that ES6 has to offer is still available to developers by transpiling the ES6 code to ES5. With the release of 6th version of ECMAScript, TC39 decided to move to yearly model of releasing updates to ECMAScript so to make sure that the new features are added as soon as they are approved and we don’t have to wait for the full specification to be drafted and approved — thus 6th version of ECMAScript was renamed as ECMAScript 2015 or ES2015 before the release in June 2015. And the next versions of ECMAScript were decided to published in June of every year. ### Release of ES7 — ECMAScript 2016 + In June 2016, seventh version of ECMAScript was released. As ECMAScript has been moved to an yearly release model, ECMAScript 2016 (ES2016) comparatively did not have much to offer. ES2016 includes just two new features -* Exponentiation operator `**` -* `Array.prototype.includes` +- Exponentiation operator `**` +- `Array.prototype.includes` ### Release of ES8 — ECMAScript 2017 + The eighth version of ECMAScript was released in June 2017. The key highlight of ES8 was the addition of async functions. Here is the list of new features in ES8 -* `Object.values()` and `Object.entries()` -* String padding i.e. `String.prototype.padEnd()` and `String.prototype.padStart()` -* `Object.getOwnPropertyDescriptors` -* Trailing commas in function parameter lists and calls -* Async functions +- `Object.values()` and `Object.entries()` +- String padding i.e. `String.prototype.padEnd()` and `String.prototype.padStart()` +- `Object.getOwnPropertyDescriptors` +- Trailing commas in function parameter lists and calls +- Async functions ### What is ESNext then? + ESNext is a dynamic name that refers to whatever the current version of ECMAScript is at the given time. For example, at the time of this writing `ES2017` or `ES8` is `ESNext`. ### What does the future hold? + Since the release of ES6, [TC39](https://github.com/tc39) has quite streamlined their process. TC39 operates through a Github organization now and there are [several proposals](https://github.com/tc39/proposals) for new features or syntax to be added to the next versions of ECMAScript. Any one can go ahead and [submit a proposal](https://github.com/tc39/proposals) thus resulting in increasing the participation from the community. Every proposal goes through [four stages of maturity](https://tc39.github.io/process-document/) before it makes it into the specification. And that about wraps it up. Feel free to leave your feedback in the comments section below. Also here are the links to original language specifications [ES6](https://www.ecma-international.org/ecma-262/6.0/), [ES7](https://www.ecma-international.org/ecma-262/7.0/) and [ES8](https://www.ecma-international.org/ecma-262/8.0/). diff --git a/src/data/guides/how-to-setup-a-jump-server.md b/src/data/guides/how-to-setup-a-jump-server.md index 6d992cc07..e8cfe988f 100644 --- a/src/data/guides/how-to-setup-a-jump-server.md +++ b/src/data/guides/how-to-setup-a-jump-server.md @@ -1,23 +1,23 @@ --- -title: "Jump Servers: What, Why and How" -description: "Learn what is a Jump Server and how to set it up for SSH access." +title: 'Jump Servers: What, Why and How' +description: 'Learn what is a Jump Server and how to set it up for SSH access.' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "Jump Servers: What, Why and How - roadmap.sh" - description: "Learn what is a Jump Server and how to set it up for SSH access." + title: 'Jump Servers: What, Why and How - roadmap.sh' + description: 'Learn what is a Jump Server and how to set it up for SSH access.' isNew: true -type: "visual" +type: 'visual' date: 2023-03-20 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "visual-guide" - - "guide-sitemap" + - 'guide' + - 'visual-guide' + - 'guide-sitemap' --- Given below is the demonstration of a sample production environment for a web application that consists of two different components, application server and database server. @@ -34,7 +34,7 @@ A jump server is a server that is used to access other servers. It is also known In the above example, the application server is called the jump server. -For example, you might have this infrastructure on AWS, where you have a custom VPC with two subnets. +For example, you might have this infrastructure on AWS, where you have a custom VPC with two subnets. - **Public Subnet:** Outside world can access - **Private Subnet:** Only accessible from within the VPC @@ -51,7 +51,7 @@ We can easily SSH into the application server from the internet i.e. ssh -i ~/.ssh/mykey.pem ec2-user@3.112.5.67 ``` -But the database server doesn't have a public IP address. So, we can't SSH into it from the internet. For example, following won't work +But the database server doesn't have a public IP address. So, we can't SSH into it from the internet. For example, following won't work ```bash # Won't work because the IP address is private @@ -81,11 +81,11 @@ Warning: Identity file /home/ubuntu/.ssh/mykey.pem not accessible: No such file ubuntu@192.168.1.0: Permission denied (publickey). ``` -What happened? The reason is that the private key is not present on the application server i.e. `~/.ssh/mykey.pem`. Now, there are two ways to solve this problem. +What happened? The reason is that the private key is not present on the application server i.e. `~/.ssh/mykey.pem`. Now, there are two ways to solve this problem. ### Solution 1 - Copy the Private Key to Server -We can copy the private key from our local machine to the application server and use it there to access the database server. You can do that by running the following command on your local machine: +We can copy the private key from our local machine to the application server and use it there to access the database server. You can do that by running the following command on your local machine: ```bash scp -i path/to/key.pem examplefile yourusername@yourserver:/home/yourusername/ @@ -188,4 +188,4 @@ ssh db ## Conclusion -In this article, we learned about the jump server and how to use SSH agent forwarding to access a server that is not accessible from the internet. We also learned how to simplify the SSH command by adding host entries to the `~/.ssh/config` file. \ No newline at end of file +In this article, we learned about the jump server and how to use SSH agent forwarding to access a server that is not accessible from the internet. We also learned how to simplify the SSH command by adding host entries to the `~/.ssh/config` file. diff --git a/src/data/guides/http-basic-authentication.md b/src/data/guides/http-basic-authentication.md index 386f98fae..f1b565813 100644 --- a/src/data/guides/http-basic-authentication.md +++ b/src/data/guides/http-basic-authentication.md @@ -1,23 +1,23 @@ --- -title: "HTTP Basic Authentication" -description: "Learn what is HTTP Basic Authentication and how to implement it in Node.js" +title: 'HTTP Basic Authentication' +description: 'Learn what is HTTP Basic Authentication and how to implement it in Node.js' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "HTTP Basic Authentication - roadmap.sh" - description: "Learn what is HTTP Basic Authentication and how to implement it in Node.js" + title: 'HTTP Basic Authentication - roadmap.sh' + description: 'Learn what is HTTP Basic Authentication and how to implement it in Node.js' isNew: false -type: "textual" +type: 'textual' date: 2022-10-03 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "textual-guide" - - "guide-sitemap" + - 'guide' + - 'textual-guide' + - 'guide-sitemap' --- Our last guide was about the [basics of authentication](/guides/basics-of-authentication), where we discussed authentication, authorization, types of authentication, authentication factors, authentication strategies, and so on. @@ -27,17 +27,19 @@ In this guide today, we will be learning about basic authentication, and we will ## What is Basic Authentication? + Given the name "Basic Authentication", you should not confuse Basic Authentication with the standard username and password authentication. Basic authentication is a part of the HTTP specification, and the details can be [found in the RFC7617](https://www.rfc-editor.org/rfc/rfc7617.html). Because it is a part of the HTTP specifications, all the browsers have native support for "HTTP Basic Authentication". Given below is the screenshot from the implementation in Google Chrome. ![Chrome Basic Authentication](/guides/basic-authentication/chrome-basic-auth.png) - ## How does it Work? + Now that we know what basic authentication is, the question is, how does it work? The answer is: it is controlled by the response of the server. ### Step 1 + When the browser first requests the server, the server tries to check the availability of the `Authorization` header in the request. Because it is the first request, no `Authorization` header is found in the request. So the server responds with the `401 Unauthorized` response code and also sends the `WWW-Authenticate` header with the value set to `Basic`, which tells the browser that it needs to trigger the basic authentication flow. ``` @@ -50,19 +52,23 @@ If you notice the response, we have an additional parameter called `realm`, whic The browser might use Realm to cache the credential. In the future, when there is an authentication failure browser will check if it has the credentials in the cache for the given realm of the domain, and it may use the same credentials. ## Step 2 + Upon receiving the response from the server, the browser will notice the `WWW-Authenticate` header and will show the authentication popup. ![Chrome Basic Authentication](/guides/basic-authentication/chrome-basic-auth.png) ## Step 3 + After the user submits the credentials through this authentication popup, the browser will automatically encode the credentials using the `base64` encoding and send them in the `Authorization` header of the same request. ### Step 4 + Upon receiving the request, the server will decode and verify the credentials. If the credentials are valid, the server will send the response to the client. So that is how Basic Authentication works. ## Basic Authentication in Node.js + I have prepared the sample project in Node.js, which can be found on GitHub [kamranahmedse/node-basic-auth-example](https://github.com/kamranahmedse/node-basic-auth-example). If you look at the codebase of the project, we have two files `index.js` with the following content: ```javascript @@ -74,7 +80,7 @@ const authMiddleware = require('./auth'); const app = express(); const port = 3000; -// This middleware is where we have the +// This middleware is where we have the // basic authentication implementation app.use(authMiddleware); @@ -84,22 +90,24 @@ app.get('/', (req, res) => { app.listen(port, () => { console.log(`App running @ http://localhost:${port}`); -}) +}); ``` As you can see, it's just a regular express server. `authMiddleware` registration is where we have all the code for "Basic Authentication". Here is the content of the middleware: ```javascript // src/auth.js -const base64 = require("base-64"); +const base64 = require('base-64'); function decodeCredentials(authHeader) { // ... } -module.exports = function(req, res, next) { - // Take the header and decode credentials - const [username, password] = decodeCredentials(req.headers.authorization || ''); +module.exports = function (req, res, next) { + // Take the header and decode credentials + const [username, password] = decodeCredentials( + req.headers.authorization || '' + ); // Verify the credentials if (username === 'admin' && password === 'admin') { @@ -109,7 +117,7 @@ module.exports = function(req, res, next) { // Respond with authenticate header on auth failure. res.set('WWW-Authenticate', 'Basic realm="user_pages"'); res.status(401).send('Authentication required.'); -} +}; ``` And that is how the basic authentication is implemented in Node.js. diff --git a/src/data/guides/http-caching.md b/src/data/guides/http-caching.md index cbc658d82..fe0a3ba91 100644 --- a/src/data/guides/http-caching.md +++ b/src/data/guides/http-caching.md @@ -1,30 +1,30 @@ --- -title: "HTTP Caching" -description: "Everything you need to know about web caching" +title: 'HTTP Caching' +description: 'Everything you need to know about web caching' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "HTTP Caching - roadmap.sh" - description: "Everything you need to know about web caching" + title: 'HTTP Caching - roadmap.sh' + description: 'Everything you need to know about web caching' isNew: false -type: "textual" +type: 'textual' date: 2018-11-29 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "textual-guide" - - "guide-sitemap" + - 'guide' + - 'textual-guide' + - 'guide-sitemap' --- -As users, we easily get frustrated by the buffering of videos, the images that take seconds to load, and pages that got stuck because the content is being loaded. Loading the resources from some cache is much faster than fetching the same from the originating server. It reduces latency, speeds up the loading of resources, decreases the load on the server, cuts down the bandwidth costs etc. +As users, we easily get frustrated by the buffering of videos, the images that take seconds to load, and pages that got stuck because the content is being loaded. Loading the resources from some cache is much faster than fetching the same from the originating server. It reduces latency, speeds up the loading of resources, decreases the load on the server, cuts down the bandwidth costs etc. ### Introduction -What is a web cache? It is something that sits somewhere between the client and the server, continuously looking at the requests and their responses, looking for any responses that can be cached. So that there is less time consumed when the same request is made again. +What is a web cache? It is something that sits somewhere between the client and the server, continuously looking at the requests and their responses, looking for any responses that can be cached. So that there is less time consumed when the same request is made again. ![Web Cache](https://i.imgur.com/mJYVvTh.png) @@ -68,7 +68,7 @@ Unlike browser cache which serves a single user, proxy caches may serve hundreds A Reverse proxy cache or surrogate cache is implemented close to the origin servers in order to reduce the load on the server. Unlike proxy caches which are implemented by ISPs etc to reduce the bandwidth usage in a network, surrogates or reverse proxy caches are implemented near the origin servers by the server administrators to reduce the load on the server. ![Reverse Proxy Cache](http://i.imgur.com/Eg4Cru3.png) - + Although you can control the reverse proxy caches (since it is implemented by you on your server) you can not avoid or control browser and proxy caches. And if your website is not configured to use these caches properly, it will still be cached using whatever defaults are set on these caches. ### Caching Headers @@ -108,9 +108,9 @@ Before HTTP/1.1 and the introduction of `Cache-Control`, there was an `Expires` Expires: Mon, 13 Mar 2017 12:22:00 GMT ``` -It should be noted that the date cannot be more than a year and if the date format is wrong, the content will be considered stale. Also, the clock on the cache has to be in sync with the clock on the server, otherwise, the desired results might not be achieved. +It should be noted that the date cannot be more than a year and if the date format is wrong, the content will be considered stale. Also, the clock on the cache has to be in sync with the clock on the server, otherwise, the desired results might not be achieved. -Although the `Expires` header is still valid and is supported widely by the caches, preference should be given to HTTP/1.1 successor of it i.e. `Cache-Control`. +Although the `Expires` header is still valid and is supported widely by the caches, preference should be given to HTTP/1.1 successor of it i.e. `Cache-Control`. #### Pragma @@ -119,17 +119,18 @@ Another one from the old, pre HTTP/1.1 days, is `Pragma`. Everything that it cou #### Cache-Control Cache-Control specifies how long and in what manner should the content be cached. This family of headers was introduced in HTTP/1.1 to overcome the limitations of the `Expires` header. - -Value for the `Cache-Control` header is composite i.e. it can have multiple directive/values. Let's look at the possible values that this header may contain. + +Value for the `Cache-Control` header is composite i.e. it can have multiple directive/values. Let's look at the possible values that this header may contain. ##### private + Setting the cache to `private` means that the content will not be cached in any of the proxies and it will only be cached by the client (i.e. browser) ```html Cache-Control: private ``` -Having said that, don't let it fool you into thinking that setting this header will make your data any secure; you still have to use SSL for that purpose. +Having said that, don't let it fool you into thinking that setting this header will make your data any secure; you still have to use SSL for that purpose. ##### public @@ -140,6 +141,7 @@ Cache-Control: public ``` ##### no-store + **`no-store`** specifies that the content is not to be cached by any of the caches ```html @@ -147,6 +149,7 @@ Cache-Control: no-store ``` ##### no-cache + **`no-cache`** indicates that the cache can be maintained but the cached content is to be re-validated (using `ETag` for example) from the server before being served. That is, there is still a request to server but for validation and not to download the cached content. ```html @@ -154,14 +157,17 @@ Cache-Control: max-age=3600, no-cache, public ``` ##### max-age: seconds + **`max-age`** specifies the number of seconds for which the content will be cached. For example, if the `cache-control` looks like below: ```html Cache-Control: max-age=3600, public ``` + it would mean that the content is publicly cacheable and will be considered stale after 60 minutes ##### s-maxage: seconds + **`s-maxage`** here `s-` prefix stands for shared. This directive specifically targets the shared caches. Like `max-age` it also gets the number of seconds for which something is to be cached. If present, it will override `max-age` and `expires` headers for shared caching. ```html @@ -169,43 +175,43 @@ Cache-Control: s-maxage=3600, public ``` ##### must-revalidate -**`must-revalidate`** it might happen sometimes that if you have network problems and the content cannot be retrieved from the server, the browser may serve stale content without validation. `must-revalidate` avoids that. If this directive is present, it means that stale content cannot be served in any case and the data must be re-validated from the server before serving. + +**`must-revalidate`** it might happen sometimes that if you have network problems and the content cannot be retrieved from the server, the browser may serve stale content without validation. `must-revalidate` avoids that. If this directive is present, it means that stale content cannot be served in any case and the data must be re-validated from the server before serving. ```html Cache-Control: max-age=3600, public, must-revalidate ``` ##### proxy-revalidate -**`proxy-revalidate`** is similar to `must-revalidate` but it specifies the same for shared or proxy caches. In other words `proxy-revalidate` is to `must-revalidate` as `s-maxage` is to `max-age`. But why did they not call it `s-revalidate`?. I have no idea why, if you have any clue please leave a comment below. + +**`proxy-revalidate`** is similar to `must-revalidate` but it specifies the same for shared or proxy caches. In other words `proxy-revalidate` is to `must-revalidate` as `s-maxage` is to `max-age`. But why did they not call it `s-revalidate`?. I have no idea why, if you have any clue please leave a comment below. ##### Mixing Values -You can combine these directives in different ways to achieve different caching behaviors, however `no-cache/no-store` and `public/private` are mutually exclusive. + +You can combine these directives in different ways to achieve different caching behaviors, however `no-cache/no-store` and `public/private` are mutually exclusive. If you specify both `no-store` and `no-cache`, `no-store` will be given precedence over `no-cache`. ```html -; If specified both -Cache-Control: no-store, no-cache - -; Below will be considered +; If specified both Cache-Control: no-store, no-cache ; Below will be considered Cache-Control: no-store ``` For `private/public`, for any unauthenticated requests cache is considered `public` and for any authenticated ones cache is considered `private`. -### Validators +### Validators Up until now we only discussed how the content is cached and how long the cached content is to be considered fresh but we did not discuss how the client does the validation from the server. Below we discuss the headers used for this purpose. #### ETag -Etag or "entity tag" was introduced in HTTP/1.1 specs. Etag is just a unique identifier that the server attaches with some resource. This ETag is later on used by the client to make conditional HTTP requests stating `"give me this resource if ETag is not same as the ETag that I have"` and the content is downloaded only if the etags do not match. +Etag or "entity tag" was introduced in HTTP/1.1 specs. Etag is just a unique identifier that the server attaches with some resource. This ETag is later on used by the client to make conditional HTTP requests stating `"give me this resource if ETag is not same as the ETag that I have"` and the content is downloaded only if the etags do not match. Method by which ETag is generated is not specified in the HTTP docs and usually some collision-resistant hash function is used to assign etags to each version of a resource. There could be two types of etags i.e. strong and weak ```html -ETag: "j82j8232ha7sdh0q2882" - Strong Etag -ETag: W/"j82j8232ha7sdh0q2882" - Weak Etag (prefixed with `W/`) +ETag: "j82j8232ha7sdh0q2882" - Strong Etag ETag: W/"j82j8232ha7sdh0q2882" - Weak +Etag (prefixed with `W/`) ``` A strong validating ETag means that two resources are **exactly** same and there is no difference between them at all. While a weak ETag means that two resources although not strictly the same but could be considered the same. Weak etags might be useful for dynamic content, for example. @@ -223,7 +229,7 @@ Server will then compare this ETag with the ETag of the current version of resou #### Last-Modified Server might include the `Last-Modified` header indicating the date and time at which some content was last modified on. - + ```html Last-Modified: Wed, 15 Mar 2017 12:30:26 GMT ``` @@ -234,21 +240,21 @@ When the content gets stale, client will make a conditional request including th If-Modified-Since: Wed, 15 Mar 2017 12:30:26 GMT ``` -You might be questioning now, what if the cached content has both the `Last-Modified` and `ETag` assigned to it? Well, in that case both are to be used i.e. there will not be any re-downloading of the resource if and only if `ETag` matches the newly retrieved one and so does the `Last-Modified` date. If either the `ETag` does not match or the `Last-Modified` is greater than the one from the server, content has to be downloaded again. +You might be questioning now, what if the cached content has both the `Last-Modified` and `ETag` assigned to it? Well, in that case both are to be used i.e. there will not be any re-downloading of the resource if and only if `ETag` matches the newly retrieved one and so does the `Last-Modified` date. If either the `ETag` does not match or the `Last-Modified` is greater than the one from the server, content has to be downloaded again. ### Where do I start? -Now that we have got *everything* covered, let us put everything in perspective and see how you can use this information. +Now that we have got _everything_ covered, let us put everything in perspective and see how you can use this information. #### Utilizing Server -Before we get into the possible caching strategies , let me add the fact that most of the servers including Apache and Nginx allow you to implement your caching policy through the server so that you don't have to juggle with headers in your code. +Before we get into the possible caching strategies , let me add the fact that most of the servers including Apache and Nginx allow you to implement your caching policy through the server so that you don't have to juggle with headers in your code. **For example**, if you are using Apache and you have your static content placed at `/static`, you can put below `.htaccess` file in the directory to make all the content in it be cached for an year using below ```html -# Cache everything for an year -Header set Cache-Control "max-age=31536000, public" +# Cache everything for an year Header set Cache-Control "max-age=31536000, +public" ``` You can further use `filesMatch` directive to add conditionals and use different caching strategy for different kinds of files e.g. @@ -265,18 +271,18 @@ You can further use `filesMatch` directive to add conditionals and use different ``` -Or if you don't want to use the `.htaccess` file you can modify Apache's configuration file `http.conf`. Same goes for Nginx, you can add the caching information in the location or server block. +Or if you don't want to use the `.htaccess` file you can modify Apache's configuration file `http.conf`. Same goes for Nginx, you can add the caching information in the location or server block. #### Caching Recommendations There is no golden rule or set standards about how your caching policy should look like, each of the application is different and you have to look and find what suits your application the best. However, just to give you a rough idea - - You can have aggressive caching (e.g. cache for an year) on any static content and use fingerprinted filenames (e.g. `style.ju2i90.css`) so that the cache is automatically rejected whenever the files are updated. - Also it should be noted that you should not cross the upper limit of one year as it [might not be honored](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) - - Look and decide do you even need caching for any dynamic content, if yes how long it should be. For example, in case of some RSS feed of a blog there could be the caching of a few hours but there couldn't be any caching for inventory items in an ERP. - - Always add the validators (preferably ETags) in your response. - - Pay attention while choosing the visibility (private or public) of the cached content. Make sure that you do not accidentally cache any user-specific or sensitive content in any public proxies. When in doubt, do not use cache at all. - - Separate the content that changes often from the content that doesn't change that often (e.g. in javascript bundles) so that when it is updated it doesn't need to make the whole cached content stale. - - Test and monitor the caching headers being served by your site. You can use the browser console or `curl -I http://some-url.com` for that purpose. +- You can have aggressive caching (e.g. cache for an year) on any static content and use fingerprinted filenames (e.g. `style.ju2i90.css`) so that the cache is automatically rejected whenever the files are updated. + Also it should be noted that you should not cross the upper limit of one year as it [might not be honored](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) +- Look and decide do you even need caching for any dynamic content, if yes how long it should be. For example, in case of some RSS feed of a blog there could be the caching of a few hours but there couldn't be any caching for inventory items in an ERP. +- Always add the validators (preferably ETags) in your response. +- Pay attention while choosing the visibility (private or public) of the cached content. Make sure that you do not accidentally cache any user-specific or sensitive content in any public proxies. When in doubt, do not use cache at all. +- Separate the content that changes often from the content that doesn't change that often (e.g. in javascript bundles) so that when it is updated it doesn't need to make the whole cached content stale. +- Test and monitor the caching headers being served by your site. You can use the browser console or `curl -I http://some-url.com` for that purpose. And that about wraps it up. Stay tuned for more! diff --git a/src/data/guides/journey-to-http2.md b/src/data/guides/journey-to-http2.md index cd95cb9b0..e0d1a286f 100644 --- a/src/data/guides/journey-to-http2.md +++ b/src/data/guides/journey-to-http2.md @@ -1,23 +1,23 @@ --- -title: "Journey to HTTP/2" -description: "The evolution of HTTP. How it all started and where we stand today" +title: 'Journey to HTTP/2' +description: 'The evolution of HTTP. How it all started and where we stand today' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "Journey to HTTP/2 - roadmap.sh" - description: "The evolution of HTTP. How it all started and where we stand today" + title: 'Journey to HTTP/2 - roadmap.sh' + description: 'The evolution of HTTP. How it all started and where we stand today' isNew: false -type: "textual" +type: 'textual' date: 2018-12-04 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "textual-guide" - - "guide-sitemap" + - 'guide' + - 'textual-guide' + - 'guide-sitemap' --- HTTP is the protocol that every web developer should know as it powers the whole web and knowing it is definitely going to help you develop better applications. In this guide, I am going to be discussing what HTTP is, how it came to be, where it is today and how did we get here. @@ -26,41 +26,39 @@ HTTP is the protocol that every web developer should know as it powers the whole First things first, what is HTTP? HTTP is the `TCP/IP` based application layer communication protocol which standardizes how the client and server communicate with each other. It defines how the content is requested and transmitted across the internet. By application layer protocol, I mean it's just an abstraction layer that standardizes how the hosts (clients and servers) communicate and itself it depends upon `TCP/IP` to get request and response between the client and server. By default TCP port `80` is used but other ports can be used as well. HTTPS, however, uses port `443`. -### HTTP/0.9 – The One Liner (1991) +### HTTP/0.9 – The One Liner (1991) The first documented version of HTTP was [`HTTP/0.9`](https://www.w3.org/Protocols/HTTP/AsImplemented.html) which was put forward in 1991. It was the simplest protocol ever; having a single method called `GET`. If a client had to access some webpage on the server, it would have made the simple request like below ```html GET /index.html ``` + And the response from server would have looked as follows ```html -(response body) -(connection closed) +(response body) (connection closed) ``` -That is, the server would get the request, reply with the HTML in response and as soon as the content has been transferred, the connection will be closed. There were +That is, the server would get the request, reply with the HTML in response and as soon as the content has been transferred, the connection will be closed. There were - No headers -- `GET` was the only allowed method +- `GET` was the only allowed method - Response had to be HTML As you can see, the protocol really had nothing more than being a stepping stone for what was to come. ### HTTP/1.0 - 1996 -In 1996, the next version of HTTP i.e. `HTTP/1.0` evolved that vastly improved over the original version. +In 1996, the next version of HTTP i.e. `HTTP/1.0` evolved that vastly improved over the original version. Unlike `HTTP/0.9` which was only designed for HTML response, `HTTP/1.0` could now deal with other response formats i.e. images, video files, plain text or any other content type as well. It added more methods (i.e. `POST` and `HEAD`), request/response formats got changed, HTTP headers got added to both the request and responses, status codes were added to identify the response, character set support was introduced, multi-part types, authorization, caching, content encoding and more was included. Here is how a sample `HTTP/1.0` request and response might have looked like: ```html -GET / HTTP/1.0 -Host: kamranahmed.info -User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) -Accept: */* +GET / HTTP/1.0 Host: kamranahmed.info User-Agent: Mozilla/5.0 (Macintosh; Intel +Mac OS X 10_10_5) Accept: */* ``` As you can see, alongside the request, client has also sent its personal information, required response type etc. While in `HTTP/0.9` client could never send such information because there were no headers. @@ -68,26 +66,20 @@ As you can see, alongside the request, client has also sent its personal informa Example response to the request above may have looked like below ```html -HTTP/1.0 200 OK -Content-Type: text/plain -Content-Length: 137582 -Expires: Thu, 05 Dec 1997 16:00:00 GMT -Last-Modified: Wed, 5 August 1996 15:55:28 GMT -Server: Apache 0.84 - -(response body) -(connection closed) +HTTP/1.0 200 OK Content-Type: text/plain Content-Length: 137582 Expires: Thu, 05 +Dec 1997 16:00:00 GMT Last-Modified: Wed, 5 August 1996 15:55:28 GMT Server: +Apache 0.84 (response body) (connection closed) ``` -In the very beginning of the response there is `HTTP/1.0` (HTTP followed by the version number), then there is the status code `200` followed by the reason phrase (or description of the status code, if you will). +In the very beginning of the response there is `HTTP/1.0` (HTTP followed by the version number), then there is the status code `200` followed by the reason phrase (or description of the status code, if you will). In this newer version, request and response headers were still kept as `ASCII` encoded, but the response body could have been of any type i.e. image, video, HTML, plain text or any other content type. So, now that server could send any content type to the client; not so long after the introduction, the term "Hyper Text" in `HTTP` became misnomer. `HMTP` or Hypermedia transfer protocol might have made more sense but, I guess, we are stuck with the name for life. One of the major drawbacks of `HTTP/1.0` were you couldn't have multiple requests per connection. That is, whenever a client will need something from the server, it will have to open a new TCP connection and after that single request has been fulfilled, connection will be closed. And for any next requirement, it will have to be on a new connection. Why is it bad? Well, let's assume that you visit a webpage having `10` images, `5` stylesheets and `5` javascript files, totalling to `20` items that needs to fetched when request to that webpage is made. Since the server closes the connection as soon as the request has been fulfilled, there will be a series of `20` separate connections where each of the items will be served one by one on their separate connections. This large number of connections results in a serious performance hit as requiring a new `TCP` connection imposes a significant performance penalty because of three-way handshake followed by slow-start. -#### Three-way Handshake +#### Three-way Handshake -Three-way handshake in its simplest form is that all the `TCP` connections begin with a three-way handshake in which the client and the server share a series of packets before starting to share the application data. +Three-way handshake in its simplest form is that all the `TCP` connections begin with a three-way handshake in which the client and the server share a series of packets before starting to share the application data. - `SYN` - Client picks up a random number, let's say `x`, and sends it to the server. - `SYN ACK` - Server acknowledges the request by sending an `ACK` packet back to the client which is made up of a random number, let's say `y` picked up by server and the number `x+1` where `x` is the number that was sent by the client @@ -97,7 +89,7 @@ Once the three-way handshake is completed, the data sharing between the client a ![Three-way Handshake](https://i.imgur.com/uERG2G2.png) -> Please note that there is a minor issue with the image, the last `ACK` packet sent by the client to end the handshake contains only `y+1` i.e. it should have been `ACK:y+1` instead of `ACK: x+1, y+1` +> Please note that there is a minor issue with the image, the last `ACK` packet sent by the client to end the handshake contains only `y+1` i.e. it should have been `ACK:y+1` instead of `ACK: x+1, y+1` However, some implementations of `HTTP/1.0` tried to overcome this issue by introducing a new header called `Connection: keep-alive` which was meant to tell the server "Hey server, do not close this connection, I need it again". But still, it wasn't that widely supported and the problem still persisted. @@ -115,7 +107,7 @@ After merely 3 years of `HTTP/1.0`, the next version i.e. `HTTP/1.1` was release - **Pipelining** It also introduced the support for pipelining, where the client could send multiple requests to the server without waiting for the response from server on the same connection and server had to send the response in the same sequence in which requests were received. But how does the client know that this is the point where first response download completes and the content for next response starts, you may ask! Well, to solve this, there must be `Content-Length` header present which clients can use to identify where the response ends and it can start waiting for the next response. - > It should be noted that in order to benefit from persistent connections or pipelining, `Content-Length` header must be available on the response, because this would let the client know when the transmission completes and it can send the next request (in normal sequential way of sending requests) or start waiting for the next response (when pipelining is enabled). + > It should be noted that in order to benefit from persistent connections or pipelining, `Content-Length` header must be available on the response, because this would let the client know when the transmission completes and it can send the next request (in normal sequential way of sending requests) or start waiting for the next response (when pipelining is enabled). > But there was still an issue with this approach. And that is, what if the data is dynamic and server cannot find the content length before hand? Well in that case, you really can't benefit from persistent connections, could you?! In order to solve this `HTTP/1.1` introduced chunked encoding. In such cases server may omit content-Length in favor of chunked encoding (more to it in a moment). However, if none of them are available, then the connection must be closed at the end of request. @@ -129,7 +121,7 @@ After merely 3 years of `HTTP/1.0`, the next version i.e. `HTTP/1.1` was release - Client cookies - Enhanced compression support - New status codes -- ..and more +- ..and more I am not going to dwell about all the `HTTP/1.1` features in this post as it is a topic in itself and you can already find a lot about it. The one such document that I would recommend you to read is [Key differences between `HTTP/1.0` and HTTP/1.1](https://www.ra.ethz.ch/cdstore/www8/data/2136/pdf/pd1.pdf) and here is the link to [original RFC](https://tools.ietf.org/html/rfc2616) for the overachievers. @@ -137,7 +129,7 @@ I am not going to dwell about all the `HTTP/1.1` features in this post as it is ### SPDY - 2009 -Google went ahead and started experimenting with alternative protocols to make the web faster and improving web security while reducing the latency of web pages. In 2009, they announced `SPDY`. +Google went ahead and started experimenting with alternative protocols to make the web faster and improving web security while reducing the latency of web pages. In 2009, they announced `SPDY`. > `SPDY` is a trademark of Google and isn't an acronym. @@ -147,13 +139,13 @@ It was seen that if we keep increasing the bandwidth, the network performance in The features of `SPDY` included, multiplexing, compression, prioritization, security etc. I am not going to get into the details of SPDY, as you will get the idea when we get into the nitty gritty of `HTTP/2` in the next section as I said `HTTP/2` is mostly inspired from SPDY. -`SPDY` didn't really try to replace HTTP; it was a translation layer over HTTP which existed at the application layer and modified the request before sending it over to the wire. It started to become a defacto standards and majority of browsers started implementing it. +`SPDY` didn't really try to replace HTTP; it was a translation layer over HTTP which existed at the application layer and modified the request before sending it over to the wire. It started to become a defacto standards and majority of browsers started implementing it. -In 2015, at Google, they didn't want to have two competing standards and so they decided to merge it into HTTP while giving birth to `HTTP/2` and deprecating SPDY. +In 2015, at Google, they didn't want to have two competing standards and so they decided to merge it into HTTP while giving birth to `HTTP/2` and deprecating SPDY. ### HTTP/2 - 2015 -By now, you must be convinced that why we needed another revision of the HTTP protocol. `HTTP/2` was designed for low latency transport of content. The key features or differences from the old version of `HTTP/1.1` include +By now, you must be convinced that why we needed another revision of the HTTP protocol. `HTTP/2` was designed for low latency transport of content. The key features or differences from the old version of `HTTP/1.1` include - Binary instead of Textual - Multiplexing - Multiple asynchronous HTTP requests over a single connection @@ -164,25 +156,22 @@ By now, you must be convinced that why we needed another revision of the HTTP pr ![HTTP Model](https://i.imgur.com/S85j8gg.png) - #### 1. Binary Protocol `HTTP/2` tends to address the issue of increased latency that existed in HTTP/1.x by making it a binary protocol. Being a binary protocol, it easier to parse but unlike `HTTP/1.x` it is no longer readable by the human eye. The major building blocks of `HTTP/2` are Frames and Streams ##### Frames and Streams -HTTP messages are now composed of one or more frames. There is a `HEADERS` frame for the meta data and `DATA` frame for the payload and there exist several other types of frames (`HEADERS`, `DATA`, `RST_STREAM`, `SETTINGS`, `PRIORITY` etc) that you can check through [the `HTTP/2` specs](https:/http2.github.iohttp2-spec/#FrameTypes). +HTTP messages are now composed of one or more frames. There is a `HEADERS` frame for the meta data and `DATA` frame for the payload and there exist several other types of frames (`HEADERS`, `DATA`, `RST_STREAM`, `SETTINGS`, `PRIORITY` etc) that you can check through [the `HTTP/2` specs](https:/http2.github.iohttp2-spec/#FrameTypes). Every `HTTP/2` request and response is given a unique stream ID and it is divided into frames. Frames are nothing but binary pieces of data. A collection of frames is called a Stream. Each frame has a stream id that identifies the stream to which it belongs and each frame has a common header. Also, apart from stream ID being unique, it is worth mentioning that, any request initiated by client uses odd numbers and the response from server has even numbers stream IDs. Apart from the `HEADERS` and `DATA`, another frame type that I think worth mentioning here is `RST_STREAM` which is a special frame type that is used to abort some stream i.e. client may send this frame to let the server know that I don't need this stream anymore. In `HTTP/1.1` the only way to make the server stop sending the response to client was closing the connection which resulted in increased latency because a new connection had to be opened for any consecutive requests. While in HTTP/2, client can use `RST_STREAM` and stop receiving a specific stream while the connection will still be open and the other streams will still be in play. - #### 2. Multiplexing Since `HTTP/2` is now a binary protocol and as I said above that it uses frames and streams for requests and responses, once a TCP connection is opened, all the streams are sent asynchronously through the same connection without opening any additional connections. And in turn, the server responds in the same asynchronous way i.e. the response has no order and the client uses the assigned stream id to identify the stream to which a specific packet belongs. This also solves the **head-of-line blocking** issue that existed in HTTP/1.x i.e. the client will not have to wait for the request that is taking time and other requests will still be getting processed. - #### 3. HPACK Header Compression It was part of a separate RFC which was specifically aimed at optimizing the sent headers. The essence of it is that when we are constantly accessing the server from a same client there is alot of redundant data that we are sending in the headers over and over, and sometimes there might be cookies increasing the headers size which results in bandwidth usage and increased latency. To overcome this, `HTTP/2` introduced header compression. @@ -193,7 +182,6 @@ Unlike request and response, headers are not compressed in `gzip` or `compress` While we are talking headers, let me add here that the headers are still the same as in HTTP/1.1, except for the addition of some pseudo headers i.e. `:method`, `:scheme`, `:host` and `:path` - #### 4. Server Push Server push is another tremendous feature of `HTTP/2` where the server, knowing that the client is going to ask for a certain resource, can push it to the client without even client asking for it. For example, let's say a browser loads a web page, it parses the whole page to find out the remote content that it has to load from the server and then sends consequent requests to the server to get that content. @@ -210,8 +198,8 @@ Without any priority information, server processes the requests asynchronously i There was extensive discussion on whether security (through `TLS`) should be made mandatory for `HTTP/2` or not. In the end, it was decided not to make it mandatory. However, most vendors stated that they will only support `HTTP/2` when it is used over `TLS`. So, although `HTTP/2` doesn't require encryption by specs but it has kind of become mandatory by default anyway. With that out of the way, `HTTP/2` when implemented over `TLS` does impose some requirements i.e. `TLS` version `1.2` or higher must be used, there must be a certain level of minimum key sizes, ephemeral keys are required etc. -`HTTP/2` is here and it has already [surpassed SPDY in adaption](https://caniuse.com/#search=http2) which is gradually increasing. `HTTP/2` has alot to offer in terms of performance gain and it is about time we should start using it. +`HTTP/2` is here and it has already [surpassed SPDY in adaption](https://caniuse.com/#search=http2) which is gradually increasing. `HTTP/2` has alot to offer in terms of performance gain and it is about time we should start using it. -For anyone interested in further details here is the [link to specs](https:/http2.github.iohttp2-spec) and a link [demonstrating the performance benefits of `HTTP/2`](https://www.http2demo.io/). +For anyone interested in further details here is the [link to specs](https:/http2.github.iohttp2-spec) and a link [demonstrating the performance benefits of `HTTP/2`](https://www.http2demo.io/). And that about wraps it up. Until next time! stay tuned. diff --git a/src/data/guides/jwt-authentication.md b/src/data/guides/jwt-authentication.md index 871cca708..5a1faa514 100644 --- a/src/data/guides/jwt-authentication.md +++ b/src/data/guides/jwt-authentication.md @@ -1,24 +1,23 @@ --- -title: "JWT Authentication" -description: "Understand what is JWT authentication and how is it implemented" +title: 'JWT Authentication' +description: 'Understand what is JWT authentication and how is it implemented' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "JWT Authentication - roadmap.sh" - description: "Understand what is JWT authentication and how is it implemented" + title: 'JWT Authentication - roadmap.sh' + description: 'Understand what is JWT authentication and how is it implemented' isNew: false -type: "visual" +type: 'visual' date: 2021-06-20 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "visual-guide" - - "guide-sitemap" + - 'guide' + - 'visual-guide' + - 'guide-sitemap' --- [![JWT Authentication](/guides/jwt-authentication.png)](/guides/jwt-authentication.png) - diff --git a/src/data/guides/levels-of-seniority.md b/src/data/guides/levels-of-seniority.md index 8d29a0084..d5d9ffb61 100644 --- a/src/data/guides/levels-of-seniority.md +++ b/src/data/guides/levels-of-seniority.md @@ -1,23 +1,23 @@ --- -title: "Levels of Seniority" -description: "How to Step Up as a Junior, Mid Level or a Senior Developer?" +title: 'Levels of Seniority' +description: 'How to Step Up as a Junior, Mid Level or a Senior Developer?' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "Levels of Seniority - roadmap.sh" - description: "How to Step Up as a Junior, Mid Level or a Senior Developer?" + title: 'Levels of Seniority - roadmap.sh' + description: 'How to Step Up as a Junior, Mid Level or a Senior Developer?' isNew: false -type: "textual" +type: 'textual' date: 2020-12-03 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "textual-guide" - - "guide-sitemap" + - 'guide' + - 'textual-guide' + - 'guide-sitemap' --- I have been working on redoing the [roadmaps](https://roadmap.sh) – splitting the skillset based on the seniority levels to make them easier to follow and not scare the new developers away. Since the roadmaps are going to be just about the technical knowledge, I thought it would be a good idea to reiterate and have an article on what I think of different seniority roles. @@ -25,47 +25,50 @@ I have been working on redoing the [roadmaps](https://roadmap.sh) – splitting I have seen many organizations decide the seniority of developers by giving more significance to the years of experience than they should. I have seen developers labeled "Junior" doing the work of Senior Developers and I have seen "Lead" developers who weren't even qualified to be called "Senior". The seniority of a developer cannot just be decided by their age, years of experience or technical knowledge that they have got. There are other factors in play here -- their perception of work, how they interact with their peers and how they approach problems. We discuss these three key factors in detail for each of the seniority levels below. ### Different Seniority Titles + Different organizations might have different seniority titles but they mainly fall into three categories: -* Junior Developer -* Mid Level Developer -* Senior Developer +- Junior Developer +- Mid Level Developer +- Senior Developer ### Junior Developer + Junior developers are normally fresh graduates and it's either they don't have or they have minimal industry experience. Not only they have weak coding skills but there are also a few other things that give Junior developers away: -* Their main mantra is "making it work" without giving much attention to how the solution is achieved. To them, a working software and good software are equivalent. -* They usually require very specific and structured directions to achieve something. They suffer from tunnel vision, need supervision and continuous guidance to be effective team members. -* Most of the Junior developers just try to live up to the role and, when stuck, they might leave work for a senior developer instead of at least trying to take a stab at something. -* They don't know about the business side of the company and don't realize how management/sales/marketing/etc think and they don't realize how much rework, wasted effort, and end-user aggravation could be saved by getting to know the business domain. -* Over-engineering is a major problem, often leading to fragility and bugs. -* When given a problem, they often try to fix just the current problem a.k.a. fixing the symptoms instead of fixing the root problem. -* You might notice the "[Somebody Else's Problem](https://en.wikipedia.org/wiki/Somebody_else%27s_problem)" behavior from them. -* They don't know what or how much they don't know, thanks to the [Dunning–Kruger effect](https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect). -* They don't take initiatives and they might be afraid to work on an unfamiliar codebase. -* They don't participate in team discussions. +- Their main mantra is "making it work" without giving much attention to how the solution is achieved. To them, a working software and good software are equivalent. +- They usually require very specific and structured directions to achieve something. They suffer from tunnel vision, need supervision and continuous guidance to be effective team members. +- Most of the Junior developers just try to live up to the role and, when stuck, they might leave work for a senior developer instead of at least trying to take a stab at something. +- They don't know about the business side of the company and don't realize how management/sales/marketing/etc think and they don't realize how much rework, wasted effort, and end-user aggravation could be saved by getting to know the business domain. +- Over-engineering is a major problem, often leading to fragility and bugs. +- When given a problem, they often try to fix just the current problem a.k.a. fixing the symptoms instead of fixing the root problem. +- You might notice the "[Somebody Else's Problem](https://en.wikipedia.org/wiki/Somebody_else%27s_problem)" behavior from them. +- They don't know what or how much they don't know, thanks to the [Dunning–Kruger effect](https://en.wikipedia.org/wiki/Dunning%E2%80%93Kruger_effect). +- They don't take initiatives and they might be afraid to work on an unfamiliar codebase. +- They don't participate in team discussions. Being a Junior developer in the team is not necessarily a bad thing; since you are just starting out, you are not expected to be a know-it-all person. However, it is your responsibility to learn, gain experience, not get stuck with the "Junior" title and improve yourself. Here are a few tips for Junior developers to help move up the ladder of seniority: -* All sorts of problems can be solved if you work on them long enough. Do not give up if Stack Overflow or an issue on GitHub doesn't have an answer. Saying "I am stuck, but I have tried X, Y, and Z. Do you have any pointers?" to your lead is much better than saying "This is beyond me." -* Read a lot of code, not just code in the projects that you are working on, but reference/framework source code, open-source. Ask your fellow developers, perhaps on Reddit too, about the good open-source examples for the language/tools of your choice. -* Do personal side-projects, share them with people, contribute to the open-source community. Reach out to people for help. You will be surprised how much support you can get from the community. I still remember my first open-source project on GitHub from around 6 years ago which was a small PHP script (a library) that fetched details for a given address from Google's Geocoding API. The codebase was super messy, it did not have any tests, did not have any linters or sniffers, and it did not have any CI because I didn't know about any of this at that time. I am not sure how but one kind soul somehow found the project, forked it, refactored it, "modernized" it, added linting, code sniffing, added CI and opened the pull request. This one pull request taught me so many things that I might have never learned that fast on my own because I was still in college, working for a small service-based company and doing just small websites all on my own without knowing what is right and what is not. This one PR on GitHub was my introduction to open-source and I owe everything to that. -* Avoid what is known as ["Somebody Else's Problem Field"](https://en.wikipedia.org/wiki/Somebody_else%27s_problem) behavior. -* When given a problem to solve, try to identify the root cause and fix that instead of fixing the symptoms. And remember, not being able to reproduce means not solved. It is solved when you understand why it occurred and why it no longer does. -* Have respect for the code that was written before you. Be generous when passing judgment on the architecture or the design decisions made in the codebase. Understand that code is often ugly and weird for a reason other than incompetence. Learning to live with and thrive with legacy code is a great skill. Never assume anybody is stupid. Instead, figure out how these intelligent, well-intentioned and experienced people have come to a decision that is stupid now. Approach inheriting legacy code with an "opportunity mindset" rather than a complaining one. -* It's okay to not know things. You don't need to be ashamed of not knowing things already. There are no stupid questions, ask however many questions that would allow you to work effectively. -* Don't let yourself be limited by the job title that you have. Keep working on your self-improvement. -* Do your homework. Predict what’s coming down the pipe. Be involved in the team discussions. Even if you are wrong, you will learn something. -* Learn about the domain that you are working with. Understand the product end-to-end as an end-user. Do not assume things, ask questions and get things cleared when in doubt. -* Learn to communicate effectively - soft skills matter. Learn how to write good emails, how to present your work, how to phrase your questions in a thoughtful manner. -* Sit with the senior developers, watch them work, find a mentor. No one likes a know-it-all. Get hold of your ego and be humble enough to take lessons from experienced people. -* Don't just blindly follow the advice of "experts", take it with a grain of salt. -* If you are asked to provide an estimate for some work, do not give an answer unless you have all the details to make a reasonable estimate. If you are forced to do that, pad it 2x or more depending on how much you don't know about what needs to be done for the task to be marked 'done'. -* Take some time to learn how to use a debugger. Debuggers are quite beneficial when navigating new, undocumented or poorly documented codebase, or to debug weird issues. -* Avoid saying "it works on my machine" -- yes, I have heard that a lot. -* Try to turn any feelings of inadequacy or imposter syndrome into energy to push yourself forward and increase your skills and knowledge. +- All sorts of problems can be solved if you work on them long enough. Do not give up if Stack Overflow or an issue on GitHub doesn't have an answer. Saying "I am stuck, but I have tried X, Y, and Z. Do you have any pointers?" to your lead is much better than saying "This is beyond me." +- Read a lot of code, not just code in the projects that you are working on, but reference/framework source code, open-source. Ask your fellow developers, perhaps on Reddit too, about the good open-source examples for the language/tools of your choice. +- Do personal side-projects, share them with people, contribute to the open-source community. Reach out to people for help. You will be surprised how much support you can get from the community. I still remember my first open-source project on GitHub from around 6 years ago which was a small PHP script (a library) that fetched details for a given address from Google's Geocoding API. The codebase was super messy, it did not have any tests, did not have any linters or sniffers, and it did not have any CI because I didn't know about any of this at that time. I am not sure how but one kind soul somehow found the project, forked it, refactored it, "modernized" it, added linting, code sniffing, added CI and opened the pull request. This one pull request taught me so many things that I might have never learned that fast on my own because I was still in college, working for a small service-based company and doing just small websites all on my own without knowing what is right and what is not. This one PR on GitHub was my introduction to open-source and I owe everything to that. +- Avoid what is known as ["Somebody Else's Problem Field"](https://en.wikipedia.org/wiki/Somebody_else%27s_problem) behavior. +- When given a problem to solve, try to identify the root cause and fix that instead of fixing the symptoms. And remember, not being able to reproduce means not solved. It is solved when you understand why it occurred and why it no longer does. +- Have respect for the code that was written before you. Be generous when passing judgment on the architecture or the design decisions made in the codebase. Understand that code is often ugly and weird for a reason other than incompetence. Learning to live with and thrive with legacy code is a great skill. Never assume anybody is stupid. Instead, figure out how these intelligent, well-intentioned and experienced people have come to a decision that is stupid now. Approach inheriting legacy code with an "opportunity mindset" rather than a complaining one. +- It's okay to not know things. You don't need to be ashamed of not knowing things already. There are no stupid questions, ask however many questions that would allow you to work effectively. +- Don't let yourself be limited by the job title that you have. Keep working on your self-improvement. +- Do your homework. Predict what’s coming down the pipe. Be involved in the team discussions. Even if you are wrong, you will learn something. +- Learn about the domain that you are working with. Understand the product end-to-end as an end-user. Do not assume things, ask questions and get things cleared when in doubt. +- Learn to communicate effectively - soft skills matter. Learn how to write good emails, how to present your work, how to phrase your questions in a thoughtful manner. +- Sit with the senior developers, watch them work, find a mentor. No one likes a know-it-all. Get hold of your ego and be humble enough to take lessons from experienced people. +- Don't just blindly follow the advice of "experts", take it with a grain of salt. +- If you are asked to provide an estimate for some work, do not give an answer unless you have all the details to make a reasonable estimate. If you are forced to do that, pad it 2x or more depending on how much you don't know about what needs to be done for the task to be marked 'done'. +- Take some time to learn how to use a debugger. Debuggers are quite beneficial when navigating new, undocumented or poorly documented codebase, or to debug weird issues. +- Avoid saying "it works on my machine" -- yes, I have heard that a lot. +- Try to turn any feelings of inadequacy or imposter syndrome into energy to push yourself forward and increase your skills and knowledge. ### Mid Level Developers + The next level after the Junior developers is Mid Level developers. They are technically stronger than the Junior developers and can work with minimal supervision. They still have some issues to address in order to jump to Senior level. Intermediate developers are more competent than the Junior developer. They start to see the flaws in their old codebase. They gain the knowledge but they get trapped into the next chain i.e. messing things up while trying to do them "the right way" e.g. hasty abstractions, overuse or unnecessary usage of Design Patterns -- they may be able to provide solution faster than the Junior developers but the solution might put you into another rabbit-hole in the long run. Without supervision, they might delay the execution while trying to "do things properly". They don't know when to make tradeoffs and they still don't know when to be dogmatic and when to be pragmatic. They can easily become attached to their solution, become myopic, and be unable to take feedback. @@ -73,21 +76,23 @@ Intermediate developers are more competent than the Junior developer. They start Mid-level developers are quite common. Most of the organizations wrongly label them as "Senior Developers". However, they need further mentoring in order to become Senior Developers. The next section describes the responsibilities of a senior developer and how you can become one. ### Senior Developers + Senior developers are the next level after the Mid-level developers. They are the people who can get things done on their own without any supervision and without creating any issues down the road. They are more mature, have gained experience by delivering both good and bad software in the past and have learned from it — they know how to be pragmatic. Here is the list of things that are normally expected of a Senior Developer: -* With their past experiences, mistakes made, issues faced by over-designed or under-designed software, they can foresee the problems and persuade the direction of the codebase or the architecture. -* They don't have a "Shiny-Toy" syndrome. They are pragmatic in the execution. They can make the tradeoffs when required, and they know why. They know where to be dogmatic and where to be pragmatic. -* They have a good picture of the field, know what the best tool for the job is in most cases (even if they don't know the tool). They have the innate ability to pick up a new tool/language/paradigm/etc in order to solve a problem that requires it. -* They are aware they're on a team. They view it as a part of their responsibility to mentor others. This can range from pair programming with junior devs to taking un-glorious tasks of writing docs or tests or whatever else needs to be done. -* They have a deep understanding of the domain - they know about the business side of the company and realize how management/sales/marketing/etc think and benefit from their knowledge of the business domain during the development. -* They don't make empty complaints, they make judgments based on the empirical evidence and they have suggestions for solutions. -* They think much more than just code - they know that their job is to provide solutions to the problems and not just to write code. -* They have the ability to take on large ill-defined problems, define them, break them up, and execute the pieces. A senior developer can take something big and abstract, and run with it. They will come up with a few options, discuss them with the team and implement them. -* They have respect for the code that was written before them. They are generous when passing judgment on the architecture or the design decisions made in the codebase. They approach inheriting legacy code with an "opportunity mindset" rather than a complaining one. -* They know how to give feedback without hurting anyone. +- With their past experiences, mistakes made, issues faced by over-designed or under-designed software, they can foresee the problems and persuade the direction of the codebase or the architecture. +- They don't have a "Shiny-Toy" syndrome. They are pragmatic in the execution. They can make the tradeoffs when required, and they know why. They know where to be dogmatic and where to be pragmatic. +- They have a good picture of the field, know what the best tool for the job is in most cases (even if they don't know the tool). They have the innate ability to pick up a new tool/language/paradigm/etc in order to solve a problem that requires it. +- They are aware they're on a team. They view it as a part of their responsibility to mentor others. This can range from pair programming with junior devs to taking un-glorious tasks of writing docs or tests or whatever else needs to be done. +- They have a deep understanding of the domain - they know about the business side of the company and realize how management/sales/marketing/etc think and benefit from their knowledge of the business domain during the development. +- They don't make empty complaints, they make judgments based on the empirical evidence and they have suggestions for solutions. +- They think much more than just code - they know that their job is to provide solutions to the problems and not just to write code. +- They have the ability to take on large ill-defined problems, define them, break them up, and execute the pieces. A senior developer can take something big and abstract, and run with it. They will come up with a few options, discuss them with the team and implement them. +- They have respect for the code that was written before them. They are generous when passing judgment on the architecture or the design decisions made in the codebase. They approach inheriting legacy code with an "opportunity mindset" rather than a complaining one. +- They know how to give feedback without hurting anyone. ### Conclusion -All teams are made up of a mix of all these seniority roles. Being content with your role is a bad thing and you should always strive to improve yourself for the next step. This article is based on my beliefs and observations in the industry. Lots of companies care more for the years of experience to decide the seniority which is a crappy metric -- you don't gain experience just by spending years. You gain it by continuously solving different sorts of problems, irrespective of the number of years you spend in the industry. I have seen fresh graduates having no industry experience get up to speed quickly and producing work of a Senior Engineer and I have seen Senior developers labeled "senior" merely because of their age and "years of experience". + +All teams are made up of a mix of all these seniority roles. Being content with your role is a bad thing and you should always strive to improve yourself for the next step. This article is based on my beliefs and observations in the industry. Lots of companies care more for the years of experience to decide the seniority which is a crappy metric -- you don't gain experience just by spending years. You gain it by continuously solving different sorts of problems, irrespective of the number of years you spend in the industry. I have seen fresh graduates having no industry experience get up to speed quickly and producing work of a Senior Engineer and I have seen Senior developers labeled "senior" merely because of their age and "years of experience". The most important traits that you need to have in order to step up in your career are: not settling with mediocrity, having an open mindset, being humble, learning from your mistakes, working on the challenging problems and having an opportunity mindset rather than a complaining one. diff --git a/src/data/guides/oauth.md b/src/data/guides/oauth.md index 42e1ea278..0fc5efcd2 100644 --- a/src/data/guides/oauth.md +++ b/src/data/guides/oauth.md @@ -1,24 +1,23 @@ --- -title: "OAuth — Open Authorization" -description: "Learn and understand what is OAuth and how it works" +title: 'OAuth — Open Authorization' +description: 'Learn and understand what is OAuth and how it works' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "OAuth — Open Authorization - roadmap.sh" - description: "Learn and understand what is OAuth and how it works" + title: 'OAuth — Open Authorization - roadmap.sh' + description: 'Learn and understand what is OAuth and how it works' isNew: false -type: "visual" +type: 'visual' date: 2021-06-28 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "visual-guide" - - "guide-sitemap" + - 'guide' + - 'visual-guide' + - 'guide-sitemap' --- [![OAuth - Open Authorization](/guides/oauth.png)](/guides/oauth.png) - diff --git a/src/data/guides/proxy-servers.md b/src/data/guides/proxy-servers.md index 7f45a25b4..de53315cf 100644 --- a/src/data/guides/proxy-servers.md +++ b/src/data/guides/proxy-servers.md @@ -1,69 +1,72 @@ --- -title: "Proxy Servers" -description: "How do proxy servers work and what are forward and reverse proxies?" +title: 'Proxy Servers' +description: 'How do proxy servers work and what are forward and reverse proxies?' author: - name: "Ebrahim Bharmal" - url: "https://twitter.com/BharmalEbrahim" - imageUrl: "/authors/ebrahimbharmal007.png" + name: 'Ebrahim Bharmal' + url: 'https://twitter.com/BharmalEbrahim' + imageUrl: '/authors/ebrahimbharmal007.png' seo: - title: "Proxy Servers - roadmap.sh" - description: "How do proxy servers work and what are forward and reverse proxies?" + title: 'Proxy Servers - roadmap.sh' + description: 'How do proxy servers work and what are forward and reverse proxies?' isNew: false -type: "textual" +type: 'textual' date: 2017-10-24 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "textual-guide" - - "guide-sitemap" + - 'guide' + - 'textual-guide' + - 'guide-sitemap' --- -The Internet has connected people across the world using social media and audio/video calling features along with providing an overabundance of knowledge and tools. All this comes with an inherent danger of security and privacy breaches. In this guide, we will talk about **proxies** that play a vital role in mitigating these risks. We will cover the following topics in this guide: +The Internet has connected people across the world using social media and audio/video calling features along with providing an overabundance of knowledge and tools. All this comes with an inherent danger of security and privacy breaches. In this guide, we will talk about **proxies** that play a vital role in mitigating these risks. We will cover the following topics in this guide: - [Proxy Server](#proxy-server) - [Forward Proxy Server](#forward-proxy-server) - [Reverse Proxy Server](#reverse-proxy-server) - [Summary](#summary) -## Proxy Server +## Proxy Server -***Every web request which is sent from the client to a web server goes through some type of proxy server.*** A proxy server acts as a gateway between client *(you)* and the internet and separates end-users from the websites you browse. It replaces the source IP address of the web request with the proxy server's IP address and then forwards it to the web server. The web server is unaware of the client, it only sees the proxy server. +**_Every web request which is sent from the client to a web server goes through some type of proxy server._** A proxy server acts as a gateway between client _(you)_ and the internet and separates end-users from the websites you browse. It replaces the source IP address of the web request with the proxy server's IP address and then forwards it to the web server. The web server is unaware of the client, it only sees the proxy server. -![Proxy Server Description](/guides/proxy/proxy-example.png) -> NOTE: This is not an accurate description but rather just an illustration. +![Proxy Server Description](/guides/proxy/proxy-example.png) + +> NOTE: This is not an accurate description but rather just an illustration. Proxy servers serve as a single point of control making it easier to enforce security policies. It also provides caching mechanism which stores the requested web pages on the proxy server to improve performance. If the requested web-page is available in cache memory then instead of forwarding the request to the web-server it will send the cached webpage back to the client. This **saves big companies thousands of dollars** by reducing the load on their servers as their website is visited by millions of users every day. - -## Forward Proxy Server -A forward proxy is generally implemented on the client side and **sits in front of multiple clients** or client sources. Forward proxy servers are mainly used by companies to **manage the internet usage** of their employees and **restrict content**. It is also used as a **firewall** to secure the company's network by blocking any request which would pose threat to the company's network. Proxy servers are also used to **bypass geo-restriction** and browse content that might be blocked in the user's country. It enables users to **browse anonymously**, as the proxy server masks their details from the website's servers. +## Forward Proxy Server + +A forward proxy is generally implemented on the client side and **sits in front of multiple clients** or client sources. Forward proxy servers are mainly used by companies to **manage the internet usage** of their employees and **restrict content**. It is also used as a **firewall** to secure the company's network by blocking any request which would pose threat to the company's network. Proxy servers are also used to **bypass geo-restriction** and browse content that might be blocked in the user's country. It enables users to **browse anonymously**, as the proxy server masks their details from the website's servers. + +![Forward Proxy Description](/guides/proxy/forward-proxy.png) -![Forward Proxy Description](/guides/proxy/forward-proxy.png) > NOTE: This is not an accurate description but rather just an illustration -## Reverse Proxy Server +## Reverse Proxy Server + +Reverse proxy servers are implemented on the **server side** instead of the client side. It **sits in front of multiple webservers** and manages incoming requests by forwarding them to the web servers. It provides anonymity for the **back-end web servers and not the client**. Reverse proxy servers are generally used to perform tasks such as **authentication, content caching, and encryption/decryption** on behalf of the web server. These tasks would **hog CPU cycles** on the web server and degrade the performance of the website by introducing a high amount of delay in loading the webpage. Reverse proxies are also used as **load balancers** to distribute the incoming traffic efficiently among the web servers but it is **not optimized** for this task. In essence, a reverse proxy server is a gateway to a web-server or group of web-servers. -Reverse proxy servers are implemented on the **server side** instead of the client side. It **sits in front of multiple webservers** and manages incoming requests by forwarding them to the web servers. It provides anonymity for the **back-end web servers and not the client**. Reverse proxy servers are generally used to perform tasks such as **authentication, content caching, and encryption/decryption** on behalf of the web server. These tasks would **hog CPU cycles** on the web server and degrade the performance of the website by introducing a high amount of delay in loading the webpage. Reverse proxies are also used as **load balancers** to distribute the incoming traffic efficiently among the web servers but it is **not optimized** for this task. In essence, a reverse proxy server is a gateway to a web-server or group of web-servers. +![Reverse Proxy Description](/guides/proxy/reverse-proxy.png) -![Reverse Proxy Description](/guides/proxy/reverse-proxy.png) -> NOTE: This is not an accurate description but rather just an illustration. Red lines represent the server's response and black lines represent the initial request from client(s). +> NOTE: This is not an accurate description but rather just an illustration. Red lines represent the server's response and black lines represent the initial request from client(s). -## Summary +## Summary -A proxy server acts as a gateway between client *(you)* and the internet and separates end-users from the websites you browse. ***The position of the proxy server on the network determines whether it is a forward or a reverse proxy server***. A Forward proxy is implemented on the client side and **sits in front of multiple clients** or client sources and forwards requests to the web server. Reverse proxy servers are implemented on the **server side** it **sits in front of multiple webservers** and manage the incoming requests by forwarding them to the web servers. +A proxy server acts as a gateway between client _(you)_ and the internet and separates end-users from the websites you browse. **_The position of the proxy server on the network determines whether it is a forward or a reverse proxy server_**. A Forward proxy is implemented on the client side and **sits in front of multiple clients** or client sources and forwards requests to the web server. Reverse proxy servers are implemented on the **server side** it **sits in front of multiple webservers** and manage the incoming requests by forwarding them to the web servers. -If all this was too much to take in, I have a simple analogy for you. +If all this was too much to take in, I have a simple analogy for you. -At a restaurant, the waiter/waitress takes your order and gives it to the kitchen head chef. The head chef then calls out the order and assigns tasks to everyone in the kitchen. +At a restaurant, the waiter/waitress takes your order and gives it to the kitchen head chef. The head chef then calls out the order and assigns tasks to everyone in the kitchen. -In this analogy: +In this analogy: -* You are the client -* Your order is the web request -* Waiter/Waitress is your forward proxy server -* Kitchen head chef is the reverse proxy server -* Other chefs working in the kitchen are the web servers +- You are the client +- Your order is the web request +- Waiter/Waitress is your forward proxy server +- Kitchen head chef is the reverse proxy server +- Other chefs working in the kitchen are the web servers With that said our guide comes to an end. Thank you for reading and feel free to submit any updates to the guide using the links below. diff --git a/src/data/guides/random-numbers.md b/src/data/guides/random-numbers.md index 4b9c6eda3..96389c310 100644 --- a/src/data/guides/random-numbers.md +++ b/src/data/guides/random-numbers.md @@ -1,26 +1,25 @@ --- -title: "Random Numbers: Are they?" -description: "Learn how they are generated and why they may not be truly random." +title: 'Random Numbers: Are they?' +description: 'Learn how they are generated and why they may not be truly random.' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "Random Numbers: Are they? - roadmap.sh" - description: "Learn how they are generated and why they may not be truly random." + title: 'Random Numbers: Are they? - roadmap.sh' + description: 'Learn how they are generated and why they may not be truly random.' isNew: false -type: "visual" +type: 'visual' date: 2021-03-14 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "visual-guide" - - "guide-sitemap" + - 'guide' + - 'visual-guide' + - 'guide-sitemap' --- -Random numbers are everywhere from computer games to lottery systems, graphics software, statistical sampling, computer simulation and cryptography. Graphic below is a quick explanation to how the random numbers are generated and why they may not be truly random. +Random numbers are everywhere from computer games to lottery systems, graphics software, statistical sampling, computer simulation and cryptography. Graphic below is a quick explanation to how the random numbers are generated and why they may not be truly random. [![Random Numbers](/guides/random-numbers.png)](/guides/random-numbers.png) - diff --git a/src/data/guides/scaling-databases.md b/src/data/guides/scaling-databases.md index fcd6390fa..ebbed72d4 100644 --- a/src/data/guides/scaling-databases.md +++ b/src/data/guides/scaling-databases.md @@ -1,26 +1,25 @@ --- -title: "Scaling Databases" -description: "Learn the ups and downs of different database scaling strategies" +title: 'Scaling Databases' +description: 'Learn the ups and downs of different database scaling strategies' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "Scaling Databases - roadmap.sh" - description: "Learn the ups and downs of different database scaling strategies" + title: 'Scaling Databases - roadmap.sh' + description: 'Learn the ups and downs of different database scaling strategies' isNew: false -type: "visual" +type: 'visual' date: 2021-02-18 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "visual-guide" - - "guide-sitemap" + - 'guide' + - 'visual-guide' + - 'guide-sitemap' --- The chart below aims to give you a really basic understanding of how the capability of a DBMS is increased to handle a growing amount of load. [![Scaling Databases](/guides/scaling-databases.svg)](/guides/scaling-databases.svg) - diff --git a/src/data/guides/session-authentication.md b/src/data/guides/session-authentication.md index 2a9cb7194..355e0d801 100644 --- a/src/data/guides/session-authentication.md +++ b/src/data/guides/session-authentication.md @@ -1,24 +1,23 @@ --- -title: "Session Based Authentication" -description: "Understand what is session based authentication and how it is implemented" +title: 'Session Based Authentication' +description: 'Understand what is session based authentication and how it is implemented' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "Session Based Authentication - roadmap.sh" - description: "Understand what is session based authentication and how it is implemented" + title: 'Session Based Authentication - roadmap.sh' + description: 'Understand what is session based authentication and how it is implemented' isNew: false -type: "visual" +type: 'visual' date: 2021-05-26 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "visual-guide" - - "guide-sitemap" + - 'guide' + - 'visual-guide' + - 'guide-sitemap' --- [![Session Authentication](/guides/session-authentication.png)](/guides/session-authentication.png) - diff --git a/src/data/guides/session-based-authentication.md b/src/data/guides/session-based-authentication.md index 8d4f4c7a9..c06006f9c 100644 --- a/src/data/guides/session-based-authentication.md +++ b/src/data/guides/session-based-authentication.md @@ -1,43 +1,46 @@ --- -title: "Session Based Authentication" -description: "Learn what is Session Based Authentication and how to implement it in Node.js" +title: 'Session Based Authentication' +description: 'Learn what is Session Based Authentication and how to implement it in Node.js' author: - name: "Kamran Ahmed" - url: "https://twitter.com/kamranahmedse" - imageUrl: "/authors/kamranahmedse.jpeg" + name: 'Kamran Ahmed' + url: 'https://twitter.com/kamranahmedse' + imageUrl: '/authors/kamranahmedse.jpeg' seo: - title: "Session Based Authentication - roadmap.sh" - description: "Learn what is Session Based Authentication and how to implement it in Node.js" + title: 'Session Based Authentication - roadmap.sh' + description: 'Learn what is Session Based Authentication and how to implement it in Node.js' isNew: false -type: "textual" +type: 'textual' date: 2022-11-01 sitemap: priority: 0.7 - changefreq: "weekly" + changefreq: 'weekly' tags: - - "guide" - - "textual-guide" - - "guide-sitemap" + - 'guide' + - 'textual-guide' + - 'guide-sitemap' --- HTTP is the internet protocol that standardizes how clients and servers interact with each other. When you open a website, among other things, HTTP is the protocol that helps load the website in the browser. ## HTTP is Stateless + HTTP is a stateless protocol which means that each request made from the client to the server is treated as a standalone request; neither the client nor the server keeps track of the subsequent requests. Sessions allow you to change that; with sessions, the server has a way to associate some information with the client so that when the same client requests the server, it can retrieve that information. In this guide, we will learn what is Session-Based Authentication and how to implement it in Node.js. We also have a separate [visual guide on Session-Based Authentication](/guides/session-authentication) as well that explains the topic visually. ## What is Session-Based Authentication? + Session-based authentication is a stateful authentication technique where we use sessions to keep track of the authenticated user. Here is how Session Based Authentication works: -* User submits the login request for authentication. -* Server validates the credentials. If the credentials are valid, the server initiates a session and stores some information about the client. This information can be stored in memory, file system, or database. The server also generates a unique identifier that it can later use to retrieve this session information from the storage. Server sends this unique session identifier to the client. -* Client saves the session id in a cookie and this cookie is sent to the server in each request made after the authentication. -* Server, upon receiving a request, checks if the session id is present in the request and uses this session id to get information about the client. +- User submits the login request for authentication. +- Server validates the credentials. If the credentials are valid, the server initiates a session and stores some information about the client. This information can be stored in memory, file system, or database. The server also generates a unique identifier that it can later use to retrieve this session information from the storage. Server sends this unique session identifier to the client. +- Client saves the session id in a cookie and this cookie is sent to the server in each request made after the authentication. +- Server, upon receiving a request, checks if the session id is present in the request and uses this session id to get information about the client. And that is how session-based authentication works. ## Session-Based Authentication in Node.js + Now that we know what session-based authentication is, let's see how we can implement session-based authentication in Node.js. Please note that, for the sake of simplicity, I have intentionally kept the project strictly relevant to the Session Based Authentication and have left out a lot of details that a production-ready application may require. Also, if you don't want to follow along, project [codebase can be found on GitHub](https://github.com/kamranahmedse/node-session-auth-example). @@ -47,17 +50,23 @@ First things first, create an empty directory that will be holding our applicati ```shell mkdir session-auth-example ``` + Now run the following command to setup a sample `package.json` file: + ```shell npm init -y ``` + Next, we need to install the dependencies: + ```shell npm install express express-session ``` + `Express` is the application framework, and `express-session` is the package that helps work with sessions easily. ### Setting up the server + Now create an `index.js` file at the root of the project with the following content: ```javascript @@ -66,17 +75,19 @@ const sessions = require('express-session'); const app = express(); -app.use(sessions({ - secret: "some secret", - cookie: { - maxAge: 1000 * 60 * 60 * 24 // 24 hours - }, - resave: true, - saveUninitialized: false, -})); +app.use( + sessions({ + secret: 'some secret', + cookie: { + maxAge: 1000 * 60 * 60 * 24, // 24 hours + }, + resave: true, + saveUninitialized: false, + }) +); app.use(express.json()); -app.use(express.urlencoded({extended: true})); +app.use(express.urlencoded({ extended: true })); // @todo register routes @@ -84,17 +95,20 @@ app.listen(3000, () => { console.log(`Server Running at port 3000`); }); ``` + The important piece to note here is the `express-session` middleware registration which automatically handles the session initialization, cooking parsing and session data retrieval, and so on. In our example here, we are passing the following configuration options: -* `secret`: This is used to sign the session ID cookie. Using a secret that cannot be guessed will reduce the ability to hijack a session. -* `cookie`: Object containing the configuration for session id cookie. -* `resave`: Forces the session to be saved back to the session store, even if the session data was never modified during the request. -* `saveUninitialized`: Forces an "uninitialized" session to be saved to the store, i.e., saves a session to the store even if the session was not initiated. + +- `secret`: This is used to sign the session ID cookie. Using a secret that cannot be guessed will reduce the ability to hijack a session. +- `cookie`: Object containing the configuration for session id cookie. +- `resave`: Forces the session to be saved back to the session store, even if the session data was never modified during the request. +- `saveUninitialized`: Forces an "uninitialized" session to be saved to the store, i.e., saves a session to the store even if the session was not initiated. Another important option is `store` which we can configure to change how/where the session data is stored on the server. By default, this data is stored in the memory, i.e., `MemoryStore`. Look at the [express-session documentation](https://github.com/expressjs/session) to learn more about the available options. ### Creating Handlers + Create a directory called the `handlers` at the project's root. This is the directory where we will be placing all the route-handling functions. Now let's create the homepage route, which will show the welcome message and a link to log out for the logged-in users and redirect to the login screen for the logged-out users. Create a file at `handlers/home.js` with the following content. @@ -105,14 +119,14 @@ module.exports = function HomeHandler(req, res) { return res.redirect('/login'); } - res.setHeader('Content-Type', 'text/HTML') + res.setHeader('Content-Type', 'text/HTML'); res.write(`