diff --git a/docs/general/Architecture/ErrorHandling.md b/docs/general/Architecture/ErrorHandling.md
index 21ce718c22ea19900154bb141e2e06ac0707c629..b23265bef0991347859ce17f0bb28ffc507cf66f 100644
--- a/docs/general/Architecture/ErrorHandling.md
+++ b/docs/general/Architecture/ErrorHandling.md
@@ -14,7 +14,7 @@ If an error occurs somewhere outside of thunks, use the showToast function direc
 ![][image2]  
 **Example:** Thunk error middleware
 
-##### References
+## References
 
 - [https://redux.js.org/usage/writing-logic-thunks](https://redux.js.org/usage/writing-logic-thunks)
 - [https://redux-toolkit.js.org/api/createAsyncThunk](https://redux-toolkit.js.org/api/createAsyncThunk)
diff --git a/docs/general/Architecture/MapMiddleware.md b/docs/general/Architecture/MapMiddleware.md
index 78a6866c269b8d242fcb069f0fb44d8b009be0d5..f347e5928d776dd5debc43033874600f4091cb67 100644
--- a/docs/general/Architecture/MapMiddleware.md
+++ b/docs/general/Architecture/MapMiddleware.md
@@ -13,14 +13,14 @@
 
 The job of the middleware is to parse the new state of the map in Redux into data, which then goes back into Redux. This is due to the fact that every time the map changes, its current parameters change. Hence, for the sake of data integrity, we have created middleware that handles this situation.
 
-##### Example
+## Example
 
 When we open an already opened map (setActiveMap), the system determines a new background id, a new position of the user on the map (so that it returns to the position at which it was last on this map), a new model id, and then performs the action of changing the position and data.
 
-##### Middleware file path
+## Middleware file path
 
 [src/redux/map/middleware/map.middleware.ts](https://gitlab.lcsb.uni.lu/minerva/frontend/-/tree/development/src/redux/map/middleware/map.middleware.ts)
 
-##### References
+## References
 
 - [https://redux-toolkit.js.org/api/createListenerMiddleware](https://redux-toolkit.js.org/api/createListenerMiddleware)
diff --git a/docs/general/Architecture/OpenLayersImplementation.md b/docs/general/Architecture/OpenLayersImplementation.md
index 757a6dfb3ef9fae7653b456eaad5b05cf4d9e9e7..00348b67528dfee238d300331309ba71d97a6ad2 100644
--- a/docs/general/Architecture/OpenLayersImplementation.md
+++ b/docs/general/Architecture/OpenLayersImplementation.md
@@ -8,7 +8,7 @@ The core part of the application is the map, its rendering, browsing and display
 
 The structure of the OL implementation is divided into two main elements: config and listeners. The config contains functions that handle the layers displayed on the map (pins, surfaces, markers, overlays), while the listeners contain functions that listen for various changes on the map (user clicks, position moves and other actions).
 
-##### References
+## References
 
 - [https://react.dev/reference/react/hooks](https://react.dev/reference/react/hooks)
 - [https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html](https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html)
diff --git a/docs/general/Architecture/Services.md b/docs/general/Architecture/Services.md
index d5c98fce59f4ab0760fe1734af678fc120139b63..9e3036c6603871d3c717bd8dabb849e76706d727 100644
--- a/docs/general/Architecture/Services.md
+++ b/docs/general/Architecture/Services.md
@@ -11,6 +11,6 @@ The application includes three services: two Axios-based and one internal. Axios
 3. PluginsManager Service:
    - It is an internal service that handles the communication between the application-plugin
 
-##### References
+## References
 
 - [https://github.com/axios/axios](https://github.com/axios/axios)
diff --git a/docs/general/Architecture/UnitTests.md b/docs/general/Architecture/UnitTests.md
index 47abc2aac180ad4650241164e51e170171152f3b..ef0d9caf66e8ac087f7ca7a7862115e891e7ae2d 100644
--- a/docs/general/Architecture/UnitTests.md
+++ b/docs/general/Architecture/UnitTests.md
@@ -8,13 +8,13 @@ Test coverage in the application is between 90-95%. This is due to the fact that
 
 ![][image1]
 
-##### Example
+## Example
 
 - Testing the hook function with renderHook (React Testing Library)
 - BDD approach: When something, then something
 - An internal util was used to enable mocking of the Redux store. This is important because the hook tested here uses Redux data with the help of selectors
 
-##### References
+## References
 
 - [https://katalon.com/resources-center/blog/bdd-testing](https://katalon.com/resources-center/blog/bdd-testing)
 - [https://jestjs.io/](https://jestjs.io/)
diff --git a/docs/general/Architecture/Zod.md b/docs/general/Architecture/Zod.md
index 84271b2da121a630ee0b9815d7662cc7ab1932ee..79afffe073343eb0bba9553c9dc650da61d838ce 100644
--- a/docs/general/Architecture/Zod.md
+++ b/docs/general/Architecture/Zod.md
@@ -10,7 +10,7 @@ We use the models in two ways, firstly to convert them into the form of interfac
 ![][image2]  
 Secondly, we use it in thunks, where we parse the incoming data from the backend and compare it with the structure in the model. When the incoming object from the backend differs from the model, it is discarded and an error is thrown. This protects the application from misbehaving when the backend behaves unexpectedly.
 
-##### References
+## References
 
 - [https://github.com/colinhacks/zod](https://github.com/colinhacks/zod)
 - [https://www.typescriptlang.org/](https://www.typescriptlang.org/)
diff --git a/docs/general/CoverPage.md b/docs/general/CoverPage.md
new file mode 100644
index 0000000000000000000000000000000000000000..d8b6ec75990463eb13e7b80905c5138ac8c5e54a
--- /dev/null
+++ b/docs/general/CoverPage.md
@@ -0,0 +1,5 @@
+# Minerva
+
+## General Documentation
+
+### AppUnite + AT Computers / March 2025
diff --git a/docs/general/General_Documentation_Minerva.pdf b/docs/general/General_Documentation_Minerva.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..458258a3fce6da04a93d15886ef24f58b1f5224d
Binary files /dev/null and b/docs/general/General_Documentation_Minerva.pdf differ
diff --git a/docs/general/generatePdf.mjs b/docs/general/generatePdf.mjs
new file mode 100644
index 0000000000000000000000000000000000000000..a456529640c84758de8984f4a7729ae84d6d5b0d
--- /dev/null
+++ b/docs/general/generatePdf.mjs
@@ -0,0 +1,337 @@
+/* eslint-disable no-magic-numbers */
+/* eslint-disable no-console */
+
+import fs from 'fs-extra';
+import path from 'path';
+import { marked } from 'marked';
+import puppeteer from 'puppeteer';
+import Prism from 'prismjs';
+import { PDFDocument } from 'pdf-lib';
+
+const dir = './docs/general';
+const markdownFiles = [
+  `${dir}/CoverPage.md`,
+  `${dir}/BaseGuide.md`,
+  `${dir}/Architecture/CI_CD.md`,
+  `${dir}/Architecture/CodeStandard.md`,
+  `${dir}/Modules/Modules.md`,
+  `${dir}/MapRendering/MapRendering.md`,
+  `${dir}/StateManagement/StateManagement.md`,
+  `${dir}/Architecture/DynamicEnvironmentVariables-Config.js.md`,
+  `${dir}/Architecture/ErrorHandling.md`,
+  `${dir}/Architecture/MapMiddleware.md`,
+  `${dir}/Architecture/OpenLayersImplementation.md`,
+  `${dir}/Architecture/Services.md`,
+  `${dir}/Architecture/SharedComponents.md`,
+  `${dir}/Architecture/UnitTests.md`,
+  `${dir}/Architecture/Zod.md`,
+];
+
+const outputDir = dir;
+const outputCoverHtml = path.join(outputDir, 'outputCover.html');
+const outputContentHtml = path.join(outputDir, 'outputContent.html');
+const coverPdfPath = path.join(outputDir, 'cover.pdf');
+const contentPdfPath = path.join(outputDir, 'content.pdf');
+const finalPdfPath = path.join(outputDir, 'General_Documentation_Minerva.pdf');
+
+marked.setOptions({
+  highlight: (code, lang) => {
+    const validLang = Prism.languages[lang] ? lang : 'javascript';
+    return Prism.highlight(code, Prism.languages[validLang], validLang);
+  },
+});
+
+async function convertImagesToBase64(originalHtmlContent, mdFilePath) {
+  const imageRegex = /<img[^>]+src="([^">]+)"/g;
+  const matches = [...originalHtmlContent.matchAll(imageRegex)];
+
+  const replacements = await Promise.all(
+    matches.map(async match => {
+      const imgPath = match[1];
+      if (imgPath.startsWith('http') || imgPath.startsWith('data:')) {
+        return null;
+      }
+
+      const mdFileDir = path.dirname(mdFilePath);
+      const absolutePath = path.resolve(mdFileDir, imgPath);
+
+      if (!fs.existsSync(absolutePath)) {
+        console.warn(`⚠️ Image does not exist: ${absolutePath}`);
+        return null;
+      }
+
+      const imageBuffer = await fs.readFile(absolutePath);
+      const base64Image = `data:image/png;base64,${imageBuffer.toString('base64')}`;
+      return { oldPath: imgPath, newPath: base64Image };
+    }),
+  );
+
+  let newHtmlContent = originalHtmlContent;
+  replacements.forEach(rep => {
+    if (rep && rep.oldPath && rep.newPath) {
+      newHtmlContent = newHtmlContent.replace(rep.oldPath, rep.newPath);
+    }
+  });
+
+  return newHtmlContent;
+}
+
+async function getMarkdownHtml(filePath, index) {
+  if (!fs.existsSync(filePath)) {
+    console.warn(`⚠️ File does not exist: ${filePath}`);
+    return { index, title: '', html: '' };
+  }
+  const content = await fs.readFile(filePath, 'utf8');
+  const title = path.basename(filePath, '.md');
+  const rawHtml = marked(content);
+  const finalHtml = await convertImagesToBase64(rawHtml, filePath);
+  return { index, title, html: finalHtml };
+}
+
+async function mergeMarkdownToHtml(files) {
+  const results = await Promise.all(files.map((file, index) => getMarkdownHtml(file, index)));
+  const [coverItem, ...restItems] = results;
+  const coverPageHtml = coverItem ? coverItem.html : '';
+
+  let contentHtml = '';
+  restItems.forEach(item => {
+    contentHtml += `<div class="page-break"></div>${item.html}`;
+  });
+
+  const fullContentHtml = `
+  <html lang="en">
+  <head>
+    <meta charset="UTF-8">
+    <title>Minerva General Documentation</title>
+    <style>
+      body {
+        font-family: Arial, sans-serif;
+        font-size: 11pt;
+        line-height: 1.6;
+      }
+      a {
+        text-decoration: none;
+      }
+      @page {
+        size: A4;
+      }
+      @page {
+        @bottom-right {
+          content: counter(page);
+        }
+      }
+      .page-break {
+        page-break-before: always;
+      }
+      pre {
+        background: #f3f3f3;
+      }
+      pre code {
+        width: 100%;
+        white-space: pre-wrap;
+        font-size: 8pt;
+      }
+      img {
+        max-width: 100%;
+        height: auto;
+        display: block;
+        margin: auto;
+        page-break-inside: avoid;
+      }
+      .toc {
+        margin-bottom: 20px;
+      }
+      .toc h1 {
+        font-size: 1.2em;
+        margin-bottom: 10px;
+      }
+      .toc-list, .toc-sublist {
+        list-style: none;
+        margin: 0;
+        padding: 0;
+      }
+      .toc-sublist {
+        margin-left: 20px;
+      }
+      .toc-list li {
+        margin-bottom: 4px;
+      }
+    </style>
+  </head>
+  <body>
+    <!-- TOC_PLACEHOLDER -->
+    ${contentHtml}
+    <script>
+      document.addEventListener("DOMContentLoaded", function () {
+        Prism.highlightAll();
+      });
+    </script>
+  </body>
+  </html>`;
+
+  const fullCoverHtml = `
+  <html lang="en">
+  <head>
+    <meta charset="UTF-8">
+    <title>Minerva General Documentation - Cover</title>
+    <style>
+      body {
+        font-family: Arial, sans-serif;
+        font-size: 11pt;
+        line-height: 1.6;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        height: 100vh;
+        text-align: center;
+      }
+    </style>
+  </head>
+  <body>
+    ${coverPageHtml}
+    <script>
+      document.addEventListener("DOMContentLoaded", function () {
+        Prism.highlightAll();
+      });
+    </script>
+  </body>
+  </html>`;
+
+  return { cover: fullCoverHtml, content: fullContentHtml };
+}
+
+function slugify(text) {
+  return text
+    .toLowerCase()
+    .replace(/[^\w]+/g, '-')
+    .replace(/^-+|-+$/g, '');
+}
+
+function buildTOC(headings) {
+  if (!headings.length) return '';
+  let toc =
+    '<nav class="toc"><h1 style="font-size: 30px">Table of Contents</h1><ul class="toc-list">';
+  let inSublist = false;
+
+  headings.forEach(heading => {
+    if (heading.level === 1) {
+      if (inSublist) {
+        toc += '</ul>';
+        inSublist = false;
+      }
+      toc += `<li><strong>${heading.text}</strong></li>`;
+    } else if (heading.level === 2) {
+      if (!inSublist) {
+        toc += '<ul class="toc-sublist">';
+        inSublist = true;
+      }
+      toc += `<li><strong>${heading.text}</strong></li>`;
+    }
+  });
+
+  if (inSublist) {
+    toc += '</ul>';
+  }
+  toc += '</ul></nav>';
+  return toc;
+}
+
+function injectHeadingsAndTOC(html) {
+  const headingRegex = /<h([12])\b[^>]*>(.*?)<\/h\1>/g;
+  const headings = [];
+  const newHtml = html.replace(headingRegex, (fullMatch, levelStr, headingText) => {
+    const level = parseInt(levelStr, 10);
+    const id = slugify(headingText);
+    headings.push({ level, text: headingText, id });
+    return `<h${level} id="${id}">${headingText}</h${level}>`;
+  });
+  const tocHtml = buildTOC(headings);
+  return newHtml.replace(/<!--\s*TOC_PLACEHOLDER\s*-->/, tocHtml);
+}
+
+async function saveHtmlToFile(html, outputPath) {
+  await fs.writeFile(outputPath, html);
+}
+
+async function convertHtmlToPdf(htmlPath, pdfPath, options = {}) {
+  const browser = await puppeteer.launch();
+  const page = await browser.newPage();
+  await page.emulateMediaType('print');
+  await page.goto(`file://${path.resolve(htmlPath)}`, { waitUntil: 'networkidle0' });
+  const pdfOptions = {
+    path: pdfPath,
+    format: 'A4',
+    printBackground: true,
+    scale: 1,
+    margin: { top: '20mm', right: '20mm', bottom: '20mm', left: '20mm' },
+    ...options,
+  };
+  await page.pdf(pdfOptions);
+  await browser.close();
+}
+
+async function mergePdfs(coverPath, contentPath, mergedPath) {
+  const coverPdfBytes = await fs.readFile(coverPath);
+  const contentPdfBytes = await fs.readFile(contentPath);
+  const mergedPdf = await PDFDocument.create();
+  const coverPdfDoc = await PDFDocument.load(coverPdfBytes);
+  const contentPdfDoc = await PDFDocument.load(contentPdfBytes);
+  const coverPages = await mergedPdf.copyPages(coverPdfDoc, coverPdfDoc.getPageIndices());
+  coverPages.forEach(page => mergedPdf.addPage(page));
+  const contentPages = await mergedPdf.copyPages(contentPdfDoc, contentPdfDoc.getPageIndices());
+  contentPages.forEach(page => mergedPdf.addPage(page));
+  const mergedPdfBytes = await mergedPdf.save();
+  await fs.writeFile(mergedPath, mergedPdfBytes);
+}
+
+async function cleanupOutputFiles() {
+  const filesToDelete = [outputCoverHtml, outputContentHtml, coverPdfPath, contentPdfPath];
+
+  const removalPromises = filesToDelete.map(file =>
+    fs.pathExists(file).then(exists => {
+      if (exists) {
+        return fs.remove(file);
+      }
+      return false;
+    }),
+  );
+
+  await Promise.all(removalPromises);
+  console.log('Cleaning completed.');
+}
+
+(async function main() {
+  try {
+    console.log('📂 Downloading Markdown files...');
+    console.log('🔄 Markdown → HTML conversion...');
+    const { cover, content } = await mergeMarkdownToHtml(markdownFiles);
+    const finalContentHtml = injectHeadingsAndTOC(content);
+    await saveHtmlToFile(cover, outputCoverHtml);
+    await saveHtmlToFile(finalContentHtml, outputContentHtml);
+
+    console.log('📄 Generate PDF for cover page...');
+    await convertHtmlToPdf(outputCoverHtml, coverPdfPath, { displayHeaderFooter: false });
+    console.log('📄 Generate a PDF for the rest of the document...');
+    await convertHtmlToPdf(outputContentHtml, contentPdfPath, {
+      displayHeaderFooter: true,
+      headerTemplate: `
+        <div style="width: 100%; text-align: left; font-size: 7pt; padding-left: 15mm; color: #d1d1d1">
+          <span>Minerva General Documentation</span>
+        </div>
+      `,
+      footerTemplate: `
+        <div style="width: 100%; text-align: left; font-size: 11px; padding-left: 15mm;">
+          <span class="pageNumber"></span>
+        </div>
+      `,
+    });
+
+    console.log('🔀 PDF merging...');
+    await mergePdfs(coverPdfPath, contentPdfPath, finalPdfPath);
+    console.log(`✅ PDF file generated: ${finalPdfPath}`);
+    await cleanupOutputFiles();
+  } catch (err) {
+    console.error('❌ Error:', err);
+  }
+})();
diff --git a/docs/general/to_pdf.ts b/docs/general/to_pdf.ts
deleted file mode 100644
index d68b7937217315666d4550031405b2ad330b18a7..0000000000000000000000000000000000000000
--- a/docs/general/to_pdf.ts
+++ /dev/null
@@ -1,282 +0,0 @@
-/* eslint-disable no-magic-numbers */
-// import fs from 'fs-extra';
-// import path from 'path';
-// import { marked } from 'marked';
-// import puppeteer from 'puppeteer';
-
-import type { Token } from 'marked';
-
-const fs = require('fs-extra');
-const path = require('path');
-const { marked } = require('marked');
-const puppeteer = require('puppeteer');
-
-// const getMarked = async () => {
-//   const { marked } = await import('marked');
-//   return marked;
-// };
-//
-// (async () => {
-//   const marked = await getMarked();
-//   console.log(marked('# Nagłówek'));
-// })();
-
-// 🔹 Ręczne podanie plików .md (możesz dodać więcej)
-const dir = './docs/general';
-const markdownFiles: string[] = [
-  `${dir}/BaseGuide.md`,
-  `${dir}/Architecture/CI_CD.md`,
-  `${dir}/Modules/Modules.md`,
-  // './Architecture/CodeStandard.md',
-];
-
-const outputHtml: string = 'docs/general/output.html';
-const outputPdf: string = 'docs/general/output.pdf';
-
-// 🔹 Funkcja łącząca pliki Markdown w HTML
-// const mergeMarkdownToHtml = async (files: string[]): Promise<string> => {
-//   let htmlContent = `
-//   <html>
-//   <head>
-//     <meta charset="UTF-8">
-//     <title>Dokument PDF</title>
-//     <style>
-//       body {
-//         font-family: Arial, sans-serif;
-//         font-size: 15pt;
-//       }
-//       h1, h2:not(:first-of-type) {
-//         page-break-before: always; /* 🔹 Każdy nagłówek zaczyna nową stronę */
-//       }
-//       a { color: blue; text-decoration: none; }
-//
-//       /* 🔹 Ustawienie marginesów */
-//       @page {
-//         size: A4;
-//       }
-//
-//       /* 🔹 Stylowanie stopki i numerów stron */
-//       @page {
-//         @bottom-right {
-//           content: counter(page);
-//         }
-//       }
-//
-//       /* 🔹 Każdy nowy plik zaczyna się od nowej strony */
-//       .page-break {
-//         page-break-before: always;
-//       }
-//     </style>
-//   </head>
-//   <body>
-//     <h1>Spis Treści</h1>
-//     <ul>
-//   `;
-//
-//   let mergedContent = '';
-//
-//   for (const file of files) {
-//     if (!fs.existsSync(file)) {
-//       console.warn(`⚠️ Plik nie istnieje: ${file}`);
-//       continue;
-//     }
-//
-//     const content = await fs.readFile(file, 'utf8');
-//     const title = path.basename(file, '.md');
-//
-//     // 🔹 Dodanie linku do spisu treści
-//     htmlContent += `<li><a href="#${title}">${title}</a></li>`;
-//
-//     // 🔹 Nowa strona przed każdym rozdziałem
-//     mergedContent += `<div class="page-break"></div>`;
-//
-//     // 🔹 Konwersja Markdown na HTML
-//     mergedContent += marked(content);
-//   }
-//
-//   htmlContent += `</ul>${mergedContent}</body></html>`;
-//   return htmlContent;
-// };
-
-const mergeMarkdownToHtml = async (files: string[]): Promise<string> => {
-  let tableOfContents = `<h1>Table of Contents</h1><ul>`;
-  let contentHtml = '';
-
-  for (const file of files) {
-    if (!fs.existsSync(file)) {
-      console.warn(`⚠️ Plik nie istnieje: ${file}`);
-      continue;
-    }
-
-    const content = await fs.readFile(file, 'utf8');
-    const tokens = marked.lexer(content); // Parsujemy Markdown na tokeny
-
-    let fileHtml = '';
-    tokens.forEach((token: Token) => {
-      if (token.type === 'heading' && (token.depth === 1 || token.depth === 2)) {
-        const id = token.text.toLowerCase().replace(/\s+/g, '-'); // Tworzymy ID na podstawie tytułu
-        fileHtml += `<h${token.depth} id="${id}" class="page-break">${token.text}</h${token.depth}>`;
-
-        // 🔹 Dodajemy wpis do spisu treści z numerem strony
-        if (token.depth === 1) {
-          tableOfContents += `<li><strong><a href="#${id}">${token.text} <span class="toc-page-number"></span></a></strong></li>`;
-        } else {
-          tableOfContents += `<li style="margin-left: 20px;"><a href="#${id}">${token.text} <span class="toc-page-number"></span></a></li>`;
-        }
-      } else {
-        fileHtml += marked.parser([token]); // Normalna konwersja Markdown do HTML
-      }
-    });
-
-    contentHtml += fileHtml;
-  }
-
-  tableOfContents += '</ul>';
-
-  return `
-  <html>
-  <head>
-    <meta charset="UTF-8">
-    <title>Dokument PDF</title>
-    <style>
-      body {
-        font-family: Arial, sans-serif;
-        font-size: 15pt;
-        line-height: 1.6;
-      }
-
-      h1, h2:not(:first-of-type) {
-        page-break-before: always; /* 🔹 Każdy nagłówek zaczyna nową stronę */
-      }
-
-      a {
-        color: blue;
-        text-decoration: none;
-      }
-
-      /* 🔹 Ustawienie marginesów */
-      @page {
-        size: A4;
-      }
-
-      /* 🔹 Stylowanie stopki i numerów stron */
-      @page {
-        @bottom-right {
-          content: counter(page);
-        }
-      }
-
-      /* 🔹 Formatowanie TOC */
-      .toc-page-number::after {
-        content: " ..... " attr(data-page);
-        float: right;
-      }
-
-      /* 🔹 Każdy nowy plik zaczyna się od nowej strony */
-      .page-break {
-        page-break-before: always;
-      }
-    </style>
-  </head>
-  <body>
-    ${tableOfContents}
-    ${contentHtml}
-  </body>
-  </html>`;
-};
-
-// 🔹 Funkcja zapisująca HTML do pliku
-const saveHtmlToFile = async (html: string): Promise<void> => {
-  await fs.writeFile(outputHtml, html);
-};
-
-// 🔹 Konwersja HTML → PDF z numeracją stron i TOC
-// const convertHtmlToPdf = async (): Promise<void> => {
-//   const browser = await puppeteer.launch();
-//   const page = await browser.newPage();
-//
-//   await page.goto(`file://${path.resolve(outputHtml)}`, { waitUntil: 'load' });
-//
-//   // 🔹 Ustawienie numeracji stron i stopki
-//   await page.pdf({
-//     path: outputPdf,
-//     format: 'A4',
-//     printBackground: true,
-//     displayHeaderFooter: true,
-//     headerTemplate: `
-//       <div style="width: 100%; text-align: left; font-size: 6pt; padding-left: 20mm; color: #d1d1d1">
-//         <span>Minerva General Documentation</span>
-//       </div>
-//     `,
-//     footerTemplate: `
-//       <div style="width: 100%; text-align: left; font-size: 11px; padding-left: 20mm;">
-//         <span class="pageNumber"></span>
-//       </div>
-//     `,
-//     margin: { top: '25mm', right: '25mm', bottom: '25mm', left: '25mm' },
-//   });
-//
-//   await browser.close();
-// };
-
-const convertHtmlToPdf = async (): Promise<void> => {
-  const browser = await puppeteer.launch();
-  const page = await browser.newPage();
-
-  await page.goto(`file://${path.resolve(outputHtml)}`, { waitUntil: 'load' });
-
-  // 🔹 Wypełniamy numery stron w spisie treści
-  await page.evaluate(() => {
-    const links = document.querySelectorAll("a[href^='#']");
-    links.forEach(link => {
-      const href = link.getAttribute('href');
-      if (!href) {
-        return;
-      }
-      const targetId = href.substring(1);
-      const targetElement = document.getElementById(targetId);
-
-      if (targetElement) {
-        const pageNumberSpan = link.querySelector('.toc-page-number');
-        if (pageNumberSpan) {
-          const pageNumber = Math.floor(targetElement.getBoundingClientRect().top / 842) + 1;
-          pageNumberSpan.setAttribute('data-page', pageNumber.toString());
-        }
-      }
-    });
-  });
-
-  await page.pdf({
-    path: outputPdf,
-    format: 'A4',
-    printBackground: true,
-    displayHeaderFooter: true,
-    headerTemplate: `<span></span>`,
-    footerTemplate: `
-      <div style="width: 100%; text-align: center; font-size: 10px;">
-        Page <span class="pageNumber"></span> of <span class="totalPages"></span>
-      </div>
-    `,
-    margin: { top: '25mm', right: '25mm', bottom: '25mm', left: '25mm' },
-  });
-
-  await browser.close();
-};
-
-// 🔹 Uruchomienie całego procesu
-(async () => {
-  try {
-    console.log('📂 Pobieranie plików Markdown...');
-
-    console.log('🔄 Konwersja Markdown → HTML...');
-    const htmlContent = await mergeMarkdownToHtml(markdownFiles);
-    await saveHtmlToFile(htmlContent);
-
-    console.log('📄 Konwersja HTML → PDF...');
-    await convertHtmlToPdf();
-
-    console.log(`✅ Plik PDF wygenerowany: ${outputPdf}`);
-  } catch (err) {
-    console.error('❌ Błąd:', err);
-  }
-})();
diff --git a/package-lock.json b/package-lock.json
index 5c864d3aa9f8baaea4c51709434681d0b1747845..1150cdff94c8c0a8c0fc624ff9655438cc9c95e0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -23,13 +23,20 @@
         "crypto-js": "4.2.0",
         "downshift": "8.3.1",
         "eslint-config-next": "13.4.19",
+        "fs-extra": "10.1.0",
         "is-uuid": "1.0.2",
+        "marked": "4.0.12",
         "molart": "1.15.0",
         "next": "13.4.19",
         "ol": "10.2.0",
         "ol-ext": "4.0.24",
+        "pagedjs": "^0.4.3",
+        "path": "0.12.7",
+        "pdf-lib": "^1.17.1",
         "polished": "4.3.1",
         "postcss": "8.4.29",
+        "prismjs": "^1.30.0",
+        "puppeteer": "19.0.0",
         "query-string": "7.1.3",
         "react": "18.2.0",
         "react-accessible-accordion": "5.0.0",
@@ -57,6 +64,7 @@
         "@testing-library/react": "14.1.2",
         "@testing-library/user-event": "14.5.2",
         "@types/crypto-js": "4.2.2",
+        "@types/fs-extra": "11.0.4",
         "@types/is-uuid": "1.0.2",
         "@types/jest": "29.5.11",
         "@types/ol-ext": "npm:@siedlerchr/types-ol-ext@3.6.1",
@@ -725,6 +733,28 @@
         "@babel/core": "^7.0.0-0"
       }
     },
+    "node_modules/@babel/polyfill": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.12.1.tgz",
+      "integrity": "sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==",
+      "deprecated": "🚨 This package has been deprecated in favor of separate inclusion of a polyfill and regenerator-runtime (when needed). See the @babel/polyfill docs (https://babeljs.io/docs/en/babel-polyfill) for more information.",
+      "dependencies": {
+        "core-js": "^2.6.5",
+        "regenerator-runtime": "^0.13.4"
+      }
+    },
+    "node_modules/@babel/polyfill/node_modules/core-js": {
+      "version": "2.6.12",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
+      "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
+      "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.",
+      "hasInstallScript": true
+    },
+    "node_modules/@babel/polyfill/node_modules/regenerator-runtime": {
+      "version": "0.13.11",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
+      "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
+    },
     "node_modules/@babel/runtime": {
       "version": "7.26.0",
       "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz",
@@ -995,6 +1025,20 @@
         "node": ">=v14"
       }
     },
+    "node_modules/@commitlint/read/node_modules/fs-extra": {
+      "version": "11.3.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
+      "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
+      "dev": true,
+      "dependencies": {
+        "graceful-fs": "^4.2.0",
+        "jsonfile": "^6.0.1",
+        "universalify": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=14.14"
+      }
+    },
     "node_modules/@commitlint/resolve-extends": {
       "version": "17.8.1",
       "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.8.1.tgz",
@@ -2103,6 +2147,32 @@
         "node": ">= 8"
       }
     },
+    "node_modules/@pdf-lib/standard-fonts": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz",
+      "integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==",
+      "dependencies": {
+        "pako": "^1.0.6"
+      }
+    },
+    "node_modules/@pdf-lib/standard-fonts/node_modules/pako": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+      "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
+    },
+    "node_modules/@pdf-lib/upng": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz",
+      "integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==",
+      "dependencies": {
+        "pako": "^1.0.10"
+      }
+    },
+    "node_modules/@pdf-lib/upng/node_modules/pako": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+      "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
+    },
     "node_modules/@petamoriken/float16": {
       "version": "3.8.4",
       "resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.8.4.tgz",
@@ -2469,6 +2539,16 @@
       "resolved": "https://registry.npmjs.org/@types/downloadjs/-/downloadjs-1.4.6.tgz",
       "integrity": "sha512-mp3w70vsaiLRT9ix92fmI9Ob2yJAPZm6tShJtofo2uHbN11G2i6a0ApIEjBl/kv3e9V7Pv7jMjk1bUwYWvMHvA=="
     },
+    "node_modules/@types/fs-extra": {
+      "version": "11.0.4",
+      "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz",
+      "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/jsonfile": "*",
+        "@types/node": "*"
+      }
+    },
     "node_modules/@types/graceful-fs": {
       "version": "4.1.9",
       "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
@@ -2575,6 +2655,15 @@
       "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
       "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
     },
+    "node_modules/@types/jsonfile": {
+      "version": "6.1.4",
+      "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz",
+      "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
     "node_modules/@types/minimist": {
       "version": "1.2.5",
       "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz",
@@ -2751,7 +2840,6 @@
       "version": "2.10.3",
       "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
       "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
-      "dev": true,
       "optional": true,
       "dependencies": {
         "@types/node": "*"
@@ -3018,7 +3106,6 @@
       "version": "6.0.2",
       "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
       "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
-      "dev": true,
       "dependencies": {
         "debug": "4"
       },
@@ -3685,7 +3772,6 @@
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
       "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
-      "dev": true,
       "funding": [
         {
           "type": "github",
@@ -3722,7 +3808,6 @@
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
       "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
-      "dev": true,
       "dependencies": {
         "buffer": "^5.5.0",
         "inherits": "^2.0.4",
@@ -3818,7 +3903,6 @@
       "version": "5.7.1",
       "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
       "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
-      "dev": true,
       "funding": [
         {
           "type": "github",
@@ -3842,7 +3926,6 @@
       "version": "0.2.13",
       "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
       "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
-      "dev": true,
       "engines": {
         "node": "*"
       }
@@ -4091,6 +4174,11 @@
         "fsevents": "~2.3.2"
       }
     },
+    "node_modules/chownr": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
+    },
     "node_modules/ci-info": {
       "version": "3.9.0",
       "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
@@ -4126,6 +4214,11 @@
         "node": ">=6"
       }
     },
+    "node_modules/clear-cut": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/clear-cut/-/clear-cut-2.0.2.tgz",
+      "integrity": "sha512-WVgn/gSejQ+0aoR8ucbKIdo6icduPZW6AbWwyUmAUgxy63rUYjwa5rj/HeoNPhf0/XPrl82X8bO/hwBkSmsFtg=="
+    },
     "node_modules/cli-cursor": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
@@ -4724,6 +4817,14 @@
       "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
       "devOptional": true
     },
+    "node_modules/cross-fetch": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
+      "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
+      "dependencies": {
+        "node-fetch": "2.6.7"
+      }
+    },
     "node_modules/cross-spawn": {
       "version": "7.0.3",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -4753,6 +4854,18 @@
         "utrie": "^1.0.2"
       }
     },
+    "node_modules/css-tree": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
+      "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
+      "dependencies": {
+        "mdn-data": "2.0.14",
+        "source-map": "^0.6.1"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
     "node_modules/css.escape": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
@@ -5052,6 +5165,18 @@
         "node": ">=4"
       }
     },
+    "node_modules/d": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz",
+      "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==",
+      "dependencies": {
+        "es5-ext": "^0.10.64",
+        "type": "^2.7.2"
+      },
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
     "node_modules/d3": {
       "version": "3.5.17",
       "resolved": "https://registry.npmjs.org/d3/-/d3-3.5.17.tgz",
@@ -5303,6 +5428,11 @@
         "node": ">=8"
       }
     },
+    "node_modules/devtools-protocol": {
+      "version": "0.0.1045489",
+      "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1045489.tgz",
+      "integrity": "sha512-D+PTmWulkuQW4D1NTiCRCFxF7pQPn0hgp4YyX4wAQ6xYXKOadSWPR3ENGDQ47MW/Ewc9v2rpC/UEEGahgBYpSQ=="
+    },
     "node_modules/didyoumean": {
       "version": "1.2.2",
       "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
@@ -5486,7 +5616,6 @@
       "version": "1.4.4",
       "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
       "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
-      "dev": true,
       "dependencies": {
         "once": "^1.4.0"
       }
@@ -5687,11 +5816,48 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/es5-ext": {
+      "version": "0.10.64",
+      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz",
+      "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==",
+      "hasInstallScript": true,
+      "dependencies": {
+        "es6-iterator": "^2.0.3",
+        "es6-symbol": "^3.1.3",
+        "esniff": "^2.0.1",
+        "next-tick": "^1.1.0"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
+    "node_modules/es6-iterator": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+      "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
+      "dependencies": {
+        "d": "1",
+        "es5-ext": "^0.10.35",
+        "es6-symbol": "^3.1.1"
+      }
+    },
     "node_modules/es6-promise": {
       "version": "4.2.8",
       "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
       "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
     },
+    "node_modules/es6-symbol": {
+      "version": "3.1.4",
+      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz",
+      "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==",
+      "dependencies": {
+        "d": "^1.0.2",
+        "ext": "^1.7.0"
+      },
+      "engines": {
+        "node": ">=0.12"
+      }
+    },
     "node_modules/escalade": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
@@ -6532,6 +6698,20 @@
         "node": ">=8"
       }
     },
+    "node_modules/esniff": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz",
+      "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==",
+      "dependencies": {
+        "d": "^1.0.1",
+        "es5-ext": "^0.10.62",
+        "event-emitter": "^0.3.5",
+        "type": "^2.7.2"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
     "node_modules/espree": {
       "version": "9.6.1",
       "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
@@ -6599,6 +6779,15 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/event-emitter": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+      "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
+      "dependencies": {
+        "d": "1",
+        "es5-ext": "~0.10.14"
+      }
+    },
     "node_modules/eventemitter2": {
       "version": "6.4.7",
       "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz",
@@ -6697,6 +6886,14 @@
         "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
+    "node_modules/ext": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
+      "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
+      "dependencies": {
+        "type": "^2.7.2"
+      }
+    },
     "node_modules/extend": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -6733,7 +6930,6 @@
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
       "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
-      "dev": true,
       "dependencies": {
         "debug": "^4.1.1",
         "get-stream": "^5.1.0",
@@ -6753,7 +6949,6 @@
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
       "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
-      "dev": true,
       "dependencies": {
         "pump": "^3.0.0"
       },
@@ -6830,7 +7025,6 @@
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
       "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
-      "dev": true,
       "dependencies": {
         "pend": "~1.2.0"
       }
@@ -7040,18 +7234,22 @@
         "url": "https://github.com/sponsors/rawify"
       }
     },
+    "node_modules/fs-constants": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+      "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
+    },
     "node_modules/fs-extra": {
-      "version": "11.2.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
-      "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
-      "dev": true,
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
       "dependencies": {
         "graceful-fs": "^4.2.0",
         "jsonfile": "^6.0.1",
         "universalify": "^2.0.0"
       },
       "engines": {
-        "node": ">=14.14"
+        "node": ">=12"
       }
     },
     "node_modules/fs.realpath": {
@@ -7604,7 +7802,6 @@
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
       "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
-      "dev": true,
       "dependencies": {
         "agent-base": "6",
         "debug": "4"
@@ -7653,7 +7850,6 @@
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
       "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
-      "dev": true,
       "funding": [
         {
           "type": "github",
@@ -9692,7 +9888,6 @@
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
       "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
-      "dev": true,
       "dependencies": {
         "universalify": "^2.0.0"
       },
@@ -10672,6 +10867,22 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/marked": {
+      "version": "4.0.12",
+      "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.12.tgz",
+      "integrity": "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ==",
+      "bin": {
+        "marked": "bin/marked.js"
+      },
+      "engines": {
+        "node": ">= 12"
+      }
+    },
+    "node_modules/mdn-data": {
+      "version": "2.0.14",
+      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
+      "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="
+    },
     "node_modules/memoize-one": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
@@ -10824,6 +11035,11 @@
         "node": ">=10"
       }
     },
+    "node_modules/mkdirp-classic": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+      "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
+    },
     "node_modules/molart": {
       "version": "1.15.0",
       "resolved": "https://registry.npmjs.org/molart/-/molart-1.15.0.tgz",
@@ -10951,6 +11167,11 @@
         "react": ">=17.0.0"
       }
     },
+    "node_modules/next-tick": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
+      "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
+    },
     "node_modules/next/node_modules/postcss": {
       "version": "8.4.14",
       "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
@@ -10982,6 +11203,44 @@
         "url": "https://github.com/sponsors/colinhacks"
       }
     },
+    "node_modules/node-fetch": {
+      "version": "2.6.7",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
+      "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+      "dependencies": {
+        "whatwg-url": "^5.0.0"
+      },
+      "engines": {
+        "node": "4.x || >=6.0.0"
+      },
+      "peerDependencies": {
+        "encoding": "^0.1.0"
+      },
+      "peerDependenciesMeta": {
+        "encoding": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/node-fetch/node_modules/tr46": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+      "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+    },
+    "node_modules/node-fetch/node_modules/webidl-conversions": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+      "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+    },
+    "node_modules/node-fetch/node_modules/whatwg-url": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+      "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+      "dependencies": {
+        "tr46": "~0.0.3",
+        "webidl-conversions": "^3.0.0"
+      }
+    },
     "node_modules/node-int64": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
@@ -11350,6 +11609,18 @@
         "node": ">=6"
       }
     },
+    "node_modules/pagedjs": {
+      "version": "0.4.3",
+      "resolved": "https://registry.npmjs.org/pagedjs/-/pagedjs-0.4.3.tgz",
+      "integrity": "sha512-YtAN9JAjsQw1142gxEjEAwXvOF5nYQuDwnQ67RW2HZDkMLI+b4RsBE37lULZa9gAr6kDAOGBOhXI4wGMoY3raw==",
+      "dependencies": {
+        "@babel/polyfill": "^7.10.1",
+        "@babel/runtime": "^7.21.0",
+        "clear-cut": "^2.0.2",
+        "css-tree": "^1.1.3",
+        "event-emitter": "^0.3.5"
+      }
+    },
     "node_modules/pako": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
@@ -11409,6 +11680,15 @@
         "url": "https://github.com/inikulin/parse5?sponsor=1"
       }
     },
+    "node_modules/path": {
+      "version": "0.12.7",
+      "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz",
+      "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==",
+      "dependencies": {
+        "process": "^0.11.1",
+        "util": "^0.10.3"
+      }
+    },
     "node_modules/path-exists": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -11472,11 +11752,31 @@
         "pbf": "bin/pbf"
       }
     },
+    "node_modules/pdf-lib": {
+      "version": "1.17.1",
+      "resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz",
+      "integrity": "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==",
+      "dependencies": {
+        "@pdf-lib/standard-fonts": "^1.0.0",
+        "@pdf-lib/upng": "^1.0.1",
+        "pako": "^1.0.11",
+        "tslib": "^1.11.1"
+      }
+    },
+    "node_modules/pdf-lib/node_modules/pako": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+      "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
+    },
+    "node_modules/pdf-lib/node_modules/tslib": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+    },
     "node_modules/pend": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
-      "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
-      "dev": true
+      "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="
     },
     "node_modules/performance-now": {
       "version": "2.1.0",
@@ -11856,11 +12156,18 @@
       "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
       "dev": true
     },
+    "node_modules/prismjs": {
+      "version": "1.30.0",
+      "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz",
+      "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==",
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/process": {
       "version": "0.11.10",
       "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
       "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
-      "dev": true,
       "engines": {
         "node": ">= 0.6.0"
       }
@@ -11870,6 +12177,14 @@
       "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
       "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
     },
+    "node_modules/progress": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+      "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/prompts": {
       "version": "2.4.2",
       "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
@@ -11934,7 +12249,6 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
       "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
-      "dev": true,
       "dependencies": {
         "end-of-stream": "^1.1.0",
         "once": "^1.3.1"
@@ -11948,6 +12262,62 @@
         "node": ">=6"
       }
     },
+    "node_modules/puppeteer": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-19.0.0.tgz",
+      "integrity": "sha512-3Ga5IVerQQ2hKU9q7T28RmcUsd8F2kL6cYuPcPCzeclSjmHhGydPBZL/KJKC02sG6J6Wfry85uiWpbkjQ5qBiw==",
+      "deprecated": "< 22.8.2 is no longer supported",
+      "hasInstallScript": true,
+      "dependencies": {
+        "https-proxy-agent": "5.0.1",
+        "progress": "2.0.3",
+        "proxy-from-env": "1.1.0",
+        "puppeteer-core": "19.0.0"
+      },
+      "engines": {
+        "node": ">=14.1.0"
+      }
+    },
+    "node_modules/puppeteer-core": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-19.0.0.tgz",
+      "integrity": "sha512-OljQ9W5M4cBX68vnOAGbcRkVENDHn6lfj6QYoGsnLQsxPAh6ExTQAhHauwdFdQkhYdDExZFWlKArnBONzeHY+g==",
+      "dependencies": {
+        "cross-fetch": "3.1.5",
+        "debug": "4.3.4",
+        "devtools-protocol": "0.0.1045489",
+        "extract-zip": "2.0.1",
+        "https-proxy-agent": "5.0.1",
+        "proxy-from-env": "1.1.0",
+        "rimraf": "3.0.2",
+        "tar-fs": "2.1.1",
+        "unbzip2-stream": "1.4.3",
+        "ws": "8.9.0"
+      },
+      "engines": {
+        "node": ">=14.1.0"
+      }
+    },
+    "node_modules/puppeteer-core/node_modules/ws": {
+      "version": "8.9.0",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz",
+      "integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==",
+      "engines": {
+        "node": ">=10.0.0"
+      },
+      "peerDependencies": {
+        "bufferutil": "^4.0.1",
+        "utf-8-validate": "^5.0.2"
+      },
+      "peerDependenciesMeta": {
+        "bufferutil": {
+          "optional": true
+        },
+        "utf-8-validate": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/pure-rand": {
       "version": "6.0.4",
       "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz",
@@ -12370,7 +12740,6 @@
       "version": "3.6.2",
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
       "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
-      "dev": true,
       "dependencies": {
         "inherits": "^2.0.3",
         "string_decoder": "^1.1.1",
@@ -12723,7 +13092,6 @@
       "version": "5.2.1",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
       "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
-      "dev": true,
       "funding": [
         {
           "type": "github",
@@ -12964,7 +13332,6 @@
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
       "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
@@ -13131,7 +13498,6 @@
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
       "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
-      "dev": true,
       "dependencies": {
         "safe-buffer": "~5.2.0"
       }
@@ -13572,6 +13938,32 @@
         "node": ">=6"
       }
     },
+    "node_modules/tar-fs": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
+      "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+      "dependencies": {
+        "chownr": "^1.1.1",
+        "mkdirp-classic": "^0.5.2",
+        "pump": "^3.0.0",
+        "tar-stream": "^2.1.4"
+      }
+    },
+    "node_modules/tar-stream": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+      "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+      "dependencies": {
+        "bl": "^4.0.3",
+        "end-of-stream": "^1.4.1",
+        "fs-constants": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^3.1.1"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/test-exclude": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
@@ -13642,8 +14034,7 @@
     "node_modules/through": {
       "version": "2.3.8",
       "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-      "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
-      "dev": true
+      "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
     },
     "node_modules/through2": {
       "version": "4.0.2",
@@ -13864,6 +14255,11 @@
       "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
       "dev": true
     },
+    "node_modules/type": {
+      "version": "2.7.3",
+      "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz",
+      "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ=="
+    },
     "node_modules/type-check": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -13983,6 +14379,15 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/unbzip2-stream": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
+      "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
+      "dependencies": {
+        "buffer": "^5.2.1",
+        "through": "^2.3.8"
+      }
+    },
     "node_modules/underscore": {
       "version": "1.13.6",
       "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
@@ -13998,7 +14403,6 @@
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
       "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
-      "dev": true,
       "engines": {
         "node": ">= 10.0.0"
       }
@@ -14091,11 +14495,24 @@
         "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
       }
     },
+    "node_modules/util": {
+      "version": "0.10.4",
+      "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
+      "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
+      "dependencies": {
+        "inherits": "2.0.3"
+      }
+    },
     "node_modules/util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
       "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
     },
+    "node_modules/util/node_modules/inherits": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+      "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw=="
+    },
     "node_modules/utrie": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
@@ -14612,7 +15029,6 @@
       "version": "2.10.0",
       "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
       "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
-      "dev": true,
       "dependencies": {
         "buffer-crc32": "~0.2.3",
         "fd-slicer": "~1.1.0"
@@ -15138,6 +15554,27 @@
         "@babel/helper-plugin-utils": "^7.22.5"
       }
     },
+    "@babel/polyfill": {
+      "version": "7.12.1",
+      "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.12.1.tgz",
+      "integrity": "sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==",
+      "requires": {
+        "core-js": "^2.6.5",
+        "regenerator-runtime": "^0.13.4"
+      },
+      "dependencies": {
+        "core-js": {
+          "version": "2.6.12",
+          "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
+          "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ=="
+        },
+        "regenerator-runtime": {
+          "version": "0.13.11",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
+          "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
+        }
+      }
+    },
     "@babel/runtime": {
       "version": "7.26.0",
       "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz",
@@ -15353,6 +15790,19 @@
         "fs-extra": "^11.0.0",
         "git-raw-commits": "^2.0.11",
         "minimist": "^1.2.6"
+      },
+      "dependencies": {
+        "fs-extra": {
+          "version": "11.3.0",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz",
+          "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.2.0",
+            "jsonfile": "^6.0.1",
+            "universalify": "^2.0.0"
+          }
+        }
       }
     },
     "@commitlint/resolve-extends": {
@@ -16189,6 +16639,36 @@
         "fastq": "^1.6.0"
       }
     },
+    "@pdf-lib/standard-fonts": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz",
+      "integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==",
+      "requires": {
+        "pako": "^1.0.6"
+      },
+      "dependencies": {
+        "pako": {
+          "version": "1.0.11",
+          "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+          "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
+        }
+      }
+    },
+    "@pdf-lib/upng": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz",
+      "integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==",
+      "requires": {
+        "pako": "^1.0.10"
+      },
+      "dependencies": {
+        "pako": {
+          "version": "1.0.11",
+          "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+          "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
+        }
+      }
+    },
     "@petamoriken/float16": {
       "version": "3.8.4",
       "resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.8.4.tgz",
@@ -16463,6 +16943,16 @@
       "resolved": "https://registry.npmjs.org/@types/downloadjs/-/downloadjs-1.4.6.tgz",
       "integrity": "sha512-mp3w70vsaiLRT9ix92fmI9Ob2yJAPZm6tShJtofo2uHbN11G2i6a0ApIEjBl/kv3e9V7Pv7jMjk1bUwYWvMHvA=="
     },
+    "@types/fs-extra": {
+      "version": "11.0.4",
+      "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz",
+      "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==",
+      "dev": true,
+      "requires": {
+        "@types/jsonfile": "*",
+        "@types/node": "*"
+      }
+    },
     "@types/graceful-fs": {
       "version": "4.1.9",
       "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
@@ -16562,6 +17052,15 @@
       "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
       "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
     },
+    "@types/jsonfile": {
+      "version": "6.1.4",
+      "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz",
+      "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==",
+      "dev": true,
+      "requires": {
+        "@types/node": "*"
+      }
+    },
     "@types/minimist": {
       "version": "1.2.5",
       "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz",
@@ -16733,7 +17232,6 @@
       "version": "2.10.3",
       "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
       "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
-      "dev": true,
       "optional": true,
       "requires": {
         "@types/node": "*"
@@ -16895,7 +17393,6 @@
       "version": "6.0.2",
       "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
       "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
-      "dev": true,
       "requires": {
         "debug": "4"
       }
@@ -17373,8 +17870,7 @@
     "base64-js": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
-      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
-      "dev": true
+      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
     },
     "bcrypt-pbkdf": {
       "version": "1.0.2",
@@ -17394,7 +17890,6 @@
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
       "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
-      "dev": true,
       "requires": {
         "buffer": "^5.5.0",
         "inherits": "^2.0.4",
@@ -17461,7 +17956,6 @@
       "version": "5.7.1",
       "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
       "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
-      "dev": true,
       "requires": {
         "base64-js": "^1.3.1",
         "ieee754": "^1.1.13"
@@ -17470,8 +17964,7 @@
     "buffer-crc32": {
       "version": "0.2.13",
       "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
-      "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
-      "dev": true
+      "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="
     },
     "buffer-from": {
       "version": "1.1.2",
@@ -17644,6 +18137,11 @@
         "readdirp": "~3.6.0"
       }
     },
+    "chownr": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+      "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
+    },
     "ci-info": {
       "version": "3.9.0",
       "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
@@ -17667,6 +18165,11 @@
       "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
       "dev": true
     },
+    "clear-cut": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/clear-cut/-/clear-cut-2.0.2.tgz",
+      "integrity": "sha512-WVgn/gSejQ+0aoR8ucbKIdo6icduPZW6AbWwyUmAUgxy63rUYjwa5rj/HeoNPhf0/XPrl82X8bO/hwBkSmsFtg=="
+    },
     "cli-cursor": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
@@ -18118,6 +18621,14 @@
       "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
       "devOptional": true
     },
+    "cross-fetch": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
+      "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
+      "requires": {
+        "node-fetch": "2.6.7"
+      }
+    },
     "cross-spawn": {
       "version": "7.0.3",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -18144,6 +18655,15 @@
         "utrie": "^1.0.2"
       }
     },
+    "css-tree": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz",
+      "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==",
+      "requires": {
+        "mdn-data": "2.0.14",
+        "source-map": "^0.6.1"
+      }
+    },
     "css.escape": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
@@ -18389,6 +18909,15 @@
         }
       }
     },
+    "d": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz",
+      "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==",
+      "requires": {
+        "es5-ext": "^0.10.64",
+        "type": "^2.7.2"
+      }
+    },
     "d3": {
       "version": "3.5.17",
       "resolved": "https://registry.npmjs.org/d3/-/d3-3.5.17.tgz",
@@ -18574,6 +19103,11 @@
       "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
       "dev": true
     },
+    "devtools-protocol": {
+      "version": "0.0.1045489",
+      "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1045489.tgz",
+      "integrity": "sha512-D+PTmWulkuQW4D1NTiCRCFxF7pQPn0hgp4YyX4wAQ6xYXKOadSWPR3ENGDQ47MW/Ewc9v2rpC/UEEGahgBYpSQ=="
+    },
     "didyoumean": {
       "version": "1.2.2",
       "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
@@ -18726,7 +19260,6 @@
       "version": "1.4.4",
       "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
       "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
-      "dev": true,
       "requires": {
         "once": "^1.4.0"
       }
@@ -18893,11 +19426,41 @@
         "is-symbol": "^1.0.2"
       }
     },
+    "es5-ext": {
+      "version": "0.10.64",
+      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz",
+      "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==",
+      "requires": {
+        "es6-iterator": "^2.0.3",
+        "es6-symbol": "^3.1.3",
+        "esniff": "^2.0.1",
+        "next-tick": "^1.1.0"
+      }
+    },
+    "es6-iterator": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+      "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
+      "requires": {
+        "d": "1",
+        "es5-ext": "^0.10.35",
+        "es6-symbol": "^3.1.1"
+      }
+    },
     "es6-promise": {
       "version": "4.2.8",
       "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
       "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
     },
+    "es6-symbol": {
+      "version": "3.1.4",
+      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz",
+      "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==",
+      "requires": {
+        "d": "^1.0.2",
+        "ext": "^1.7.0"
+      }
+    },
     "escalade": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
@@ -19443,6 +20006,17 @@
       "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
       "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="
     },
+    "esniff": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz",
+      "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==",
+      "requires": {
+        "d": "^1.0.1",
+        "es5-ext": "^0.10.62",
+        "event-emitter": "^0.3.5",
+        "type": "^2.7.2"
+      }
+    },
     "espree": {
       "version": "9.6.1",
       "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
@@ -19485,6 +20059,15 @@
       "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
       "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
     },
+    "event-emitter": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+      "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
+      "requires": {
+        "d": "1",
+        "es5-ext": "~0.10.14"
+      }
+    },
     "eventemitter2": {
       "version": "6.4.7",
       "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz",
@@ -19564,6 +20147,14 @@
         "jest-util": "^29.7.0"
       }
     },
+    "ext": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
+      "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
+      "requires": {
+        "type": "^2.7.2"
+      }
+    },
     "extend": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -19596,7 +20187,6 @@
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
       "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
-      "dev": true,
       "requires": {
         "@types/yauzl": "^2.9.1",
         "debug": "^4.1.1",
@@ -19608,7 +20198,6 @@
           "version": "5.2.0",
           "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
           "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
-          "dev": true,
           "requires": {
             "pump": "^3.0.0"
           }
@@ -19675,7 +20264,6 @@
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
       "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
-      "dev": true,
       "requires": {
         "pend": "~1.2.0"
       }
@@ -19825,11 +20413,15 @@
       "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
       "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="
     },
+    "fs-constants": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+      "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
+    },
     "fs-extra": {
-      "version": "11.2.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
-      "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
-      "dev": true,
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
       "requires": {
         "graceful-fs": "^4.2.0",
         "jsonfile": "^6.0.1",
@@ -20237,7 +20829,6 @@
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
       "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
-      "dev": true,
       "requires": {
         "agent-base": "6",
         "debug": "4"
@@ -20267,8 +20858,7 @@
     "ieee754": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
-      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
-      "dev": true
+      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
     },
     "ignore": {
       "version": "5.3.0",
@@ -21729,7 +22319,6 @@
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
       "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
-      "dev": true,
       "requires": {
         "graceful-fs": "^4.1.6",
         "universalify": "^2.0.0"
@@ -22451,6 +23040,16 @@
       "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
       "dev": true
     },
+    "marked": {
+      "version": "4.0.12",
+      "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.12.tgz",
+      "integrity": "sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ=="
+    },
+    "mdn-data": {
+      "version": "2.0.14",
+      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
+      "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="
+    },
     "memoize-one": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
@@ -22561,6 +23160,11 @@
       "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
       "dev": true
     },
+    "mkdirp-classic": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+      "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
+    },
     "molart": {
       "version": "1.15.0",
       "resolved": "https://registry.npmjs.org/molart/-/molart-1.15.0.tgz",
@@ -22668,6 +23272,40 @@
       "dev": true,
       "requires": {}
     },
+    "next-tick": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
+      "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
+    },
+    "node-fetch": {
+      "version": "2.6.7",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
+      "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+      "requires": {
+        "whatwg-url": "^5.0.0"
+      },
+      "dependencies": {
+        "tr46": {
+          "version": "0.0.3",
+          "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+          "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+        },
+        "webidl-conversions": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+          "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+        },
+        "whatwg-url": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+          "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+          "requires": {
+            "tr46": "~0.0.3",
+            "webidl-conversions": "^3.0.0"
+          }
+        }
+      }
+    },
     "node-int64": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
@@ -22936,6 +23574,18 @@
       "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
       "dev": true
     },
+    "pagedjs": {
+      "version": "0.4.3",
+      "resolved": "https://registry.npmjs.org/pagedjs/-/pagedjs-0.4.3.tgz",
+      "integrity": "sha512-YtAN9JAjsQw1142gxEjEAwXvOF5nYQuDwnQ67RW2HZDkMLI+b4RsBE37lULZa9gAr6kDAOGBOhXI4wGMoY3raw==",
+      "requires": {
+        "@babel/polyfill": "^7.10.1",
+        "@babel/runtime": "^7.21.0",
+        "clear-cut": "^2.0.2",
+        "css-tree": "^1.1.3",
+        "event-emitter": "^0.3.5"
+      }
+    },
     "pako": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
@@ -22980,6 +23630,15 @@
         "entities": "^4.4.0"
       }
     },
+    "path": {
+      "version": "0.12.7",
+      "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz",
+      "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==",
+      "requires": {
+        "process": "^0.11.1",
+        "util": "^0.10.3"
+      }
+    },
     "path-exists": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -23022,11 +23681,33 @@
         "resolve-protobuf-schema": "^2.1.0"
       }
     },
+    "pdf-lib": {
+      "version": "1.17.1",
+      "resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz",
+      "integrity": "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==",
+      "requires": {
+        "@pdf-lib/standard-fonts": "^1.0.0",
+        "@pdf-lib/upng": "^1.0.1",
+        "pako": "^1.0.11",
+        "tslib": "^1.11.1"
+      },
+      "dependencies": {
+        "pako": {
+          "version": "1.0.11",
+          "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+          "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
+        },
+        "tslib": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+          "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+        }
+      }
+    },
     "pend": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
-      "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
-      "dev": true
+      "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="
     },
     "performance-now": {
       "version": "2.1.0",
@@ -23213,17 +23894,26 @@
         }
       }
     },
+    "prismjs": {
+      "version": "1.30.0",
+      "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz",
+      "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="
+    },
     "process": {
       "version": "0.11.10",
       "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
-      "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
-      "dev": true
+      "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="
     },
     "process-nextick-args": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
       "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
     },
+    "progress": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+      "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
+    },
     "prompts": {
       "version": "2.4.2",
       "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
@@ -23289,7 +23979,6 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
       "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
-      "dev": true,
       "requires": {
         "end-of-stream": "^1.1.0",
         "once": "^1.3.1"
@@ -23300,6 +23989,42 @@
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
       "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="
     },
+    "puppeteer": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-19.0.0.tgz",
+      "integrity": "sha512-3Ga5IVerQQ2hKU9q7T28RmcUsd8F2kL6cYuPcPCzeclSjmHhGydPBZL/KJKC02sG6J6Wfry85uiWpbkjQ5qBiw==",
+      "requires": {
+        "https-proxy-agent": "5.0.1",
+        "progress": "2.0.3",
+        "proxy-from-env": "1.1.0",
+        "puppeteer-core": "19.0.0"
+      }
+    },
+    "puppeteer-core": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-19.0.0.tgz",
+      "integrity": "sha512-OljQ9W5M4cBX68vnOAGbcRkVENDHn6lfj6QYoGsnLQsxPAh6ExTQAhHauwdFdQkhYdDExZFWlKArnBONzeHY+g==",
+      "requires": {
+        "cross-fetch": "3.1.5",
+        "debug": "4.3.4",
+        "devtools-protocol": "0.0.1045489",
+        "extract-zip": "2.0.1",
+        "https-proxy-agent": "5.0.1",
+        "proxy-from-env": "1.1.0",
+        "rimraf": "3.0.2",
+        "tar-fs": "2.1.1",
+        "unbzip2-stream": "1.4.3",
+        "ws": "8.9.0"
+      },
+      "dependencies": {
+        "ws": {
+          "version": "8.9.0",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz",
+          "integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==",
+          "requires": {}
+        }
+      }
+    },
     "pure-rand": {
       "version": "6.0.4",
       "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz",
@@ -23590,7 +24315,6 @@
       "version": "3.6.2",
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
       "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
-      "dev": true,
       "requires": {
         "inherits": "^2.0.3",
         "string_decoder": "^1.1.1",
@@ -23849,8 +24573,7 @@
     "safe-buffer": {
       "version": "5.2.1",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
-      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
-      "dev": true
+      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
     },
     "safe-regex-test": {
       "version": "1.0.0",
@@ -24029,8 +24752,7 @@
     "source-map": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "dev": true
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
     },
     "source-map-js": {
       "version": "1.0.2",
@@ -24164,7 +24886,6 @@
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
       "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
-      "dev": true,
       "requires": {
         "safe-buffer": "~5.2.0"
       }
@@ -24479,6 +25200,29 @@
       "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
       "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="
     },
+    "tar-fs": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
+      "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+      "requires": {
+        "chownr": "^1.1.1",
+        "mkdirp-classic": "^0.5.2",
+        "pump": "^3.0.0",
+        "tar-stream": "^2.1.4"
+      }
+    },
+    "tar-stream": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+      "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+      "requires": {
+        "bl": "^4.0.3",
+        "end-of-stream": "^1.4.1",
+        "fs-constants": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^3.1.1"
+      }
+    },
     "test-exclude": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
@@ -24537,8 +25281,7 @@
     "through": {
       "version": "2.3.8",
       "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-      "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
-      "dev": true
+      "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
     },
     "through2": {
       "version": "4.0.2",
@@ -24705,6 +25448,11 @@
       "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
       "dev": true
     },
+    "type": {
+      "version": "2.7.3",
+      "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz",
+      "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ=="
+    },
     "type-check": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -24784,6 +25532,15 @@
         "which-boxed-primitive": "^1.0.2"
       }
     },
+    "unbzip2-stream": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
+      "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
+      "requires": {
+        "buffer": "^5.2.1",
+        "through": "^2.3.8"
+      }
+    },
     "underscore": {
       "version": "1.13.6",
       "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
@@ -24798,8 +25555,7 @@
     "universalify": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
-      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
-      "dev": true
+      "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="
     },
     "untildify": {
       "version": "4.0.0",
@@ -24852,6 +25608,21 @@
       "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
       "requires": {}
     },
+    "util": {
+      "version": "0.10.4",
+      "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz",
+      "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==",
+      "requires": {
+        "inherits": "2.0.3"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+          "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw=="
+        }
+      }
+    },
     "util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -25254,7 +26025,6 @@
       "version": "2.10.0",
       "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
       "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
-      "dev": true,
       "requires": {
         "buffer-crc32": "~0.2.3",
         "fd-slicer": "~1.1.0"
diff --git a/package.json b/package.json
index 5d0cb06b70c7feaecd6439110106d5eaaf512c68..427958f18811e080141acbcffe4e216ef56dea2c 100644
--- a/package.json
+++ b/package.json
@@ -20,7 +20,8 @@
     "test:coverage": "jest --watchAll --coverage --config ./jest.config.ts --transformIgnorePatterns 'node_modules/(?!(ol|geotiff|quick-lru|.*\\.mjs$))'",
     "test:coveragee": "jest --coverage --transformIgnorePatterns 'node_modules/(?!(ol|geotiff|quick-lru|.*\\.mjs$))'",
     "coverage": "open ./coverage/lcov-report/index.html",
-    "cypress": "cypress open"
+    "cypress": "cypress open",
+    "docs:pdf": "node --no-warnings --loader ts-node/esm docs/general/generatePdf.mjs"
   },
   "dependencies": {
     "@next/font": "13.5.6",
@@ -37,13 +38,20 @@
     "crypto-js": "4.2.0",
     "downshift": "8.3.1",
     "eslint-config-next": "13.4.19",
+    "fs-extra": "10.1.0",
     "is-uuid": "1.0.2",
+    "marked": "4.0.12",
     "molart": "1.15.0",
     "next": "13.4.19",
     "ol": "10.2.0",
     "ol-ext": "4.0.24",
+    "pagedjs": "^0.4.3",
+    "path": "0.12.7",
+    "pdf-lib": "^1.17.1",
     "polished": "4.3.1",
     "postcss": "8.4.29",
+    "prismjs": "^1.30.0",
+    "puppeteer": "19.0.0",
     "query-string": "7.1.3",
     "react": "18.2.0",
     "react-accessible-accordion": "5.0.0",
@@ -71,6 +79,7 @@
     "@testing-library/react": "14.1.2",
     "@testing-library/user-event": "14.5.2",
     "@types/crypto-js": "4.2.2",
+    "@types/fs-extra": "11.0.4",
     "@types/is-uuid": "1.0.2",
     "@types/jest": "29.5.11",
     "@types/ol-ext": "npm:@siedlerchr/types-ol-ext@3.6.1",