backend for portfolio page

This commit is contained in:
Kim, Jimin 2022-01-06 08:55:09 +09:00
parent fe7cc3bde3
commit 012f446e64
12 changed files with 273 additions and 43 deletions

View file

@ -1,15 +1,44 @@
import fs from "fs" import fs from "fs"
import { contentDirectoryPath, mapFilePath } from "./config" import {
contentDirectoryPath,
iconsDirectoryPath,
mapFilePath,
portfolioFilePath,
searchIndexFilePath,
} from "./config"
export default function clean() { export default function clean() {
/**
* Delete directories
*/
try { try {
fs.rmSync(contentDirectoryPath, { recursive: true }) fs.rmSync(contentDirectoryPath, { recursive: true })
// eslint-disable-next-line no-empty // eslint-disable-next-line no-empty
} catch (err) {} } catch (err) {}
try {
fs.rmSync(iconsDirectoryPath, { recursive: true })
// eslint-disable-next-line no-empty
} catch (err) {}
/**
* Delete folders
*/
try { try {
fs.unlinkSync(mapFilePath) fs.unlinkSync(mapFilePath)
// eslint-disable-next-line no-empty // eslint-disable-next-line no-empty
} catch (err) {} } catch (err) {}
try {
fs.unlinkSync(portfolioFilePath)
// eslint-disable-next-line no-empty
} catch (err) {}
try {
fs.unlinkSync(searchIndexFilePath)
// eslint-disable-next-line no-empty
} catch (err) {}
} }

View file

@ -2,4 +2,7 @@ export const markdownPath = "./markdown" // where it will look for markdown docu
export const outPath = "./src/data" // path to the json database export const outPath = "./src/data" // path to the json database
export const contentDirectoryPath = `${outPath}/content` export const contentDirectoryPath = `${outPath}/content`
export const iconsDirectoryPath = `${outPath}/icons`
export const mapFilePath = `${outPath}/map.json` export const mapFilePath = `${outPath}/map.json`
export const portfolioFilePath = `${outPath}/portfolio.json`
export const searchIndexFilePath = `${outPath}/search.json`

View file

@ -8,7 +8,7 @@
import fs from "fs" import fs from "fs"
import { mapFilePath, markdownPath } from "./config" import { mapFilePath, markdownPath, portfolioFilePath } from "./config"
import { recursiveParse } from "./recursiveParse" import { recursiveParse } from "./recursiveParse"
import { saveIndex } from "./searchIndex" import { saveIndex } from "./searchIndex"
import postProcess from "./postProcess" import postProcess from "./postProcess"
@ -29,7 +29,7 @@ export const map: Map = {
export const seriesMap: SeriesMap = {} export const seriesMap: SeriesMap = {}
export const portfolioData: PortfolioData = { export const portfolioData: PortfolioData = {
overview: "", overview: "",
projects: [], projects: {},
} }
/** /**
@ -74,4 +74,5 @@ postProcess()
*/ */
fs.writeFileSync(mapFilePath, JSON.stringify(map)) fs.writeFileSync(mapFilePath, JSON.stringify(map))
fs.writeFileSync(portfolioFilePath, JSON.stringify(portfolioData))
saveIndex() saveIndex()

View file

@ -1,14 +1,15 @@
import fs from "fs" import fs from "fs"
import simpleIcons from "simple-icons" // badge icons
import readTimeEstimate from "read-time-estimate" // post read time estimation import readTimeEstimate from "read-time-estimate" // post read time estimation
import { path2FileOrFolderName, path2URL, writeToJSON } from "./util" import { path2FileOrFolderName, path2URL, writeToFile } from "./util"
import { generateToc, parseFrontMatter } from "./parseMarkdown" import { generateToc, parseFrontMatter } from "./parseMarkdown"
import { contentDirectoryPath } from "./config" import { contentDirectoryPath, iconsDirectoryPath } from "./config"
import { addDocument } from "./searchIndex" import { addDocument } from "./searchIndex"
import { map, seriesMap } from "." import { map, portfolioData, seriesMap } from "."
import { MarkdownData, ParseMode, PostData } from "../types/types" import { ParseMode, PortfolioProject, PostData } from "../types/types"
/** /**
* Data that's passed from {@link parseFile} to other function * Data that's passed from {@link parseFile} to other function
@ -17,7 +18,10 @@ interface DataToPass {
path: string path: string
urlPath: string urlPath: string
markdownRaw: string markdownRaw: string
markdownData: MarkdownData markdownData: {
content: string
[key: string]: unknown
}
humanizedDuration: string humanizedDuration: string
totalWords: number totalWords: number
} }
@ -60,7 +64,7 @@ function parseFile(mode: ParseMode, path: string, fileName: string): void {
*/ */
const markdownRaw = fs.readFileSync(path, "utf8") const markdownRaw = fs.readFileSync(path, "utf8")
const markdownData: MarkdownData = parseFrontMatter(markdownRaw, path, mode) const markdownData = parseFrontMatter(markdownRaw, path, mode)
const { humanizedDuration, totalWords } = readTimeEstimate( const { humanizedDuration, totalWords } = readTimeEstimate(
markdownData.content, markdownData.content,
275, 275,
@ -107,7 +111,7 @@ function parsePost(data: DataToPass): void {
} = data } = data
const postData: PostData = { const postData: PostData = {
title: markdownData.title, title: markdownData.title as string,
date: "", date: "",
readTime: humanizedDuration, readTime: humanizedDuration,
wordCount: totalWords, wordCount: totalWords,
@ -118,7 +122,7 @@ function parsePost(data: DataToPass): void {
* Dates * Dates
*/ */
const postDate = new Date(markdownData.date) const postDate = new Date(markdownData.date as string)
postData.date = postDate.toLocaleString("default", { postData.date = postDate.toLocaleString("default", {
month: "short", month: "short",
day: "numeric", day: "numeric",
@ -136,7 +140,7 @@ function parsePost(data: DataToPass): void {
* Tags * Tags
*/ */
postData.tags = markdownData.tags postData.tags = markdownData.tags as string[]
if (postData.tags) { if (postData.tags) {
postData.tags.forEach((tag) => { postData.tags.forEach((tag) => {
if (map.tags[tag]) { if (map.tags[tag]) {
@ -157,7 +161,7 @@ function parsePost(data: DataToPass): void {
body: markdownData.content, body: markdownData.content,
url: urlPath, url: urlPath,
}) })
writeToJSON( writeToFile(
`${contentDirectoryPath}${urlPath}.json`, `${contentDirectoryPath}${urlPath}.json`,
JSON.stringify({ JSON.stringify({
content: markdownData.content, content: markdownData.content,
@ -204,7 +208,7 @@ function parseSeries(data: DataToPass): void {
// todo: separate interface for series descriptor (no word count and read time) // todo: separate interface for series descriptor (no word count and read time)
const postData: PostData = { const postData: PostData = {
title: markdownData.title, title: markdownData.title as string,
date: "", date: "",
readTime: humanizedDuration, readTime: humanizedDuration,
wordCount: totalWords, wordCount: totalWords,
@ -215,7 +219,7 @@ function parseSeries(data: DataToPass): void {
* Date * Date
*/ */
const postDate = new Date(markdownData.date) const postDate = new Date(markdownData.date as string)
postData.date = postDate.toLocaleString("default", { postData.date = postDate.toLocaleString("default", {
month: "short", month: "short",
day: "numeric", day: "numeric",
@ -233,7 +237,7 @@ function parseSeries(data: DataToPass): void {
* Tags * Tags
*/ */
postData.tags = markdownData.tags postData.tags = markdownData.tags as string[]
if (postData.tags) { if (postData.tags) {
postData.tags.forEach((tag) => { postData.tags.forEach((tag) => {
if (map.tags[tag]) { if (map.tags[tag]) {
@ -297,7 +301,7 @@ function parseSeries(data: DataToPass): void {
* Save content * Save content
*/ */
writeToJSON( writeToFile(
`${contentDirectoryPath}${urlPath}.json`, `${contentDirectoryPath}${urlPath}.json`,
JSON.stringify({ JSON.stringify({
content: markdownData.content, content: markdownData.content,
@ -320,14 +324,14 @@ function parseUnsearchable(data: DataToPass): void {
// Parse data that will be written to map.js // Parse data that will be written to map.js
map.unsearchable[urlPath] = { map.unsearchable[urlPath] = {
title: markdownData.title, title: markdownData.title as string,
} }
/** /**
* Save content * Save content
*/ */
writeToJSON( writeToFile(
`${contentDirectoryPath}/unsearchable${urlPath}.json`, `${contentDirectoryPath}/unsearchable${urlPath}.json`,
JSON.stringify({ JSON.stringify({
content: markdownData.content, content: markdownData.content,
@ -336,5 +340,47 @@ function parseUnsearchable(data: DataToPass): void {
} }
function parsePortfolio(data: DataToPass): void { function parsePortfolio(data: DataToPass): void {
console.log("portfolio file:", data.path) const { urlPath, markdownData } = data
const lastPath = urlPath.slice(urlPath.lastIndexOf("/") + 1)
// check if the file is a portfolio overview or a project
if (lastPath == "0") {
portfolioData.overview = markdownData.content
} else {
// todo: generate svg in post process
// todo: add badges to portfolio meta (for searchable and for svg)
;(markdownData.badges as string[]).forEach((slug) => {
const icon = simpleIcons.Get(slug)
// save svg icon
writeToFile(
`${iconsDirectoryPath}/${icon.slug}.json`,
JSON.stringify({
svg: icon.svg,
hex: icon.hex,
title: icon.title,
})
)
})
// todo: simple-icons
const project: PortfolioProject = {
name: markdownData.name as string,
image: markdownData.image as string,
overview: markdownData.overview as string,
badges: markdownData.badges as string[],
repo: markdownData.repo as string,
}
portfolioData.projects[urlPath] = project
writeToFile(
`${contentDirectoryPath}${urlPath}.json`,
JSON.stringify({
content: markdownData.content,
})
)
}
} }

View file

@ -5,7 +5,7 @@
import fs from "fs" import fs from "fs"
import elasticlunr from "elasticlunr" import elasticlunr from "elasticlunr"
import { outPath } from "./config" import { searchIndexFilePath } from "./config"
const elasticlunrIndex = elasticlunr(function () { const elasticlunrIndex = elasticlunr(function () {
this.addField("title" as never) this.addField("title" as never)
@ -18,5 +18,5 @@ export function addDocument(doc: unknown) {
} }
export function saveIndex() { export function saveIndex() {
fs.writeFileSync(outPath + "/search.json", JSON.stringify(elasticlunrIndex)) fs.writeFileSync(searchIndexFilePath, JSON.stringify(elasticlunrIndex))
} }

View file

@ -42,12 +42,12 @@ export function nthIndex(str: string, pat: string, n: number) {
return i return i
} }
export function writeToJSON(JSONFilePath: string, dataToWrite: string) { export function writeToFile(filePath: string, dataToWrite: string) {
// create directory to put json content files // create directory to put the files
fs.mkdirSync(JSONFilePath.slice(0, JSONFilePath.lastIndexOf("/")), { fs.mkdirSync(filePath.slice(0, filePath.lastIndexOf("/")), {
recursive: true, recursive: true,
}) })
// write content to json file // write content to the file
fs.writeFileSync(JSONFilePath, dataToWrite) fs.writeFileSync(filePath, dataToWrite)
} }

View file

@ -0,0 +1,7 @@
---
github: https://github.com/developomp
---
## Skills
## Education

View file

@ -0,0 +1,16 @@
---
name: Mocha Downloader
overview: A cross-platform desktop download manager built with web technologies.
image: /img/icon.png
repo: https://github.com/Mocha-Downloader
badges:
- typescript
- javascript
- nodedotjs
- electron
- react
- html5
- css3
---
Mocha Downloader is a cross-platform desktop download manager built with web technologies.

View file

@ -0,0 +1,14 @@
---
name: War Brokers Mods
overview: A game mod for a unity game. Provides in-game UI and OBS overlays.
image: /img/icon.png
repo: https://github.com/War-Brokers-Mods
badges:
- csharp
- dotnet
- javascript
- html5
- css3
---
War Brokers Mods (WBM) is a mod for the game War Brokers. It also provides OBS overlays for streamers too.

View file

@ -53,6 +53,7 @@
"eslint-plugin-react": "^7.27.1", "eslint-plugin-react": "^7.27.1",
"gray-matter": "^4.0.3", "gray-matter": "^4.0.3",
"jsdom": "^19.0.0", "jsdom": "^19.0.0",
"jspdf": "^2.5.0",
"markdown-it": "^12.3.0", "markdown-it": "^12.3.0",
"markdown-it-anchor": "^8.4.1", "markdown-it-anchor": "^8.4.1",
"markdown-it-attrs": "^4.1.0", "markdown-it-attrs": "^4.1.0",
@ -66,6 +67,7 @@
"markdown-toc": "^1.2.0", "markdown-toc": "^1.2.0",
"prettier": "^2.5.1", "prettier": "^2.5.1",
"read-time-estimate": "^0.0.3", "read-time-estimate": "^0.0.3",
"simple-icons": "^6.5.0",
"ts-node": "^10.4.0", "ts-node": "^10.4.0",
"tslint-config-prettier": "^1.18.0", "tslint-config-prettier": "^1.18.0",
"typescript": "^4.5.4" "typescript": "^4.5.4"

View file

@ -33,11 +33,6 @@ export interface Map {
* General * General
*/ */
export interface Badge {
icon: string
text: string
}
export enum ParseMode { export enum ParseMode {
POSTS, POSTS,
SERIES, SERIES,
@ -47,9 +42,7 @@ export enum ParseMode {
export interface MarkdownData { export interface MarkdownData {
content: string content: string
date: string [key: string]: unknown
title: string
tags: string[]
} }
export interface PostData { export interface PostData {
@ -99,8 +92,13 @@ export interface SeriesEntry {
*/ */
export interface PortfolioData { export interface PortfolioData {
// rendered markdown html
overview: string overview: string
projects: PortfolioProject[]
// key: url
projects: {
[key: string]: PortfolioProject
}
} }
export interface PortfolioOverview { export interface PortfolioOverview {
@ -110,15 +108,9 @@ export interface PortfolioOverview {
} }
export interface PortfolioProject { export interface PortfolioProject {
// shown in card
name: string name: string
image: string // url to the image image: string // url to the image
overview: string overview: string
badges: Badge[] badges: string[] // array of valid simpleIcons slug
repo: string // url of the git repository repo: string // url of the git repository
// page content
description: string // html render of markdown description
} }

View file

@ -1171,6 +1171,13 @@
dependencies: dependencies:
regenerator-runtime "^0.13.4" regenerator-runtime "^0.13.4"
"@babel/runtime@^7.14.0":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa"
integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.7.6": "@babel/runtime@^7.7.6":
version "7.16.5" version "7.16.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.5.tgz#7f3e34bf8bdbbadf03fbb7b1ea0d929569c9487a" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.5.tgz#7f3e34bf8bdbbadf03fbb7b1ea0d929569c9487a"
@ -2061,6 +2068,11 @@
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24"
integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug== integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==
"@types/raf@^3.4.0":
version "3.4.0"
resolved "https://registry.yarnpkg.com/@types/raf/-/raf-3.4.0.tgz#2b72cbd55405e071f1c4d29992638e022b20acc2"
integrity sha512-taW5/WYqo36N7V39oYyHP9Ipfd5pNFvGTIQsNGj86xV88YQ7GnI30/yMfKDF7Zgin0m3e+ikX88FvImnK4RjGw==
"@types/react-collapse@^5.0.1": "@types/react-collapse@^5.0.1":
version "5.0.1" version "5.0.1"
resolved "https://registry.yarnpkg.com/@types/react-collapse/-/react-collapse-5.0.1.tgz#078ea1ad15e00ba2063f2e4d8d6760c9375a2023" resolved "https://registry.yarnpkg.com/@types/react-collapse/-/react-collapse-5.0.1.tgz#078ea1ad15e00ba2063f2e4d8d6760c9375a2023"
@ -3246,6 +3258,16 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
base64-arraybuffer@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz#4b944fac0191aa5907afe2d8c999ccc57ce80f45"
integrity sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==
base64-arraybuffer@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-1.0.1.tgz#87bd13525626db4a9838e00a508c2b73efcf348c"
integrity sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA==
base64-js@^1.0.2: base64-js@^1.0.2:
version "1.5.1" version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
@ -3486,6 +3508,11 @@ bser@2.1.1:
dependencies: dependencies:
node-int64 "^0.4.0" node-int64 "^0.4.0"
btoa@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73"
integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==
buffer-from@^1.0.0: buffer-from@^1.0.0:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
@ -3668,6 +3695,20 @@ canvas@^2.8.0:
nan "^2.14.0" nan "^2.14.0"
simple-get "^3.0.3" simple-get "^3.0.3"
canvg@^3.0.6:
version "3.0.9"
resolved "https://registry.yarnpkg.com/canvg/-/canvg-3.0.9.tgz#9ba095f158b94b97ca2c9c1c40785b11dc08df6d"
integrity sha512-rDXcnRPuz4QHoCilMeoTxql+fvGqNAxp+qV/KHD8rOiJSAfVjFclbdUNHD2Uqfthr+VMg17bD2bVuk6F07oLGw==
dependencies:
"@babel/runtime" "^7.12.5"
"@types/raf" "^3.4.0"
core-js "^3.8.3"
raf "^3.4.1"
regenerator-runtime "^0.13.7"
rgbcolor "^1.0.1"
stackblur-canvas "^2.0.0"
svg-pathdata "^6.0.3"
capture-exit@^2.0.0: capture-exit@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4"
@ -4096,6 +4137,11 @@ core-js@^2.4.0:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
core-js@^3.6.0, core-js@^3.8.3:
version "3.20.2"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.20.2.tgz#46468d8601eafc8b266bd2dd6bf9dee622779581"
integrity sha512-nuqhq11DcOAbFBV4zCbKeGbKQsUDRqTX0oqx7AttUBuqe3h20ixsE039QHelbL6P4h+9kytVqyEtyZ6gsiwEYw==
core-js@^3.6.5: core-js@^3.6.5:
version "3.12.1" version "3.12.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.12.1.tgz#6b5af4ff55616c08a44d386f1f510917ff204112" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.12.1.tgz#6b5af4ff55616c08a44d386f1f510917ff204112"
@ -4249,6 +4295,13 @@ css-has-pseudo@^0.10.0:
postcss "^7.0.6" postcss "^7.0.6"
postcss-selector-parser "^5.0.0-rc.4" postcss-selector-parser "^5.0.0-rc.4"
css-line-break@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/css-line-break/-/css-line-break-2.0.1.tgz#3dc74c2ed5eb64211480281932475790243e7338"
integrity sha512-gwKYIMUn7xodIcb346wgUhE2Dt5O1Kmrc16PWi8sL4FTfyDj8P5095rzH7+O8CTZudJr+uw2GCI/hwEkDJFI2w==
dependencies:
base64-arraybuffer "^0.2.0"
css-loader@4.3.0: css-loader@4.3.0:
version "4.3.0" version "4.3.0"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-4.3.0.tgz#c888af64b2a5b2e85462c72c0f4a85c7e2e0821e" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-4.3.0.tgz#c888af64b2a5b2e85462c72c0f4a85c7e2e0821e"
@ -4818,6 +4871,11 @@ domhandler@^2.3.0:
dependencies: dependencies:
domelementtype "1" domelementtype "1"
dompurify@^2.2.0:
version "2.3.4"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.4.tgz#1cf5cf0105ccb4debdf6db162525bd41e6ddacc6"
integrity sha512-6BVcgOAVFXjI0JTjEvZy901Rghm+7fDQOrNIcxB4+gdhj6Kwp6T9VBhBY/AbagKHJocRkDYGd6wvI+p4/10xtQ==
domutils@^1.5.1, domutils@^1.7.0: domutils@^1.5.1, domutils@^1.7.0:
version "1.7.0" version "1.7.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
@ -5646,6 +5704,11 @@ fb-watchman@^2.0.0:
dependencies: dependencies:
bser "2.1.1" bser "2.1.1"
fflate@^0.4.8:
version "0.4.8"
resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.4.8.tgz#f90b82aefbd8ac174213abb338bd7ef848f0f5ae"
integrity sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==
figgy-pudding@^3.5.1: figgy-pudding@^3.5.1:
version "3.5.2" version "3.5.2"
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e"
@ -6397,6 +6460,14 @@ html-webpack-plugin@4.5.0:
tapable "^1.1.3" tapable "^1.1.3"
util.promisify "1.0.0" util.promisify "1.0.0"
html2canvas@^1.0.0-rc.5:
version "1.4.0"
resolved "https://registry.yarnpkg.com/html2canvas/-/html2canvas-1.4.0.tgz#e9db68a47486f2e884fea46b28a3a10f6c17b66f"
integrity sha512-vQMssxs2HvLuy7T0JrQqirRQxnhfB7KaHRSsQVV2WaNlXMqqhwv0gH+JUkkaWCednbDWZtRF7Msb/pbTkbcrpA==
dependencies:
css-line-break "2.0.1"
text-segmentation "^1.0.2"
htmlparser2@^3.10.1: htmlparser2@^3.10.1:
version "3.10.1" version "3.10.1"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
@ -7750,6 +7821,21 @@ jsonfile@^6.0.1:
optionalDependencies: optionalDependencies:
graceful-fs "^4.1.6" graceful-fs "^4.1.6"
jspdf@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/jspdf/-/jspdf-2.5.0.tgz#d0a1a2a9a73f0e7bc00599315ab5a9c825cbbcc2"
integrity sha512-XT0E2m8A9P1xl7ItA2OUbmhokzbDQEyZEdWQZD2olADiTiBEZGDRiK1J1zWxBRUG2KezQJOZq//GYZTkvEZuJg==
dependencies:
"@babel/runtime" "^7.14.0"
atob "^2.1.2"
btoa "^1.2.1"
fflate "^0.4.8"
optionalDependencies:
canvg "^3.0.6"
core-js "^3.6.0"
dompurify "^2.2.0"
html2canvas "^1.0.0-rc.5"
jsprim@^1.2.2: jsprim@^1.2.2:
version "1.4.1" version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
@ -10827,6 +10913,11 @@ rgba-regex@^1.0.0:
resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3"
integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=
rgbcolor@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/rgbcolor/-/rgbcolor-1.0.1.tgz#d6505ecdb304a6595da26fa4b43307306775945d"
integrity sha1-1lBezbMEplldom+ktDMHMGd1lF0=
rimraf@^2.5.4, rimraf@^2.6.3: rimraf@^2.5.4, rimraf@^2.6.3:
version "2.7.1" version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
@ -11223,6 +11314,11 @@ simple-get@^3.0.3:
once "^1.3.1" once "^1.3.1"
simple-concat "^1.0.0" simple-concat "^1.0.0"
simple-icons@^6.5.0:
version "6.5.0"
resolved "https://registry.yarnpkg.com/simple-icons/-/simple-icons-6.5.0.tgz#72656982ad9d046d15dbf8c18727b714cc900f26"
integrity sha512-LHasJ9YZ663RKlW10C2EFqt1xCjeXTp/IqrIZEPppHSUgsIEa2jDSFFouM9n5xsvrBhfpDIPuwXb/D8sbXpxMQ==
simple-swizzle@^0.2.2: simple-swizzle@^0.2.2:
version "0.2.2" version "0.2.2"
resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
@ -11458,6 +11554,11 @@ stack-utils@^2.0.2:
dependencies: dependencies:
escape-string-regexp "^2.0.0" escape-string-regexp "^2.0.0"
stackblur-canvas@^2.0.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/stackblur-canvas/-/stackblur-canvas-2.5.0.tgz#aa87bbed1560fdcd3138fff344fc6a1c413ebac4"
integrity sha512-EeNzTVfj+1In7aSLPKDD03F/ly4RxEuF/EX0YcOG0cKoPXs+SLZxDawQbexQDBzwROs4VKLWTOaZQlZkGBFEIQ==
stackframe@^1.1.1: stackframe@^1.1.1:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303" resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303"
@ -11767,6 +11868,11 @@ svg-parser@^2.0.2:
resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5"
integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==
svg-pathdata@^6.0.3:
version "6.0.3"
resolved "https://registry.yarnpkg.com/svg-pathdata/-/svg-pathdata-6.0.3.tgz#80b0e0283b652ccbafb69ad4f8f73e8d3fbf2cac"
integrity sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==
svgo@^1.0.0, svgo@^1.2.2: svgo@^1.0.0, svgo@^1.2.2:
version "1.3.2" version "1.3.2"
resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167"
@ -11911,6 +12017,13 @@ test-exclude@^6.0.0:
glob "^7.1.4" glob "^7.1.4"
minimatch "^3.0.4" minimatch "^3.0.4"
text-segmentation@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/text-segmentation/-/text-segmentation-1.0.2.tgz#1f828fa14aa101c114ded1bda35ba7dcc17c9858"
integrity sha512-uTqvLxdBrVnx/CFQOtnf8tfzSXFm+1Qxau7Xi54j4OPTZokuDOX8qncQzrg2G8ZicAMOM8TgzFAYTb+AqNO4Cw==
dependencies:
utrie "^1.0.1"
text-table@0.2.0, text-table@^0.2.0: text-table@0.2.0, text-table@^0.2.0:
version "0.2.0" version "0.2.0"
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
@ -12401,6 +12514,13 @@ utils-merge@1.0.1:
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
utrie@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/utrie/-/utrie-1.0.1.tgz#e155235ebcbddc89ae09261ab6e773ce61401b2f"
integrity sha512-JPaDXF3vzgZxfeEwutdGzlrNoVFL5UvZcbO6Qo9D4GoahrieUPoMU8GCpVpR7MQqcKhmShIh8VlbEN3PLM3EBg==
dependencies:
base64-arraybuffer "^1.0.1"
uuid@^3.3.2, uuid@^3.4.0: uuid@^3.3.2, uuid@^3.4.0:
version "3.4.0" version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"