3
.vscode/settings.json
vendored
|
@ -3,5 +3,6 @@
|
|||
"editor.formatOnSave": true,
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
}
|
||||
},
|
||||
"files.associations": { "*.svx": "markdown" }
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-svelte3": "^3.2.1",
|
||||
"mdsvex": "^0.10.6",
|
||||
"prettier": "^2.4.1",
|
||||
"prettier-plugin-svelte": "^2.4.0",
|
||||
"svelte": "^3.48.0",
|
||||
|
@ -37,11 +38,9 @@
|
|||
"@sveltejs/adapter-static": "^1.0.0-next.21",
|
||||
"@types/js-yaml": "^4.0.4",
|
||||
"cookie": "^0.4.1",
|
||||
"html-minifier": "^4.0.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"marked": "^4.0.3"
|
||||
"html-minifier": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +1,14 @@
|
|||
<script lang="ts" context="module">
|
||||
import type { APIBlogPost } from './[slug].json'
|
||||
import type { Load } from '@sveltejs/kit'
|
||||
|
||||
export const prerender = true
|
||||
|
||||
export const load: Load = async ({ params, fetch }) => {
|
||||
const slug: string = params.slug ?? ''
|
||||
|
||||
const resp = await fetch(`/blog/${slug}.json`)
|
||||
if (resp.status === 404)
|
||||
return {
|
||||
status: 404,
|
||||
}
|
||||
|
||||
const post: APIBlogPost = await resp.json()
|
||||
|
||||
return {
|
||||
props: {
|
||||
title: post.title,
|
||||
html: post.html,
|
||||
published: new Date(post.published),
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
<script context="module">
|
||||
import img from './components/img.svelte'
|
||||
import BackAnchor from '$lib/BackAnchor.svelte'
|
||||
|
||||
export let title: string
|
||||
export let html: string
|
||||
export let published: Date
|
||||
// mdsvex moment
|
||||
export { img as image, img }
|
||||
</script>
|
||||
|
||||
<script>
|
||||
export let title = 'Untitled'
|
||||
export let published = ''
|
||||
</script>
|
||||
|
||||
<div class="article-container">
|
||||
|
@ -40,10 +18,10 @@
|
|||
<article>
|
||||
<div class="article-header">
|
||||
<h1>{title}</h1>
|
||||
<time>{published.toLocaleDateString()}</time>
|
||||
<time>{new Date(published).toLocaleDateString()}</time>
|
||||
</div>
|
||||
|
||||
{@html html}
|
||||
<slot />
|
||||
</article>
|
||||
</div>
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
import type { BlogPostPreview } from 'src/routes/blog/index.json'
|
||||
|
||||
export let post: BlogPostPreview
|
||||
// HACK: we have to do this otherwise sveltekit does a dumb
|
||||
const postHtml = `${post.html}<sty` + `le>${post.css}</style>`
|
||||
</script>
|
||||
|
||||
<a href="/blog/{post.slug}" class="preview-anchor">
|
||||
|
@ -12,7 +14,9 @@
|
|||
</div>
|
||||
|
||||
<div class="disappearing-text-preview" />
|
||||
<div class="preview">{@html post.html}</div>
|
||||
<div class="preview">
|
||||
{@html postHtml}
|
||||
</div>
|
||||
</article>
|
||||
</a>
|
||||
|
||||
|
|
107
src/lib/blog.ts
|
@ -1,21 +1,42 @@
|
|||
import yaml from 'js-yaml'
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
|
||||
export const postsDir = 'src/posts' as const
|
||||
export const postsDir = 'src/routes/blog' as const
|
||||
|
||||
export async function listBlogPostSlugs(): Promise<string[]> {
|
||||
await fs.promises.readdir(postsDir)
|
||||
|
||||
const existingPosts: string[] = await fs.promises.readdir(postsDir)
|
||||
|
||||
// https://stackoverflow.com/a/46842181
|
||||
async function filter<T>(arr: T[], callback: (item: T) => Promise<boolean>): Promise<T[]> {
|
||||
const fail = Symbol()
|
||||
return (
|
||||
await Promise.all(arr.map(async (item) => ((await callback(item)) ? item : fail)))
|
||||
).filter((i) => i !== fail) as any
|
||||
}
|
||||
|
||||
return await filter(existingPosts, (slug) =>
|
||||
fs.promises
|
||||
.stat(path.join(postsDir, slug, 'index.svx'))
|
||||
.then(() => true)
|
||||
.catch(() => false)
|
||||
)
|
||||
}
|
||||
|
||||
interface BlogPost {
|
||||
title: string
|
||||
published: string
|
||||
body: string
|
||||
html: string
|
||||
css: string
|
||||
slug: string
|
||||
}
|
||||
|
||||
/** Checks whether a slug is valid or not */
|
||||
async function doesBlogPostExist(slug: string) {
|
||||
const existingPosts: string[] = await fs.promises.readdir(postsDir)
|
||||
|
||||
return existingPosts.includes(slug)
|
||||
if (!existingPosts.includes(slug)) return false
|
||||
return true
|
||||
}
|
||||
|
||||
/** Checks whether an asset exists in a blog post */
|
||||
|
@ -32,29 +53,77 @@ export async function doesAssetExist(postSlug: string, assetName: string): Promi
|
|||
export async function getPost(slug: string): Promise<BlogPost | null> {
|
||||
if (!doesBlogPostExist(slug)) return null
|
||||
|
||||
const url = new URL(`protocol://-/blog/${slug}`)
|
||||
|
||||
const { default: post, metadata } = await import(`../routes/blog/${slug}/index.svx`)
|
||||
|
||||
// ok the post exists, so we can safely read the md file
|
||||
const postMarkdown = (
|
||||
await fs.promises.readFile(path.join(postsDir, slug, 'index.md'), 'utf8')
|
||||
).replace(/\r\n/g, '\n')
|
||||
// const postMarkdown = (
|
||||
// await fs.promises.readFile(path.join(postsDir, slug, 'index.md'), 'utf8')
|
||||
// ).replace(/\r\n/g, '\n')
|
||||
|
||||
const [_, yamlMetadata = null, markdownContent = null] =
|
||||
postMarkdown.match(/^---\n([\w\W]+?)\n---\n([\w\W]+)$/) ?? []
|
||||
// const [_, yamlMetadata = null, markdownContent = null] =
|
||||
// postMarkdown.match(/^---\n([\w\W]+?)\n---\n([\w\W]+)$/) ?? []
|
||||
|
||||
if (yamlMetadata === null) throw new Error(`Blog post "${slug}" has no metadata.`)
|
||||
if (markdownContent === null) throw new Error(`Blog post "${slug}" has no content.`)
|
||||
// if (yamlMetadata === null) throw new Error(`Blog post "${slug}" has no metadata.`)
|
||||
// if (markdownContent === null) throw new Error(`Blog post "${slug}" has no content.`)
|
||||
|
||||
const metadata: NonNullable<any> = yaml.load(yamlMetadata)
|
||||
// const metadata: NonNullable<any> = yaml.load(yamlMetadata)
|
||||
|
||||
// make sure the post has all the required metadata
|
||||
const requiredFields = ['title', 'published']
|
||||
for (const requiredField of requiredFields)
|
||||
if (!(requiredField in metadata))
|
||||
throw new Error(`Blog post "${slug}" is missing metadata field "${requiredField}"`)
|
||||
// // make sure the post has all the required metadata
|
||||
// const requiredFields = ['title', 'published']
|
||||
// for (const requiredField of requiredFields)
|
||||
// if (!(requiredField in metadata))
|
||||
// throw new Error(`Blog post "${slug}" is missing metadata field "${requiredField}"`)
|
||||
|
||||
const result: {
|
||||
title: string
|
||||
head: string
|
||||
css: Set<{
|
||||
map: null
|
||||
code: string
|
||||
}>
|
||||
} = { title: '', head: '', css: new Set() }
|
||||
|
||||
const renderHtml = post.$$render(
|
||||
result,
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
new Map([
|
||||
[
|
||||
'__svelte__',
|
||||
{
|
||||
page: {
|
||||
// HACK: this is necessary so the hack with images works
|
||||
// probably a war crime :)
|
||||
subscribe: (r: any) => {
|
||||
r({ url })
|
||||
},
|
||||
},
|
||||
navigating: {
|
||||
subscribe: () => {
|
||||
return
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
])
|
||||
)
|
||||
|
||||
// HACK: i'm probably comitting a felony by putting this here
|
||||
// but i couldn't come up with a better solution
|
||||
const html = /^[\w\W]*?<\/div>\s*([\w\W]+)<\/article>[\w\W]*?$/.exec(renderHtml)?.[1] ?? ''
|
||||
|
||||
const css = Array.from(result.css)
|
||||
.map((css) => css.code)
|
||||
.join('')
|
||||
|
||||
return {
|
||||
title: metadata.title,
|
||||
published: new Date(metadata.published).toString(),
|
||||
body: markdownContent.trim(),
|
||||
html,
|
||||
css,
|
||||
slug,
|
||||
}
|
||||
}
|
||||
|
|
14
src/lib/components/img.svelte
Normal file
|
@ -0,0 +1,14 @@
|
|||
<script lang="ts">
|
||||
import { page } from '$app/stores'
|
||||
export let src: string
|
||||
export let alt: string
|
||||
|
||||
page.subscribe((p) => {
|
||||
// hack so images work
|
||||
if (!src.includes('//') && !src.startsWith('/')) {
|
||||
src = `${p.url.pathname}/${src}`
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<img {src} {alt} />
|
|
@ -1,30 +0,0 @@
|
|||
import { marked } from 'marked'
|
||||
|
||||
export function markdownToHtml(md: string, baseUrl?: string): string {
|
||||
const renderer: Partial<marked.Renderer> = {
|
||||
image(href: string, title: string, text: string) {
|
||||
// href = cleanUrl(this.options.sanitize, this.options.baseUrl, href)
|
||||
href = baseUrl ? resolveUrl(baseUrl, href) : href
|
||||
if (href === null) return text
|
||||
let out = `<img src="${href}" alt="${text}"`
|
||||
if (title) out += ` title="${title}"`
|
||||
out += '/>'
|
||||
return out
|
||||
},
|
||||
}
|
||||
|
||||
marked.use({ renderer })
|
||||
|
||||
return marked.parse(md, { baseUrl, breaks: true })
|
||||
}
|
||||
|
||||
// https://nodejs.org/api/url.html#urlresolvefrom-to
|
||||
function resolveUrl(from: string, to: string): string {
|
||||
const resolvedUrl = new URL(to, new URL(from, 'resolve://'))
|
||||
if (resolvedUrl.protocol === 'resolve:') {
|
||||
// `from` is a relative URL.
|
||||
const { pathname, search, hash } = resolvedUrl
|
||||
return pathname + search + hash
|
||||
}
|
||||
return resolvedUrl.toString()
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
import { getPost } from '$lib/blog'
|
||||
import { markdownToHtml } from '$lib/utils'
|
||||
import type { RequestHandler } from '@sveltejs/kit'
|
||||
|
||||
export interface APIBlogPost {
|
||||
|
@ -25,7 +24,7 @@ export const get: RequestHandler = async ({ params }) => {
|
|||
body: {
|
||||
title: post.title,
|
||||
published: post.published,
|
||||
html: markdownToHtml(post.body, `/blog/${post.slug}/index.md`),
|
||||
html: post.html,
|
||||
} as APIBlogPost,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { doesAssetExist, getPost, postsDir } from '$lib/blog'
|
||||
import { markdownToHtml } from '$lib/utils'
|
||||
import type { RequestHandler } from '@sveltejs/kit'
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
import { getPost } from '$lib/blog'
|
||||
import { markdownToHtml } from '$lib/utils'
|
||||
import { getPost, listBlogPostSlugs } from '$lib/blog'
|
||||
import type { RequestHandler } from '@sveltejs/kit'
|
||||
import fs from 'fs'
|
||||
|
||||
const postsDir = 'src/posts'
|
||||
|
||||
export interface BlogPostPreview {
|
||||
title: string
|
||||
published: string
|
||||
html: string
|
||||
css: string
|
||||
slug: string
|
||||
}
|
||||
|
||||
export const get: RequestHandler = async () => {
|
||||
const existingPosts: string[] = await fs.promises.readdir(postsDir)
|
||||
const existingPosts: string[] = await listBlogPostSlugs()
|
||||
|
||||
const posts = (
|
||||
await Promise.all(
|
||||
|
@ -26,14 +23,10 @@ export const get: RequestHandler = async () => {
|
|||
return {
|
||||
title: blogPost.title,
|
||||
published: blogPost.published,
|
||||
// cut it off after 255 characters because that's a nice number
|
||||
html: markdownToHtml(
|
||||
blogPost.body
|
||||
.slice(0, 512)
|
||||
.replace(/!\[[^\]]+?\]\([^)]+?\)/g, '')
|
||||
.replace(/\[([^\]]+?)\]\([^)]+?\)/g, '$1'),
|
||||
`/blog/${blogPost.slug}/index.md`
|
||||
),
|
||||
// HACK: remove images, i WILL parse html with regex and you won't stop me
|
||||
// TODO: cut off the html so it's not sending a bunch of unnecessary data over the network
|
||||
html: blogPost.html.replace(/<img.+?\/?>/g, ''),
|
||||
css: blogPost.css,
|
||||
slug: blogPost.slug,
|
||||
}
|
||||
})
|
||||
|
|
|
@ -64,13 +64,3 @@ Titles:
|
|||
|
||||
Image:
|
||||
!\[description](https://image)
|
||||
|
||||
<-
|
||||
**Float left**
|
||||
`<- text <-`
|
||||
<-
|
||||
|
||||
->
|
||||
**Float right**
|
||||
`-> text ->`
|
||||
->
|
|
@ -13,7 +13,7 @@ It all started on April 27th, 2020. I was bored and wanted to make a Hypixel For
|
|||
# madcausebad11
|
||||
|
||||
I didn’t do anything with this idea until a couple weeks later on May 14th, when I remembered it, and was actually motivated to create it. I asked around on the SkyBlock Community Discord for what it should be called and what it should do, and I decided on calling it madcausebad11 (name chosen by @TatorCheese), and making it say “thats crazy but I dont remember asking” (@Bliziq chose that one) to all posts that mentioned being scammed.
|
||||

|
||||

|
||||
When that had been decided, I started working on the code. It was written in Python, using BeautifulSoup to scrape the web pages and aiohttp to make the requests. After an hour of writing code, madcausebad11 was working.
|
||||
|
||||
Less than an hour after the bot started working, it got banned for the reason “spam”.
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
@ -67,7 +67,7 @@ We also found out that they had deleted their webhook, which meant we couldn't s
|
|||
|
||||
The first two quickly left, but one sent us a message before leaving.
|
||||
|
||||

|
||||

|
||||
|
||||
We asked kzh to join back again.
|
||||
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 5 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
@ -4,6 +4,7 @@ published: 2019-04-25T01:08:27.057+00:00
|
|||
---
|
||||
|
||||
Welcome to mat does dev. You might have some questions, so I'm here to answer them.
|
||||
|
||||

|
||||
|
||||
---
|
|
@ -1,11 +1,19 @@
|
|||
import staticAdapter from '@sveltejs/adapter-static'
|
||||
import preprocess from 'svelte-preprocess'
|
||||
import { mdsvex } from 'mdsvex'
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
// Consult https://github.com/sveltejs/svelte-preprocess
|
||||
// for more information about preprocessors
|
||||
preprocess: preprocess(),
|
||||
preprocess: [
|
||||
preprocess(),
|
||||
mdsvex({
|
||||
layout: './src/lib/PostLayout.svelte'
|
||||
}),
|
||||
],
|
||||
|
||||
extensions: ['.svelte', '.svx'],
|
||||
|
||||
kit: {
|
||||
adapter: staticAdapter({}),
|
||||
|
@ -25,7 +33,10 @@ const config = {
|
|||
// }
|
||||
// : {},
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
|
||||
export default config
|
||||
|
|
55
yarn.lock
|
@ -202,6 +202,11 @@
|
|||
dependencies:
|
||||
source-map "^0.6.1"
|
||||
|
||||
"@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3":
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
|
||||
integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^4.31.1":
|
||||
version "4.33.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276"
|
||||
|
@ -341,11 +346,6 @@ argparse@^1.0.7:
|
|||
dependencies:
|
||||
sprintf-js "~1.0.2"
|
||||
|
||||
argparse@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
||||
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
|
||||
|
||||
array-union@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
|
||||
|
@ -1069,13 +1069,6 @@ js-yaml@^3.13.1:
|
|||
argparse "^1.0.7"
|
||||
esprima "^4.0.0"
|
||||
|
||||
js-yaml@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
|
||||
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
|
||||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
|
||||
json-schema-traverse@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||
|
@ -1138,10 +1131,15 @@ magic-string@^0.26.2:
|
|||
dependencies:
|
||||
sourcemap-codec "^1.4.8"
|
||||
|
||||
marked@^4.0.3:
|
||||
version "4.0.13"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.13.tgz#4fd46ca93da46448f3d83f054d938c4f905a258d"
|
||||
integrity sha512-lS/ZCa4X0gsRcfWs1eoh6dLnHr9kVH3K1t2X4M/tTtNouhZ7anS1Csb6464VGLQHv8b2Tw1cLeZQs58Jav8Rzw==
|
||||
mdsvex@^0.10.6:
|
||||
version "0.10.6"
|
||||
resolved "https://registry.yarnpkg.com/mdsvex/-/mdsvex-0.10.6.tgz#5ba975f4616e5255ca31cd93d33e2c2a22845631"
|
||||
integrity sha512-aGRDY0r5jx9+OOgFdyB9Xm3EBr9OUmcrTDPWLB7a7g8VPRxzPy4MOBmcVYgz7ErhAJ7bZ/coUoj6aHio3x/2mA==
|
||||
dependencies:
|
||||
"@types/unist" "^2.0.3"
|
||||
prism-svelte "^0.4.7"
|
||||
prismjs "^1.17.1"
|
||||
vfile-message "^2.0.4"
|
||||
|
||||
merge2@^1.3.0, merge2@^1.4.1:
|
||||
version "1.4.1"
|
||||
|
@ -1304,6 +1302,16 @@ prettier@^2.4.1:
|
|||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032"
|
||||
integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==
|
||||
|
||||
prism-svelte@^0.4.7:
|
||||
version "0.4.7"
|
||||
resolved "https://registry.yarnpkg.com/prism-svelte/-/prism-svelte-0.4.7.tgz#fbc6709450b4e2ed660ddb82c3718817fc584cbe"
|
||||
integrity sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ==
|
||||
|
||||
prismjs@^1.17.1:
|
||||
version "1.28.0"
|
||||
resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.28.0.tgz#0d8f561fa0f7cf6ebca901747828b149147044b6"
|
||||
integrity sha512-8aaXdYvl1F7iC7Xm1spqSaY/OJBpYW3v+KJ+F17iYxvdc8sfjW194COK5wVhMZX45tGteiBQgdvD/nhxcRwylw==
|
||||
|
||||
progress@^2.0.0:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
|
||||
|
@ -1626,6 +1634,13 @@ uglify-js@^3.5.1:
|
|||
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.15.3.tgz#9aa82ca22419ba4c0137642ba0df800cb06e0471"
|
||||
integrity sha512-6iCVm2omGJbsu3JWac+p6kUiOpg3wFO2f8lIXjfEb8RrmLjzog1wTPMmwKB7swfzzqxj9YM+sGUM++u1qN4qJg==
|
||||
|
||||
unist-util-stringify-position@^2.0.0:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da"
|
||||
integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==
|
||||
dependencies:
|
||||
"@types/unist" "^2.0.2"
|
||||
|
||||
upper-case@^1.1.1:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598"
|
||||
|
@ -1643,6 +1658,14 @@ v8-compile-cache@^2.0.3:
|
|||
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
||||
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
|
||||
|
||||
vfile-message@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a"
|
||||
integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==
|
||||
dependencies:
|
||||
"@types/unist" "^2.0.0"
|
||||
unist-util-stringify-position "^2.0.0"
|
||||
|
||||
vite@^2.9.10:
|
||||
version "2.9.12"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-2.9.12.tgz#b1d636b0a8ac636afe9d83e3792d4895509a941b"
|
||||
|
|