From d0f4ced950965e1d7c0f4df8924ff787c064c42e Mon Sep 17 00:00:00 2001 From: matrixthecow Date: Wed, 17 Apr 2024 01:23:22 +0200 Subject: [PATCH] Changes --- .../[experiment]/info/markdown.css | 560 ++++++++++++++++++ .../(experiments)/[experiment]/info/page.tsx | 36 ++ .../app/(experiments)/donut/page.md | 48 ++ .../app/(experiments)/donut/page.module.css | 6 + .../app/(experiments)/donut/page.tsx | 53 +- .../app/(experiments)/mandelbrot/page.md | 8 + .../app/(homepage)/layout.module.css | 6 + .../app/(homepage)/page.module.css | 35 +- alexanderristinmaa/app/(homepage)/page.tsx | 36 +- alexanderristinmaa/package-lock.json | 37 ++ alexanderristinmaa/package.json | 2 + 11 files changed, 801 insertions(+), 26 deletions(-) create mode 100644 alexanderristinmaa/app/(experiments)/[experiment]/info/markdown.css create mode 100644 alexanderristinmaa/app/(experiments)/[experiment]/info/page.tsx create mode 100644 alexanderristinmaa/app/(experiments)/donut/page.md create mode 100644 alexanderristinmaa/app/(experiments)/mandelbrot/page.md diff --git a/alexanderristinmaa/app/(experiments)/[experiment]/info/markdown.css b/alexanderristinmaa/app/(experiments)/[experiment]/info/markdown.css new file mode 100644 index 0000000..3bf1a92 --- /dev/null +++ b/alexanderristinmaa/app/(experiments)/[experiment]/info/markdown.css @@ -0,0 +1,560 @@ +/* +"GitHub Flavor", a GitHub flavored CSS style sheet for Markdown documents. +Based on Chris Patuzzo's github.css (https://gist.github.com/tuzz/3331384). + + +author: Fabrizio Musacchio (https://www.fabriziomusacchio.com) +date: 03.01.2020 + + +License: + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +/*Main body*/ +body { + font-family: Helvetica, arial, sans-serif; + font-size: 14px; + line-height: 1.4em; + background-color: white; + padding-top: 10px; + padding-bottom: 10px; + padding-left: 25px; + padding-right: 25px; } + +body > *:first-child { + margin-top: 0 !important; } +body > *:last-child { + margin-bottom:0 !important; } + +/* Smooth scrolling */ +@media screen and (prefers-reduced-motion: no-preference) { + html { + scroll-behavior: smooth; + } +} + +/*Links*/ +a { + color: #3973ad; + text-decoration: none;} +a:hover{ + /* text-decoration: underline; */ + color: #4183C4; +} +a.absent { + color: #cc0000; } +a.anchor { + display: block; + padding-left: 30px; + margin-left: -30px; + cursor: pointer; + position: absolute; + top: 0; + left: 0; + bottom: 0; } + +/*Headlines*/ +h1, h2, h3, h4, h5, h6 { + margin: 20px 0 10px; + padding: 0; + line-height: 1.4em; + font-weight: bold; + -webkit-font-smoothing: antialiased; + cursor: text; + position: relative; } + +h1 tt, h1 code { + font-size: inherit; } + +h2 tt, h2 code { + font-size: inherit; } + +h3 tt, h3 code { + font-size: inherit; } + +h4 tt, h4 code { + font-size: inherit; } + +h5 tt, h5 code { + font-size: inherit; } + +h6 tt, h6 code { + font-size: inherit; } + +h1 { + font-size: 28px; + color: black; } + +h2 { + font-size: 24px; + border-bottom: 1px solid #cccccc; + color: black; } + +h3 { + font-size: 18px; } + +h4 { + font-size: 16px; } + +h5 { + font-size: 14px; } + +h6 { + color: #777777; + font-size: 14px; } + +p, blockquote, ul, ol, dl, li, table, pre { + margin: 15px 0; } + +/*Margins and paddings of the first line content*/ +body > h2:first-child { + margin-top: 0; + padding-top: 0; } +body > h1:first-child { + margin-top: 0; + padding-top: 0; } + body > h1:first-child + h2 { + margin-top: 0; + padding-top: 0; } +body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child { + margin-top: 0; + padding-top: 0; } + +a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 { + margin-top: 0; + padding-top: 0; } + +h1 p, h2 p, h3 p, h4 p, h5 p, h6 p { + margin-top: 0; +} + +/*Lists*/ +ul li,ol li{ + margin-top: .15em; + margin-bottom: .15em; +} +ul li li{ + margin-left: -15px; +} +ul ul,ul ol,ol ol,ol ul{ + margin-top: 0; + margin-bottom: 0em; +} + +/*Footnotes*/ +a[href^="#fn:"]:after{ + content: ')'; + font-size: 0.83em; + vertical-align: super; + line-height: 0; +} +/*Highlights the BG of current jumped-to footnote:*/ +li:target { + background-color: #e8fef6; +} +.footnotes > ol > li > p { + display: inline; +} +.footnotes ol { + list-style: none; + counter-reset: footnotes; + padding-left: 15px; +} +.footnotes ol li { + counter-increment:footnotes; +} +.footnotes ol li:before { + /* background-color: #e8fef6; */ + font-weight: bold; + /* counter-reset: footnotes; */ + content: counters(footnotes, ".") ")"; +} +.footnotes li { + padding-bottom: 0.45em; +} +.footnotes { + /* only use is for border, background-color of block */ + /* border: dashed 0px #f4f5f8; */ + background-color: #f4f5f8; + padding: 0em 0em 0.25em 0em; +} +/*.footnotes:before{ + content: "Footnotes"; + font-size: 1.2em; + font-weight: bold; + line-height: 2.5em; + padding-left: 0.5em; +}*/ + +/*TOC (for DEVONthink Markdown documents; for other editors, try e.g. ".toc")*/ +.TOC { + background: #f4f5f8 none repeat scroll 0 0; + border: 0px solid #aaa; + border-radius: 10px; + display: table; + font-size: 95%; + margin-bottom: 1em; + padding-left: 2px; + padding-top: 2px; + padding-bottom: 2px; + padding-right: 2px; + width: 100%; +} + +/*uncomment if you'd like to automatically add a title to your TOC:*/ +/*.TOC:before { + content: "Table of Contents"; + font-weight: bold; + font-size: 1.1em; + color: #3973ad; + padding-left: 1em; + margin-bottom: -1em; + line-height: 3em; +}*/ + +.TOC li, .TOC ul, .TOC ul li{ + list-style: decimal; +} + +.top-link { + transition: all .25s ease-in-out; + position: fixed; + bottom: 0; + right: 0; + display: inline-flex; + color: #000000; + + cursor: pointer; + align-items: center; + justify-content: center; + margin: 0 2em 2em 0; + border-radius: 50%; + padding: .25em; + width: 1em; + height: 1em; + background-color: #F8F8F8; +} + +/*Check-Boxes/To-Do-Boxes (doesn't work in DEVONthink Markdown documents)*/ +/* ul li.checkbox { + appearance: none; + background-color: #fff; + margin: 0; + font: inherit; + color: #b2b2b2; + width: 1.15em; + height: 1.15em; + border: 0.15em solid #b2b2b2; + border-radius: 0.15em; +} */ + +/* input[type="checkbox"] { + appearance: none; + background-color: #fff; + margin: 0; + font: inherit; + color: #b2b2b2; + width: 1.15em; + height: 1.15em; + border: 0.15em solid #b2b2b2; + border-radius: 0.15em; +} + +input[type="checkbox"]::before { + content: " "; + width: 0.65em; + height: 0.65em; + clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%); +} + +input[type="checkbox"]:checked::after { + content: "_"; + color: #cdef9a; + box-shadow: inset 4em 2em #cdef9a; +} + +.task-list-item { + list-style-type: none; + margin-top: 0px; + margin-bottom: 0px; +} + +.task-list-item input { + margin: 0 0.2em .25em -1.6em; + vertical-align: middle; + padding-bottom: 0px; + opacity: 1; +} */ + +/*Definition lists*/ +dl { + padding: 0; } + dl dt { + font-size: 14px; + font-weight: bold; + font-style: italic; + padding: 0; + margin: 15px 0 5px; } + dl dt:first-child { + padding: 0; } + dl dt > :first-child { + margin-top: 0; } + dl dt > :last-child { + margin-bottom: 0; } + dl dd { + margin: 0 0 15px; + padding: 0 15px; } + dl dd > :first-child { + margin-top: 0; } + dl dd > :last-child { + margin-bottom: 0; } + +/*Quotes*/ +blockquote { + border-left: 4px solid #dddddd; + padding: 0 15px; + font-style: normal; + color: #5598c1; } /* 777777 */ + blockquote > :first-child { + margin-top: 0; } + blockquote > :last-child { + margin-bottom: 0; } + +/*Tables*/ +table { + padding: 0;border-collapse: collapse; + margin-left: auto; + margin-right: auto; + text-align: center;} + table tr { + /* border-top: 1px solid #cccccc; */ + background-color: white; + margin: 0; + padding: 0; } + table tr:nth-child(2n) { + background-color: #f8f8f8; } + table tr th { + font-weight: bold; + /* border: 0.5px solid #cccccc; */ + /* border-left: 0.5px solid #cccccc; + border-right: 0.5px solid #cccccc; */ + background-color: #eefbff; + font-size: 14px; + margin: 0; + padding: 0.4em 0.35em 0.4em 0.35em; } + table tr td { + /* border: 1px solid #cccccc; */ + margin: 0; + font-size: 14px; + padding: 5px 5px; } + table tr th :first-child, table tr td :first-child { + margin-top: 0; } + table tr th :last-child, table tr td :last-child { + margin-bottom: 0; } + +/*Images*/ +img { + max-width: 100%;} +/*Alternative: center Images*/ +/* img { + display: block; + max-width: 100%; + margin-left: auto; + margin-right: auto; } +*/ + +/*Span*/ +span.frame { + display: block; + overflow: hidden; +} +span.frame > span { + border: 1px solid #dddddd; + display: block; + float: left; + overflow: hidden; + margin: 13px 0 0; + padding: 7px; + width: auto; +} +span.frame span img { + display: block; + float: left; +} +span.frame span span { + clear: both; + color: #333333; + display: block; + padding: 5px 0 0; +} +span.align-center { + display: block; + overflow: hidden; + clear: both; +} +span.align-center > span { + display: block; + overflow: hidden; + margin: 13px auto 0; + text-align: center; +} +span.align-center span img { + margin: 0 auto; + text-align: center; +} +span.align-right { + display: block; + overflow: hidden; + clear: both; +} +span.align-right > span { + display: block; + overflow: hidden; + margin: 13px 0 0; + text-align: right; +} +span.align-right span img { + margin: 0; + text-align: right; +} +span.float-left { + display: block; + margin-right: 13px; + overflow: hidden; + float: left; +} +span.float-left span { + margin: 13px 0 0; +} +span.float-right { + display: block; + margin-left: 13px; + overflow: hidden; + float: right; +} +span.float-right > span { + display: block; + overflow: hidden; + margin: 13px auto 0; + text-align: right; +} + +/*Code blocks*/ +code, tt { + margin: 0 2px; + padding: 0 5px; + white-space: nowrap; + border: 1px solid #eaeaea; + background-color: #f8f8f8; + border-radius: 3px; +} + +pre code { + margin: 0; + padding: 0; + white-space: pre; + border: none; + background: transparent; +} + +.highlight pre { + background-color: #f8f8f8; + border: 1px solid #cccccc; + font-size: 13px; + line-height: 19px; + overflow: auto; + padding: 6px 10px; + border-radius: 3px; +} + +/*Preformatted text*/ +pre { + background-color: #f8f8f8; + border: 1px solid #cccccc; + /*font-size: 13px;*/ + font-size: 0.90em !important; + line-height: 1.6em !important; + overflow: auto; + padding: 6px 10px; + border-radius: 3px; +} +pre code, pre tt { + background-color: transparent; + border: none; +} + +/*Superscript text*/ +sup { + font-size: 0.83em; + vertical-align: super; + line-height: 0; +} + +/*Subscript text*/ +sub { + font-size: 0.83em; + vertical-align: sub; + line-height: 0; +} + +/*Define keyboard input*/ +kbd { + display: inline-block; + padding: 3px 5px; + font-size: 11px; + line-height: 10px; + color: #555; + vertical-align: middle; + background-color: #fcfcfc; + border: solid 1px #ccc; + border-bottom-color:#bbb; + border-radius: 3px; + box-shadow: inset 0 -1px 0 #bbb +} + +/*Color of highlighted text*/ +mark { + background-color: #fdfdcc; + color: black; +} + +/*Adjustments for printing*/ +* { + -webkit-print-color-adjust: exact; +} +@media screen and (min-width: 914px) { + body { + width: 854px; + margin: 0 auto; + } +} +@media print { + table, pre { + page-break-inside: avoid; + } + pre { + word-wrap: break-word; + } + body { + padding: 2cm; + } +} \ No newline at end of file diff --git a/alexanderristinmaa/app/(experiments)/[experiment]/info/page.tsx b/alexanderristinmaa/app/(experiments)/[experiment]/info/page.tsx new file mode 100644 index 0000000..c8450b8 --- /dev/null +++ b/alexanderristinmaa/app/(experiments)/[experiment]/info/page.tsx @@ -0,0 +1,36 @@ +// styles +import './markdown.css'; + +// other +import * as fs from 'fs'; +import {marked} from 'marked'; +import parseMD from 'parse-md'; + +marked.use({ + gfm: true +}) + +export function generateStaticParams() { + const experiments = + fs.readdirSync('./app/(experiments)', {withFileTypes: true}) + .filter(pathname => pathname.isDirectory() && fs.existsSync(`./app/(experiments)/${pathname.name}/page.md`)) + .map(foldername => ({experiment: foldername.name})); + + // Should return a list of objects with the parameter experiment (because the dynamic path is [experiment]) + // with the value of the path [experiment]/info where experiment is the different paths + // ex return [{experiment: 'donut/info'}] + return experiments; + } + +// Multiple versions of this page will be statically generated +// using the `params` returned by `generateStaticParams` +export default async function Page({ params } : { params: { experiment: string } }) { + const { experiment } = params; + const markdownString = fs.readFileSync(`./app/(experiments)/${experiment}/page.md`, 'utf8'); + const htmlFromMarkdown = await marked.parse(parseMD(markdownString).content); + + return ( +
+
+ ) + } \ No newline at end of file diff --git a/alexanderristinmaa/app/(experiments)/donut/page.md b/alexanderristinmaa/app/(experiments)/donut/page.md new file mode 100644 index 0000000..5ecd492 --- /dev/null +++ b/alexanderristinmaa/app/(experiments)/donut/page.md @@ -0,0 +1,48 @@ +--- +name: The (3D) Donut +description: A little spinning 3d donut made with three.js +tags: + - three.js + - 3d +--- +# THE (3D) DONUT + +This amazing viewer-experience shows a (SPINNING) model of a 3D donut using three.js with some encouraging music. + +## How does it work? +Using three.js and a 3d object stored in a .gltf file it is no problem loading and displaying it. + +The setup is **identical** to the [three.js startup docs](https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene). +```typescript +const scene = new THREE.Scene(); +const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); +const renderer = new THREE.WebGLRenderer(); +``` + +*then* adding the **donut** to the scene using the builtin GLTFLoader. +```typescript +const loader = new GLTFLoader(); +const donut = ... => loader.load('/donuts.gltf', ...); +scene.add(donut.scene); +``` + +Animating the donut is as simple as creating a function which calls `renderer.render(scene, camera)` and then requests an animation frame for itself. In between these, update the donut's rotation. +```typescript +const renderScene = () => { + requestAnimationFrame(renderScene); + + donut.scene.rotation.x += 0.01; + donut.scene.rotation.y += 0.01; + + renderer.render(scene, camera); +}; + +renderScene(); +``` + + +# Credit +This work is based on "DONUTS" (https://sketchfab.com/3d-models/donuts-1710b0f3f44d429ea7b41114f3ce0a09) by jun_sketchsoft (https://sketchfab.com/jun_sketchsoft) licensed under CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/) + +Music by Bensound.com +License code: RZYLPS60JH8KEXM5 \ No newline at end of file diff --git a/alexanderristinmaa/app/(experiments)/donut/page.module.css b/alexanderristinmaa/app/(experiments)/donut/page.module.css index 333b1ff..9c6bb1b 100644 --- a/alexanderristinmaa/app/(experiments)/donut/page.module.css +++ b/alexanderristinmaa/app/(experiments)/donut/page.module.css @@ -12,4 +12,10 @@ transform: translateX(-50%); color: white; font-size: 30px; +} + +#enableAudio { + top: 10px; + left: 10px; + color: white; } \ No newline at end of file diff --git a/alexanderristinmaa/app/(experiments)/donut/page.tsx b/alexanderristinmaa/app/(experiments)/donut/page.tsx index 441dcbd..42495ab 100644 --- a/alexanderristinmaa/app/(experiments)/donut/page.tsx +++ b/alexanderristinmaa/app/(experiments)/donut/page.tsx @@ -1,6 +1,6 @@ 'use client' -import { useEffect, useRef } from 'react'; +import { createRef, useEffect, useRef, useState } from 'react'; // style import styles from './page.module.css'; @@ -12,10 +12,34 @@ import { GLTF, GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; export default function Home() { const containerRef = useRef(null); + const audioRef = createRef(); + let [hasPlayed, setHasPlayed] = useState(false); useEffect(() => { + const handleResize = () => { + const width = window.innerWidth; + const height = window.innerHeight; + + camera.aspect = width / height; + camera.updateProjectionMatrix(); + + renderer.setSize(width, height); + }; + + window.addEventListener('resize', handleResize); + + const handleFirstPlay = (event : any) => { + setHasPlayed(true); + event.target.removeEventListener('timeupdate', handleFirstPlay); + } + + audioRef.current?.addEventListener('timeupdate', handleFirstPlay); + + // THREEJS BUSINESS + // LOAD AND RENDER DONUT + const scene = new THREE.Scene(); - const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 10000); + const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); @@ -26,52 +50,43 @@ export default function Home() { const loader = new GLTFLoader(); (async () => { - let donut = await new Promise((resolve, reject) => loader.load('/donuts.gltf', data => resolve(data), undefined, reject)) as GLTF; + const donut = await new Promise((resolve, reject) => loader.load('/donuts.gltf', data => resolve(data), undefined, reject)) as GLTF; scene.add(donut.scene); // Render the scene and camera // Add this function inside the useEffect hook const renderScene = () => { + requestAnimationFrame(renderScene); + donut.scene.rotation.x += 0.01; donut.scene.rotation.y += 0.01; renderer.render(scene, camera); - requestAnimationFrame(renderScene); }; // Call the renderScene function to start the animation loop renderScene(); })(); - - - const handleResize = () => { - const width = window.innerWidth; - const height = window.innerHeight; - - camera.aspect = width / height; - camera.updateProjectionMatrix(); - - renderer.setSize(width, height); - }; - - window.addEventListener('resize', handleResize); return () => { // Cleanup of the renderer element // Cleanup of the window element // Good article here: https://react.dev/learn/synchronizing-with-effects#step-3-add-cleanup-if-needed + renderer.domElement.remove(); window.removeEventListener('resize', handleResize); + audioRef.current?.removeEventListener('timeupdate', handleFirstPlay); } }, []); + return (
+ {hasPlayed ? '' : Please enable audio and refresh the page.} THE DONUT
-
diff --git a/alexanderristinmaa/app/(experiments)/mandelbrot/page.md b/alexanderristinmaa/app/(experiments)/mandelbrot/page.md new file mode 100644 index 0000000..642d938 --- /dev/null +++ b/alexanderristinmaa/app/(experiments)/mandelbrot/page.md @@ -0,0 +1,8 @@ +--- +name: Mandelbrot in WASM! +description: The beautiful mandelbrot fractal computed and rendered with compiled WebAssembly! +tags: + - WebAssembly + - Fractals +--- +# Mandelbrot with Webassembly \ No newline at end of file diff --git a/alexanderristinmaa/app/(homepage)/layout.module.css b/alexanderristinmaa/app/(homepage)/layout.module.css index 8ae58df..cd0d738 100644 --- a/alexanderristinmaa/app/(homepage)/layout.module.css +++ b/alexanderristinmaa/app/(homepage)/layout.module.css @@ -57,4 +57,10 @@ justify-content: center; text-align: center; white-space: pre-line; +} + +@media screen and (max-width: 900px) { + #main { + padding: 20px 40px; + } } \ No newline at end of file diff --git a/alexanderristinmaa/app/(homepage)/page.module.css b/alexanderristinmaa/app/(homepage)/page.module.css index a43708f..65df288 100644 --- a/alexanderristinmaa/app/(homepage)/page.module.css +++ b/alexanderristinmaa/app/(homepage)/page.module.css @@ -1,9 +1,13 @@ -#imgDiv { - width: 50%; - float: right; +#contentDiv { + display: flex; + gap: 20px; +} + +#contentDiv > div { + flex: 1; } -#imgDiv > p{ +#imgDiv > p { margin-top: 8px; float: right; } @@ -11,4 +15,27 @@ #img { width: 100%; border: 2px solid var(--black); +} + +#experimentsTitle { + font-size: 1.05em; + margin-bottom: 10px; +} + +#experimentsList { + list-style: none; +} + +#experimentsList > * > li { + margin-bottom: 10px; +} + +.experimentTitle { + margin-bottom: 4px; +} + +@media screen and (max-width: 900px) { + #contentDiv { + flex-direction: column; + } } \ No newline at end of file diff --git a/alexanderristinmaa/app/(homepage)/page.tsx b/alexanderristinmaa/app/(homepage)/page.tsx index 463195c..2aa5ada 100644 --- a/alexanderristinmaa/app/(homepage)/page.tsx +++ b/alexanderristinmaa/app/(homepage)/page.tsx @@ -1,16 +1,46 @@ // nextjs import Link from 'next/link' +import { metadata } from './layout'; // style import styles from './page.module.css'; +// other +import * as fs from 'fs'; +import parseMD from 'parse-md'; + export default function Home() { + let getExperiments = () => { + return fs.readdirSync('./app/(experiments)', {withFileTypes: true}) + .filter(v => v.isDirectory() && fs.existsSync(`./app/(experiments)/${v.name}/page.md`)) + .map(v => ({data: fs.readFileSync(`./app/(experiments)/${v.name}/page.md`, 'utf8'), experiment: v.name})) + .map(v => ({metadata: parseMD(v.data).metadata as any, experiment: v.experiment})); + } + + return ( -
-

Om du vågar kolla runt kan du säkert hitta vad du letar efter.

+
+
+

Om du vågar kolla runt kan du säkert hitta vad du letar efter.


+

Mina senaste experiment:

+
    + { + getExperiments().map((v) => { + return ( + +
  • +

    {v.metadata.name}

    +

    {v.metadata.description}

    +
  • + + ) + }) + } +
+
Cool img -

Kebnekaise toppstuga och en räddningshelikopter

+

Kebnekaise toppstuga och en räddningshelikopter

diff --git a/alexanderristinmaa/package-lock.json b/alexanderristinmaa/package-lock.json index 7a5d214..a8ca28e 100644 --- a/alexanderristinmaa/package-lock.json +++ b/alexanderristinmaa/package-lock.json @@ -8,7 +8,9 @@ "name": "alexanderristinmaa", "version": "0.1.0", "dependencies": { + "marked": "^12.0.1", "next": "14.1.4", + "parse-md": "^3.0.3", "react": "^18", "react-dom": "^18" }, @@ -234,6 +236,11 @@ "integrity": "sha512-nC9116Gd4N+CqTxqo6gvCfhAMAzgRcfS8ZsciNodHq8uwW4JCVKwhagw8yN0XmC7mHrLnWqniJpoVEiR+72Drw==", "dev": true }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -291,6 +298,17 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -302,6 +320,17 @@ "loose-envify": "cli.js" } }, + "node_modules/marked": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/marked/-/marked-12.0.1.tgz", + "integrity": "sha512-Y1/V2yafOcOdWQCX0XpAKXzDakPOpn6U0YLxTJs3cww6VxOzZV1BTOOYWLvH3gX38cq+iLwljHHTnMtlDfg01Q==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/meshoptimizer": { "version": "0.18.1", "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.18.1.tgz", @@ -370,6 +399,14 @@ } } }, + "node_modules/parse-md": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/parse-md/-/parse-md-3.0.3.tgz", + "integrity": "sha512-2kpNrrW1GBgli5VT9X9/Y6n4PVsIFVdG49tguq1PHwzsRSK0Cu0yJPTUFOwWouFT85atYNWQ1T/rmqfj7kLd8g==", + "dependencies": { + "js-yaml": "^4.1.0" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", diff --git a/alexanderristinmaa/package.json b/alexanderristinmaa/package.json index fa350a3..81f5768 100644 --- a/alexanderristinmaa/package.json +++ b/alexanderristinmaa/package.json @@ -9,7 +9,9 @@ "lint": "next lint" }, "dependencies": { + "marked": "^12.0.1", "next": "14.1.4", + "parse-md": "^3.0.3", "react": "^18", "react-dom": "^18" },