GitFOSS
feat(syntax_highlight): add syntax highlighting api endpoint with html/json output!
+ 3870
- 3406
@@ -1,10 +1,10 @@
 {
-  "_generatedAtUnix": 1664493709726,
+  "_generatedAtUnix": 1664503855283,
   "_hashAlgorithm": "sha1",
   "_version": 2,
   "islands": {
     "Code": {
-      "hash": "6b04788e5f7abcf319aaa7ed122b91c6fa6ac952",
+      "hash": "1fb3b1015338a81ad565d1abb9b689372e7959e7",
       "pathSource": "./app/islands/Code.tsx",
       "pathBundle": "./public/.islands/Code.bundle.js",
       "pathSourceMap": "./public/.islands/Code.bundle.js.map"

...
@@ -34,7 +34,7 @@
       "pathSourceMap": "./public/.islands/RepositoryCreateForm.bundle.js.map"
     },
     "RepositoryFilesDiffsList": {
-      "hash": "117895a214a1d54625205f5b8a2e98a82b5ac7c6",
+      "hash": "ab4c2ce9ebcbc4e17885f9920da5d36ffb19a232",
       "pathSource": "./app/islands/RepositoryFilesDiffsList.tsx",
       "pathBundle": "./public/.islands/RepositoryFilesDiffsList.bundle.js",
       "pathSourceMap": "./public/.islands/RepositoryFilesDiffsList.bundle.js.map"

new file
app/controllers/syntax_highlight/highlightCodeAction.ts
@@ -0,0 +1,125 @@
+// 1st-party
+import { ReqHandler } from "@ethicdevs/react-monolith";
+// 3rd-party
+import Prism from "prismjs";
+import { parse as parseHtmlToJson } from "himalaya";
+// app
+import type { AppThemeScheme } from "../../types";
+import { AppRoute, AppRoutesParams } from "../../routes";
+import { escapeHtmlCode } from "../../utils/shared/escapeHtmlCode";
+
+const syntaxHighlightThemes: Record<AppThemeScheme, string> = {
+  light: `code[class*="language-"],pre[class*="language-"]{color:#000;background:0 0;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;padding-left:3.5em;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*="language-"]::-moz-selection,code[class*="language-"]::-moz-selection,pre[class*="language-"] ::-moz-selection,pre[class*="language-"]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*="language-"]::selection,code[class*="language-"]::selection,pre[class*="language-"] ::selection,pre[class*="language-"]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*="language-"],pre[class*="language-"]{text-shadow:none}}pre[class*="language-"]{padding:1em;margin:0.5em 0;overflow-y:hidden;overflow-x:auto}:not(pre) > code[class*="language-"],pre[class*="language-"]{background:#f5f2f0}:not(pre) > code[class*="language-"]{padding:0.1em;border-radius:0.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:0.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0, 0%, 100%, 0.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}`,
+  dark: `code[class*="language-"],pre[class*="language-"]{color:#fff;background:0 0;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;padding-left:3.5em;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}@media print{code[class*="language-"],pre[class*="language-"]{text-shadow:none}}:not(pre) > code[class*="language-"],pre[class*="language-"]{background:#4c3f33}pre[class*="language-"]{padding:1em;margin:0.5em 0;overflow-y:hidden;overflow-x:auto;border:0.3em solid #7a6651;border-radius:0.5em;box-shadow:1px 1px 0.5em #000 inset}:not(pre) > code[class*="language-"]{padding:0.15em 0.2em 0.05em;border-radius:0.3em;border:0.13em solid #7a6651;box-shadow:1px 1px 0.3em -0.1em #000 inset;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#997f66}.token.punctuation{opacity:0.7}.token.namespace{opacity:0.7}.token.boolean,.token.constant,.token.number,.token.property,.token.symbol,.token.tag{color:#d1939e}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#bce051}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f4b73d}.token.atrule,.token.attr-value,.token.keyword{color:#d1939e}.token.important,.token.regex{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.deleted{color:red}`,
+};
+
+function getHighlightedCode(
+  code: string,
+  language: string,
+  themeScheme: AppThemeScheme
+): { html: string; cssRules: string; durationMs: number } {
+  const _startTimeMs = Date.now();
+  const isLanguageSupportedByPrism = !!(
+    Prism.languages != null &&
+    typeof Prism.languages === "object" &&
+    language in Prism.languages &&
+    Prism.languages[language] != null
+  );
+
+  const html = isLanguageSupportedByPrism
+    ? Prism.highlight(code, Prism.languages[language], language)
+    : escapeHtmlCode(code);
+
+  return {
+    html,
+    cssRules: syntaxHighlightThemes[themeScheme],
+    durationMs: Date.now() - _startTimeMs,
+  };
+}
+
+const highlightCodeAction: ReqHandler = async (request, reply) => {
+  const { outputFormat = "html" } =
+    request.params as AppRoutesParams[AppRoute.SYNTAX_HIGHLIGHT_HIGHLIGHT_CODE_ACTION]["params"];
+
+  const {
+    code,
+    language,
+    theme_scheme: themeScheme,
+  } = request.body as AppRoutesParams[AppRoute.SYNTAX_HIGHLIGHT_HIGHLIGHT_CODE_ACTION]["body"];
+
+  if (request.validationError != null) {
+    if (outputFormat === "html") {
+      return reply.status(500).send(`<div class="error">
+  <h1>Woops, Internal Server Error...</h1>
+  <p>${request.validationError.message}</p>
+</div>`);
+    }
+
+    // json
+    return reply.status(500).send({
+      success: false,
+      error: request.validationError,
+    });
+  }
+
+  const result = getHighlightedCode(code, language, themeScheme);
+
+  if (outputFormat === "html") {
+    return reply.status(200).send(result);
+  } else if (outputFormat === "json") {
+    const parsedJson = parseHtmlToJson(result.html);
+
+    console.log("parsedJson:", parsedJson);
+
+    const tokens = parsedJson.reduce((acc, node) => {
+      const getNodeTextRecursive = (n: typeof node, depth = 0): string => {
+        if (depth > 1000) throw new Error("Too much recursion.");
+        return n.type === "text"
+          ? n.content.replace(/\r\n/i, "\n")
+          : getNodeTextRecursive(n.children[0], depth + 1);
+      };
+      const getNodesRecursive = (
+        n: typeof node,
+        depth = 0
+      ): { text: string; type: string }[] => {
+        if (depth > 1000) throw new Error("Too much recursion.");
+        return n.type === "text"
+          ? [
+              {
+                text: n.content.replace(/\r\n/i, "\n"),
+                type: "text",
+              },
+            ]
+          : n.children.map((childNode) => ({
+              text: getNodeTextRecursive(childNode),
+              type:
+                childNode.type === "text"
+                  ? "text"
+                  : childNode.attributes[0].key === "class"
+                  ? childNode.attributes[0].value.replace(/^token /i, "")
+                  : "attr",
+            }));
+      };
+      if (node.type === "text") {
+        acc = [
+          ...acc,
+          { text: node.content.replace(/\r\n/i, "\n"), type: "text" },
+        ];
+      } else {
+        acc = [...acc, ...getNodesRecursive(node)];
+      }
+      return acc;
+    }, [] as { text: string; type: string }[]);
+    return reply.status(200).send(tokens);
+  }
+
+  // unknown format
+  return reply.status(200).send({
+    success: false,
+    error: {
+      message: "Unknown output format. Must be one of: `html` | `json`.",
+    },
+  });
+};
+
+export default highlightCodeAction;

new file
app/controllers/syntax_highlight/index.ts
@@ -0,0 +1,6 @@
+// request handlers
+import { default as highlightCodeAction } from "./highlightCodeAction";
+
+export const SyntaxHighlightController = {
+  highlightCodeAction,
+};

new file
app/controllers/syntax_highlight/theme.dark.css
@@ -0,0 +1,103 @@
+code[class*="language-"],
+pre[class*="language-"] {
+  color: #fff;
+  background: 0 0;
+  text-align: left;
+  white-space: pre;
+  word-spacing: normal;
+  word-break: normal;
+  word-wrap: normal;
+  padding-left: 3.5em;
+  line-height: 1.5;
+  -moz-tab-size: 4;
+  -o-tab-size: 4;
+  tab-size: 4;
+  -webkit-hyphens: none;
+  -moz-hyphens: none;
+  -ms-hyphens: none;
+  hyphens: none;
+}
+@media print {
+  code[class*="language-"],
+  pre[class*="language-"] {
+    text-shadow: none;
+  }
+}
+:not(pre) > code[class*="language-"],
+pre[class*="language-"] {
+  background: #4c3f33;
+}
+pre[class*="language-"] {
+  padding: 1em;
+  margin: 0.5em 0;
+  overflow-y: hidden;
+  overflow-x: auto;
+  border: 0.3em solid #7a6651;
+  border-radius: 0.5em;
+  box-shadow: 1px 1px 0.5em #000 inset;
+}
+:not(pre) > code[class*="language-"] {
+  padding: 0.15em 0.2em 0.05em;
+  border-radius: 0.3em;
+  border: 0.13em solid #7a6651;
+  box-shadow: 1px 1px 0.3em -0.1em #000 inset;
+  white-space: normal;
+}
+.token.cdata,
+.token.comment,
+.token.doctype,
+.token.prolog {
+  color: #997f66;
+}
+.token.punctuation {
+  opacity: 0.7;
+}
+.token.namespace {
+  opacity: 0.7;
+}
+.token.boolean,
+.token.constant,
+.token.number,
+.token.property,
+.token.symbol,
+.token.tag {
+  color: #d1939e;
+}
+.token.attr-name,
+.token.builtin,
+.token.char,
+.token.inserted,
+.token.selector,
+.token.string {
+  color: #bce051;
+}
+.language-css .token.string,
+.style .token.string,
+.token.entity,
+.token.operator,
+.token.url,
+.token.variable {
+  color: #f4b73d;
+}
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+  color: #d1939e;
+}
+.token.important,
+.token.regex {
+  color: #e90;
+}
+.token.bold,
+.token.important {
+  font-weight: 700;
+}
+.token.italic {
+  font-style: italic;
+}
+.token.entity {
+  cursor: help;
+}
+.token.deleted {
+  color: red;
+}

new file
app/controllers/syntax_highlight/theme.light.css
@@ -0,0 +1,115 @@
+code[class*="language-"],
+pre[class*="language-"] {
+  color: #000;
+  background: 0 0;
+  text-align: left;
+  white-space: pre;
+  word-spacing: normal;
+  word-break: normal;
+  word-wrap: normal;
+  padding-left: 3.5em;
+  line-height: 1.5;
+  -moz-tab-size: 4;
+  -o-tab-size: 4;
+  tab-size: 4;
+  -webkit-hyphens: none;
+  -moz-hyphens: none;
+  -ms-hyphens: none;
+  hyphens: none;
+}
+code[class*="language-"] ::-moz-selection,
+code[class*="language-"]::-moz-selection,
+pre[class*="language-"] ::-moz-selection,
+pre[class*="language-"]::-moz-selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+code[class*="language-"] ::selection,
+code[class*="language-"]::selection,
+pre[class*="language-"] ::selection,
+pre[class*="language-"]::selection {
+  text-shadow: none;
+  background: #b3d4fc;
+}
+@media print {
+  code[class*="language-"],
+  pre[class*="language-"] {
+    text-shadow: none;
+  }
+}
+pre[class*="language-"] {
+  padding: 1em;
+  margin: 0.5em 0;
+  overflow-y: hidden;
+  overflow-x: auto;
+}
+:not(pre) > code[class*="language-"],
+pre[class*="language-"] {
+  background: #f5f2f0;
+}
+:not(pre) > code[class*="language-"] {
+  padding: 0.1em;
+  border-radius: 0.3em;
+  white-space: normal;
+}
+.token.cdata,
+.token.comment,
+.token.doctype,
+.token.prolog {
+  color: #708090;
+}
+.token.punctuation {
+  color: #999;
+}
+.token.namespace {
+  opacity: 0.7;
+}
+.token.boolean,
+.token.constant,
+.token.deleted,
+.token.number,
+.token.property,
+.token.symbol,
+.token.tag {
+  color: #905;
+}
+.token.attr-name,
+.token.builtin,
+.token.char,
+.token.inserted,
+.token.selector,
+.token.string {
+  color: #690;
+}
+.language-css .token.string,
+.style .token.string,
+.token.entity,
+.token.operator,
+.token.url {
+  color: #9a6e3a;
+  background: hsla(0, 0%, 100%, 0.5);
+}
+.token.atrule,
+.token.attr-value,
+.token.keyword {
+  color: #07a;
+}
+.token.class-name,
+.token.function {
+  color: #dd4a68;
+}
+.token.important,
+.token.regex,
+.token.variable {
+  color: #e90;
+}
+.token.bold,
+.token.important {
+  font-weight: 700;
+}
+.token.italic {
+  font-style: italic;
+}
+.token.entity {
+  cursor: help;
+}

app/islands/Code.tsx
@@ -1,13 +1,14 @@
 // 1st-party
 import { ReactIsland } from "@ethicdevs/react-monolith";
 // 3rd-party
-import React, { useCallback, useEffect, useState } from "react";
+import React, { useCallback, useEffect, useMemo, useState } from "react";
 import Prism from "prismjs";
 import styled, { css } from "styled-components";
 // app
 import type { AppThemeScheme, WithThemeSchemeProp } from "../types";
 import { NamedColors } from "../utils/style";
 import { ClientSideRouterEvents } from "./InstantRouterIndicator";
+import { escapeHtmlCode } from "../utils/shared/escapeHtmlCode";
 
 interface CodeProps {
   code: string;

...
@@ -15,14 +16,29 @@ interface CodeProps {
   [x: string]: unknown;
 }
 
-function escapeHtml(text: string): string {
-  return (text || "")
-    .split(/&/gm)
-    .join("&amp;")
-    .split(/</gm)
-    .join("&lt;")
-    .split(/>/gm)
-    .join("&gt;");
+function getLineStartsAt(maybeGitdiff: string): {
+  before: number;
+  after: number;
+} {
+  if (maybeGitdiff == null) {
+    return {
+      before: 0,
+      after: 0,
+    };
+  }
+  const gitdiffLinesRegExp = /@@ -([\d]+),[\d]+ \+[\d]+,([\d]+) @@/i;
+  const matches = gitdiffLinesRegExp.exec(maybeGitdiff);
+  if (matches == null || Array.isArray(matches) === false) {
+    return {
+      before: 0,
+      after: 0,
+    };
+  }
+  const [_, beforeLineNumber, afterLineNumber] = matches;
+  return {
+    before: parseInt(beforeLineNumber, 10) - 1,
+    after: parseInt(afterLineNumber, 10) - 1,
+  };
 }
 
 const Code: ReactIsland<CodeProps & WithThemeSchemeProp> = ({

...
@@ -31,6 +47,9 @@ const Code: ReactIsland<CodeProps & WithThemeSchemeProp> = ({
   themeScheme,
   ...props
 }) => {
+  const codeBlockLineStartsAt = useMemo(() => getLineStartsAt(code), [code]);
+  const lineStartAt = codeBlockLineStartsAt.before;
+
   const computeSyntaxHighlighting = useCallback(() => {
     const innerHtml = {
       __html:

...
@@ -43,16 +62,20 @@ const Code: ReactIsland<CodeProps & WithThemeSchemeProp> = ({
         language in Prism.languages &&
         Prism.languages[language] != null
           ? Prism.highlight(code, Prism.languages[language], language)
-          : escapeHtml(code),
+          : escapeHtmlCode(code),
     };
+
     const linesCount = innerHtml.__html.split("\n").length;
+
     innerHtml.__html += `\n<span aria-hidden="true" class="line-numbers-rows">`;
     for (let i = linesCount; i > 0; i--) {
-      innerHtml.__html += `<span></span>`;
+      const lineNumber = lineStartAt + (linesCount - i + 1);
+      innerHtml.__html += `<a id="l-${lineNumber}" href="#l-${lineNumber}" data-line-number="${lineNumber}"></a>`;
     }
     innerHtml.__html += `</span>`;
+
     return innerHtml;
-  }, [code, language]);
+  }, [code, language, lineStartAt]);
 
   const [innerHtml, setInnerHtml] = useState<{ __html: string }>(
     computeSyntaxHighlighting()

...
@@ -81,7 +104,7 @@ const Code: ReactIsland<CodeProps & WithThemeSchemeProp> = ({
     <div className="line-numbers" style={{ width: "100%" }}>
       <StylePreTag
         data-language={language}
-        data-start={1}
+        data-start={lineStartAt}
         className={` language-${language} line-numbers`}
         themeScheme={themeScheme}
         style={{ counterReset: "linenumber 0" }}

...
@@ -97,13 +120,13 @@ export const getThemedCodeCss = (themeScheme: AppThemeScheme): JSX.Element => (
     {themeScheme === "light" ? (
       <style
         dangerouslySetInnerHTML={{
-          __html: `code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;padding-left:3.5em;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}`,
+          __html: `code[class*=language-],pre[class*=language-]{color:#000;background:0 0;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;padding-left:3.5em;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow-y:hidden;overflow-x:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#9a6e3a;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.class-name,.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}`,
         }}
       />
     ) : (
       <style
         dangerouslySetInnerHTML={{
-          __html: `code[class*=language-],pre[class*=language-]{color:#fff;background:0 0;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;padding-left:3.5em;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}:not(pre)>code[class*=language-],pre[class*=language-]{background:#4c3f33}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;border:.3em solid #7a6651;border-radius:.5em;box-shadow:1px 1px .5em #000 inset}:not(pre)>code[class*=language-]{padding:.15em .2em .05em;border-radius:.3em;border:.13em solid #7a6651;box-shadow:1px 1px .3em -.1em #000 inset;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#997f66}.token.punctuation{opacity:.7}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.number,.token.property,.token.symbol,.token.tag{color:#d1939e}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#bce051}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f4b73d}.token.atrule,.token.attr-value,.token.keyword{color:#d1939e}.token.important,.token.regex{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.deleted{color:red}`,
+          __html: `code[class*=language-],pre[class*=language-]{color:#fff;background:0 0;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;padding-left:3.5em;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}:not(pre)>code[class*=language-],pre[class*=language-]{background:#4c3f33}pre[class*=language-]{padding:1em;margin:.5em 0;overflow-y:hidden;overflow-x:auto;border:.3em solid #7a6651;border-radius:.5em;box-shadow:1px 1px .5em #000 inset}:not(pre)>code[class*=language-]{padding:.15em .2em .05em;border-radius:.3em;border:.13em solid #7a6651;box-shadow:1px 1px .3em -.1em #000 inset;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#997f66}.token.punctuation{opacity:.7}.token.namespace{opacity:.7}.token.boolean,.token.constant,.token.number,.token.property,.token.symbol,.token.tag{color:#d1939e}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#bce051}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url,.token.variable{color:#f4b73d}.token.atrule,.token.attr-value,.token.keyword{color:#d1939e}.token.important,.token.regex{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.deleted{color:red}`,
         }}
       />
     )}

...
@@ -121,36 +144,37 @@ pre.line-numbers > code {
 	position: relative;
   display: block;
 	padding-left: 3.5em;
+  padding-bottom: 0;
   white-space: inherit;
 }
 
 .line-numbers .line-numbers-rows {
 	position: absolute;
-	pointer-events: none;
 	top: 0;
-	font-size: 100%;
+  bottom: 0;
 	left: 0;
+	font-size: 100%;
 	width: 3em; /* works for line-numbers below 1000 lines */
 	letter-spacing: -1px;
-	border-right: 1px solid #999;
+	border-right: 1px solid ${NamedColors.BORDER_DEFAULT[themeScheme]};
 
 	-webkit-user-select: none;
 	-moz-user-select: none;
 	-ms-user-select: none;
 	user-select: none;
-
 }
 
-.line-numbers-rows > span {
+.line-numbers-rows > a {
   display: block;
   counter-increment: linenumber;
+  font-weight: normal;
 }
 
-.line-numbers-rows > span:before {
-  content: counter(linenumber);
-  color: #999;
+.line-numbers-rows > a:before {
+  content: attr(data-line-number);
+  color: ${NamedColors.TEXT_MUTED[themeScheme]};
   display: block;
-  padding-right: 0.8em;
+  padding-right: 0.4em;
   text-align: right;
 }
 `,

...
@@ -167,6 +191,8 @@ const StylePreTag = styled.pre<WithThemeSchemeProp>`
   box-shadow: none !important;
   text-shadow: none !important;
 
+  border-radius: 8px;
+
   ${({ themeScheme }) => css`
     background-color: ${NamedColors.CARD[themeScheme]} !important;
     border: 1px solid ${NamedColors.BORDER_DEFAULT[themeScheme]} !important;

app/islands/RepositoryFilesDiffsList.tsx
@@ -74,9 +74,9 @@ const RepositoryFilesDiffsList: ReactIsland<
             </Grid.Row>
           </Grid.Col>
           <Grid.Col fluid style={{ marginTop: 8 }}>
-            {chunks.map((chunk, idx) => (
+            {chunks.map((chunk, subIdx) => (
               <div
-                data-islandid={`${Code.name}$$${idx + 1}`}
+                data-islandid={`${Code.name}$$${idx + 1}${subIdx + 1}`}
                 key={[idx, chunk.content].join(":")}
                 style={{ width: "100%" }}
               >

@@ -15,6 +15,8 @@ import { RepositoryController } from "./controllers/repository";
 import { UserController } from "./controllers/user";
 import * as HomeController from "./controllers/HomeController";
 import * as ThemeController from "./controllers/ThemeController";
+import { AppThemeScheme } from "./types";
+import { SyntaxHighlightController } from "./controllers/syntax_highlight";
 
 export enum AppRoute {
   HOME = "home",

...
@@ -38,6 +40,7 @@ export enum AppRoute {
   REPOSITORY_FORK_ACTION = "repository.fork.action",
   REPOSITORY_PULL_REQUESTS = "repository.pull_requests",
   REPOSITORY_SHOW_OBJECT = "repository.show_object",
+  SYNTAX_HIGHLIGHT_HIGHLIGHT_CODE_ACTION = "syntax_highlight.highlight_code.action",
 }
 
 export interface AppRoutesParams extends IRouteParams {

...
@@ -151,6 +154,16 @@ export interface AppRoutesParams extends IRouteParams {
       objectId: string;
     };
   };
+  [AppRoute.SYNTAX_HIGHLIGHT_HIGHLIGHT_CODE_ACTION]: {
+    params: {
+      outputFormat?: "html" | "json";
+    };
+    body: {
+      code: string;
+      language: string;
+      theme_scheme: AppThemeScheme;
+    };
+  };
 }
 
 export const AppRoutesSchemas: Record<AppRoute, undefined | FastifySchema> = {

...
@@ -448,6 +461,36 @@ export const AppRoutesSchemas: Record<AppRoute, undefined | FastifySchema> = {
       },
     },
   },
+  [AppRoute.SYNTAX_HIGHLIGHT_HIGHLIGHT_CODE_ACTION]: {
+    params: {
+      type: "object",
+      required: [],
+      additionalProperties: false,
+      properties: {
+        outputFormat: {
+          type: "string",
+          enum: ["html", "json"],
+        },
+      },
+    },
+    body: {
+      type: "object",
+      required: ["code", "language", "theme_scheme"],
+      additionalProperties: false,
+      properties: {
+        code: {
+          type: "string",
+        },
+        language: {
+          type: "string",
+        },
+        theme_scheme: {
+          type: "string",
+          enum: ["light", "dark"],
+        },
+      },
+    },
+  },
 };
 
 const RootAppRouter: AppRouter = () => {

...
@@ -624,6 +667,16 @@ const RootAppRouter: AppRouter = () => {
           schema={AppRoutesSchemas[AppRoute.REPOSITORY_SHOW_OBJECT]}
           handler={RepositoryController.getRepositoryShowObjectView}
         />
+        {/* --- */}
+        <Router.Route
+          name={AppRoute.SYNTAX_HIGHLIGHT_HIGHLIGHT_CODE_ACTION}
+          method={"POST"}
+          path={"/api/syntax/highlight/:outputFormat"}
+          schema={
+            AppRoutesSchemas[AppRoute.SYNTAX_HIGHLIGHT_HIGHLIGHT_CODE_ACTION]
+          }
+          handler={SyntaxHighlightController.highlightCodeAction}
+        />
       </Router.Group>
     </Router.Root>
   );

@@ -182,7 +182,7 @@ async function main(): Promise<AppServer> {
         type: "application/javascript",
         textContent: `if (typeof window !== "undefined") {
   window.Prism = window.Prism || { plugins: {} };
-  window.Prism.manual = false;
+  window.Prism.manual = true;
   window.Prism.plugins.autoloader = {
     use_minifed: ${env === "production" ? "true" : "false"},
     languages_path: "/public/assets/prism/components/",

new file
app/utils/shared/escapeHtmlCode.ts
@@ -0,0 +1,9 @@
+export function escapeHtmlCode(text: string): string {
+  return (text || "")
+    .split(/&/gm)
+    .join("&amp;")
+    .split(/</gm)
+    .join("&lt;")
+    .split(/>/gm)
+    .join("&gt;");
+}

app/utils/style/NamedColors.ts
@@ -18,7 +18,7 @@ const NamedColors = {
     dark: Colors.PRIMARY_01,
   },
   CARD: {
-    dark: Colors.GRAY_DARK_02,
+    dark: Colors.GRAY_DARK_01,
     light: Colors.WHITE_01,
   },
   CARD_OVERLAY: {

@@ -41,6 +41,7 @@
     "fastify-static": "^4.6.1",
     "file-extension": "^4.0.5",
     "gray-matter": "^4.0.3",
+    "himalaya": "^1.1.0",
     "image-extensions": "^1.1.0",
     "is-image": "^3.1.0",
     "language-detect": "^1.1.0",

new file
public/.deps/prismjs.development.disabled.js
@@ -0,0 +1,3373 @@
+/* PrismJS 1.29.0
+https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+diff&plugins=line-highlight+line-numbers+autoloader+normalize-whitespace+diff-highlight */
+/// <reference lib="WebWorker"/>
+s;
+var _self =
+  typeof window !== "undefined"
+    ? window // if in browser
+    : typeof WorkerGlobalScope !== "undefined" &&
+      self instanceof WorkerGlobalScope
+    ? self // if in worker
+    : {}; // if in node js
+
+/**
+ * Prism: Lightweight, robust, elegant syntax highlighting
+ *
+ * @license MIT <https://opensource.org/licenses/MIT>
+ * @author Lea Verou <https://lea.verou.me>
+ * @namespace
+ * @public
+ */
+var Prism = (function (_self) {
+  // Private helper vars
+  var lang = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i;
+  var uniqueId = 0;
+
+  // The grammar object for plaintext
+  var plainTextGrammar = {};
+
+  var _ = {
+    /**
+     * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the
+     * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load
+     * additional languages or plugins yourself.
+     *
+     * By setting this value to `true`, Prism will not automatically highlight all code elements on the page.
+     *
+     * You obviously have to change this value before the automatic highlighting started. To do this, you can add an
+     * empty Prism object into the global scope before loading the Prism script like this:
+     *
+     * ```js
+     * window.Prism = window.Prism || {};
+     * Prism.manual = true;
+     * // add a new <script> to load Prism's script
+     * ```
+     *
+     * @default false
+     * @type {boolean}
+     * @memberof Prism
+     * @public
+     */
+    manual: _self.Prism && _self.Prism.manual,
+    /**
+     * By default, if Prism is in a web worker, it assumes that it is in a worker it created itself, so it uses
+     * `addEventListener` to communicate with its parent instance. However, if you're using Prism manually in your
+     * own worker, you don't want it to do this.
+     *
+     * By setting this value to `true`, Prism will not add its own listeners to the worker.
+     *
+     * You obviously have to change this value before Prism executes. To do this, you can add an
+     * empty Prism object into the global scope before loading the Prism script like this:
+     *
+     * ```js
+     * window.Prism = window.Prism || {};
+     * Prism.disableWorkerMessageHandler = true;
+     * // Load Prism's script
+     * ```
+     *
+     * @default false
+     * @type {boolean}
+     * @memberof Prism
+     * @public
+     */
+    disableWorkerMessageHandler:
+      _self.Prism && _self.Prism.disableWorkerMessageHandler,
+
+    /**
+     * A namespace for utility methods.
+     *
+     * All function in this namespace that are not explicitly marked as _public_ are for __internal use only__ and may
+     * change or disappear at any time.
+     *
+     * @namespace
+     * @memberof Prism
+     */
+    util: {
+      encode: function encode(tokens) {
+        if (tokens instanceof Token) {
+          return new Token(tokens.type, encode(tokens.content), tokens.alias);
+        } else if (Array.isArray(tokens)) {
+          return tokens.map(encode);
+        } else {
+          return tokens
+            .replace(/&/g, "&amp;")
+            .replace(/</g, "&lt;")
+            .replace(/\u00a0/g, " ");
+        }
+      },
+
+      /**
+       * Returns the name of the type of the given value.
+       *
+       * @param {any} o
+       * @returns {string}
+       * @example
+       * type(null)      === 'Null'
+       * type(undefined) === 'Undefined'
+       * type(123)       === 'Number'
+       * type('foo')     === 'String'
+       * type(true)      === 'Boolean'
+       * type([1, 2])    === 'Array'
+       * type({})        === 'Object'
+       * type(String)    === 'Function'
+       * type(/abc+/)    === 'RegExp'
+       */
+      type: function (o) {
+        return Object.prototype.toString.call(o).slice(8, -1);
+      },
+
+      /**
+       * Returns a unique number for the given object. Later calls will still return the same number.
+       *
+       * @param {Object} obj
+       * @returns {number}
+       */
+      objId: function (obj) {
+        if (!obj["__id"]) {
+          Object.defineProperty(obj, "__id", { value: ++uniqueId });
+        }
+        return obj["__id"];
+      },
+
+      /**
+       * Creates a deep clone of the given object.
+       *
+       * The main intended use of this function is to clone language definitions.
+       *
+       * @param {T} o
+       * @param {Record<number, any>} [visited]
+       * @returns {T}
+       * @template T
+       */
+      clone: function deepClone(o, visited) {
+        visited = visited || {};
+
+        var clone;
+        var id;
+        switch (_.util.type(o)) {
+          case "Object":
+            id = _.util.objId(o);
+            if (visited[id]) {
+              return visited[id];
+            }
+            clone = /** @type {Record<string, any>} */ ({});
+            visited[id] = clone;
+
+            for (var key in o) {
+              if (o.hasOwnProperty(key)) {
+                clone[key] = deepClone(o[key], visited);
+              }
+            }
+
+            return /** @type {any} */ (clone);
+
+          case "Array":
+            id = _.util.objId(o);
+            if (visited[id]) {
+              return visited[id];
+            }
+            clone = [];
+            visited[id] = clone;
+
+            /** @type {Array} */ (/** @type {any} */ (o)).forEach(function (
+              v,
+              i
+            ) {
+              clone[i] = deepClone(v, visited);
+            });
+
+            return /** @type {any} */ (clone);
+
+          default:
+            return o;
+        }
+      },
+
+      /**
+       * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class.
+       *
+       * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned.
+       *
+       * @param {Element} element
+       * @returns {string}
+       */
+      getLanguage: function (element) {
+        while (element) {
+          var m = lang.exec(element.className);
+          if (m) {
+            return m[1].toLowerCase();
+          }
+          element = element.parentElement;
+        }
+        return "none";
+      },
+
+      /**
+       * Sets the Prism `language-xxxx` class of the given element.
+       *
+       * @param {Element} element
+       * @param {string} language
+       * @returns {void}
+       */
+      setLanguage: function (element, language) {
+        // remove all `language-xxxx` classes
+        // (this might leave behind a leading space)
+        element.className = element.className.replace(RegExp(lang, "gi"), "");
+
+        // add the new `language-xxxx` class
+        // (using `classList` will automatically clean up spaces for us)
+        element.classList.add("language-" + language);
+      },
+
+      /**
+       * Returns the script element that is currently executing.
+       *
+       * This does __not__ work for line script element.
+       *
+       * @returns {HTMLScriptElement | null}
+       */
+      currentScript: function () {
+        if (typeof document === "undefined") {
+          return null;
+        }
+        if (
+          "currentScript" in document &&
+          1 < 2 /* hack to trip TS' flow analysis */
+        ) {
+          return /** @type {any} */ (document.currentScript);
+        }
+
+        // IE11 workaround
+        // we'll get the src of the current script by parsing IE11's error stack trace
+        // this will not work for inline scripts
+
+        try {
+          throw new Error();
+        } catch (err) {
+          // Get file src url from stack. Specifically works with the format of stack traces in IE.
+          // A stack will look like this:
+          //
+          // Error
+          //    at _.util.currentScript (http://localhost/components/prism-core.js:119:5)
+          //    at Global code (http://localhost/components/prism-core.js:606:1)
+
+          var src = (/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(err.stack) ||
+            [])[1];
+          if (src) {
+            var scripts = document.getElementsByTagName("script");
+            for (var i in scripts) {
+              if (scripts[i].src == src) {
+                return scripts[i];
+              }
+            }
+          }
+          return null;
+        }
+      },
+
+      /**
+       * Returns whether a given class is active for `element`.
+       *
+       * The class can be activated if `element` or one of its ancestors has the given class and it can be deactivated
+       * if `element` or one of its ancestors has the negated version of the given class. The _negated version_ of the
+       * given class is just the given class with a `no-` prefix.
+       *
+       * Whether the class is active is determined by the closest ancestor of `element` (where `element` itself is
+       * closest ancestor) that has the given class or the negated version of it. If neither `element` nor any of its
+       * ancestors have the given class or the negated version of it, then the default activation will be returned.
+       *
+       * In the paradoxical situation where the closest ancestor contains __both__ the given class and the negated
+       * version of it, the class is considered active.
+       *
+       * @param {Element} element
+       * @param {string} className
+       * @param {boolean} [defaultActivation=false]
+       * @returns {boolean}
+       */
+      isActive: function (element, className, defaultActivation) {
+        var no = "no-" + className;
+
+        while (element) {
+          var classList = element.classList;
+          if (classList.contains(className)) {
+            return true;
+          }
+          if (classList.contains(no)) {
+            return false;
+          }
+          element = element.parentElement;
+        }
+        return !!defaultActivation;
+      },
+    },
+
+    /**
+     * This namespace contains all currently loaded languages and the some helper functions to create and modify languages.
+     *
+     * @namespace
+     * @memberof Prism
+     * @public
+     */
+    languages: {
+      /**
+       * The grammar for plain, unformatted text.
+       */
+      plain: plainTextGrammar,
+      plaintext: plainTextGrammar,
+      text: plainTextGrammar,
+      txt: plainTextGrammar,
+
+      /**
+       * Creates a deep copy of the language with the given id and appends the given tokens.
+       *
+       * If a token in `redef` also appears in the copied language, then the existing token in the copied language
+       * will be overwritten at its original position.
+       *
+       * ## Best practices
+       *
+       * Since the position of overwriting tokens (token in `redef` that overwrite tokens in the copied language)
+       * doesn't matter, they can technically be in any order. However, this can be confusing to others that trying to
+       * understand the language definition because, normally, the order of tokens matters in Prism grammars.
+       *
+       * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens.
+       * Furthermore, all non-overwriting tokens should be placed after the overwriting ones.
+       *
+       * @param {string} id The id of the language to extend. This has to be a key in `Prism.languages`.
+       * @param {Grammar} redef The new tokens to append.
+       * @returns {Grammar} The new language created.
+       * @public
+       * @example
+       * Prism.languages['css-with-colors'] = Prism.languages.extend('css', {
+       *     // Prism.languages.css already has a 'comment' token, so this token will overwrite CSS' 'comment' token
+       *     // at its original position
+       *     'comment': { ... },
+       *     // CSS doesn't have a 'color' token, so this token will be appended
+       *     'color': /\b(?:red|green|blue)\b/
+       * });
+       */
+      extend: function (id, redef) {
+        var lang = _.util.clone(_.languages[id]);
+
+        for (var key in redef) {
+          lang[key] = redef[key];
+        }
+
+        return lang;
+      },
+
+      /**
+       * Inserts tokens _before_ another token in a language definition or any other grammar.
+       *
+       * ## Usage
+       *
+       * This helper method makes it easy to modify existing languages. For example, the CSS language definition
+       * not only defines CSS highlighting for CSS documents, but also needs to define highlighting for CSS embedded
+       * in HTML through `<style>` elements. To do this, it needs to modify `Prism.languages.markup` and add the
+       * appropriate tokens. However, `Prism.languages.markup` is a regular JavaScript object literal, so if you do
+       * this:
+       *
+       * ```js
+       * Prism.languages.markup.style = {
+       *     // token
+       * };
+       * ```
+       *
+       * then the `style` token will be added (and processed) at the end. `insertBefore` allows you to insert tokens
+       * before existing tokens. For the CSS example above, you would use it like this:
+       *
+       * ```js
+       * Prism.languages.insertBefore('markup', 'cdata', {
+       *     'style': {
+       *         // token
+       *     }
+       * });
+       * ```
+       *
+       * ## Special cases
+       *
+       * If the grammars of `inside` and `insert` have tokens with the same name, the tokens in `inside`'s grammar
+       * will be ignored.
+       *
+       * This behavior can be used to insert tokens after `before`:
+       *
+       * ```js
+       * Prism.languages.insertBefore('markup', 'comment', {
+       *     'comment': Prism.languages.markup.comment,
+       *     // tokens after 'comment'
+       * });
+       * ```
+       *
+       * ## Limitations
+       *
+       * The main problem `insertBefore` has to solve is iteration order. Since ES2015, the iteration order for object
+       * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave
+       * differently when keys are deleted and re-inserted. So `insertBefore` can't be implemented by temporarily
+       * deleting properties which is necessary to insert at arbitrary positions.
+       *
+       * To solve this problem, `insertBefore` doesn't actually insert the given tokens into the target object.
+       * Instead, it will create a new object and replace all references to the target object with the new one. This
+       * can be done without temporarily deleting properties, so the iteration order is well-defined.
+       *
+       * However, only references that can be reached from `Prism.languages` or `insert` will be replaced. I.e. if
+       * you hold the target object in a variable, then the value of the variable will not change.
+       *
+       * ```js
+       * var oldMarkup = Prism.languages.markup;
+       * var newMarkup = Prism.languages.insertBefore('markup', 'comment', { ... });
+       *
+       * assert(oldMarkup !== Prism.languages.markup);
+       * assert(newMarkup === Prism.languages.markup);
+       * ```
+       *
+       * @param {string} inside The property of `root` (e.g. a language id in `Prism.languages`) that contains the
+       * object to be modified.
+       * @param {string} before The key to insert before.
+       * @param {Grammar} insert An object containing the key-value pairs to be inserted.
+       * @param {Object<string, any>} [root] The object containing `inside`, i.e. the object that contains the
+       * object to be modified.
+       *
+       * Defaults to `Prism.languages`.
+       * @returns {Grammar} The new grammar object.
+       * @public
+       */
+      insertBefore: function (inside, before, insert, root) {
+        root = root || /** @type {any} */ (_.languages);
+        var grammar = root[inside];
+        /** @type {Grammar} */
+        var ret = {};
+
+        for (var token in grammar) {
+          if (grammar.hasOwnProperty(token)) {
+            if (token == before) {
+              for (var newToken in insert) {
+                if (insert.hasOwnProperty(newToken)) {
+                  ret[newToken] = insert[newToken];
+                }
+              }
+            }
+
+            // Do not insert token which also occur in insert. See #1525
+            if (!insert.hasOwnProperty(token)) {
+              ret[token] = grammar[token];
+            }
+          }
+        }
+
+        var old = root[inside];
+        root[inside] = ret;
+
+        // Update references in other language definitions
+        _.languages.DFS(_.languages, function (key, value) {
+          if (value === old && key != inside) {
+            this[key] = ret;
+          }
+        });
+
+        return ret;
+      },
+
+      // Traverse a language definition with Depth First Search
+      DFS: function DFS(o, callback, type, visited) {
+        visited = visited || {};
+
+        var objId = _.util.objId;
+
+        for (var i in o) {
+          if (o.hasOwnProperty(i)) {
+            callback.call(o, i, o[i], type || i);
+
+            var property = o[i];
+            var propertyType = _.util.type(property);
+
+            if (propertyType === "Object" && !visited[objId(property)]) {
+              visited[objId(property)] = true;
+              DFS(property, callback, null, visited);
+            } else if (propertyType === "Array" && !visited[objId(property)]) {
+              visited[objId(property)] = true;
+              DFS(property, callback, i, visited);
+            }
+          }
+        }
+      },
+    },
+
+    plugins: {},
+
+    /**
+     * This is the most high-level function in Prism’s API.
+     * It fetches all the elements that have a `.language-xxxx` class and then calls {@link Prism.highlightElement} on
+     * each one of them.
+     *
+     * This is equivalent to `Prism.highlightAllUnder(document, async, callback)`.
+     *
+     * @param {boolean} [async=false] Same as in {@link Prism.highlightAllUnder}.
+     * @param {HighlightCallback} [callback] Same as in {@link Prism.highlightAllUnder}.
+     * @memberof Prism
+     * @public
+     */
+    highlightAll: function (async, callback) {
+      _.highlightAllUnder(document, async, callback);
+    },
+
+    /**
+     * Fetches all the descendants of `container` that have a `.language-xxxx` class and then calls
+     * {@link Prism.highlightElement} on each one of them.
+     *
+     * The following hooks will be run:
+     * 1. `before-highlightall`
+     * 2. `before-all-elements-highlight`
+     * 3. All hooks of {@link Prism.highlightElement} for each element.
+     *
+     * @param {ParentNode} container The root element, whose descendants that have a `.language-xxxx` class will be highlighted.
+     * @param {boolean} [async=false] Whether each element is to be highlighted asynchronously using Web Workers.
+     * @param {HighlightCallback} [callback] An optional callback to be invoked on each element after its highlighting is done.
+     * @memberof Prism
+     * @public
+     */
+    highlightAllUnder: function (container, async, callback) {
+      var env = {
+        callback: callback,
+        container: container,
+        selector:
+          'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code',
+      };
+
+      _.hooks.run("before-highlightall", env);
+
+      env.elements = Array.prototype.slice.apply(
+        env.container.querySelectorAll(env.selector)
+      );
+
+      _.hooks.run("before-all-elements-highlight", env);
+
+      for (var i = 0, element; (element = env.elements[i++]); ) {
+        _.highlightElement(element, async === true, env.callback);
+      }
+    },
+
+    /**
+     * Highlights the code inside a single element.
+     *
+     * The following hooks will be run:
+     * 1. `before-sanity-check`
+     * 2. `before-highlight`
+     * 3. All hooks of {@link Prism.highlight}. These hooks will be run by an asynchronous worker if `async` is `true`.
+     * 4. `before-insert`
+     * 5. `after-highlight`
+     * 6. `complete`
+     *
+     * Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for
+     * the element's language.
+     *
+     * @param {Element} element The element containing the code.
+     * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier.
+     * @param {boolean} [async=false] Whether the element is to be highlighted asynchronously using Web Workers
+     * to improve performance and avoid blocking the UI when highlighting very large chunks of code. This option is
+     * [disabled by default](https://prismjs.com/faq.html#why-is-asynchronous-highlighting-disabled-by-default).
+     *
+     * Note: All language definitions required to highlight the code must be included in the main `prism.js` file for
+     * asynchronous highlighting to work. You can build your own bundle on the
+     * [Download page](https://prismjs.com/download.html).
+     * @param {HighlightCallback} [callback] An optional callback to be invoked after the highlighting is done.
+     * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously.
+     * @memberof Prism
+     * @public
+     */
+    highlightElement: function (element, async, callback) {
+      // Find language
+      var language = _.util.getLanguage(element);
+      var grammar = _.languages[language];
+
+      // Set language on the element, if not present
+      _.util.setLanguage(element, language);
+
+      // Set language on the parent, for styling
+      var parent = element.parentElement;
+      if (parent && parent.nodeName.toLowerCase() === "pre") {
+        _.util.setLanguage(parent, language);
+      }
+
+      var code = element.textContent;
+
+      var env = {
+        element: element,
+        language: language,
+        grammar: grammar,
+        code: code,
+      };
+
+      function insertHighlightedCode(highlightedCode) {
+        env.highlightedCode = highlightedCode;
+
+        _.hooks.run("before-insert", env);
+
+        env.element.innerHTML = env.highlightedCode;
+
+        _.hooks.run("after-highlight", env);
+        _.hooks.run("complete", env);
+        callback && callback.call(env.element);
+      }
+
+      _.hooks.run("before-sanity-check", env);
+
+      // plugins may change/add the parent/element
+      parent = env.element.parentElement;
+      if (
+        parent &&
+        parent.nodeName.toLowerCase() === "pre" &&
+        !parent.hasAttribute("tabindex")
+      ) {
+        parent.setAttribute("tabindex", "0");
+      }
+
+      if (!env.code) {
+        _.hooks.run("complete", env);
+        callback && callback.call(env.element);
+        return;
+      }
+
+      _.hooks.run("before-highlight", env);
+
+      if (!env.grammar) {
+        insertHighlightedCode(_.util.encode(env.code));
+        return;
+      }
+
+      if (async && _self.Worker) {
+        var worker = new Worker(_.filename);
+
+        worker.onmessage = function (evt) {
+          insertHighlightedCode(evt.data);
+        };
+
+        worker.postMessage(
+          JSON.stringify({
+            language: env.language,
+            code: env.code,
+            immediateClose: true,
+          })
+        );
+      } else {
+        insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
+      }
+    },
+
+    /**
+     * Low-level function, only use if you know what you’re doing. It accepts a string of text as input
+     * and the language definitions to use, and returns a string with the HTML produced.
+     *
+     * The following hooks will be run:
+     * 1. `before-tokenize`
+     * 2. `after-tokenize`
+     * 3. `wrap`: On each {@link Token}.
+     *
+     * @param {string} text A string with the code to be highlighted.
+     * @param {Grammar} grammar An object containing the tokens to use.
+     *
+     * Usually a language definition like `Prism.languages.markup`.
+     * @param {string} language The name of the language definition passed to `grammar`.
+     * @returns {string} The highlighted HTML.
+     * @memberof Prism
+     * @public
+     * @example
+     * Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript');
+     */
+    highlight: function (text, grammar, language) {
+      var env = {
+        code: text,
+        grammar: grammar,
+        language: language,
+      };
+      _.hooks.run("before-tokenize", env);
+      if (!env.grammar) {
+        throw new Error('The language "' + env.language + '" has no grammar.');
+      }
+      env.tokens = _.tokenize(env.code, env.grammar);
+      _.hooks.run("after-tokenize", env);
+      return Token.stringify(_.util.encode(env.tokens), env.language);
+    },
+
+    /**
+     * This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input
+     * and the language definitions to use, and returns an array with the tokenized code.
+     *
+     * When the language definition includes nested tokens, the function is called recursively on each of these tokens.
+     *
+     * This method could be useful in other contexts as well, as a very crude parser.
+     *
+     * @param {string} text A string with the code to be highlighted.
+     * @param {Grammar} grammar An object containing the tokens to use.
+     *
+     * Usually a language definition like `Prism.languages.markup`.
+     * @returns {TokenStream} An array of strings and tokens, a token stream.
+     * @memberof Prism
+     * @public
+     * @example
+     * let code = `var foo = 0;`;
+     * let tokens = Prism.tokenize(code, Prism.languages.javascript);
+     * tokens.forEach(token => {
+     *     if (token instanceof Prism.Token && token.type === 'number') {
+     *         console.log(`Found numeric literal: ${token.content}`);
+     *     }
+     * });
+     */
+    tokenize: function (text, grammar) {
+      var rest = grammar.rest;
+      if (rest) {
+        for (var token in rest) {
+          grammar[token] = rest[token];
+        }
+
+        delete grammar.rest;
+      }
+
+      var tokenList = new LinkedList();
+      addAfter(tokenList, tokenList.head, text);
+
+      matchGrammar(text, tokenList, grammar, tokenList.head, 0);
+
+      return toArray(tokenList);
+    },
+
+    /**
+     * @namespace
+     * @memberof Prism
+     * @public
+     */
+    hooks: {
+      all: {},
+
+      /**
+       * Adds the given callback to the list of callbacks for the given hook.
+       *
+       * The callback will be invoked when the hook it is registered for is run.
+       * Hooks are usually directly run by a highlight function but you can also run hooks yourself.
+       *
+       * One callback function can be registered to multiple hooks and the same hook multiple times.
+       *
+       * @param {string} name The name of the hook.
+       * @param {HookCallback} callback The callback function which is given environment variables.
+       * @public
+       */
+      add: function (name, callback) {
+        var hooks = _.hooks.all;
+
+        hooks[name] = hooks[name] || [];
+
+        hooks[name].push(callback);
+      },
+
+      /**
+       * Runs a hook invoking all registered callbacks with the given environment variables.
+       *
+       * Callbacks will be invoked synchronously and in the order in which they were registered.
+       *
+       * @param {string} name The name of the hook.
+       * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered.
+       * @public
+       */
+      run: function (name, env) {
+        var callbacks = _.hooks.all[name];
+
+        if (!callbacks || !callbacks.length) {
+          return;
+        }
+
+        for (var i = 0, callback; (callback = callbacks[i++]); ) {
+          callback(env);
+        }
+      },
+    },
+
+    Token: Token,
+  };
+  _self.Prism = _;
+
+  // Typescript note:
+  // The following can be used to import the Token type in JSDoc:
+  //
+  //   @typedef {InstanceType<import("./prism-core")["Token"]>} Token
+
+  /**
+   * Creates a new token.
+   *
+   * @param {string} type See {@link Token#type type}
+   * @param {string | TokenStream} content See {@link Token#content content}
+   * @param {string|string[]} [alias] The alias(es) of the token.
+   * @param {string} [matchedStr=""] A copy of the full string this token was created from.
+   * @class
+   * @global
+   * @public
+   */
+  function Token(type, content, alias, matchedStr) {
+    /**
+     * The type of the token.
+     *
+     * This is usually the key of a pattern in a {@link Grammar}.
+     *
+     * @type {string}
+     * @see GrammarToken
+     * @public
+     */
+    this.type = type;
+    /**
+     * The strings or tokens contained by this token.
+     *
+     * This will be a token stream if the pattern matched also defined an `inside` grammar.
+     *
+     * @type {string | TokenStream}
+     * @public
+     */
+    this.content = content;
+    /**
+     * The alias(es) of the token.
+     *
+     * @type {string|string[]}
+     * @see GrammarToken
+     * @public
+     */
+    this.alias = alias;
+    // Copy of the full string this token was created from
+    this.length = (matchedStr || "").length | 0;
+  }
+
+  /**
+   * A token stream is an array of strings and {@link Token Token} objects.
+   *
+   * Token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process
+   * them.
+   *
+   * 1. No adjacent strings.
+   * 2. No empty strings.
+   *
+   *    The only exception here is the token stream that only contains the empty string and nothing else.
+   *
+   * @typedef {Array<string | Token>} TokenStream
+   * @global
+   * @public
+   */
+
+  /**
+   * Converts the given token or token stream to an HTML representation.
+   *
+   * The following hooks will be run:
+   * 1. `wrap`: On each {@link Token}.
+   *
+   * @param {string | Token | TokenStream} o The token or token stream to be converted.
+   * @param {string} language The name of current language.
+   * @returns {string} The HTML representation of the token or token stream.
+   * @memberof Token
+   * @static
+   */
+  Token.stringify = function stringify(o, language) {
+    if (typeof o == "string") {
+      return o;
+    }
+    if (Array.isArray(o)) {
+      var s = "";
+      o.forEach(function (e) {
+        s += stringify(e, language);
+      });
+      return s;
+    }
+
+    var env = {
+      type: o.type,
+      content: stringify(o.content, language),
+      tag: "span",
+      classes: ["token", o.type],
+      attributes: {},
+      language: language,
+    };
+
+    var aliases = o.alias;
+    if (aliases) {
+      if (Array.isArray(aliases)) {
+        Array.prototype.push.apply(env.classes, aliases);
+      } else {
+        env.classes.push(aliases);
+      }
+    }
+
+    _.hooks.run("wrap", env);
+
+    var attributes = "";
+    for (var name in env.attributes) {
+      attributes +=
+        " " +
+        name +
+        '="' +
+        (env.attributes[name] || "").replace(/"/g, "&quot;") +
+        '"';
+    }
+
+    return (
+      "<" +
+      env.tag +
+      ' class="' +
+      env.classes.join(" ") +
+      '"' +
+      attributes +
+      ">" +
+      env.content +
+      "</" +
+      env.tag +
+      ">"
+    );
+  };
+
+  /**
+   * @param {RegExp} pattern
+   * @param {number} pos
+   * @param {string} text
+   * @param {boolean} lookbehind
+   * @returns {RegExpExecArray | null}
+   */
+  function matchPattern(pattern, pos, text, lookbehind) {
+    pattern.lastIndex = pos;
+    var match = pattern.exec(text);
+    if (match && lookbehind && match[1]) {
+      // change the match to remove the text matched by the Prism lookbehind group
+      var lookbehindLength = match[1].length;
+      match.index += lookbehindLength;
+      match[0] = match[0].slice(lookbehindLength);
+    }
+    return match;
+  }
+
+  /**
+   * @param {string} text
+   * @param {LinkedList<string | Token>} tokenList
+   * @param {any} grammar
+   * @param {LinkedListNode<string | Token>} startNode
+   * @param {number} startPos
+   * @param {RematchOptions} [rematch]
+   * @returns {void}
+   * @private
+   *
+   * @typedef RematchOptions
+   * @property {string} cause
+   * @property {number} reach
+   */
+  function matchGrammar(
+    text,
+    tokenList,
+    grammar,
+    startNode,
+    startPos,
+    rematch
+  ) {
+    for (var token in grammar) {
+      if (!grammar.hasOwnProperty(token) || !grammar[token]) {
+        continue;
+      }
+
+      var patterns = grammar[token];
+      patterns = Array.isArray(patterns) ? patterns : [patterns];
+
+      for (var j = 0; j < patterns.length; ++j) {
+        if (rematch && rematch.cause == token + "," + j) {
+          return;
+        }
+
+        var patternObj = patterns[j];
+        var inside = patternObj.inside;
+        var lookbehind = !!patternObj.lookbehind;
+        var greedy = !!patternObj.greedy;
+        var alias = patternObj.alias;
+
+        if (greedy && !patternObj.pattern.global) {
+          // Without the global flag, lastIndex won't work
+          var flags = patternObj.pattern.toString().match(/[imsuy]*$/)[0];
+          patternObj.pattern = RegExp(patternObj.pattern.source, flags + "g");
+        }
+
+        /** @type {RegExp} */
+        var pattern = patternObj.pattern || patternObj;
+
+        for (
+          // iterate the token list and keep track of the current token/string position
+          var currentNode = startNode.next, pos = startPos;
+          currentNode !== tokenList.tail;
+          pos += currentNode.value.length, currentNode = currentNode.next
+        ) {
+          if (rematch && pos >= rematch.reach) {
+            break;
+          }
+
+          var str = currentNode.value;
+
+          if (tokenList.length > text.length) {
+            // Something went terribly wrong, ABORT, ABORT!
+            return;
+          }
+
+          if (str instanceof Token) {
+            continue;
+          }
+
+          var removeCount = 1; // this is the to parameter of removeBetween
+          var match;
+
+          if (greedy) {
+            match = matchPattern(pattern, pos, text, lookbehind);
+            if (!match || match.index >= text.length) {
+              break;
+            }
+
+            var from = match.index;
+            var to = match.index + match[0].length;
+            var p = pos;
+
+            // find the node that contains the match
+            p += currentNode.value.length;
+            while (from >= p) {
+              currentNode = currentNode.next;
+              p += currentNode.value.length;
+            }
+            // adjust pos (and p)
+            p -= currentNode.value.length;
+            pos = p;
+
+            // the current node is a Token, then the match starts inside another Token, which is invalid
+            if (currentNode.value instanceof Token) {
+              continue;
+            }
+
+            // find the last node which is affected by this match
+            for (
+              var k = currentNode;
+              k !== tokenList.tail && (p < to || typeof k.value === "string");
+              k = k.next
+            ) {
+              removeCount++;
+              p += k.value.length;
+            }
+            removeCount--;
+
+            // replace with the new match
+            str = text.slice(pos, p);
+            match.index -= pos;
+          } else {
+            match = matchPattern(pattern, 0, str, lookbehind);
+            if (!match) {
+              continue;
+            }
+          }
+
+          // eslint-disable-next-line no-redeclare
+          var from = match.index;
+          var matchStr = match[0];
+          var before = str.slice(0, from);
+          var after = str.slice(from + matchStr.length);
+
+          var reach = pos + str.length;
+          if (rematch && reach > rematch.reach) {
+            rematch.reach = reach;
+          }
+
+          var removeFrom = currentNode.prev;
+
+          if (before) {
+            removeFrom = addAfter(tokenList, removeFrom, before);
+            pos += before.length;
+          }
+
+          removeRange(tokenList, removeFrom, removeCount);
+
+          var wrapped = new Token(
+            token,
+            inside ? _.tokenize(matchStr, inside) : matchStr,
+            alias,
+            matchStr
+          );
+          currentNode = addAfter(tokenList, removeFrom, wrapped);
+
+          if (after) {
+            addAfter(tokenList, currentNode, after);
+          }
+
+          if (removeCount > 1) {
+            // at least one Token object was removed, so we have to do some rematching
+            // this can only happen if the current pattern is greedy
+
+            /** @type {RematchOptions} */
+            var nestedRematch = {
+              cause: token + "," + j,
+              reach: reach,
+            };
+            matchGrammar(
+              text,
+              tokenList,
+              grammar,
+              currentNode.prev,
+              pos,
+              nestedRematch
+            );
+
+            // the reach might have been extended because of the rematching
+            if (rematch && nestedRematch.reach > rematch.reach) {
+              rematch.reach = nestedRematch.reach;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * @typedef LinkedListNode
+   * @property {T} value
+   * @property {LinkedListNode<T> | null} prev The previous node.
+   * @property {LinkedListNode<T> | null} next The next node.
+   * @template T
+   * @private
+   */
+
+  /**
+   * @template T
+   * @private
+   */
+  function LinkedList() {
+    /** @type {LinkedListNode<T>} */
+    var head = { value: null, prev: null, next: null };
+    /** @type {LinkedListNode<T>} */
+    var tail = { value: null, prev: head, next: null };
+    head.next = tail;
+
+    /** @type {LinkedListNode<T>} */
+    this.head = head;
+    /** @type {LinkedListNode<T>} */
+    this.tail = tail;
+    this.length = 0;
+  }
+
+  /**
+   * Adds a new node with the given value to the list.
+   *
+   * @param {LinkedList<T>} list
+   * @param {LinkedListNode<T>} node
+   * @param {T} value
+   * @returns {LinkedListNode<T>} The added node.
+   * @template T
+   */
+  function addAfter(list, node, value) {
+    // assumes that node != list.tail && values.length >= 0
+    var next = node.next;
+
+    var newNode = { value: value, prev: node, next: next };
+    node.next = newNode;
+    next.prev = newNode;
+    list.length++;
+
+    return newNode;
+  }
+  /**
+   * Removes `count` nodes after the given node. The given node will not be removed.
+   *
+   * @param {LinkedList<T>} list
+   * @param {LinkedListNode<T>} node
+   * @param {number} count
+   * @template T
+   */
+  function removeRange(list, node, count) {
+    var next = node.next;
+    for (var i = 0; i < count && next !== list.tail; i++) {
+      next = next.next;
+    }
+    node.next = next;
+    next.prev = node;
+    list.length -= i;
+  }
+  /**
+   * @param {LinkedList<T>} list
+   * @returns {T[]}
+   * @template T
+   */
+  function toArray(list) {
+    var array = [];
+    var node = list.head.next;
+    while (node !== list.tail) {
+      array.push(node.value);
+      node = node.next;
+    }
+    return array;
+  }
+
+  if (!_self.document) {
+    if (!_self.addEventListener) {
+      // in Node.js
+      return _;
+    }
+
+    if (!_.disableWorkerMessageHandler) {
+      // In worker
+      _self.addEventListener(
+        "message",
+        function (evt) {
+          var message = JSON.parse(evt.data);
+          var lang = message.language;
+          var code = message.code;
+          var immediateClose = message.immediateClose;
+
+          _self.postMessage(_.highlight(code, _.languages[lang], lang));
+          if (immediateClose) {
+            _self.close();
+          }
+        },
+        false
+      );
+    }
+
+    return _;
+  }
+
+  // Get current script and highlight
+  var script = _.util.currentScript();
+
+  if (script) {
+    _.filename = script.src;
+
+    if (script.hasAttribute("data-manual")) {
+      _.manual = true;
+    }
+  }
+
+  function highlightAutomaticallyCallback() {
+    if (!_.manual) {
+      _.highlightAll();
+    }
+  }
+
+  if (!_.manual) {
+    // If the document state is "loading", then we'll use DOMContentLoaded.
+    // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the
+    // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they
+    // might take longer one animation frame to execute which can create a race condition where only some plugins have
+    // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded.
+    // See https://github.com/PrismJS/prism/issues/2102
+    var readyState = document.readyState;
+    if (
+      readyState === "loading" ||
+      (readyState === "interactive" && script && script.defer)
+    ) {
+      document.addEventListener(
+        "DOMContentLoaded",
+        highlightAutomaticallyCallback
+      );
+    } else {
+      if (window.requestAnimationFrame) {
+        window.requestAnimationFrame(highlightAutomaticallyCallback);
+      } else {
+        window.setTimeout(highlightAutomaticallyCallback, 16);
+      }
+    }
+  }
+
+  return _;
+})(_self);
+
+if (typeof module !== "undefined" && module.exports) {
+  module.exports = Prism;
+}
+
+// hack for components to work correctly in node.js
+if (typeof global !== "undefined") {
+  global.Prism = Prism;
+}
+
+// some additional documentation/types
+
+/**
+ * The expansion of a simple `RegExp` literal to support additional properties.
+ *
+ * @typedef GrammarToken
+ * @property {RegExp} pattern The regular expression of the token.
+ * @property {boolean} [lookbehind=false] If `true`, then the first capturing group of `pattern` will (effectively)
+ * behave as a lookbehind group meaning that the captured text will not be part of the matched text of the new token.
+ * @property {boolean} [greedy=false] Whether the token is greedy.
+ * @property {string|string[]} [alias] An optional alias or list of aliases.
+ * @property {Grammar} [inside] The nested grammar of this token.
+ *
+ * The `inside` grammar will be used to tokenize the text value of each token of this kind.
+ *
+ * This can be used to make nested and even recursive language definitions.
+ *
+ * Note: This can cause infinite recursion. Be careful when you embed different languages or even the same language into
+ * each another.
+ * @global
+ * @public
+ */
+
+/**
+ * @typedef Grammar
+ * @type {Object<string, RegExp | GrammarToken | Array<RegExp | GrammarToken>>}
+ * @property {Grammar} [rest] An optional grammar object that will be appended to this grammar.
+ * @global
+ * @public
+ */
+
+/**
+ * A function which will invoked after an element was successfully highlighted.
+ *
+ * @callback HighlightCallback
+ * @param {Element} element The element successfully highlighted.
+ * @returns {void}
+ * @global
+ * @public
+ */
+
+/**
+ * @callback HookCallback
+ * @param {Object<string, any>} env The environment variables of the hook.
+ * @returns {void}
+ * @global
+ * @public
+ */
+Prism.languages.markup = {
+  comment: {
+    pattern: /<!--(?:(?!<!--)[\s\S])*?-->/,
+    greedy: true,
+  },
+  prolog: {
+    pattern: /<\?[\s\S]+?\?>/,
+    greedy: true,
+  },
+  doctype: {
+    // https://www.w3.org/TR/xml/#NT-doctypedecl
+    pattern:
+      /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
+    greedy: true,
+    inside: {
+      "internal-subset": {
+        pattern: /(^[^\[]*\[)[\s\S]+(?=\]>$)/,
+        lookbehind: true,
+        greedy: true,
+        inside: null, // see below
+      },
+      string: {
+        pattern: /"[^"]*"|'[^']*'/,
+        greedy: true,
+      },
+      punctuation: /^<!|>$|[[\]]/,
+      "doctype-tag": /^DOCTYPE/i,
+      name: /[^\s<>'"]+/,
+    },
+  },
+  cdata: {
+    pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
+    greedy: true,
+  },
+  tag: {
+    pattern:
+      /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
+    greedy: true,
+    inside: {
+      tag: {
+        pattern: /^<\/?[^\s>\/]+/,
+        inside: {
+          punctuation: /^<\/?/,
+          namespace: /^[^\s>\/:]+:/,
+        },
+      },
+      "special-attr": [],
+      "attr-value": {
+        pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
+        inside: {
+          punctuation: [
+            {
+              pattern: /^=/,
+              alias: "attr-equals",
+            },
+            {
+              pattern: /^(\s*)["']|["']$/,
+              lookbehind: true,
+            },
+          ],
+        },
+      },
+      punctuation: /\/?>/,
+      "attr-name": {
+        pattern: /[^\s>\/]+/,
+        inside: {
+          namespace: /^[^\s>\/:]+:/,
+        },
+      },
+    },
+  },
+  entity: [
+    {
+      pattern: /&[\da-z]{1,8};/i,
+      alias: "named-entity",
+    },
+    /&#x?[\da-f]{1,8};/i,
+  ],
+};
+
+Prism.languages.markup["tag"].inside["attr-value"].inside["entity"] =
+  Prism.languages.markup["entity"];
+Prism.languages.markup["doctype"].inside["internal-subset"].inside =
+  Prism.languages.markup;
+
+// Plugin to make entity title show the real entity, idea by Roman Komarov
+Prism.hooks.add("wrap", function (env) {
+  if (env.type === "entity") {
+    env.attributes["title"] = env.content.replace(/&amp;/, "&");
+  }
+});
+
+Object.defineProperty(Prism.languages.markup.tag, "addInlined", {
+  /**
+   * Adds an inlined language to markup.
+   *
+   * An example of an inlined language is CSS with `<style>` tags.
+   *
+   * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
+   * case insensitive.
+   * @param {string} lang The language key.
+   * @example
+   * addInlined('style', 'css');
+   */
+  value: function addInlined(tagName, lang) {
+    var includedCdataInside = {};
+    includedCdataInside["language-" + lang] = {
+      pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
+      lookbehind: true,
+      inside: Prism.languages[lang],
+    };
+    includedCdataInside["cdata"] = /^<!\[CDATA\[|\]\]>$/i;
+
+    var inside = {
+      "included-cdata": {
+        pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
+        inside: includedCdataInside,
+      },
+    };
+    inside["language-" + lang] = {
+      pattern: /[\s\S]+/,
+      inside: Prism.languages[lang],
+    };
+
+    var def = {};
+    def[tagName] = {
+      pattern: RegExp(
+        /(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(
+          /__/g,
+          function () {
+            return tagName;
+          }
+        ),
+        "i"
+      ),
+      lookbehind: true,
+      greedy: true,
+      inside: inside,
+    };
+
+    Prism.languages.insertBefore("markup", "cdata", def);
+  },
+});
+Object.defineProperty(Prism.languages.markup.tag, "addAttribute", {
+  /**
+   * Adds an pattern to highlight languages embedded in HTML attributes.
+   *
+   * An example of an inlined language is CSS with `style` attributes.
+   *
+   * @param {string} attrName The name of the tag that contains the inlined language. This name will be treated as
+   * case insensitive.
+   * @param {string} lang The language key.
+   * @example
+   * addAttribute('style', 'css');
+   */
+  value: function (attrName, lang) {
+    Prism.languages.markup.tag.inside["special-attr"].push({
+      pattern: RegExp(
+        /(^|["'\s])/.source +
+          "(?:" +
+          attrName +
+          ")" +
+          /\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,
+        "i"
+      ),
+      lookbehind: true,
+      inside: {
+        "attr-name": /^[^\s=]+/,
+        "attr-value": {
+          pattern: /=[\s\S]+/,
+          inside: {
+            value: {
+              pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,
+              lookbehind: true,
+              alias: [lang, "language-" + lang],
+              inside: Prism.languages[lang],
+            },
+            punctuation: [
+              {
+                pattern: /^=/,
+                alias: "attr-equals",
+              },
+              /"|'/,
+            ],
+          },
+        },
+      },
+    });
+  },
+});
+
+Prism.languages.html = Prism.languages.markup;
+Prism.languages.mathml = Prism.languages.markup;
+Prism.languages.svg = Prism.languages.markup;
+
+Prism.languages.xml = Prism.languages.extend("markup", {});
+Prism.languages.ssml = Prism.languages.xml;
+Prism.languages.atom = Prism.languages.xml;
+Prism.languages.rss = Prism.languages.xml;
+
+(function (Prism) {
+  var string =
+    /(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;
+
+  Prism.languages.css = {
+    comment: /\/\*[\s\S]*?\*\//,
+    atrule: {
+      pattern: RegExp(
+        "@[\\w-](?:" +
+          /[^;{\s"']|\s+(?!\s)/.source +
+          "|" +
+          string.source +
+          ")*?" +
+          /(?:;|(?=\s*\{))/.source
+      ),
+      inside: {
+        rule: /^@[\w-]+/,
+        "selector-function-argument": {
+          pattern:
+            /(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,
+          lookbehind: true,
+          alias: "selector",
+        },
+        keyword: {
+          pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/,
+          lookbehind: true,
+        },
+        // See rest below
+      },
+    },
+    url: {
+      // https://drafts.csswg.org/css-values-3/#urls
+      pattern: RegExp(
+        "\\burl\\((?:" +
+          string.source +
+          "|" +
+          /(?:[^\\\r\n()"']|\\[\s\S])*/.source +
+          ")\\)",
+        "i"
+      ),
+      greedy: true,
+      inside: {
+        function: /^url/i,
+        punctuation: /^\(|\)$/,
+        string: {
+          pattern: RegExp("^" + string.source + "$"),
+          alias: "url",
+        },
+      },
+    },
+    selector: {
+      pattern: RegExp(
+        "(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|" +
+          string.source +
+          ")*(?=\\s*\\{)"
+      ),
+      lookbehind: true,
+    },
+    string: {
+      pattern: string,
+      greedy: true,
+    },
+    property: {
+      pattern:
+        /(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,
+      lookbehind: true,
+    },
+    important: /!important\b/i,
+    function: {
+      pattern: /(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,
+      lookbehind: true,
+    },
+    punctuation: /[(){};:,]/,
+  };
+
+  Prism.languages.css["atrule"].inside.rest = Prism.languages.css;
+
+  var markup = Prism.languages.markup;
+  if (markup) {
+    markup.tag.addInlined("style", "css");
+    markup.tag.addAttribute("style", "css");
+  }
+})(Prism);
+
+Prism.languages.clike = {
+  comment: [
+    {
+      pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
+      lookbehind: true,
+      greedy: true,
+    },
+    {
+      pattern: /(^|[^\\:])\/\/.*/,
+      lookbehind: true,
+      greedy: true,
+    },
+  ],
+  string: {
+    pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
+    greedy: true,
+  },
+  "class-name": {
+    pattern:
+      /(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,
+    lookbehind: true,
+    inside: {
+      punctuation: /[.\\]/,
+    },
+  },
+  keyword:
+    /\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,
+  boolean: /\b(?:false|true)\b/,
+  function: /\b\w+(?=\()/,
+  number: /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,
+  operator: /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
+  punctuation: /[{}[\];(),.:]/,
+};
+
+Prism.languages.javascript = Prism.languages.extend("clike", {
+  "class-name": [
+    Prism.languages.clike["class-name"],
+    {
+      pattern:
+        /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,
+      lookbehind: true,
+    },
+  ],
+  keyword: [
+    {
+      pattern: /((?:^|\})\s*)catch\b/,
+      lookbehind: true,
+    },
+    {
+      pattern:
+        /(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
+      lookbehind: true,
+    },
+  ],
+  // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
+  function:
+    /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
+  number: {
+    pattern: RegExp(
+      /(^|[^\w$])/.source +
+        "(?:" +
+        // constant
+        (/NaN|Infinity/.source +
+          "|" +
+          // binary integer
+          /0[bB][01]+(?:_[01]+)*n?/.source +
+          "|" +
+          // octal integer
+          /0[oO][0-7]+(?:_[0-7]+)*n?/.source +
+          "|" +
+          // hexadecimal integer
+          /0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source +
+          "|" +
+          // decimal bigint
+          /\d+(?:_\d+)*n/.source +
+          "|" +
+          // decimal number (integer or float) but no bigint
+          /(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/
+            .source) +
+        ")" +
+        /(?![\w$])/.source
+    ),
+    lookbehind: true,
+  },
+  operator:
+    /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/,
+});
+
+Prism.languages.javascript["class-name"][0].pattern =
+  /(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/;
+
+Prism.languages.insertBefore("javascript", "keyword", {
+  regex: {
+    pattern: RegExp(
+      // lookbehind
+      // eslint-disable-next-line regexp/no-dupe-characters-character-class
+      /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source +
+        // Regex pattern:
+        // There are 2 regex patterns here. The RegExp set notation proposal added support for nested character
+        // classes if the `v` flag is present. Unfortunately, nested CCs are both context-free and incompatible
+        // with the only syntax, so we have to define 2 different regex patterns.
+        /\//.source +
+        "(?:" +
+        /(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/
+          .source +
+        "|" +
+        // `v` flag syntax. This supports 3 levels of nested character classes.
+        /(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/
+          .source +
+        ")" +
+        // lookahead
+        /(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source
+    ),
+    lookbehind: true,
+    greedy: true,
+    inside: {
+      "regex-source": {
+        pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/,
+        lookbehind: true,
+        alias: "language-regex",
+        inside: Prism.languages.regex,
+      },
+      "regex-delimiter": /^\/|\/$/,
+      "regex-flags": /^[a-z]+$/,
+    },
+  },
+  // This must be declared before keyword because we use "function" inside the look-forward
+  "function-variable": {
+    pattern:
+      /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,
+    alias: "function",
+  },
+  parameter: [
+    {
+      pattern:
+        /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,
+      lookbehind: true,
+      inside: Prism.languages.javascript,
+    },
+    {
+      pattern:
+        /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,
+      lookbehind: true,
+      inside: Prism.languages.javascript,
+    },
+    {
+      pattern:
+        /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,
+      lookbehind: true,
+      inside: Prism.languages.javascript,
+    },
+    {
+      pattern:
+        /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,
+      lookbehind: true,
+      inside: Prism.languages.javascript,
+    },
+  ],
+  constant: /\b[A-Z](?:[A-Z_]|\dx?)*\b/,
+});
+
+Prism.languages.insertBefore("javascript", "string", {
+  hashbang: {
+    pattern: /^#!.*/,
+    greedy: true,
+    alias: "comment",
+  },
+  "template-string": {
+    pattern:
+      /`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,
+    greedy: true,
+    inside: {
+      "template-punctuation": {
+        pattern: /^`|`$/,
+        alias: "string",
+      },
+      interpolation: {
+        pattern:
+          /((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,
+        lookbehind: true,
+        inside: {
+          "interpolation-punctuation": {
+            pattern: /^\$\{|\}$/,
+            alias: "punctuation",
+          },
+          rest: Prism.languages.javascript,
+        },
+      },
+      string: /[\s\S]+/,
+    },
+  },
+  "string-property": {
+    pattern:
+      /((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,
+    lookbehind: true,
+    greedy: true,
+    alias: "property",
+  },
+});
+
+Prism.languages.insertBefore("javascript", "operator", {
+  "literal-property": {
+    pattern:
+      /((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,
+    lookbehind: true,
+    alias: "property",
+  },
+});
+
+if (Prism.languages.markup) {
+  Prism.languages.markup.tag.addInlined("script", "javascript");
+
+  // add attribute support for all DOM events.
+  // https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events
+  Prism.languages.markup.tag.addAttribute(
+    /on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/
+      .source,
+    "javascript"
+  );
+}
+
+Prism.languages.js = Prism.languages.javascript;
+
+(function (Prism) {
+  Prism.languages.diff = {
+    coord: [
+      // Match all kinds of coord lines (prefixed by "+++", "---" or "***").
+      /^(?:\*{3}|-{3}|\+{3}).*$/m,
+      // Match "@@ ... @@" coord lines in unified diff.
+      /^@@.*@@$/m,
+      // Match coord lines in normal diff (starts with a number).
+      /^\d.*$/m,
+    ],
+
+    // deleted, inserted, unchanged, diff
+  };
+
+  /**
+   * A map from the name of a block to its line prefix.
+   *
+   * @type {Object<string, string>}
+   */
+  var PREFIXES = {
+    "deleted-sign": "-",
+    "deleted-arrow": "<",
+    "inserted-sign": "+",
+    "inserted-arrow": ">",
+    unchanged: " ",
+    diff: "!",
+  };
+
+  // add a token for each prefix
+  Object.keys(PREFIXES).forEach(function (name) {
+    var prefix = PREFIXES[name];
+
+    var alias = [];
+    if (!/^\w+$/.test(name)) {
+      // "deleted-sign" -> "deleted"
+      alias.push(/\w+/.exec(name)[0]);
+    }
+    if (name === "diff") {
+      alias.push("bold");
+    }
+
+    Prism.languages.diff[name] = {
+      pattern: RegExp("^(?:[" + prefix + "].*(?:\r\n?|\n|(?![\\s\\S])))+", "m"),
+      alias: alias,
+      inside: {
+        line: {
+          pattern: /(.)(?=[\s\S]).*(?:\r\n?|\n)?/,
+          lookbehind: true,
+        },
+        prefix: {
+          pattern: /[\s\S]/,
+          alias: /\w+/.exec(name)[0],
+        },
+      },
+    };
+  });
+
+  // make prefixes available to Diff plugin
+  Object.defineProperty(Prism.languages.diff, "PREFIXES", {
+    value: PREFIXES,
+  });
+})(Prism);
+
+(function () {
+  if (
+    typeof Prism === "undefined" ||
+    typeof document === "undefined" ||
+    !document.querySelector
+  ) {
+    return;
+  }
+
+  var LINE_NUMBERS_CLASS = "line-numbers";
+  var LINKABLE_LINE_NUMBERS_CLASS = "linkable-line-numbers";
+  var NEW_LINE_EXP = /\n(?!$)/g;
+
+  /**
+   * @param {string} selector
+   * @param {ParentNode} [container]
+   * @returns {HTMLElement[]}
+   */
+  function $$(selector, container) {
+    return Array.prototype.slice.call(
+      (container || document).querySelectorAll(selector)
+    );
+  }
+
+  /**
+   * Returns whether the given element has the given class.
+   *
+   * @param {Element} element
+   * @param {string} className
+   * @returns {boolean}
+   */
+  function hasClass(element, className) {
+    return element.classList.contains(className);
+  }
+
+  /**
+   * Calls the given function.
+   *
+   * @param {() => any} func
+   * @returns {void}
+   */
+  function callFunction(func) {
+    func();
+  }
+
+  // Some browsers round the line-height, others don't.
+  // We need to test for it to position the elements properly.
+  var isLineHeightRounded = (function () {
+    var res;
+    return function () {
+      if (typeof res === "undefined") {
+        var d = document.createElement("div");
+        d.style.fontSize = "13px";
+        d.style.lineHeight = "1.5";
+        d.style.padding = "0";
+        d.style.border = "0";
+        d.innerHTML = "&nbsp;<br />&nbsp;";
+        document.body.appendChild(d);
+        // Browsers that round the line-height should have offsetHeight === 38
+        // The others should have 39.
+        res = d.offsetHeight === 38;
+        document.body.removeChild(d);
+      }
+      return res;
+    };
+  })();
+
+  /**
+   * Returns the top offset of the content box of the given parent and the content box of one of its children.
+   *
+   * @param {HTMLElement} parent
+   * @param {HTMLElement} child
+   */
+  function getContentBoxTopOffset(parent, child) {
+    var parentStyle = getComputedStyle(parent);
+    var childStyle = getComputedStyle(child);
+
+    /**
+     * Returns the numeric value of the given pixel value.
+     *
+     * @param {string} px
+     */
+    function pxToNumber(px) {
+      return +px.substr(0, px.length - 2);
+    }
+
+    return (
+      child.offsetTop +
+      pxToNumber(childStyle.borderTopWidth) +
+      pxToNumber(childStyle.paddingTop) -
+      pxToNumber(parentStyle.paddingTop)
+    );
+  }
+
+  /**
+   * Returns whether the Line Highlight plugin is active for the given element.
+   *
+   * If this function returns `false`, do not call `highlightLines` for the given element.
+   *
+   * @param {HTMLElement | null | undefined} pre
+   * @returns {boolean}
+   */
+  function isActiveFor(pre) {
+    if (!pre || !/pre/i.test(pre.nodeName)) {
+      return false;
+    }
+
+    if (pre.hasAttribute("data-line")) {
+      return true;
+    }
+
+    if (pre.id && Prism.util.isActive(pre, LINKABLE_LINE_NUMBERS_CLASS)) {
+      // Technically, the line numbers plugin is also necessary but this plugin doesn't control the classes of
+      // the line numbers plugin, so we can't assume that they are present.
+      return true;
+    }
+
+    return false;
+  }
+
+  var scrollIntoView = true;
+
+  Prism.plugins.lineHighlight = {
+    /**
+     * Highlights the lines of the given pre.
+     *
+     * This function is split into a DOM measuring and mutate phase to improve performance.
+     * The returned function mutates the DOM when called.
+     *
+     * @param {HTMLElement} pre
+     * @param {string | null} [lines]
+     * @param {string} [classes='']
+     * @returns {() => void}
+     */
+    highlightLines: function highlightLines(pre, lines, classes) {
+      lines =
+        typeof lines === "string" ? lines : pre.getAttribute("data-line") || "";
+
+      var ranges = lines.replace(/\s+/g, "").split(",").filter(Boolean);
+      var offset = +pre.getAttribute("data-line-offset") || 0;
+
+      var parseMethod = isLineHeightRounded() ? parseInt : parseFloat;
+      var lineHeight = parseMethod(getComputedStyle(pre).lineHeight);
+      var hasLineNumbers = Prism.util.isActive(pre, LINE_NUMBERS_CLASS);
+      var codeElement = pre.querySelector("code");
+      var parentElement = hasLineNumbers ? pre : codeElement || pre;
+      var mutateActions = /** @type {(() => void)[]} */ ([]);
+      var lineBreakMatch = codeElement.textContent.match(NEW_LINE_EXP);
+      var numberOfLines = lineBreakMatch ? lineBreakMatch.length + 1 : 1;
+      /**
+       * The top offset between the content box of the <code> element and the content box of the parent element of
+       * the line highlight element (either `<pre>` or `<code>`).
+       *
+       * This offset might not be zero for some themes where the <code> element has a top margin. Some plugins
+       * (or users) might also add element above the <code> element. Because the line highlight is aligned relative
+       * to the <pre> element, we have to take this into account.
+       *
+       * This offset will be 0 if the parent element of the line highlight element is the `<code>` element.
+       */
+      var codePreOffset =
+        !codeElement || parentElement == codeElement
+          ? 0
+          : getContentBoxTopOffset(pre, codeElement);
+
+      ranges.forEach(function (currentRange) {
+        var range = currentRange.split("-");
+
+        var start = +range[0];
+        var end = +range[1] || start;
+        end = Math.min(numberOfLines + offset, end);
+
+        if (end < start) {
+          return;
+        }
+
+        /** @type {HTMLElement} */
+        var line =
+          pre.querySelector(
+            '.line-highlight[data-range="' + currentRange + '"]'
+          ) || document.createElement("div");
+
+        mutateActions.push(function () {
+          line.setAttribute("aria-hidden", "true");
+          line.setAttribute("data-range", currentRange);
+          line.className = (classes || "") + " line-highlight";
+        });
+
+        // if the line-numbers plugin is enabled, then there is no reason for this plugin to display the line numbers
+        if (hasLineNumbers && Prism.plugins.lineNumbers) {
+          var startNode = Prism.plugins.lineNumbers.getLine(pre, start);
+          var endNode = Prism.plugins.lineNumbers.getLine(pre, end);
+
+          if (startNode) {
+            var top = startNode.offsetTop + codePreOffset + "px";
+            mutateActions.push(function () {
+              line.style.top = top;
+            });
+          }
+
+          if (endNode) {
+            var height =
+              endNode.offsetTop -
+              startNode.offsetTop +
+              endNode.offsetHeight +
+              "px";
+            mutateActions.push(function () {
+              line.style.height = height;
+            });
+          }
+        } else {
+          mutateActions.push(function () {
+            line.setAttribute("data-start", String(start));
+
+            if (end > start) {
+              line.setAttribute("data-end", String(end));
+            }
+
+            line.style.top =
+              (start - offset - 1) * lineHeight + codePreOffset + "px";
+
+            line.textContent = new Array(end - start + 2).join(" \n");
+          });
+        }
+
+        mutateActions.push(function () {
+          line.style.width = pre.scrollWidth + "px";
+        });
+
+        mutateActions.push(function () {
+          // allow this to play nicely with the line-numbers plugin
+          // need to attack to pre as when line-numbers is enabled, the code tag is relatively which screws up the positioning
+          parentElement.appendChild(line);
+        });
+      });
+
+      var id = pre.id;
+      if (
+        hasLineNumbers &&
+        Prism.util.isActive(pre, LINKABLE_LINE_NUMBERS_CLASS) &&
+        id
+      ) {
+        // This implements linkable line numbers. Linkable line numbers use Line Highlight to create a link to a
+        // specific line. For this to work, the pre element has to:
+        //  1) have line numbers,
+        //  2) have the `linkable-line-numbers` class or an ascendant that has that class, and
+        //  3) have an id.
+
+        if (!hasClass(pre, LINKABLE_LINE_NUMBERS_CLASS)) {
+          // add class to pre
+          mutateActions.push(function () {
+            pre.classList.add(LINKABLE_LINE_NUMBERS_CLASS);
+          });
+        }
+
+        var start = parseInt(pre.getAttribute("data-start") || "1");
+
+        // iterate all line number spans
+        $$(".line-numbers-rows > span", pre).forEach(function (lineSpan, i) {
+          var lineNumber = i + start;
+          lineSpan.onclick = function () {
+            var hash = id + "." + lineNumber;
+
+            // this will prevent scrolling since the span is obviously in view
+            scrollIntoView = false;
+            location.hash = hash;
+            setTimeout(function () {
+              scrollIntoView = true;
+            }, 1);
+          };
+        });
+      }
+
+      return function () {
+        mutateActions.forEach(callFunction);
+      };
+    },
+  };
+
+  function applyHash() {
+    var hash = location.hash.slice(1);
+
+    // Remove pre-existing temporary lines
+    $$(".temporary.line-highlight").forEach(function (line) {
+      line.parentNode.removeChild(line);
+    });
+
+    var range = (hash.match(/\.([\d,-]+)$/) || [, ""])[1];
+
+    if (!range || document.getElementById(hash)) {
+      return;
+    }
+
+    var id = hash.slice(0, hash.lastIndexOf("."));
+    var pre = document.getElementById(id);
+
+    if (!pre) {
+      return;
+    }
+
+    if (!pre.hasAttribute("data-line")) {
+      pre.setAttribute("data-line", "");
+    }
+
+    var mutateDom = Prism.plugins.lineHighlight.highlightLines(
+      pre,
+      range,
+      "temporary "
+    );
+    mutateDom();
+
+    if (scrollIntoView) {
+      document.querySelector(".temporary.line-highlight").scrollIntoView();
+    }
+  }
+
+  var fakeTimer = 0; // Hack to limit the number of times applyHash() runs
+
+  Prism.hooks.add("before-sanity-check", function (env) {
+    var pre = env.element.parentElement;
+    if (!isActiveFor(pre)) {
+      return;
+    }
+
+    /*
+     * Cleanup for other plugins (e.g. autoloader).
+     *
+     * Sometimes <code> blocks are highlighted multiple times. It is necessary
+     * to cleanup any left-over tags, because the whitespace inside of the <div>
+     * tags change the content of the <code> tag.
+     */
+    var num = 0;
+    $$(".line-highlight", pre).forEach(function (line) {
+      num += line.textContent.length;
+      line.parentNode.removeChild(line);
+    });
+    // Remove extra whitespace
+    if (num && /^(?: \n)+$/.test(env.code.slice(-num))) {
+      env.code = env.code.slice(0, -num);
+    }
+  });
+
+  Prism.hooks.add("complete", function completeHook(env) {
+    var pre = env.element.parentElement;
+    if (!isActiveFor(pre)) {
+      return;
+    }
+
+    clearTimeout(fakeTimer);
+
+    var hasLineNumbers = Prism.plugins.lineNumbers;
+    var isLineNumbersLoaded = env.plugins && env.plugins.lineNumbers;
+
+    if (
+      hasClass(pre, LINE_NUMBERS_CLASS) &&
+      hasLineNumbers &&
+      !isLineNumbersLoaded
+    ) {
+      Prism.hooks.add("line-numbers", completeHook);
+    } else {
+      var mutateDom = Prism.plugins.lineHighlight.highlightLines(pre);
+      mutateDom();
+      fakeTimer = setTimeout(applyHash, 1);
+    }
+  });
+
+  window.addEventListener("hashchange", applyHash);
+  window.addEventListener("resize", function () {
+    var actions = $$("pre")
+      .filter(isActiveFor)
+      .map(function (pre) {
+        return Prism.plugins.lineHighlight.highlightLines(pre);
+      });
+    actions.forEach(callFunction);
+  });
+})();
+
+(function () {
+  if (typeof Prism === "undefined" || typeof document === "undefined") {
+    return;
+  }
+
+  /**
+   * Plugin name which is used as a class name for <pre> which is activating the plugin
+   *
+   * @type {string}
+   */
+  var PLUGIN_NAME = "line-numbers";
+
+  /**
+   * Regular expression used for determining line breaks
+   *
+   * @type {RegExp}
+   */
+  var NEW_LINE_EXP = /\n(?!$)/g;
+
+  /**
+   * Global exports
+   */
+  var config = (Prism.plugins.lineNumbers = {
+    /**
+     * Get node for provided line number
+     *
+     * @param {Element} element pre element
+     * @param {number} number line number
+     * @returns {Element|undefined}
+     */
+    getLine: function (element, number) {
+      if (
+        element.tagName !== "PRE" ||
+        !element.classList.contains(PLUGIN_NAME)
+      ) {
+        return;
+      }
+
+      var lineNumberRows = element.querySelector(".line-numbers-rows");
+      if (!lineNumberRows) {
+        return;
+      }
+      var lineNumberStart =
+        parseInt(element.getAttribute("data-start"), 10) || 1;
+      var lineNumberEnd =
+        lineNumberStart + (lineNumberRows.children.length - 1);
+
+      if (number < lineNumberStart) {
+        number = lineNumberStart;
+      }
+      if (number > lineNumberEnd) {
+        number = lineNumberEnd;
+      }
+
+      var lineIndex = number - lineNumberStart;
+
+      return lineNumberRows.children[lineIndex];
+    },
+
+    /**
+     * Resizes the line numbers of the given element.
+     *
+     * This function will not add line numbers. It will only resize existing ones.
+     *
+     * @param {HTMLElement} element A `<pre>` element with line numbers.
+     * @returns {void}
+     */
+    resize: function (element) {
+      resizeElements([element]);
+    },
+
+    /**
+     * Whether the plugin can assume that the units font sizes and margins are not depended on the size of
+     * the current viewport.
+     *
+     * Setting this to `true` will allow the plugin to do certain optimizations for better performance.
+     *
+     * Set this to `false` if you use any of the following CSS units: `vh`, `vw`, `vmin`, `vmax`.
+     *
+     * @type {boolean}
+     */
+    assumeViewportIndependence: true,
+  });
+
+  /**
+   * Resizes the given elements.
+   *
+   * @param {HTMLElement[]} elements
+   */
+  function resizeElements(elements) {
+    elements = elements.filter(function (e) {
+      var codeStyles = getStyles(e);
+      var whiteSpace = codeStyles["white-space"];
+      return whiteSpace === "pre-wrap" || whiteSpace === "pre-line";
+    });
+
+    if (elements.length == 0) {
+      return;
+    }
+
+    var infos = elements
+      .map(function (element) {
+        var codeElement = element.querySelector("code");
+        var lineNumbersWrapper = element.querySelector(".line-numbers-rows");
+        if (!codeElement || !lineNumbersWrapper) {
+          return undefined;
+        }
+
+        /** @type {HTMLElement} */
+        var lineNumberSizer = element.querySelector(".line-numbers-sizer");
+        var codeLines = codeElement.textContent.split(NEW_LINE_EXP);
+
+        if (!lineNumberSizer) {
+          lineNumberSizer = document.createElement("span");
+          lineNumberSizer.className = "line-numbers-sizer";
+
+          codeElement.appendChild(lineNumberSizer);
+        }
+
+        lineNumberSizer.innerHTML = "0";
+        lineNumberSizer.style.display = "block";
+
+        var oneLinerHeight = lineNumberSizer.getBoundingClientRect().height;
+        lineNumberSizer.innerHTML = "";
+
+        return {
+          element: element,
+          lines: codeLines,
+          lineHeights: [],
+          oneLinerHeight: oneLinerHeight,
+          sizer: lineNumberSizer,
+        };
+      })
+      .filter(Boolean);
+
+    infos.forEach(function (info) {
+      var lineNumberSizer = info.sizer;
+      var lines = info.lines;
+      var lineHeights = info.lineHeights;
+      var oneLinerHeight = info.oneLinerHeight;
+
+      lineHeights[lines.length - 1] = undefined;
+      lines.forEach(function (line, index) {
+        if (line && line.length > 1) {
+          var e = lineNumberSizer.appendChild(document.createElement("span"));
+          e.style.display = "block";
+          e.textContent = line;
+        } else {
+          lineHeights[index] = oneLinerHeight;
+        }
+      });
+    });
+
+    infos.forEach(function (info) {
+      var lineNumberSizer = info.sizer;
+      var lineHeights = info.lineHeights;
+
+      var childIndex = 0;
+      for (var i = 0; i < lineHeights.length; i++) {
+        if (lineHeights[i] === undefined) {
+          lineHeights[i] =
+            lineNumberSizer.children[
+              childIndex++
+            ].getBoundingClientRect().height;
+        }
+      }
+    });
+
+    infos.forEach(function (info) {
+      var lineNumberSizer = info.sizer;
+      var wrapper = info.element.querySelector(".line-numbers-rows");
+
+      lineNumberSizer.style.display = "none";
+      lineNumberSizer.innerHTML = "";
+
+      info.lineHeights.forEach(function (height, lineNumber) {
+        wrapper.children[lineNumber].style.height = height + "px";
+      });
+    });
+  }
+
+  /**
+   * Returns style declarations for the element
+   *
+   * @param {Element} element
+   */
+  function getStyles(element) {
+    if (!element) {
+      return null;
+    }
+
+    return window.getComputedStyle
+      ? getComputedStyle(element)
+      : element.currentStyle || null;
+  }
+
+  var lastWidth = undefined;
+  window.addEventListener("resize", function () {
+    if (config.assumeViewportIndependence && lastWidth === window.innerWidth) {
+      return;
+    }
+    lastWidth = window.innerWidth;
+
+    resizeElements(
+      Array.prototype.slice.call(
+        document.querySelectorAll("pre." + PLUGIN_NAME)
+      )
+    );
+  });
+
+  Prism.hooks.add("complete", function (env) {
+    if (!env.code) {
+      return;
+    }
+
+    var code = /** @type {Element} */ (env.element);
+    var pre = /** @type {HTMLElement} */ (code.parentNode);
+
+    // works only for <code> wrapped inside <pre> (not inline)
+    if (!pre || !/pre/i.test(pre.nodeName)) {
+      return;
+    }
+
+    // Abort if line numbers already exists
+    if (code.querySelector(".line-numbers-rows")) {
+      return;
+    }
+
+    // only add line numbers if <code> or one of its ancestors has the `line-numbers` class
+    if (!Prism.util.isActive(code, PLUGIN_NAME)) {
+      return;
+    }
+
+    // Remove the class 'line-numbers' from the <code>
+    code.classList.remove(PLUGIN_NAME);
+    // Add the class 'line-numbers' to the <pre>
+    pre.classList.add(PLUGIN_NAME);
+
+    var match = env.code.match(NEW_LINE_EXP);
+    var linesNum = match ? match.length + 1 : 1;
+    var lineNumbersWrapper;
+
+    var lines = new Array(linesNum + 1).join("<span></span>");
+
+    lineNumbersWrapper = document.createElement("span");
+    lineNumbersWrapper.setAttribute("aria-hidden", "true");
+    lineNumbersWrapper.className = "line-numbers-rows";
+    lineNumbersWrapper.innerHTML = lines;
+
+    if (pre.hasAttribute("data-start")) {
+      pre.style.counterReset =
+        "linenumber " + (parseInt(pre.getAttribute("data-start"), 10) - 1);
+    }
+
+    env.element.appendChild(lineNumbersWrapper);
+
+    resizeElements([pre]);
+
+    Prism.hooks.run("line-numbers", env);
+  });
+
+  Prism.hooks.add("line-numbers", function (env) {
+    env.plugins = env.plugins || {};
+    env.plugins.lineNumbers = true;
+  });
+})();
+
+(function () {
+  if (typeof Prism === "undefined" || typeof document === "undefined") {
+    return;
+  }
+
+  /* eslint-disable */
+
+  /**
+   * The dependencies map is built automatically with gulp.
+   *
+   * @type {Object<string, string | string[]>}
+   */
+  var lang_dependencies = /*dependencies_placeholder[*/ {
+    javascript: "clike",
+    actionscript: "javascript",
+    apex: ["clike", "sql"],
+    arduino: "cpp",
+    aspnet: ["markup", "csharp"],
+    birb: "clike",
+    bison: "c",
+    c: "clike",
+    csharp: "clike",
+    cpp: "c",
+    cfscript: "clike",
+    chaiscript: ["clike", "cpp"],
+    cilkc: "c",
+    cilkcpp: "cpp",
+    coffeescript: "javascript",
+    crystal: "ruby",
+    "css-extras": "css",
+    d: "clike",
+    dart: "clike",
+    django: "markup-templating",
+    ejs: ["javascript", "markup-templating"],
+    etlua: ["lua", "markup-templating"],
+    erb: ["ruby", "markup-templating"],
+    fsharp: "clike",
+    "firestore-security-rules": "clike",
+    flow: "javascript",
+    ftl: "markup-templating",
+    gml: "clike",
+    glsl: "c",
+    go: "clike",
+    gradle: "clike",
+    groovy: "clike",
+    haml: "ruby",
+    handlebars: "markup-templating",
+    haxe: "clike",
+    hlsl: "c",
+    idris: "haskell",
+    java: "clike",
+    javadoc: ["markup", "java", "javadoclike"],
+    jolie: "clike",
+    jsdoc: ["javascript", "javadoclike", "typescript"],
+    "js-extras": "javascript",
+    json5: "json",
+    jsonp: "json",
+    "js-templates": "javascript",
+    kotlin: "clike",
+    latte: ["clike", "markup-templating", "php"],
+    less: "css",
+    lilypond: "scheme",
+    liquid: "markup-templating",
+    markdown: "markup",
+    "markup-templating": "markup",
+    mongodb: "javascript",
+    n4js: "javascript",
+    objectivec: "c",
+    opencl: "c",
+    parser: "markup",
+    php: "markup-templating",
+    phpdoc: ["php", "javadoclike"],
+    "php-extras": "php",
+    plsql: "sql",
+    processing: "clike",
+    protobuf: "clike",
+    pug: ["markup", "javascript"],
+    purebasic: "clike",
+    purescript: "haskell",
+    qsharp: "clike",
+    qml: "javascript",
+    qore: "clike",
+    racket: "scheme",
+    cshtml: ["markup", "csharp"],
+    jsx: ["markup", "javascript"],
+    tsx: ["jsx", "typescript"],
+    reason: "clike",
+    ruby: "clike",
+    sass: "css",
+    scss: "css",
+    scala: "java",
+    "shell-session": "bash",
+    smarty: "markup-templating",
+    solidity: "clike",
+    soy: "markup-templating",
+    sparql: "turtle",
+    sqf: "clike",
+    squirrel: "clike",
+    stata: ["mata", "java", "python"],
+    "t4-cs": ["t4-templating", "csharp"],
+    "t4-vb": ["t4-templating", "vbnet"],
+    tap: "yaml",
+    tt2: ["clike", "markup-templating"],
+    textile: "markup",
+    twig: "markup-templating",
+    typescript: "javascript",
+    v: "clike",
+    vala: "clike",
+    vbnet: "basic",
+    velocity: "markup",
+    wiki: "markup",
+    xeora: "markup",
+    "xml-doc": "markup",
+    xquery: "markup",
+  }; /*]*/
+
+  var lang_aliases = /*aliases_placeholder[*/ {
+    html: "markup",
+    xml: "markup",
+    svg: "markup",
+    mathml: "markup",
+    ssml: "markup",
+    atom: "markup",
+    rss: "markup",
+    js: "javascript",
+    g4: "antlr4",
+    ino: "arduino",
+    "arm-asm": "armasm",
+    art: "arturo",
+    adoc: "asciidoc",
+    avs: "avisynth",
+    avdl: "avro-idl",
+    gawk: "awk",
+    sh: "bash",
+    shell: "bash",
+    shortcode: "bbcode",
+    rbnf: "bnf",
+    oscript: "bsl",
+    cs: "csharp",
+    dotnet: "csharp",
+    cfc: "cfscript",
+    "cilk-c": "cilkc",
+    "cilk-cpp": "cilkcpp",
+    cilk: "cilkcpp",
+    coffee: "coffeescript",
+    conc: "concurnas",
+    jinja2: "django",
+    "dns-zone": "dns-zone-file",
+    dockerfile: "docker",
+    gv: "dot",
+    eta: "ejs",
+    xlsx: "excel-formula",
+    xls: "excel-formula",
+    gamemakerlanguage: "gml",
+    po: "gettext",
+    gni: "gn",
+    ld: "linker-script",
+    "go-mod": "go-module",
+    hbs: "handlebars",
+    mustache: "handlebars",
+    hs: "haskell",
+    idr: "idris",
+    gitignore: "ignore",
+    hgignore: "ignore",
+    npmignore: "ignore",
+    webmanifest: "json",
+    kt: "kotlin",
+    kts: "kotlin",
+    kum: "kumir",
+    tex: "latex",
+    context: "latex",
+    ly: "lilypond",
+    emacs: "lisp",
+    elisp: "lisp",
+    "emacs-lisp": "lisp",
+    md: "markdown",
+    moon: "moonscript",
+    n4jsd: "n4js",
+    nani: "naniscript",
+    objc: "objectivec",
+    qasm: "openqasm",
+    objectpascal: "pascal",
+    px: "pcaxis",
+    pcode: "peoplecode",
+    plantuml: "plant-uml",
+    pq: "powerquery",
+    mscript: "powerquery",
+    pbfasm: "purebasic",
+    purs: "purescript",
+    py: "python",
+    qs: "qsharp",
+    rkt: "racket",
+    razor: "cshtml",
+    rpy: "renpy",
+    res: "rescript",
+    robot: "robotframework",
+    rb: "ruby",
+    "sh-session": "shell-session",
+    shellsession: "shell-session",
+    smlnj: "sml",
+    sol: "solidity",
+    sln: "solution-file",
+    rq: "sparql",
+    sclang: "supercollider",
+    t4: "t4-cs",
+    trickle: "tremor",
+    troy: "tremor",
+    trig: "turtle",
+    ts: "typescript",
+    tsconfig: "typoscript",
+    uscript: "unrealscript",
+    uc: "unrealscript",
+    url: "uri",
+    vb: "visual-basic",
+    vba: "visual-basic",
+    webidl: "web-idl",
+    mathematica: "wolfram",
+    nb: "wolfram",
+    wl: "wolfram",
+    xeoracube: "xeora",
+    yml: "yaml",
+  }; /*]*/
+
+  /* eslint-enable */
+
+  /**
+   * @typedef LangDataItem
+   * @property {{ success?: () => void, error?: () => void }[]} callbacks
+   * @property {boolean} [error]
+   * @property {boolean} [loading]
+   */
+  /** @type {Object<string, LangDataItem>} */
+  var lang_data = {};
+
+  var ignored_language = "none";
+  var languages_path = "/public/assets/prism/components/";
+
+  var script = Prism.util.currentScript();
+  /*if (script) {
+    var autoloaderFile =
+      /\bplugins\/autoloader\/prism-autoloader\.(?:min\.)?js(?:\?[^\r\n/]*)?$/i;
+    var prismFile = /(^|\/)[\w-]+\.(?:min\.)?js(?:\?[^\r\n/]*)?$/i;
+
+    var autoloaderPath = script.getAttribute("data-autoloader-path");
+    if (autoloaderPath != null) {
+      // data-autoloader-path is set, so just use it
+      languages_path = autoloaderPath.trim().replace(/\/?$/, "/");
+    } else {
+      var src = script.src;
+      if (autoloaderFile.test(src)) {
+        // the script is the original autoloader script in the usual Prism project structure
+        languages_path = src.replace(autoloaderFile, "components/");
+      } else if (prismFile.test(src)) {
+        // the script is part of a bundle like a custom prism.js from the download page
+        languages_path = src.replace(prismFile, "$1components/");
+      }
+    }
+  }*/
+
+  var config = (Prism.plugins.autoloader = {
+    languages_path: languages_path,
+    use_minified: true,
+    loadLanguages: loadLanguages,
+  });
+
+  /**
+   * Lazily loads an external script.
+   *
+   * @param {string} src
+   * @param {() => void} [success]
+   * @param {() => void} [error]
+   */
+  function addScript(src, success, error) {
+    var s = document.createElement("script");
+    s.src = src;
+    s.async = true;
+    s.onload = function () {
+      document.body.removeChild(s);
+      success && success();
+    };
+    s.onerror = function () {
+      document.body.removeChild(s);
+      error && error();
+    };
+    document.body.appendChild(s);
+  }
+
+  /**
+   * Returns all additional dependencies of the given element defined by the `data-dependencies` attribute.
+   *
+   * @param {Element} element
+   * @returns {string[]}
+   */
+  function getDependencies(element) {
+    var deps = (element.getAttribute("data-dependencies") || "").trim();
+    if (!deps) {
+      var parent = element.parentElement;
+      if (parent && parent.tagName.toLowerCase() === "pre") {
+        deps = (parent.getAttribute("data-dependencies") || "").trim();
+      }
+    }
+    return deps ? deps.split(/\s*,\s*/g) : [];
+  }
+
+  /**
+   * Returns whether the given language is currently loaded.
+   *
+   * @param {string} lang
+   * @returns {boolean}
+   */
+  function isLoaded(lang) {
+    if (lang.indexOf("!") >= 0) {
+      // forced reload
+      return false;
+    }
+
+    lang = lang_aliases[lang] || lang; // resolve alias
+
+    if (lang in Prism.languages) {
+      // the given language is already loaded
+      return true;
+    }
+
+    // this will catch extensions like CSS extras that don't add a grammar to Prism.languages
+    var data = lang_data[lang];
+    return data && !data.error && data.loading === false;
+  }
+
+  /**
+   * Returns the path to a grammar, using the language_path and use_minified config keys.
+   *
+   * @param {string} lang
+   * @returns {string}
+   */
+  function getLanguagePath(lang) {
+    return (
+      config.languages_path +
+      "prism-" +
+      lang +
+      (config.use_minified ? ".min" : "") +
+      ".js"
+    );
+  }
+
+  /**
+   * Loads all given grammars concurrently.
+   *
+   * @param {string[]|string} languages
+   * @param {(languages: string[]) => void} [success]
+   * @param {(language: string) => void} [error] This callback will be invoked on the first language to fail.
+   */
+  function loadLanguages(languages, success, error) {
+    if (typeof languages === "string") {
+      languages = [languages];
+    }
+
+    var total = languages.length;
+    var completed = 0;
+    var failed = false;
+
+    if (total === 0) {
+      if (success) {
+        setTimeout(success, 0);
+      }
+      return;
+    }
+
+    function successCallback() {
+      if (failed) {
+        return;
+      }
+      completed++;
+      if (completed === total) {
+        success && success(languages);
+      }
+    }
+
+    languages.forEach(function (lang) {
+      loadLanguage(lang, successCallback, function () {
+        if (failed) {
+          return;
+        }
+        failed = true;
+        error && error(lang);
+      });
+    });
+  }
+
+  /**
+   * Loads a grammar with its dependencies.
+   *
+   * @param {string} lang
+   * @param {() => void} [success]
+   * @param {() => void} [error]
+   */
+  function loadLanguage(lang, success, error) {
+    var force = lang.indexOf("!") >= 0;
+
+    lang = lang.replace("!", "");
+    lang = lang_aliases[lang] || lang;
+
+    function load() {
+      var data = lang_data[lang];
+      if (!data) {
+        data = lang_data[lang] = {
+          callbacks: [],
+        };
+      }
+      data.callbacks.push({
+        success: success,
+        error: error,
+      });
+
+      if (!force && isLoaded(lang)) {
+        // the language is already loaded and we aren't forced to reload
+        languageCallback(lang, "success");
+      } else if (!force && data.error) {
+        // the language failed to load before and we don't reload
+        languageCallback(lang, "error");
+      } else if (force || !data.loading) {
+        // the language isn't currently loading and/or we are forced to reload
+        data.loading = true;
+        data.error = false;
+
+        addScript(
+          getLanguagePath(lang),
+          function () {
+            data.loading = false;
+            languageCallback(lang, "success");
+          },
+          function () {
+            data.loading = false;
+            data.error = true;
+            languageCallback(lang, "error");
+          }
+        );
+      }
+    }
+
+    var dependencies = lang_dependencies[lang];
+    if (dependencies && dependencies.length) {
+      loadLanguages(dependencies, load, error);
+    } else {
+      load();
+    }
+  }
+
+  /**
+   * Runs all callbacks of the given type for the given language.
+   *
+   * @param {string} lang
+   * @param {"success" | "error"} type
+   */
+  function languageCallback(lang, type) {
+    if (lang_data[lang]) {
+      var callbacks = lang_data[lang].callbacks;
+      for (var i = 0, l = callbacks.length; i < l; i++) {
+        var callback = callbacks[i][type];
+        if (callback) {
+          setTimeout(callback, 0);
+        }
+      }
+      callbacks.length = 0;
+    }
+  }
+
+  Prism.hooks.add("complete", function (env) {
+    var element = env.element;
+    var language = env.language;
+    if (!element || !language || language === ignored_language) {
+      return;
+    }
+
+    var deps = getDependencies(element);
+    if (/^diff-./i.test(language)) {
+      // the "diff-xxxx" format is used by the Diff Highlight plugin
+      deps.push("diff");
+      deps.push(language.substr("diff-".length));
+    } else {
+      deps.push(language);
+    }
+
+    if (!deps.every(isLoaded)) {
+      // the language or some dependencies aren't loaded
+      loadLanguages(deps, function () {
+        Prism.highlightElement(element);
+      });
+    }
+  });
+})();
+
+(function () {
+  if (typeof Prism === "undefined") {
+    return;
+  }
+
+  var assign =
+    Object.assign ||
+    function (obj1, obj2) {
+      for (var name in obj2) {
+        if (obj2.hasOwnProperty(name)) {
+          obj1[name] = obj2[name];
+        }
+      }
+      return obj1;
+    };
+
+  function NormalizeWhitespace(defaults) {
+    this.defaults = assign({}, defaults);
+  }
+
+  function toCamelCase(value) {
+    return value.replace(/-(\w)/g, function (match, firstChar) {
+      return firstChar.toUpperCase();
+    });
+  }
+
+  function tabLen(str) {
+    var res = 0;
+    for (var i = 0; i < str.length; ++i) {
+      if (str.charCodeAt(i) == "\t".charCodeAt(0)) {
+        res += 3;
+      }
+    }
+    return str.length + res;
+  }
+
+  var settingsConfig = {
+    "remove-trailing": "boolean",
+    "remove-indent": "boolean",
+    "left-trim": "boolean",
+    "right-trim": "boolean",
+    "break-lines": "number",
+    indent: "number",
+    "remove-initial-line-feed": "boolean",
+    "tabs-to-spaces": "number",
+    "spaces-to-tabs": "number",
+  };
+
+  NormalizeWhitespace.prototype = {
+    setDefaults: function (defaults) {
+      this.defaults = assign(this.defaults, defaults);
+    },
+    normalize: function (input, settings) {
+      settings = assign(this.defaults, settings);
+
+      for (var name in settings) {
+        var methodName = toCamelCase(name);
+        if (
+          name !== "normalize" &&
+          methodName !== "setDefaults" &&
+          settings[name] &&
+          this[methodName]
+        ) {
+          input = this[methodName].call(this, input, settings[name]);
+        }
+      }
+
+      return input;
+    },
+
+    /*
+     * Normalization methods
+     */
+    leftTrim: function (input) {
+      return input.replace(/^\s+/, "");
+    },
+    rightTrim: function (input) {
+      return input.replace(/\s+$/, "");
+    },
+    tabsToSpaces: function (input, spaces) {
+      spaces = spaces | 0 || 4;
+      return input.replace(/\t/g, new Array(++spaces).join(" "));
+    },
+    spacesToTabs: function (input, spaces) {
+      spaces = spaces | 0 || 4;
+      return input.replace(RegExp(" {" + spaces + "}", "g"), "\t");
+    },
+    removeTrailing: function (input) {
+      return input.replace(/\s*?$/gm, "");
+    },
+    // Support for deprecated plugin remove-initial-line-feed
+    removeInitialLineFeed: function (input) {
+      return input.replace(/^(?:\r?\n|\r)/, "");
+    },
+    removeIndent: function (input) {
+      var indents = input.match(/^[^\S\n\r]*(?=\S)/gm);
+
+      if (!indents || !indents[0].length) {
+        return input;
+      }
+
+      indents.sort(function (a, b) {
+        return a.length - b.length;
+      });
+
+      if (!indents[0].length) {
+        return input;
+      }
+
+      return input.replace(RegExp("^" + indents[0], "gm"), "");
+    },
+    indent: function (input, tabs) {
+      return input.replace(
+        /^[^\S\n\r]*(?=\S)/gm,
+        new Array(++tabs).join("\t") + "$&"
+      );
+    },
+    breakLines: function (input, characters) {
+      characters = characters === true ? 80 : characters | 0 || 80;
+
+      var lines = input.split("\n");
+      for (var i = 0; i < lines.length; ++i) {
+        if (tabLen(lines[i]) <= characters) {
+          continue;
+        }
+
+        var line = lines[i].split(/(\s+)/g);
+        var len = 0;
+
+        for (var j = 0; j < line.length; ++j) {
+          var tl = tabLen(line[j]);
+          len += tl;
+          if (len > characters) {
+            line[j] = "\n" + line[j];
+            len = tl;
+          }
+        }
+        lines[i] = line.join("");
+      }
+      return lines.join("\n");
+    },
+  };
+
+  // Support node modules
+  if (typeof module !== "undefined" && module.exports) {
+    module.exports = NormalizeWhitespace;
+  }
+
+  Prism.plugins.NormalizeWhitespace = new NormalizeWhitespace({
+    "remove-trailing": true,
+    "remove-indent": true,
+    "left-trim": true,
+    "right-trim": true,
+    /*'break-lines': 80,
+    'indent': 2,
+    'remove-initial-line-feed': false,
+    'tabs-to-spaces': 4,
+    'spaces-to-tabs': 4*/
+  });
+
+  Prism.hooks.add("before-sanity-check", function (env) {
+    var Normalizer = Prism.plugins.NormalizeWhitespace;
+
+    // Check settings
+    if (env.settings && env.settings["whitespace-normalization"] === false) {
+      return;
+    }
+
+    // Check classes
+    if (!Prism.util.isActive(env.element, "whitespace-normalization", true)) {
+      return;
+    }
+
+    // Simple mode if there is no env.element
+    if ((!env.element || !env.element.parentNode) && env.code) {
+      env.code = Normalizer.normalize(env.code, env.settings);
+      return;
+    }
+
+    // Normal mode
+    var pre = env.element.parentNode;
+    if (!env.code || !pre || pre.nodeName.toLowerCase() !== "pre") {
+      return;
+    }
+
+    if (env.settings == null) {
+      env.settings = {};
+    }
+
+    // Read settings from 'data-' attributes
+    for (var key in settingsConfig) {
+      if (Object.hasOwnProperty.call(settingsConfig, key)) {
+        var settingType = settingsConfig[key];
+        if (pre.hasAttribute("data-" + key)) {
+          try {
+            var value = JSON.parse(pre.getAttribute("data-" + key) || "true");
+            if (typeof value === settingType) {
+              env.settings[key] = value;
+            }
+          } catch (_error) {
+            // ignore error
+          }
+        }
+      }
+    }
+
+    var children = pre.childNodes;
+    var before = "";
+    var after = "";
+    var codeFound = false;
+
+    // Move surrounding whitespace from the <pre> tag into the <code> tag
+    for (var i = 0; i < children.length; ++i) {
+      var node = children[i];
+
+      if (node == env.element) {
+        codeFound = true;
+      } else if (node.nodeName === "#text") {
+        if (codeFound) {
+          after += node.nodeValue;
+        } else {
+          before += node.nodeValue;
+        }
+
+        pre.removeChild(node);
+        --i;
+      }
+    }
+
+    if (!env.element.children.length || !Prism.plugins.KeepMarkup) {
+      env.code = before + env.code + after;
+      env.code = Normalizer.normalize(env.code, env.settings);
+    } else {
+      // Preserve markup for keep-markup plugin
+      var html = before + env.element.innerHTML + after;
+      env.element.innerHTML = Normalizer.normalize(html, env.settings);
+      env.code = env.element.textContent;
+    }
+  });
+})();
+
+(function () {
+  if (typeof Prism === "undefined") {
+    return;
+  }
+
+  var LANGUAGE_REGEX = /^diff-([\w-]+)/i;
+  var HTML_TAG =
+    /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/g;
+  //this will match a line plus the line break while ignoring the line breaks HTML tags may contain.
+  var HTML_LINE = RegExp(
+    /(?:__|[^\r\n<])*(?:\r\n?|\n|(?:__|[^\r\n<])(?![^\r\n]))/.source.replace(
+      /__/g,
+      function () {
+        return HTML_TAG.source;
+      }
+    ),
+    "gi"
+  );
+
+  var warningLogged = false;
+
+  Prism.hooks.add("before-sanity-check", function (env) {
+    var lang = env.language;
+    if (LANGUAGE_REGEX.test(lang) && !env.grammar) {
+      env.grammar = Prism.languages[lang] = Prism.languages.diff;
+    }
+  });
+  Prism.hooks.add("before-tokenize", function (env) {
+    if (!warningLogged && !Prism.languages.diff && !Prism.plugins.autoloader) {
+      warningLogged = true;
+      console.warn(
+        "Prism's Diff Highlight plugin requires the Diff language definition (prism-diff.js)." +
+          "Make sure the language definition is loaded or use Prism's Autoloader plugin."
+      );
+    }
+
+    var lang = env.language;
+    if (LANGUAGE_REGEX.test(lang) && !Prism.languages[lang]) {
+      Prism.languages[lang] = Prism.languages.diff;
+    }
+  });
+
+  Prism.hooks.add("wrap", function (env) {
+    var diffLanguage;
+    var diffGrammar;
+
+    if (env.language !== "diff") {
+      var langMatch = LANGUAGE_REGEX.exec(env.language);
+      if (!langMatch) {
+        return; // not a language specific diff
+      }
+
+      diffLanguage = langMatch[1];
+      diffGrammar = Prism.languages[diffLanguage];
+    }
+
+    var PREFIXES = Prism.languages.diff && Prism.languages.diff.PREFIXES;
+
+    // one of the diff tokens without any nested tokens
+    if (PREFIXES && env.type in PREFIXES) {
+      /** @type {string} */
+      var content = env.content.replace(HTML_TAG, ""); // remove all HTML tags
+
+      /** @type {string} */
+      var decoded = content.replace(/&lt;/g, "<").replace(/&amp;/g, "&");
+
+      // remove any one-character prefix
+      var code = decoded.replace(/(^|[\r\n])./g, "$1");
+
+      // highlight, if possible
+      var highlighted;
+      if (diffGrammar) {
+        highlighted = Prism.highlight(code, diffGrammar, diffLanguage);
+      } else {
+        highlighted = Prism.util.encode(code);
+      }
+
+      // get the HTML source of the prefix token
+      var prefixToken = new Prism.Token("prefix", PREFIXES[env.type], [
+        /\w+/.exec(env.type)[0],
+      ]);
+      var prefix = Prism.Token.stringify(prefixToken, env.language);
+
+      // add prefix
+      var lines = [];
+      var m;
+      HTML_LINE.lastIndex = 0;
+      while ((m = HTML_LINE.exec(highlighted))) {
+        lines.push(prefix + m[0]);
+      }
+      if (/(?:^|[\r\n]).$/.test(decoded)) {
+        // because both "+a\n+" and "+a\n" will map to "a\n" after the line prefixes are removed
+        lines.push(prefix);
+      }
+      env.content = lines.join("");
+
+      if (diffGrammar) {
+        env.classes.push("language-" + diffLanguage);
+      }
+    }
+  });
+})();

public/.deps/prismjs.development.js
@@ -1,3373 +0,0 @@
-/* PrismJS 1.29.0
-https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+diff&plugins=line-highlight+line-numbers+autoloader+normalize-whitespace+diff-highlight */
-/// <reference lib="WebWorker"/>
-
-var _self =
-  typeof window !== "undefined"
-    ? window // if in browser
-    : typeof WorkerGlobalScope !== "undefined" &&
-      self instanceof WorkerGlobalScope
-    ? self // if in worker
-    : {}; // if in node js
-
-/**
- * Prism: Lightweight, robust, elegant syntax highlighting
- *
- * @license MIT <https://opensource.org/licenses/MIT>
- * @author Lea Verou <https://lea.verou.me>
- * @namespace
- * @public
- */
-var Prism = (function (_self) {
-  // Private helper vars
-  var lang = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i;
-  var uniqueId = 0;
-
-  // The grammar object for plaintext
-  var plainTextGrammar = {};
-
-  var _ = {
-    /**
-     * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the
-     * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load
-     * additional languages or plugins yourself.
-     *
-     * By setting this value to `true`, Prism will not automatically highlight all code elements on the page.
-     *
-     * You obviously have to change this value before the automatic highlighting started. To do this, you can add an
-     * empty Prism object into the global scope before loading the Prism script like this:
-     *
-     * ```js
-     * window.Prism = window.Prism || {};
-     * Prism.manual = true;
-     * // add a new <script> to load Prism's script
-     * ```
-     *
-     * @default false
-     * @type {boolean}
-     * @memberof Prism
-     * @public
-     */
-    manual: _self.Prism && _self.Prism.manual,
-    /**
-     * By default, if Prism is in a web worker, it assumes that it is in a worker it created itself, so it uses
-     * `addEventListener` to communicate with its parent instance. However, if you're using Prism manually in your
-     * own worker, you don't want it to do this.
-     *
-     * By setting this value to `true`, Prism will not add its own listeners to the worker.
-     *
-     * You obviously have to change this value before Prism executes. To do this, you can add an
-     * empty Prism object into the global scope before loading the Prism script like this:
-     *
-     * ```js
-     * window.Prism = window.Prism || {};
-     * Prism.disableWorkerMessageHandler = true;
-     * // Load Prism's script
-     * ```
-     *
-     * @default false
-     * @type {boolean}
-     * @memberof Prism
-     * @public
-     */
-    disableWorkerMessageHandler:
-      _self.Prism && _self.Prism.disableWorkerMessageHandler,
-
-    /**
-     * A namespace for utility methods.
-     *
-     * All function in this namespace that are not explicitly marked as _public_ are for __internal use only__ and may
-     * change or disappear at any time.
-     *
-     * @namespace
-     * @memberof Prism
-     */
-    util: {
-      encode: function encode(tokens) {
-        if (tokens instanceof Token) {
-          return new Token(tokens.type, encode(tokens.content), tokens.alias);
-        } else if (Array.isArray(tokens)) {
-          return tokens.map(encode);
-        } else {
-          return tokens
-            .replace(/&/g, "&amp;")
-            .replace(/</g, "&lt;")
-            .replace(/\u00a0/g, " ");
-        }
-      },
-
-      /**
-       * Returns the name of the type of the given value.
-       *
-       * @param {any} o
-       * @returns {string}
-       * @example
-       * type(null)      === 'Null'
-       * type(undefined) === 'Undefined'
-       * type(123)       === 'Number'
-       * type('foo')     === 'String'
-       * type(true)      === 'Boolean'
-       * type([1, 2])    === 'Array'
-       * type({})        === 'Object'
-       * type(String)    === 'Function'
-       * type(/abc+/)    === 'RegExp'
-       */
-      type: function (o) {
-        return Object.prototype.toString.call(o).slice(8, -1);
-      },
-
-      /**
-       * Returns a unique number for the given object. Later calls will still return the same number.
-       *
-       * @param {Object} obj
-       * @returns {number}
-       */
-      objId: function (obj) {
-        if (!obj["__id"]) {
-          Object.defineProperty(obj, "__id", { value: ++uniqueId });
-        }
-        return obj["__id"];
-      },
-
-      /**
-       * Creates a deep clone of the given object.
-       *
-       * The main intended use of this function is to clone language definitions.
-       *
-       * @param {T} o
-       * @param {Record<number, any>} [visited]
-       * @returns {T}
-       * @template T
-       */
-      clone: function deepClone(o, visited) {
-        visited = visited || {};
-
-        var clone;
-        var id;
-        switch (_.util.type(o)) {
-          case "Object":
-            id = _.util.objId(o);
-            if (visited[id]) {
-              return visited[id];
-            }
-            clone = /** @type {Record<string, any>} */ ({});
-            visited[id] = clone;
-
-            for (var key in o) {
-              if (o.hasOwnProperty(key)) {
-                clone[key] = deepClone(o[key], visited);
-              }
-            }
-
-            return /** @type {any} */ (clone);
-
-          case "Array":
-            id = _.util.objId(o);
-            if (visited[id]) {
-              return visited[id];
-            }
-            clone = [];
-            visited[id] = clone;
-
-            /** @type {Array} */ (/** @type {any} */ (o)).forEach(function (
-              v,
-              i
-            ) {
-              clone[i] = deepClone(v, visited);
-            });
-
-            return /** @type {any} */ (clone);
-
-          default:
-            return o;
-        }
-      },
-
-      /**
-       * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class.
-       *
-       * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned.
-       *
-       * @param {Element} element
-       * @returns {string}
-       */
-      getLanguage: function (element) {
-        while (element) {
-          var m = lang.exec(element.className);
-          if (m) {
-            return m[1].toLowerCase();
-          }
-          element = element.parentElement;
-        }
-        return "none";
-      },
-
-      /**
-       * Sets the Prism `language-xxxx` class of the given element.
-       *
-       * @param {Element} element
-       * @param {string} language
-       * @returns {void}
-       */
-      setLanguage: function (element, language) {
-        // remove all `language-xxxx` classes
-        // (this might leave behind a leading space)
-        element.className = element.className.replace(RegExp(lang, "gi"), "");
-
-        // add the new `language-xxxx` class
-        // (using `classList` will automatically clean up spaces for us)
-        element.classList.add("language-" + language);
-      },
-
-      /**
-       * Returns the script element that is currently executing.
-       *
-       * This does __not__ work for line script element.
-       *
-       * @returns {HTMLScriptElement | null}
-       */
-      currentScript: function () {
-        if (typeof document === "undefined") {
-          return null;
-        }
-        if (
-          "currentScript" in document &&
-          1 < 2 /* hack to trip TS' flow analysis */
-        ) {
-          return /** @type {any} */ (document.currentScript);
-        }
-
-        // IE11 workaround
-        // we'll get the src of the current script by parsing IE11's error stack trace
-        // this will not work for inline scripts
-
-        try {
-          throw new Error();
-        } catch (err) {
-          // Get file src url from stack. Specifically works with the format of stack traces in IE.
-          // A stack will look like this:
-          //
-          // Error
-          //    at _.util.currentScript (http://localhost/components/prism-core.js:119:5)
-          //    at Global code (http://localhost/components/prism-core.js:606:1)
-
-          var src = (/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(err.stack) ||
-            [])[1];
-          if (src) {
-            var scripts = document.getElementsByTagName("script");
-            for (var i in scripts) {
-              if (scripts[i].src == src) {
-                return scripts[i];
-              }
-            }
-          }
-          return null;
-        }
-      },
-
-      /**
-       * Returns whether a given class is active for `element`.
-       *
-       * The class can be activated if `element` or one of its ancestors has the given class and it can be deactivated
-       * if `element` or one of its ancestors has the negated version of the given class. The _negated version_ of the
-       * given class is just the given class with a `no-` prefix.
-       *
-       * Whether the class is active is determined by the closest ancestor of `element` (where `element` itself is
-       * closest ancestor) that has the given class or the negated version of it. If neither `element` nor any of its
-       * ancestors have the given class or the negated version of it, then the default activation will be returned.
-       *
-       * In the paradoxical situation where the closest ancestor contains __both__ the given class and the negated
-       * version of it, the class is considered active.
-       *
-       * @param {Element} element
-       * @param {string} className
-       * @param {boolean} [defaultActivation=false]
-       * @returns {boolean}
-       */
-      isActive: function (element, className, defaultActivation) {
-        var no = "no-" + className;
-
-        while (element) {
-          var classList = element.classList;
-          if (classList.contains(className)) {
-            return true;
-          }
-          if (classList.contains(no)) {
-            return false;
-          }
-          element = element.parentElement;
-        }
-        return !!defaultActivation;
-      },
-    },
-
-    /**
-     * This namespace contains all currently loaded languages and the some helper functions to create and modify languages.
-     *
-     * @namespace
-     * @memberof Prism
-     * @public
-     */
-    languages: {
-      /**
-       * The grammar for plain, unformatted text.
-       */
-      plain: plainTextGrammar,
-      plaintext: plainTextGrammar,
-      text: plainTextGrammar,
-      txt: plainTextGrammar,
-
-      /**
-       * Creates a deep copy of the language with the given id and appends the given tokens.
-       *
-       * If a token in `redef` also appears in the copied language, then the existing token in the copied language
-       * will be overwritten at its original position.
-       *
-       * ## Best practices
-       *
-       * Since the position of overwriting tokens (token in `redef` that overwrite tokens in the copied language)
-       * doesn't matter, they can technically be in any order. However, this can be confusing to others that trying to
-       * understand the language definition because, normally, the order of tokens matters in Prism grammars.
-       *
-       * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens.
-       * Furthermore, all non-overwriting tokens should be placed after the overwriting ones.
-       *
-       * @param {string} id The id of the language to extend. This has to be a key in `Prism.languages`.
-       * @param {Grammar} redef The new tokens to append.
-       * @returns {Grammar} The new language created.
-       * @public
-       * @example
-       * Prism.languages['css-with-colors'] = Prism.languages.extend('css', {
-       *     // Prism.languages.css already has a 'comment' token, so this token will overwrite CSS' 'comment' token
-       *     // at its original position
-       *     'comment': { ... },
-       *     // CSS doesn't have a 'color' token, so this token will be appended
-       *     'color': /\b(?:red|green|blue)\b/
-       * });
-       */
-      extend: function (id, redef) {
-        var lang = _.util.clone(_.languages[id]);
-
-        for (var key in redef) {
-          lang[key] = redef[key];
-        }
-
-        return lang;
-      },
-
-      /**
-       * Inserts tokens _before_ another token in a language definition or any other grammar.
-       *
-       * ## Usage
-       *
-       * This helper method makes it easy to modify existing languages. For example, the CSS language definition
-       * not only defines CSS highlighting for CSS documents, but also needs to define highlighting for CSS embedded
-       * in HTML through `<style>` elements. To do this, it needs to modify `Prism.languages.markup` and add the
-       * appropriate tokens. However, `Prism.languages.markup` is a regular JavaScript object literal, so if you do
-       * this:
-       *
-       * ```js
-       * Prism.languages.markup.style = {
-       *     // token
-       * };
-       * ```
-       *
-       * then the `style` token will be added (and processed) at the end. `insertBefore` allows you to insert tokens
-       * before existing tokens. For the CSS example above, you would use it like this:
-       *
-       * ```js
-       * Prism.languages.insertBefore('markup', 'cdata', {
-       *     'style': {
-       *         // token
-       *     }
-       * });
-       * ```
-       *
-       * ## Special cases
-       *
-       * If the grammars of `inside` and `insert` have tokens with the same name, the tokens in `inside`'s grammar
-       * will be ignored.
-       *
-       * This behavior can be used to insert tokens after `before`:
-       *
-       * ```js
-       * Prism.languages.insertBefore('markup', 'comment', {
-       *     'comment': Prism.languages.markup.comment,
-       *     // tokens after 'comment'
-       * });
-       * ```
-       *
-       * ## Limitations
-       *
-       * The main problem `insertBefore` has to solve is iteration order. Since ES2015, the iteration order for object
-       * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave
-       * differently when keys are deleted and re-inserted. So `insertBefore` can't be implemented by temporarily
-       * deleting properties which is necessary to insert at arbitrary positions.
-       *
-       * To solve this problem, `insertBefore` doesn't actually insert the given tokens into the target object.
-       * Instead, it will create a new object and replace all references to the target object with the new one. This
-       * can be done without temporarily deleting properties, so the iteration order is well-defined.
-       *
-       * However, only references that can be reached from `Prism.languages` or `insert` will be replaced. I.e. if
-       * you hold the target object in a variable, then the value of the variable will not change.
-       *
-       * ```js
-       * var oldMarkup = Prism.languages.markup;
-       * var newMarkup = Prism.languages.insertBefore('markup', 'comment', { ... });
-       *
-       * assert(oldMarkup !== Prism.languages.markup);
-       * assert(newMarkup === Prism.languages.markup);
-       * ```
-       *
-       * @param {string} inside The property of `root` (e.g. a language id in `Prism.languages`) that contains the
-       * object to be modified.
-       * @param {string} before The key to insert before.
-       * @param {Grammar} insert An object containing the key-value pairs to be inserted.
-       * @param {Object<string, any>} [root] The object containing `inside`, i.e. the object that contains the
-       * object to be modified.
-       *
-       * Defaults to `Prism.languages`.
-       * @returns {Grammar} The new grammar object.
-       * @public
-       */
-      insertBefore: function (inside, before, insert, root) {
-        root = root || /** @type {any} */ (_.languages);
-        var grammar = root[inside];
-        /** @type {Grammar} */
-        var ret = {};
-
-        for (var token in grammar) {
-          if (grammar.hasOwnProperty(token)) {
-            if (token == before) {
-              for (var newToken in insert) {
-                if (insert.hasOwnProperty(newToken)) {
-                  ret[newToken] = insert[newToken];
-                }
-              }
-            }
-
-            // Do not insert token which also occur in insert. See #1525
-            if (!insert.hasOwnProperty(token)) {
-              ret[token] = grammar[token];
-            }
-          }
-        }
-
-        var old = root[inside];
-        root[inside] = ret;
-
-        // Update references in other language definitions
-        _.languages.DFS(_.languages, function (key, value) {
-          if (value === old && key != inside) {
-            this[key] = ret;
-          }
-        });
-
-        return ret;
-      },
-
-      // Traverse a language definition with Depth First Search
-      DFS: function DFS(o, callback, type, visited) {
-        visited = visited || {};
-
-        var objId = _.util.objId;
-
-        for (var i in o) {
-          if (o.hasOwnProperty(i)) {
-            callback.call(o, i, o[i], type || i);
-
-            var property = o[i];
-            var propertyType = _.util.type(property);
-
-            if (propertyType === "Object" && !visited[objId(property)]) {
-              visited[objId(property)] = true;
-              DFS(property, callback, null, visited);
-            } else if (propertyType === "Array" && !visited[objId(property)]) {
-              visited[objId(property)] = true;
-              DFS(property, callback, i, visited);
-            }
-          }
-        }
-      },
-    },
-
-    plugins: {},
-
-    /**
-     * This is the most high-level function in Prism’s API.
-     * It fetches all the elements that have a `.language-xxxx` class and then calls {@link Prism.highlightElement} on
-     * each one of them.
-     *
-     * This is equivalent to `Prism.highlightAllUnder(document, async, callback)`.
-     *
-     * @param {boolean} [async=false] Same as in {@link Prism.highlightAllUnder}.
-     * @param {HighlightCallback} [callback] Same as in {@link Prism.highlightAllUnder}.
-     * @memberof Prism
-     * @public
-     */
-    highlightAll: function (async, callback) {
-      _.highlightAllUnder(document, async, callback);
-    },
-
-    /**
-     * Fetches all the descendants of `container` that have a `.language-xxxx` class and then calls
-     * {@link Prism.highlightElement} on each one of them.
-     *
-     * The following hooks will be run:
-     * 1. `before-highlightall`
-     * 2. `before-all-elements-highlight`
-     * 3. All hooks of {@link Prism.highlightElement} for each element.
-     *
-     * @param {ParentNode} container The root element, whose descendants that have a `.language-xxxx` class will be highlighted.
-     * @param {boolean} [async=false] Whether each element is to be highlighted asynchronously using Web Workers.
-     * @param {HighlightCallback} [callback] An optional callback to be invoked on each element after its highlighting is done.
-     * @memberof Prism
-     * @public
-     */
-    highlightAllUnder: function (container, async, callback) {
-      var env = {
-        callback: callback,
-        container: container,
-        selector:
-          'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code',
-      };
-
-      _.hooks.run("before-highlightall", env);
-
-      env.elements = Array.prototype.slice.apply(
-        env.container.querySelectorAll(env.selector)
-      );
-
-      _.hooks.run("before-all-elements-highlight", env);
-
-      for (var i = 0, element; (element = env.elements[i++]); ) {
-        _.highlightElement(element, async === true, env.callback);
-      }
-    },
-
-    /**
-     * Highlights the code inside a single element.
-     *
-     * The following hooks will be run:
-     * 1. `before-sanity-check`
-     * 2. `before-highlight`
-     * 3. All hooks of {@link Prism.highlight}. These hooks will be run by an asynchronous worker if `async` is `true`.
-     * 4. `before-insert`
-     * 5. `after-highlight`
-     * 6. `complete`
-     *
-     * Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for
-     * the element's language.
-     *
-     * @param {Element} element The element containing the code.
-     * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier.
-     * @param {boolean} [async=false] Whether the element is to be highlighted asynchronously using Web Workers
-     * to improve performance and avoid blocking the UI when highlighting very large chunks of code. This option is
-     * [disabled by default](https://prismjs.com/faq.html#why-is-asynchronous-highlighting-disabled-by-default).
-     *
-     * Note: All language definitions required to highlight the code must be included in the main `prism.js` file for
-     * asynchronous highlighting to work. You can build your own bundle on the
-     * [Download page](https://prismjs.com/download.html).
-     * @param {HighlightCallback} [callback] An optional callback to be invoked after the highlighting is done.
-     * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously.
-     * @memberof Prism
-     * @public
-     */
-    highlightElement: function (element, async, callback) {
-      // Find language
-      var language = _.util.getLanguage(element);
-      var grammar = _.languages[language];
-
-      // Set language on the element, if not present
-      _.util.setLanguage(element, language);
-
-      // Set language on the parent, for styling
-      var parent = element.parentElement;
-      if (parent && parent.nodeName.toLowerCase() === "pre") {
-        _.util.setLanguage(parent, language);
-      }
-
-      var code = element.textContent;
-
-      var env = {
-        element: element,
-        language: language,
-        grammar: grammar,
-        code: code,
-      };
-
-      function insertHighlightedCode(highlightedCode) {
-        env.highlightedCode = highlightedCode;
-
-        _.hooks.run("before-insert", env);
-
-        env.element.innerHTML = env.highlightedCode;
-
-        _.hooks.run("after-highlight", env);
-        _.hooks.run("complete", env);
-        callback && callback.call(env.element);
-      }
-
-      _.hooks.run("before-sanity-check", env);
-
-      // plugins may change/add the parent/element
-      parent = env.element.parentElement;
-      if (
-        parent &&
-        parent.nodeName.toLowerCase() === "pre" &&
-        !parent.hasAttribute("tabindex")
-      ) {
-        parent.setAttribute("tabindex", "0");
-      }
-
-      if (!env.code) {
-        _.hooks.run("complete", env);
-        callback && callback.call(env.element);
-        return;
-      }
-
-      _.hooks.run("before-highlight", env);
-
-      if (!env.grammar) {
-        insertHighlightedCode(_.util.encode(env.code));
-        return;
-      }
-
-      if (async && _self.Worker) {
-        var worker = new Worker(_.filename);
-
-        worker.onmessage = function (evt) {
-          insertHighlightedCode(evt.data);
-        };
-
-        worker.postMessage(
-          JSON.stringify({
-            language: env.language,
-            code: env.code,
-            immediateClose: true,
-          })
-        );
-      } else {
-        insertHighlightedCode(_.highlight(env.code, env.grammar, env.language));
-      }
-    },
-
-    /**
-     * Low-level function, only use if you know what you’re doing. It accepts a string of text as input
-     * and the language definitions to use, and returns a string with the HTML produced.
-     *
-     * The following hooks will be run:
-     * 1. `before-tokenize`
-     * 2. `after-tokenize`
-     * 3. `wrap`: On each {@link Token}.
-     *
-     * @param {string} text A string with the code to be highlighted.
-     * @param {Grammar} grammar An object containing the tokens to use.
-     *
-     * Usually a language definition like `Prism.languages.markup`.
-     * @param {string} language The name of the language definition passed to `grammar`.
-     * @returns {string} The highlighted HTML.
-     * @memberof Prism
-     * @public
-     * @example
-     * Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript');
-     */
-    highlight: function (text, grammar, language) {
-      var env = {
-        code: text,
-        grammar: grammar,
-        language: language,
-      };
-      _.hooks.run("before-tokenize", env);
-      if (!env.grammar) {
-        throw new Error('The language "' + env.language + '" has no grammar.');
-      }
-      env.tokens = _.tokenize(env.code, env.grammar);
-      _.hooks.run("after-tokenize", env);
-      return Token.stringify(_.util.encode(env.tokens), env.language);
-    },
-
-    /**
-     * This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input
-     * and the language definitions to use, and returns an array with the tokenized code.
-     *
-     * When the language definition includes nested tokens, the function is called recursively on each of these tokens.
-     *
-     * This method could be useful in other contexts as well, as a very crude parser.
-     *
-     * @param {string} text A string with the code to be highlighted.
-     * @param {Grammar} grammar An object containing the tokens to use.
-     *
-     * Usually a language definition like `Prism.languages.markup`.
-     * @returns {TokenStream} An array of strings and tokens, a token stream.
-     * @memberof Prism
-     * @public
-     * @example
-     * let code = `var foo = 0;`;
-     * let tokens = Prism.tokenize(code, Prism.languages.javascript);
-     * tokens.forEach(token => {
-     *     if (token instanceof Prism.Token && token.type === 'number') {
-     *         console.log(`Found numeric literal: ${token.content}`);
-     *     }
-     * });
-     */
-    tokenize: function (text, grammar) {
-      var rest = grammar.rest;
-      if (rest) {
-        for (var token in rest) {
-          grammar[token] = rest[token];
-        }
-
-        delete grammar.rest;
-      }
-
-      var tokenList = new LinkedList();
-      addAfter(tokenList, tokenList.head, text);
-
-      matchGrammar(text, tokenList, grammar, tokenList.head, 0);
-
-      return toArray(tokenList);
-    },
-
-    /**
-     * @namespace
-     * @memberof Prism
-     * @public
-     */
-    hooks: {
-      all: {},
-
-      /**
-       * Adds the given callback to the list of callbacks for the given hook.
-       *
-       * The callback will be invoked when the hook it is registered for is run.
-       * Hooks are usually directly run by a highlight function but you can also run hooks yourself.
-       *
-       * One callback function can be registered to multiple hooks and the same hook multiple times.
-       *
-       * @param {string} name The name of the hook.
-       * @param {HookCallback} callback The callback function which is given environment variables.
-       * @public
-       */
-      add: function (name, callback) {
-        var hooks = _.hooks.all;
-
-        hooks[name] = hooks[name] || [];
-
-        hooks[name].push(callback);
-      },
-
-      /**
-       * Runs a hook invoking all registered callbacks with the given environment variables.
-       *
-       * Callbacks will be invoked synchronously and in the order in which they were registered.
-       *
-       * @param {string} name The name of the hook.
-       * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered.
-       * @public
-       */
-      run: function (name, env) {
-        var callbacks = _.hooks.all[name];
-
-        if (!callbacks || !callbacks.length) {
-          return;
-        }
-
-        for (var i = 0, callback; (callback = callbacks[i++]); ) {
-          callback(env);
-        }
-      },
-    },
-
-    Token: Token,
-  };
-  _self.Prism = _;
-
-  // Typescript note:
-  // The following can be used to import the Token type in JSDoc:
-  //
-  //   @typedef {InstanceType<import("./prism-core")["Token"]>} Token
-
-  /**
-   * Creates a new token.
-   *
-   * @param {string} type See {@link Token#type type}
-   * @param {string | TokenStream} content See {@link Token#content content}
-   * @param {string|string[]} [alias] The alias(es) of the token.
-   * @param {string} [matchedStr=""] A copy of the full string this token was created from.
-   * @class
-   * @global
-   * @public
-   */
-  function Token(type, content, alias, matchedStr) {
-    /**
-     * The type of the token.
-     *
-     * This is usually the key of a pattern in a {@link Grammar}.
-     *
-     * @type {string}
-     * @see GrammarToken
-     * @public
-     */
-    this.type = type;
-    /**
-     * The strings or tokens contained by this token.
-     *
-     * This will be a token stream if the pattern matched also defined an `inside` grammar.
-     *
-     * @type {string | TokenStream}
-     * @public
-     */
-    this.content = content;
-    /**
-     * The alias(es) of the token.
-     *
-     * @type {string|string[]}
-     * @see GrammarToken
-     * @public
-     */
-    this.alias = alias;
-    // Copy of the full string this token was created from
-    this.length = (matchedStr || "").length | 0;
-  }
-
-  /**
-   * A token stream is an array of strings and {@link Token Token} objects.
-   *
-   * Token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process
-   * them.
-   *
-   * 1. No adjacent strings.
-   * 2. No empty strings.
-   *
-   *    The only exception here is the token stream that only contains the empty string and nothing else.
-   *
-   * @typedef {Array<string | Token>} TokenStream
-   * @global
-   * @public
-   */
-
-  /**
-   * Converts the given token or token stream to an HTML representation.
-   *
-   * The following hooks will be run:
-   * 1. `wrap`: On each {@link Token}.
-   *
-   * @param {string | Token | TokenStream} o The token or token stream to be converted.
-   * @param {string} language The name of current language.
-   * @returns {string} The HTML representation of the token or token stream.
-   * @memberof Token
-   * @static
-   */
-  Token.stringify = function stringify(o, language) {
-    if (typeof o == "string") {
-      return o;
-    }
-    if (Array.isArray(o)) {
-      var s = "";
-      o.forEach(function (e) {
-        s += stringify(e, language);
-      });
-      return s;
-    }
-
-    var env = {
-      type: o.type,
-      content: stringify(o.content, language),
-      tag: "span",
-      classes: ["token", o.type],
-      attributes: {},
-      language: language,
-    };
-
-    var aliases = o.alias;
-    if (aliases) {
-      if (Array.isArray(aliases)) {
-        Array.prototype.push.apply(env.classes, aliases);
-      } else {
-        env.classes.push(aliases);
-      }
-    }
-
-    _.hooks.run("wrap", env);
-
-    var attributes = "";
-    for (var name in env.attributes) {
-      attributes +=
-        " " +
-        name +
-        '="' +
-        (env.attributes[name] || "").replace(/"/g, "&quot;") +
-        '"';
-    }
-
-    return (
-      "<" +
-      env.tag +
-      ' class="' +
-      env.classes.join(" ") +
-      '"' +
-      attributes +
-      ">" +
-      env.content +
-      "</" +
-      env.tag +
-      ">"
-    );
-  };
-
-  /**
-   * @param {RegExp} pattern
-   * @param {number} pos
-   * @param {string} text
-   * @param {boolean} lookbehind
-   * @returns {RegExpExecArray | null}
-   */
-  function matchPattern(pattern, pos, text, lookbehind) {
-    pattern.lastIndex = pos;
-    var match = pattern.exec(text);
-    if (match && lookbehind && match[1]) {
-      // change the match to remove the text matched by the Prism lookbehind group
-      var lookbehindLength = match[1].length;
-      match.index += lookbehindLength;
-      match[0] = match[0].slice(lookbehindLength);
-    }
-    return match;
-  }
-
-  /**
-   * @param {string} text
-   * @param {LinkedList<string | Token>} tokenList
-   * @param {any} grammar
-   * @param {LinkedListNode<string | Token>} startNode
-   * @param {number} startPos
-   * @param {RematchOptions} [rematch]
-   * @returns {void}
-   * @private
-   *
-   * @typedef RematchOptions
-   * @property {string} cause
-   * @property {number} reach
-   */
-  function matchGrammar(
-    text,
-    tokenList,
-    grammar,
-    startNode,
-    startPos,
-    rematch
-  ) {
-    for (var token in grammar) {
-      if (!grammar.hasOwnProperty(token) || !grammar[token]) {
-        continue;
-      }
-
-      var patterns = grammar[token];
-      patterns = Array.isArray(patterns) ? patterns : [patterns];
-
-      for (var j = 0; j < patterns.length; ++j) {
-        if (rematch && rematch.cause == token + "," + j) {
-          return;
-        }
-
-        var patternObj = patterns[j];
-        var inside = patternObj.inside;
-        var lookbehind = !!patternObj.lookbehind;
-        var greedy = !!patternObj.greedy;
-        var alias = patternObj.alias;
-
-        if (greedy && !patternObj.pattern.global) {
-          // Without the global flag, lastIndex won't work
-          var flags = patternObj.pattern.toString().match(/[imsuy]*$/)[0];
-          patternObj.pattern = RegExp(patternObj.pattern.source, flags + "g");
-        }
-
-        /** @type {RegExp} */
-        var pattern = patternObj.pattern || patternObj;
-
-        for (
-          // iterate the token list and keep track of the current token/string position
-          var currentNode = startNode.next, pos = startPos;
-          currentNode !== tokenList.tail;
-          pos += currentNode.value.length, currentNode = currentNode.next
-        ) {
-          if (rematch && pos >= rematch.reach) {
-            break;
-          }
-
-          var str = currentNode.value;
-
-          if (tokenList.length > text.length) {
-            // Something went terribly wrong, ABORT, ABORT!
-            return;
-          }
-
-          if (str instanceof Token) {
-            continue;
-          }
-
-          var removeCount = 1; // this is the to parameter of removeBetween
-          var match;
-
-          if (greedy) {
-            match = matchPattern(pattern, pos, text, lookbehind);
-            if (!match || match.index >= text.length) {
-              break;
-            }
-
-            var from = match.index;
-            var to = match.index + match[0].length;
-            var p = pos;
-
-            // find the node that contains the match
-            p += currentNode.value.length;
-            while (from >= p) {
-              currentNode = currentNode.next;
-              p += currentNode.value.length;
-            }
-            // adjust pos (and p)
-            p -= currentNode.value.length;
-            pos = p;
-
-            // the current node is a Token, then the match starts inside another Token, which is invalid
-            if (currentNode.value instanceof Token) {
-              continue;
-            }
-
-            // find the last node which is affected by this match
-            for (
-              var k = currentNode;
-              k !== tokenList.tail && (p < to || typeof k.value === "string");
-              k = k.next
-            ) {
-              removeCount++;
-              p += k.value.length;
-            }
-            removeCount--;
-
-            // replace with the new match
-            str = text.slice(pos, p);
-            match.index -= pos;
-          } else {
-            match = matchPattern(pattern, 0, str, lookbehind);
-            if (!match) {
-              continue;
-            }
-          }
-
-          // eslint-disable-next-line no-redeclare
-          var from = match.index;
-          var matchStr = match[0];
-          var before = str.slice(0, from);
-          var after = str.slice(from + matchStr.length);
-
-          var reach = pos + str.length;
-          if (rematch && reach > rematch.reach) {
-            rematch.reach = reach;
-          }
-
-          var removeFrom = currentNode.prev;
-
-          if (before) {
-            removeFrom = addAfter(tokenList, removeFrom, before);
-            pos += before.length;
-          }
-
-          removeRange(tokenList, removeFrom, removeCount);
-
-          var wrapped = new Token(
-            token,
-            inside ? _.tokenize(matchStr, inside) : matchStr,
-            alias,
-            matchStr
-          );
-          currentNode = addAfter(tokenList, removeFrom, wrapped);
-
-          if (after) {
-            addAfter(tokenList, currentNode, after);
-          }
-
-          if (removeCount > 1) {
-            // at least one Token object was removed, so we have to do some rematching
-            // this can only happen if the current pattern is greedy
-
-            /** @type {RematchOptions} */
-            var nestedRematch = {
-              cause: token + "," + j,
-              reach: reach,
-            };
-            matchGrammar(
-              text,
-              tokenList,
-              grammar,
-              currentNode.prev,
-              pos,
-              nestedRematch
-            );
-
-            // the reach might have been extended because of the rematching
-            if (rematch && nestedRematch.reach > rematch.reach) {
-              rematch.reach = nestedRematch.reach;
-            }
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * @typedef LinkedListNode
-   * @property {T} value
-   * @property {LinkedListNode<T> | null} prev The previous node.
-   * @property {LinkedListNode<T> | null} next The next node.
-   * @template T
-   * @private
-   */
-
-  /**
-   * @template T
-   * @private
-   */
-  function LinkedList() {
-    /** @type {LinkedListNode<T>} */
-    var head = { value: null, prev: null, next: null };
-    /** @type {LinkedListNode<T>} */
-    var tail = { value: null, prev: head, next: null };
-    head.next = tail;
-
-    /** @type {LinkedListNode<T>} */
-    this.head = head;
-    /** @type {LinkedListNode<T>} */
-    this.tail = tail;
-    this.length = 0;
-  }
-
-  /**
-   * Adds a new node with the given value to the list.
-   *
-   * @param {LinkedList<T>} list
-   * @param {LinkedListNode<T>} node
-   * @param {T} value
-   * @returns {LinkedListNode<T>} The added node.
-   * @template T
-   */
-  function addAfter(list, node, value) {
-    // assumes that node != list.tail && values.length >= 0
-    var next = node.next;
-
-    var newNode = { value: value, prev: node, next: next };
-    node.next = newNode;
-    next.prev = newNode;
-    list.length++;
-
-    return newNode;
-  }
-  /**
-   * Removes `count` nodes after the given node. The given node will not be removed.
-   *
-   * @param {LinkedList<T>} list
-   * @param {LinkedListNode<T>} node
-   * @param {number} count
-   * @template T
-   */
-  function removeRange(list, node, count) {
-    var next = node.next;
-    for (var i = 0; i < count && next !== list.tail; i++) {
-      next = next.next;
-    }
-    node.next = next;
-    next.prev = node;
-    list.length -= i;
-  }
-  /**
-   * @param {LinkedList<T>} list
-   * @returns {T[]}
-   * @template T
-   */
-  function toArray(list) {
-    var array = [];
-    var node = list.head.next;
-    while (node !== list.tail) {
-      array.push(node.value);
-      node = node.next;
-    }
-    return array;
-  }
-
-  if (!_self.document) {
-    if (!_self.addEventListener) {
-      // in Node.js
-      return _;
-    }
-
-    if (!_.disableWorkerMessageHandler) {
-      // In worker
-      _self.addEventListener(
-        "message",
-        function (evt) {
-          var message = JSON.parse(evt.data);
-          var lang = message.language;
-          var code = message.code;
-          var immediateClose = message.immediateClose;
-
-          _self.postMessage(_.highlight(code, _.languages[lang], lang));
-          if (immediateClose) {
-            _self.close();
-          }
-        },
-        false
-      );
-    }
-
-    return _;
-  }
-
-  // Get current script and highlight
-  var script = _.util.currentScript();
-
-  if (script) {
-    _.filename = script.src;
-
-    if (script.hasAttribute("data-manual")) {
-      _.manual = true;
-    }
-  }
-
-  function highlightAutomaticallyCallback() {
-    if (!_.manual) {
-      _.highlightAll();
-    }
-  }
-
-  if (!_.manual) {
-    // If the document state is "loading", then we'll use DOMContentLoaded.
-    // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the
-    // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they
-    // might take longer one animation frame to execute which can create a race condition where only some plugins have
-    // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded.
-    // See https://github.com/PrismJS/prism/issues/2102
-    var readyState = document.readyState;
-    if (
-      readyState === "loading" ||
-      (readyState === "interactive" && script && script.defer)
-    ) {
-      document.addEventListener(
-        "DOMContentLoaded",
-        highlightAutomaticallyCallback
-      );
-    } else {
-      if (window.requestAnimationFrame) {
-        window.requestAnimationFrame(highlightAutomaticallyCallback);
-      } else {
-        window.setTimeout(highlightAutomaticallyCallback, 16);
-      }
-    }
-  }
-
-  return _;
-})(_self);
-
-if (typeof module !== "undefined" && module.exports) {
-  module.exports = Prism;
-}
-
-// hack for components to work correctly in node.js
-if (typeof global !== "undefined") {
-  global.Prism = Prism;
-}
-
-// some additional documentation/types
-
-/**
- * The expansion of a simple `RegExp` literal to support additional properties.
- *
- * @typedef GrammarToken
- * @property {RegExp} pattern The regular expression of the token.
- * @property {boolean} [lookbehind=false] If `true`, then the first capturing group of `pattern` will (effectively)
- * behave as a lookbehind group meaning that the captured text will not be part of the matched text of the new token.
- * @property {boolean} [greedy=false] Whether the token is greedy.
- * @property {string|string[]} [alias] An optional alias or list of aliases.
- * @property {Grammar} [inside] The nested grammar of this token.
- *
- * The `inside` grammar will be used to tokenize the text value of each token of this kind.
- *
- * This can be used to make nested and even recursive language definitions.
- *
- * Note: This can cause infinite recursion. Be careful when you embed different languages or even the same language into
- * each another.
- * @global
- * @public
- */
-
-/**
- * @typedef Grammar
- * @type {Object<string, RegExp | GrammarToken | Array<RegExp | GrammarToken>>}
- * @property {Grammar} [rest] An optional grammar object that will be appended to this grammar.
- * @global
- * @public
- */
-
-/**
- * A function which will invoked after an element was successfully highlighted.
- *
- * @callback HighlightCallback
- * @param {Element} element The element successfully highlighted.
- * @returns {void}
- * @global
- * @public
- */
-
-/**
- * @callback HookCallback
- * @param {Object<string, any>} env The environment variables of the hook.
- * @returns {void}
- * @global
- * @public
- */
-Prism.languages.markup = {
-  comment: {
-    pattern: /<!--(?:(?!<!--)[\s\S])*?-->/,
-    greedy: true,
-  },
-  prolog: {
-    pattern: /<\?[\s\S]+?\?>/,
-    greedy: true,
-  },
-  doctype: {
-    // https://www.w3.org/TR/xml/#NT-doctypedecl
-    pattern:
-      /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,
-    greedy: true,
-    inside: {
-      "internal-subset": {
-        pattern: /(^[^\[]*\[)[\s\S]+(?=\]>$)/,
-        lookbehind: true,
-        greedy: true,
-        inside: null, // see below
-      },
-      string: {
-        pattern: /"[^"]*"|'[^']*'/,
-        greedy: true,
-      },
-      punctuation: /^<!|>$|[[\]]/,
-      "doctype-tag": /^DOCTYPE/i,
-      name: /[^\s<>'"]+/,
-    },
-  },
-  cdata: {
-    pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
-    greedy: true,
-  },
-  tag: {
-    pattern:
-      /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,
-    greedy: true,
-    inside: {
-      tag: {
-        pattern: /^<\/?[^\s>\/]+/,
-        inside: {
-          punctuation: /^<\/?/,
-          namespace: /^[^\s>\/:]+:/,
-        },
-      },
-      "special-attr": [],
-      "attr-value": {
-        pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,
-        inside: {
-          punctuation: [
-            {
-              pattern: /^=/,
-              alias: "attr-equals",
-            },
-            {
-              pattern: /^(\s*)["']|["']$/,
-              lookbehind: true,
-            },
-          ],
-        },
-      },
-      punctuation: /\/?>/,
-      "attr-name": {
-        pattern: /[^\s>\/]+/,
-        inside: {
-          namespace: /^[^\s>\/:]+:/,
-        },
-      },
-    },
-  },
-  entity: [
-    {
-      pattern: /&[\da-z]{1,8};/i,
-      alias: "named-entity",
-    },
-    /&#x?[\da-f]{1,8};/i,
-  ],
-};
-
-Prism.languages.markup["tag"].inside["attr-value"].inside["entity"] =
-  Prism.languages.markup["entity"];
-Prism.languages.markup["doctype"].inside["internal-subset"].inside =
-  Prism.languages.markup;
-
-// Plugin to make entity title show the real entity, idea by Roman Komarov
-Prism.hooks.add("wrap", function (env) {
-  if (env.type === "entity") {
-    env.attributes["title"] = env.content.replace(/&amp;/, "&");
-  }
-});
-
-Object.defineProperty(Prism.languages.markup.tag, "addInlined", {
-  /**
-   * Adds an inlined language to markup.
-   *
-   * An example of an inlined language is CSS with `<style>` tags.
-   *
-   * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as
-   * case insensitive.
-   * @param {string} lang The language key.
-   * @example
-   * addInlined('style', 'css');
-   */
-  value: function addInlined(tagName, lang) {
-    var includedCdataInside = {};
-    includedCdataInside["language-" + lang] = {
-      pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,
-      lookbehind: true,
-      inside: Prism.languages[lang],
-    };
-    includedCdataInside["cdata"] = /^<!\[CDATA\[|\]\]>$/i;
-
-    var inside = {
-      "included-cdata": {
-        pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i,
-        inside: includedCdataInside,
-      },
-    };
-    inside["language-" + lang] = {
-      pattern: /[\s\S]+/,
-      inside: Prism.languages[lang],
-    };
-
-    var def = {};
-    def[tagName] = {
-      pattern: RegExp(
-        /(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(
-          /__/g,
-          function () {
-            return tagName;
-          }
-        ),
-        "i"
-      ),
-      lookbehind: true,
-      greedy: true,
-      inside: inside,
-    };
-
-    Prism.languages.insertBefore("markup", "cdata", def);
-  },
-});
-Object.defineProperty(Prism.languages.markup.tag, "addAttribute", {
-  /**
-   * Adds an pattern to highlight languages embedded in HTML attributes.
-   *
-   * An example of an inlined language is CSS with `style` attributes.
-   *
-   * @param {string} attrName The name of the tag that contains the inlined language. This name will be treated as
-   * case insensitive.
-   * @param {string} lang The language key.
-   * @example
-   * addAttribute('style', 'css');
-   */
-  value: function (attrName, lang) {
-    Prism.languages.markup.tag.inside["special-attr"].push({
-      pattern: RegExp(
-        /(^|["'\s])/.source +
-          "(?:" +
-          attrName +
-          ")" +
-          /\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,
-        "i"
-      ),
-      lookbehind: true,
-      inside: {
-        "attr-name": /^[^\s=]+/,
-        "attr-value": {
-          pattern: /=[\s\S]+/,
-          inside: {
-            value: {
-              pattern: /(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,
-              lookbehind: true,
-              alias: [lang, "language-" + lang],
-              inside: Prism.languages[lang],
-            },
-            punctuation: [
-              {
-                pattern: /^=/,
-                alias: "attr-equals",
-              },
-              /"|'/,
-            ],
-          },
-        },
-      },
-    });
-  },
-});
-
-Prism.languages.html = Prism.languages.markup;
-Prism.languages.mathml = Prism.languages.markup;
-Prism.languages.svg = Prism.languages.markup;
-
-Prism.languages.xml = Prism.languages.extend("markup", {});
-Prism.languages.ssml = Prism.languages.xml;
-Prism.languages.atom = Prism.languages.xml;
-Prism.languages.rss = Prism.languages.xml;
-
-(function (Prism) {
-  var string =
-    /(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;
-
-  Prism.languages.css = {
-    comment: /\/\*[\s\S]*?\*\//,
-    atrule: {
-      pattern: RegExp(
-        "@[\\w-](?:" +
-          /[^;{\s"']|\s+(?!\s)/.source +
-          "|" +
-          string.source +
-          ")*?" +
-          /(?:;|(?=\s*\{))/.source
-      ),
-      inside: {
-        rule: /^@[\w-]+/,
-        "selector-function-argument": {
-          pattern:
-            /(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,
-          lookbehind: true,
-          alias: "selector",
-        },
-        keyword: {
-          pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/,
-          lookbehind: true,
-        },
-        // See rest below
-      },
-    },
-    url: {
-      // https://drafts.csswg.org/css-values-3/#urls
-      pattern: RegExp(
-        "\\burl\\((?:" +
-          string.source +
-          "|" +
-          /(?:[^\\\r\n()"']|\\[\s\S])*/.source +
-          ")\\)",
-        "i"
-      ),
-      greedy: true,
-      inside: {
-        function: /^url/i,
-        punctuation: /^\(|\)$/,
-        string: {
-          pattern: RegExp("^" + string.source + "$"),
-          alias: "url",
-        },
-      },
-    },
-    selector: {
-      pattern: RegExp(
-        "(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|" +
-          string.source +
-          ")*(?=\\s*\\{)"
-      ),
-      lookbehind: true,
-    },
-    string: {
-      pattern: string,
-      greedy: true,
-    },
-    property: {
-      pattern:
-        /(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,
-      lookbehind: true,
-    },
-    important: /!important\b/i,
-    function: {
-      pattern: /(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,
-      lookbehind: true,
-    },
-    punctuation: /[(){};:,]/,
-  };
-
-  Prism.languages.css["atrule"].inside.rest = Prism.languages.css;
-
-  var markup = Prism.languages.markup;
-  if (markup) {
-    markup.tag.addInlined("style", "css");
-    markup.tag.addAttribute("style", "css");
-  }
-})(Prism);
-
-Prism.languages.clike = {
-  comment: [
-    {
-      pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,
-      lookbehind: true,
-      greedy: true,
-    },
-    {
-      pattern: /(^|[^\\:])\/\/.*/,
-      lookbehind: true,
-      greedy: true,
-    },
-  ],
-  string: {
-    pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
-    greedy: true,
-  },
-  "class-name": {
-    pattern:
-      /(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,
-    lookbehind: true,
-    inside: {
-      punctuation: /[.\\]/,
-    },
-  },
-  keyword:
-    /\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,
-  boolean: /\b(?:false|true)\b/,
-  function: /\b\w+(?=\()/,
-  number: /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,
-  operator: /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,
-  punctuation: /[{}[\];(),.:]/,
-};
-
-Prism.languages.javascript = Prism.languages.extend("clike", {
-  "class-name": [
-    Prism.languages.clike["class-name"],
-    {
-      pattern:
-        /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,
-      lookbehind: true,
-    },
-  ],
-  keyword: [
-    {
-      pattern: /((?:^|\})\s*)catch\b/,
-      lookbehind: true,
-    },
-    {
-      pattern:
-        /(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,
-      lookbehind: true,
-    },
-  ],
-  // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444)
-  function:
-    /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,
-  number: {
-    pattern: RegExp(
-      /(^|[^\w$])/.source +
-        "(?:" +
-        // constant
-        (/NaN|Infinity/.source +
-          "|" +
-          // binary integer
-          /0[bB][01]+(?:_[01]+)*n?/.source +
-          "|" +
-          // octal integer
-          /0[oO][0-7]+(?:_[0-7]+)*n?/.source +
-          "|" +
-          // hexadecimal integer
-          /0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source +
-          "|" +
-          // decimal bigint
-          /\d+(?:_\d+)*n/.source +
-          "|" +
-          // decimal number (integer or float) but no bigint
-          /(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/
-            .source) +
-        ")" +
-        /(?![\w$])/.source
-    ),
-    lookbehind: true,
-  },
-  operator:
-    /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/,
-});
-
-Prism.languages.javascript["class-name"][0].pattern =
-  /(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/;
-
-Prism.languages.insertBefore("javascript", "keyword", {
-  regex: {
-    pattern: RegExp(
-      // lookbehind
-      // eslint-disable-next-line regexp/no-dupe-characters-character-class
-      /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source +
-        // Regex pattern:
-        // There are 2 regex patterns here. The RegExp set notation proposal added support for nested character
-        // classes if the `v` flag is present. Unfortunately, nested CCs are both context-free and incompatible
-        // with the only syntax, so we have to define 2 different regex patterns.
-        /\//.source +
-        "(?:" +
-        /(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/
-          .source +
-        "|" +
-        // `v` flag syntax. This supports 3 levels of nested character classes.
-        /(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/
-          .source +
-        ")" +
-        // lookahead
-        /(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source
-    ),
-    lookbehind: true,
-    greedy: true,
-    inside: {
-      "regex-source": {
-        pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/,
-        lookbehind: true,
-        alias: "language-regex",
-        inside: Prism.languages.regex,
-      },
-      "regex-delimiter": /^\/|\/$/,
-      "regex-flags": /^[a-z]+$/,
-    },
-  },
-  // This must be declared before keyword because we use "function" inside the look-forward
-  "function-variable": {
-    pattern:
-      /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,
-    alias: "function",
-  },
-  parameter: [
-    {
-      pattern:
-        /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,
-      lookbehind: true,
-      inside: Prism.languages.javascript,
-    },
-    {
-      pattern:
-        /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,
-      lookbehind: true,
-      inside: Prism.languages.javascript,
-    },
-    {
-      pattern:
-        /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,
-      lookbehind: true,
-      inside: Prism.languages.javascript,
-    },
-    {
-      pattern:
-        /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,
-      lookbehind: true,
-      inside: Prism.languages.javascript,
-    },
-  ],
-  constant: /\b[A-Z](?:[A-Z_]|\dx?)*\b/,
-});
-
-Prism.languages.insertBefore("javascript", "string", {
-  hashbang: {
-    pattern: /^#!.*/,
-    greedy: true,
-    alias: "comment",
-  },
-  "template-string": {
-    pattern:
-      /`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,
-    greedy: true,
-    inside: {
-      "template-punctuation": {
-        pattern: /^`|`$/,
-        alias: "string",
-      },
-      interpolation: {
-        pattern:
-          /((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,
-        lookbehind: true,
-        inside: {
-          "interpolation-punctuation": {
-            pattern: /^\$\{|\}$/,
-            alias: "punctuation",
-          },
-          rest: Prism.languages.javascript,
-        },
-      },
-      string: /[\s\S]+/,
-    },
-  },
-  "string-property": {
-    pattern:
-      /((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,
-    lookbehind: true,
-    greedy: true,
-    alias: "property",
-  },
-});
-
-Prism.languages.insertBefore("javascript", "operator", {
-  "literal-property": {
-    pattern:
-      /((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,
-    lookbehind: true,
-    alias: "property",
-  },
-});
-
-if (Prism.languages.markup) {
-  Prism.languages.markup.tag.addInlined("script", "javascript");
-
-  // add attribute support for all DOM events.
-  // https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events
-  Prism.languages.markup.tag.addAttribute(
-    /on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/
-      .source,
-    "javascript"
-  );
-}
-
-Prism.languages.js = Prism.languages.javascript;
-
-(function (Prism) {
-  Prism.languages.diff = {
-    coord: [
-      // Match all kinds of coord lines (prefixed by "+++", "---" or "***").
-      /^(?:\*{3}|-{3}|\+{3}).*$/m,
-      // Match "@@ ... @@" coord lines in unified diff.
-      /^@@.*@@$/m,
-      // Match coord lines in normal diff (starts with a number).
-      /^\d.*$/m,
-    ],
-
-    // deleted, inserted, unchanged, diff
-  };
-
-  /**
-   * A map from the name of a block to its line prefix.
-   *
-   * @type {Object<string, string>}
-   */
-  var PREFIXES = {
-    "deleted-sign": "-",
-    "deleted-arrow": "<",
-    "inserted-sign": "+",
-    "inserted-arrow": ">",
-    unchanged: " ",
-    diff: "!",
-  };
-
-  // add a token for each prefix
-  Object.keys(PREFIXES).forEach(function (name) {
-    var prefix = PREFIXES[name];
-
-    var alias = [];
-    if (!/^\w+$/.test(name)) {
-      // "deleted-sign" -> "deleted"
-      alias.push(/\w+/.exec(name)[0]);
-    }
-    if (name === "diff") {
-      alias.push("bold");
-    }
-
-    Prism.languages.diff[name] = {
-      pattern: RegExp("^(?:[" + prefix + "].*(?:\r\n?|\n|(?![\\s\\S])))+", "m"),
-      alias: alias,
-      inside: {
-        line: {
-          pattern: /(.)(?=[\s\S]).*(?:\r\n?|\n)?/,
-          lookbehind: true,
-        },
-        prefix: {
-          pattern: /[\s\S]/,
-          alias: /\w+/.exec(name)[0],
-        },
-      },
-    };
-  });
-
-  // make prefixes available to Diff plugin
-  Object.defineProperty(Prism.languages.diff, "PREFIXES", {
-    value: PREFIXES,
-  });
-})(Prism);
-
-(function () {
-  if (
-    typeof Prism === "undefined" ||
-    typeof document === "undefined" ||
-    !document.querySelector
-  ) {
-    return;
-  }
-
-  var LINE_NUMBERS_CLASS = "line-numbers";
-  var LINKABLE_LINE_NUMBERS_CLASS = "linkable-line-numbers";
-  var NEW_LINE_EXP = /\n(?!$)/g;
-
-  /**
-   * @param {string} selector
-   * @param {ParentNode} [container]
-   * @returns {HTMLElement[]}
-   */
-  function $$(selector, container) {
-    return Array.prototype.slice.call(
-      (container || document).querySelectorAll(selector)
-    );
-  }
-
-  /**
-   * Returns whether the given element has the given class.
-   *
-   * @param {Element} element
-   * @param {string} className
-   * @returns {boolean}
-   */
-  function hasClass(element, className) {
-    return element.classList.contains(className);
-  }
-
-  /**
-   * Calls the given function.
-   *
-   * @param {() => any} func
-   * @returns {void}
-   */
-  function callFunction(func) {
-    func();
-  }
-
-  // Some browsers round the line-height, others don't.
-  // We need to test for it to position the elements properly.
-  var isLineHeightRounded = (function () {
-    var res;
-    return function () {
-      if (typeof res === "undefined") {
-        var d = document.createElement("div");
-        d.style.fontSize = "13px";
-        d.style.lineHeight = "1.5";
-        d.style.padding = "0";
-        d.style.border = "0";
-        d.innerHTML = "&nbsp;<br />&nbsp;";
-        document.body.appendChild(d);
-        // Browsers that round the line-height should have offsetHeight === 38
-        // The others should have 39.
-        res = d.offsetHeight === 38;
-        document.body.removeChild(d);
-      }
-      return res;
-    };
-  })();
-
-  /**
-   * Returns the top offset of the content box of the given parent and the content box of one of its children.
-   *
-   * @param {HTMLElement} parent
-   * @param {HTMLElement} child
-   */
-  function getContentBoxTopOffset(parent, child) {
-    var parentStyle = getComputedStyle(parent);
-    var childStyle = getComputedStyle(child);
-
-    /**
-     * Returns the numeric value of the given pixel value.
-     *
-     * @param {string} px
-     */
-    function pxToNumber(px) {
-      return +px.substr(0, px.length - 2);
-    }
-
-    return (
-      child.offsetTop +
-      pxToNumber(childStyle.borderTopWidth) +
-      pxToNumber(childStyle.paddingTop) -
-      pxToNumber(parentStyle.paddingTop)
-    );
-  }
-
-  /**
-   * Returns whether the Line Highlight plugin is active for the given element.
-   *
-   * If this function returns `false`, do not call `highlightLines` for the given element.
-   *
-   * @param {HTMLElement | null | undefined} pre
-   * @returns {boolean}
-   */
-  function isActiveFor(pre) {
-    if (!pre || !/pre/i.test(pre.nodeName)) {
-      return false;
-    }
-
-    if (pre.hasAttribute("data-line")) {
-      return true;
-    }
-
-    if (pre.id && Prism.util.isActive(pre, LINKABLE_LINE_NUMBERS_CLASS)) {
-      // Technically, the line numbers plugin is also necessary but this plugin doesn't control the classes of
-      // the line numbers plugin, so we can't assume that they are present.
-      return true;
-    }
-
-    return false;
-  }
-
-  var scrollIntoView = true;
-
-  Prism.plugins.lineHighlight = {
-    /**
-     * Highlights the lines of the given pre.
-     *
-     * This function is split into a DOM measuring and mutate phase to improve performance.
-     * The returned function mutates the DOM when called.
-     *
-     * @param {HTMLElement} pre
-     * @param {string | null} [lines]
-     * @param {string} [classes='']
-     * @returns {() => void}
-     */
-    highlightLines: function highlightLines(pre, lines, classes) {
-      lines =
-        typeof lines === "string" ? lines : pre.getAttribute("data-line") || "";
-
-      var ranges = lines.replace(/\s+/g, "").split(",").filter(Boolean);
-      var offset = +pre.getAttribute("data-line-offset") || 0;
-
-      var parseMethod = isLineHeightRounded() ? parseInt : parseFloat;
-      var lineHeight = parseMethod(getComputedStyle(pre).lineHeight);
-      var hasLineNumbers = Prism.util.isActive(pre, LINE_NUMBERS_CLASS);
-      var codeElement = pre.querySelector("code");
-      var parentElement = hasLineNumbers ? pre : codeElement || pre;
-      var mutateActions = /** @type {(() => void)[]} */ ([]);
-      var lineBreakMatch = codeElement.textContent.match(NEW_LINE_EXP);
-      var numberOfLines = lineBreakMatch ? lineBreakMatch.length + 1 : 1;
-      /**
-       * The top offset between the content box of the <code> element and the content box of the parent element of
-       * the line highlight element (either `<pre>` or `<code>`).
-       *
-       * This offset might not be zero for some themes where the <code> element has a top margin. Some plugins
-       * (or users) might also add element above the <code> element. Because the line highlight is aligned relative
-       * to the <pre> element, we have to take this into account.
-       *
-       * This offset will be 0 if the parent element of the line highlight element is the `<code>` element.
-       */
-      var codePreOffset =
-        !codeElement || parentElement == codeElement
-          ? 0
-          : getContentBoxTopOffset(pre, codeElement);
-
-      ranges.forEach(function (currentRange) {
-        var range = currentRange.split("-");
-
-        var start = +range[0];
-        var end = +range[1] || start;
-        end = Math.min(numberOfLines + offset, end);
-
-        if (end < start) {
-          return;
-        }
-
-        /** @type {HTMLElement} */
-        var line =
-          pre.querySelector(
-            '.line-highlight[data-range="' + currentRange + '"]'
-          ) || document.createElement("div");
-
-        mutateActions.push(function () {
-          line.setAttribute("aria-hidden", "true");
-          line.setAttribute("data-range", currentRange);
-          line.className = (classes || "") + " line-highlight";
-        });
-
-        // if the line-numbers plugin is enabled, then there is no reason for this plugin to display the line numbers
-        if (hasLineNumbers && Prism.plugins.lineNumbers) {
-          var startNode = Prism.plugins.lineNumbers.getLine(pre, start);
-          var endNode = Prism.plugins.lineNumbers.getLine(pre, end);
-
-          if (startNode) {
-            var top = startNode.offsetTop + codePreOffset + "px";
-            mutateActions.push(function () {
-              line.style.top = top;
-            });
-          }
-
-          if (endNode) {
-            var height =
-              endNode.offsetTop -
-              startNode.offsetTop +
-              endNode.offsetHeight +
-              "px";
-            mutateActions.push(function () {
-              line.style.height = height;
-            });
-          }
-        } else {
-          mutateActions.push(function () {
-            line.setAttribute("data-start", String(start));
-
-            if (end > start) {
-              line.setAttribute("data-end", String(end));
-            }
-
-            line.style.top =
-              (start - offset - 1) * lineHeight + codePreOffset + "px";
-
-            line.textContent = new Array(end - start + 2).join(" \n");
-          });
-        }
-
-        mutateActions.push(function () {
-          line.style.width = pre.scrollWidth + "px";
-        });
-
-        mutateActions.push(function () {
-          // allow this to play nicely with the line-numbers plugin
-          // need to attack to pre as when line-numbers is enabled, the code tag is relatively which screws up the positioning
-          parentElement.appendChild(line);
-        });
-      });
-
-      var id = pre.id;
-      if (
-        hasLineNumbers &&
-        Prism.util.isActive(pre, LINKABLE_LINE_NUMBERS_CLASS) &&
-        id
-      ) {
-        // This implements linkable line numbers. Linkable line numbers use Line Highlight to create a link to a
-        // specific line. For this to work, the pre element has to:
-        //  1) have line numbers,
-        //  2) have the `linkable-line-numbers` class or an ascendant that has that class, and
-        //  3) have an id.
-
-        if (!hasClass(pre, LINKABLE_LINE_NUMBERS_CLASS)) {
-          // add class to pre
-          mutateActions.push(function () {
-            pre.classList.add(LINKABLE_LINE_NUMBERS_CLASS);
-          });
-        }
-
-        var start = parseInt(pre.getAttribute("data-start") || "1");
-
-        // iterate all line number spans
-        $$(".line-numbers-rows > span", pre).forEach(function (lineSpan, i) {
-          var lineNumber = i + start;
-          lineSpan.onclick = function () {
-            var hash = id + "." + lineNumber;
-
-            // this will prevent scrolling since the span is obviously in view
-            scrollIntoView = false;
-            location.hash = hash;
-            setTimeout(function () {
-              scrollIntoView = true;
-            }, 1);
-          };
-        });
-      }
-
-      return function () {
-        mutateActions.forEach(callFunction);
-      };
-    },
-  };
-
-  function applyHash() {
-    var hash = location.hash.slice(1);
-
-    // Remove pre-existing temporary lines
-    $$(".temporary.line-highlight").forEach(function (line) {
-      line.parentNode.removeChild(line);
-    });
-
-    var range = (hash.match(/\.([\d,-]+)$/) || [, ""])[1];
-
-    if (!range || document.getElementById(hash)) {
-      return;
-    }
-
-    var id = hash.slice(0, hash.lastIndexOf("."));
-    var pre = document.getElementById(id);
-
-    if (!pre) {
-      return;
-    }
-
-    if (!pre.hasAttribute("data-line")) {
-      pre.setAttribute("data-line", "");
-    }
-
-    var mutateDom = Prism.plugins.lineHighlight.highlightLines(
-      pre,
-      range,
-      "temporary "
-    );
-    mutateDom();
-
-    if (scrollIntoView) {
-      document.querySelector(".temporary.line-highlight").scrollIntoView();
-    }
-  }
-
-  var fakeTimer = 0; // Hack to limit the number of times applyHash() runs
-
-  Prism.hooks.add("before-sanity-check", function (env) {
-    var pre = env.element.parentElement;
-    if (!isActiveFor(pre)) {
-      return;
-    }
-
-    /*
-     * Cleanup for other plugins (e.g. autoloader).
-     *
-     * Sometimes <code> blocks are highlighted multiple times. It is necessary
-     * to cleanup any left-over tags, because the whitespace inside of the <div>
-     * tags change the content of the <code> tag.
-     */
-    var num = 0;
-    $$(".line-highlight", pre).forEach(function (line) {
-      num += line.textContent.length;
-      line.parentNode.removeChild(line);
-    });
-    // Remove extra whitespace
-    if (num && /^(?: \n)+$/.test(env.code.slice(-num))) {
-      env.code = env.code.slice(0, -num);
-    }
-  });
-
-  Prism.hooks.add("complete", function completeHook(env) {
-    var pre = env.element.parentElement;
-    if (!isActiveFor(pre)) {
-      return;
-    }
-
-    clearTimeout(fakeTimer);
-
-    var hasLineNumbers = Prism.plugins.lineNumbers;
-    var isLineNumbersLoaded = env.plugins && env.plugins.lineNumbers;
-
-    if (
-      hasClass(pre, LINE_NUMBERS_CLASS) &&
-      hasLineNumbers &&
-      !isLineNumbersLoaded
-    ) {
-      Prism.hooks.add("line-numbers", completeHook);
-    } else {
-      var mutateDom = Prism.plugins.lineHighlight.highlightLines(pre);
-      mutateDom();
-      fakeTimer = setTimeout(applyHash, 1);
-    }
-  });
-
-  window.addEventListener("hashchange", applyHash);
-  window.addEventListener("resize", function () {
-    var actions = $$("pre")
-      .filter(isActiveFor)
-      .map(function (pre) {
-        return Prism.plugins.lineHighlight.highlightLines(pre);
-      });
-    actions.forEach(callFunction);
-  });
-})();
-
-(function () {
-  if (typeof Prism === "undefined" || typeof document === "undefined") {
-    return;
-  }
-
-  /**
-   * Plugin name which is used as a class name for <pre> which is activating the plugin
-   *
-   * @type {string}
-   */
-  var PLUGIN_NAME = "line-numbers";
-
-  /**
-   * Regular expression used for determining line breaks
-   *
-   * @type {RegExp}
-   */
-  var NEW_LINE_EXP = /\n(?!$)/g;
-
-  /**
-   * Global exports
-   */
-  var config = (Prism.plugins.lineNumbers = {
-    /**
-     * Get node for provided line number
-     *
-     * @param {Element} element pre element
-     * @param {number} number line number
-     * @returns {Element|undefined}
-     */
-    getLine: function (element, number) {
-      if (
-        element.tagName !== "PRE" ||
-        !element.classList.contains(PLUGIN_NAME)
-      ) {
-        return;
-      }
-
-      var lineNumberRows = element.querySelector(".line-numbers-rows");
-      if (!lineNumberRows) {
-        return;
-      }
-      var lineNumberStart =
-        parseInt(element.getAttribute("data-start"), 10) || 1;
-      var lineNumberEnd =
-        lineNumberStart + (lineNumberRows.children.length - 1);
-
-      if (number < lineNumberStart) {
-        number = lineNumberStart;
-      }
-      if (number > lineNumberEnd) {
-        number = lineNumberEnd;
-      }
-
-      var lineIndex = number - lineNumberStart;
-
-      return lineNumberRows.children[lineIndex];
-    },
-
-    /**
-     * Resizes the line numbers of the given element.
-     *
-     * This function will not add line numbers. It will only resize existing ones.
-     *
-     * @param {HTMLElement} element A `<pre>` element with line numbers.
-     * @returns {void}
-     */
-    resize: function (element) {
-      resizeElements([element]);
-    },
-
-    /**
-     * Whether the plugin can assume that the units font sizes and margins are not depended on the size of
-     * the current viewport.
-     *
-     * Setting this to `true` will allow the plugin to do certain optimizations for better performance.
-     *
-     * Set this to `false` if you use any of the following CSS units: `vh`, `vw`, `vmin`, `vmax`.
-     *
-     * @type {boolean}
-     */
-    assumeViewportIndependence: true,
-  });
-
-  /**
-   * Resizes the given elements.
-   *
-   * @param {HTMLElement[]} elements
-   */
-  function resizeElements(elements) {
-    elements = elements.filter(function (e) {
-      var codeStyles = getStyles(e);
-      var whiteSpace = codeStyles["white-space"];
-      return whiteSpace === "pre-wrap" || whiteSpace === "pre-line";
-    });
-
-    if (elements.length == 0) {
-      return;
-    }
-
-    var infos = elements
-      .map(function (element) {
-        var codeElement = element.querySelector("code");
-        var lineNumbersWrapper = element.querySelector(".line-numbers-rows");
-        if (!codeElement || !lineNumbersWrapper) {
-          return undefined;
-        }
-
-        /** @type {HTMLElement} */
-        var lineNumberSizer = element.querySelector(".line-numbers-sizer");
-        var codeLines = codeElement.textContent.split(NEW_LINE_EXP);
-
-        if (!lineNumberSizer) {
-          lineNumberSizer = document.createElement("span");
-          lineNumberSizer.className = "line-numbers-sizer";
-
-          codeElement.appendChild(lineNumberSizer);
-        }
-
-        lineNumberSizer.innerHTML = "0";
-        lineNumberSizer.style.display = "block";
-
-        var oneLinerHeight = lineNumberSizer.getBoundingClientRect().height;
-        lineNumberSizer.innerHTML = "";
-
-        return {
-          element: element,
-          lines: codeLines,
-          lineHeights: [],
-          oneLinerHeight: oneLinerHeight,
-          sizer: lineNumberSizer,
-        };
-      })
-      .filter(Boolean);
-
-    infos.forEach(function (info) {
-      var lineNumberSizer = info.sizer;
-      var lines = info.lines;
-      var lineHeights = info.lineHeights;
-      var oneLinerHeight = info.oneLinerHeight;
-
-      lineHeights[lines.length - 1] = undefined;
-      lines.forEach(function (line, index) {
-        if (line && line.length > 1) {
-          var e = lineNumberSizer.appendChild(document.createElement("span"));
-          e.style.display = "block";
-          e.textContent = line;
-        } else {
-          lineHeights[index] = oneLinerHeight;
-        }
-      });
-    });
-
-    infos.forEach(function (info) {
-      var lineNumberSizer = info.sizer;
-      var lineHeights = info.lineHeights;
-
-      var childIndex = 0;
-      for (var i = 0; i < lineHeights.length; i++) {
-        if (lineHeights[i] === undefined) {
-          lineHeights[i] =
-            lineNumberSizer.children[
-              childIndex++
-            ].getBoundingClientRect().height;
-        }
-      }
-    });
-
-    infos.forEach(function (info) {
-      var lineNumberSizer = info.sizer;
-      var wrapper = info.element.querySelector(".line-numbers-rows");
-
-      lineNumberSizer.style.display = "none";
-      lineNumberSizer.innerHTML = "";
-
-      info.lineHeights.forEach(function (height, lineNumber) {
-        wrapper.children[lineNumber].style.height = height + "px";
-      });
-    });
-  }
-
-  /**
-   * Returns style declarations for the element
-   *
-   * @param {Element} element
-   */
-  function getStyles(element) {
-    if (!element) {
-      return null;
-    }
-
-    return window.getComputedStyle
-      ? getComputedStyle(element)
-      : element.currentStyle || null;
-  }
-
-  var lastWidth = undefined;
-  window.addEventListener("resize", function () {
-    if (config.assumeViewportIndependence && lastWidth === window.innerWidth) {
-      return;
-    }
-    lastWidth = window.innerWidth;
-
-    resizeElements(
-      Array.prototype.slice.call(
-        document.querySelectorAll("pre." + PLUGIN_NAME)
-      )
-    );
-  });
-
-  Prism.hooks.add("complete", function (env) {
-    if (!env.code) {
-      return;
-    }
-
-    var code = /** @type {Element} */ (env.element);
-    var pre = /** @type {HTMLElement} */ (code.parentNode);
-
-    // works only for <code> wrapped inside <pre> (not inline)
-    if (!pre || !/pre/i.test(pre.nodeName)) {
-      return;
-    }
-
-    // Abort if line numbers already exists
-    if (code.querySelector(".line-numbers-rows")) {
-      return;
-    }
-
-    // only add line numbers if <code> or one of its ancestors has the `line-numbers` class
-    if (!Prism.util.isActive(code, PLUGIN_NAME)) {
-      return;
-    }
-
-    // Remove the class 'line-numbers' from the <code>
-    code.classList.remove(PLUGIN_NAME);
-    // Add the class 'line-numbers' to the <pre>
-    pre.classList.add(PLUGIN_NAME);
-
-    var match = env.code.match(NEW_LINE_EXP);
-    var linesNum = match ? match.length + 1 : 1;
-    var lineNumbersWrapper;
-
-    var lines = new Array(linesNum + 1).join("<span></span>");
-
-    lineNumbersWrapper = document.createElement("span");
-    lineNumbersWrapper.setAttribute("aria-hidden", "true");
-    lineNumbersWrapper.className = "line-numbers-rows";
-    lineNumbersWrapper.innerHTML = lines;
-
-    if (pre.hasAttribute("data-start")) {
-      pre.style.counterReset =
-        "linenumber " + (parseInt(pre.getAttribute("data-start"), 10) - 1);
-    }
-
-    env.element.appendChild(lineNumbersWrapper);
-
-    resizeElements([pre]);
-
-    Prism.hooks.run("line-numbers", env);
-  });
-
-  Prism.hooks.add("line-numbers", function (env) {
-    env.plugins = env.plugins || {};
-    env.plugins.lineNumbers = true;
-  });
-})();
-
-(function () {
-  if (typeof Prism === "undefined" || typeof document === "undefined") {
-    return;
-  }
-
-  /* eslint-disable */
-
-  /**
-   * The dependencies map is built automatically with gulp.
-   *
-   * @type {Object<string, string | string[]>}
-   */
-  var lang_dependencies = /*dependencies_placeholder[*/ {
-    javascript: "clike",
-    actionscript: "javascript",
-    apex: ["clike", "sql"],
-    arduino: "cpp",
-    aspnet: ["markup", "csharp"],
-    birb: "clike",
-    bison: "c",
-    c: "clike",
-    csharp: "clike",
-    cpp: "c",
-    cfscript: "clike",
-    chaiscript: ["clike", "cpp"],
-    cilkc: "c",
-    cilkcpp: "cpp",
-    coffeescript: "javascript",
-    crystal: "ruby",
-    "css-extras": "css",
-    d: "clike",
-    dart: "clike",
-    django: "markup-templating",
-    ejs: ["javascript", "markup-templating"],
-    etlua: ["lua", "markup-templating"],
-    erb: ["ruby", "markup-templating"],
-    fsharp: "clike",
-    "firestore-security-rules": "clike",
-    flow: "javascript",
-    ftl: "markup-templating",
-    gml: "clike",
-    glsl: "c",
-    go: "clike",
-    gradle: "clike",
-    groovy: "clike",
-    haml: "ruby",
-    handlebars: "markup-templating",
-    haxe: "clike",
-    hlsl: "c",
-    idris: "haskell",
-    java: "clike",
-    javadoc: ["markup", "java", "javadoclike"],
-    jolie: "clike",
-    jsdoc: ["javascript", "javadoclike", "typescript"],
-    "js-extras": "javascript",
-    json5: "json",
-    jsonp: "json",
-    "js-templates": "javascript",
-    kotlin: "clike",
-    latte: ["clike", "markup-templating", "php"],
-    less: "css",
-    lilypond: "scheme",
-    liquid: "markup-templating",
-    markdown: "markup",
-    "markup-templating": "markup",
-    mongodb: "javascript",
-    n4js: "javascript",
-    objectivec: "c",
-    opencl: "c",
-    parser: "markup",
-    php: "markup-templating",
-    phpdoc: ["php", "javadoclike"],
-    "php-extras": "php",
-    plsql: "sql",
-    processing: "clike",
-    protobuf: "clike",
-    pug: ["markup", "javascript"],
-    purebasic: "clike",
-    purescript: "haskell",
-    qsharp: "clike",
-    qml: "javascript",
-    qore: "clike",
-    racket: "scheme",
-    cshtml: ["markup", "csharp"],
-    jsx: ["markup", "javascript"],
-    tsx: ["jsx", "typescript"],
-    reason: "clike",
-    ruby: "clike",
-    sass: "css",
-    scss: "css",
-    scala: "java",
-    "shell-session": "bash",
-    smarty: "markup-templating",
-    solidity: "clike",
-    soy: "markup-templating",
-    sparql: "turtle",
-    sqf: "clike",
-    squirrel: "clike",
-    stata: ["mata", "java", "python"],
-    "t4-cs": ["t4-templating", "csharp"],
-    "t4-vb": ["t4-templating", "vbnet"],
-    tap: "yaml",
-    tt2: ["clike", "markup-templating"],
-    textile: "markup",
-    twig: "markup-templating",
-    typescript: "javascript",
-    v: "clike",
-    vala: "clike",
-    vbnet: "basic",
-    velocity: "markup",
-    wiki: "markup",
-    xeora: "markup",
-    "xml-doc": "markup",
-    xquery: "markup",
-  }; /*]*/
-
-  var lang_aliases = /*aliases_placeholder[*/ {
-    html: "markup",
-    xml: "markup",
-    svg: "markup",
-    mathml: "markup",
-    ssml: "markup",
-    atom: "markup",
-    rss: "markup",
-    js: "javascript",
-    g4: "antlr4",
-    ino: "arduino",
-    "arm-asm": "armasm",
-    art: "arturo",
-    adoc: "asciidoc",
-    avs: "avisynth",
-    avdl: "avro-idl",
-    gawk: "awk",
-    sh: "bash",
-    shell: "bash",
-    shortcode: "bbcode",
-    rbnf: "bnf",
-    oscript: "bsl",
-    cs: "csharp",
-    dotnet: "csharp",
-    cfc: "cfscript",
-    "cilk-c": "cilkc",
-    "cilk-cpp": "cilkcpp",
-    cilk: "cilkcpp",
-    coffee: "coffeescript",
-    conc: "concurnas",
-    jinja2: "django",
-    "dns-zone": "dns-zone-file",
-    dockerfile: "docker",
-    gv: "dot",
-    eta: "ejs",
-    xlsx: "excel-formula",
-    xls: "excel-formula",
-    gamemakerlanguage: "gml",
-    po: "gettext",
-    gni: "gn",
-    ld: "linker-script",
-    "go-mod": "go-module",
-    hbs: "handlebars",
-    mustache: "handlebars",
-    hs: "haskell",
-    idr: "idris",
-    gitignore: "ignore",
-    hgignore: "ignore",
-    npmignore: "ignore",
-    webmanifest: "json",
-    kt: "kotlin",
-    kts: "kotlin",
-    kum: "kumir",
-    tex: "latex",
-    context: "latex",
-    ly: "lilypond",
-    emacs: "lisp",
-    elisp: "lisp",
-    "emacs-lisp": "lisp",
-    md: "markdown",
-    moon: "moonscript",
-    n4jsd: "n4js",
-    nani: "naniscript",
-    objc: "objectivec",
-    qasm: "openqasm",
-    objectpascal: "pascal",
-    px: "pcaxis",
-    pcode: "peoplecode",
-    plantuml: "plant-uml",
-    pq: "powerquery",
-    mscript: "powerquery",
-    pbfasm: "purebasic",
-    purs: "purescript",
-    py: "python",
-    qs: "qsharp",
-    rkt: "racket",
-    razor: "cshtml",
-    rpy: "renpy",
-    res: "rescript",
-    robot: "robotframework",
-    rb: "ruby",
-    "sh-session": "shell-session",
-    shellsession: "shell-session",
-    smlnj: "sml",
-    sol: "solidity",
-    sln: "solution-file",
-    rq: "sparql",
-    sclang: "supercollider",
-    t4: "t4-cs",
-    trickle: "tremor",
-    troy: "tremor",
-    trig: "turtle",
-    ts: "typescript",
-    tsconfig: "typoscript",
-    uscript: "unrealscript",
-    uc: "unrealscript",
-    url: "uri",
-    vb: "visual-basic",
-    vba: "visual-basic",
-    webidl: "web-idl",
-    mathematica: "wolfram",
-    nb: "wolfram",
-    wl: "wolfram",
-    xeoracube: "xeora",
-    yml: "yaml",
-  }; /*]*/
-
-  /* eslint-enable */
-
-  /**
-   * @typedef LangDataItem
-   * @property {{ success?: () => void, error?: () => void }[]} callbacks
-   * @property {boolean} [error]
-   * @property {boolean} [loading]
-   */
-  /** @type {Object<string, LangDataItem>} */
-  var lang_data = {};
-
-  var ignored_language = "none";
-  var languages_path = "/public/assets/prism/components/";
-
-  var script = Prism.util.currentScript();
-  /*if (script) {
-    var autoloaderFile =
-      /\bplugins\/autoloader\/prism-autoloader\.(?:min\.)?js(?:\?[^\r\n/]*)?$/i;
-    var prismFile = /(^|\/)[\w-]+\.(?:min\.)?js(?:\?[^\r\n/]*)?$/i;
-
-    var autoloaderPath = script.getAttribute("data-autoloader-path");
-    if (autoloaderPath != null) {
-      // data-autoloader-path is set, so just use it
-      languages_path = autoloaderPath.trim().replace(/\/?$/, "/");
-    } else {
-      var src = script.src;
-      if (autoloaderFile.test(src)) {
-        // the script is the original autoloader script in the usual Prism project structure
-        languages_path = src.replace(autoloaderFile, "components/");
-      } else if (prismFile.test(src)) {
-        // the script is part of a bundle like a custom prism.js from the download page
-        languages_path = src.replace(prismFile, "$1components/");
-      }
-    }
-  }*/
-
-  var config = (Prism.plugins.autoloader = {
-    languages_path: languages_path,
-    use_minified: true,
-    loadLanguages: loadLanguages,
-  });
-
-  /**
-   * Lazily loads an external script.
-   *
-   * @param {string} src
-   * @param {() => void} [success]
-   * @param {() => void} [error]
-   */
-  function addScript(src, success, error) {
-    var s = document.createElement("script");
-    s.src = src;
-    s.async = true;
-    s.onload = function () {
-      document.body.removeChild(s);
-      success && success();
-    };
-    s.onerror = function () {
-      document.body.removeChild(s);
-      error && error();
-    };
-    document.body.appendChild(s);
-  }
-
-  /**
-   * Returns all additional dependencies of the given element defined by the `data-dependencies` attribute.
-   *
-   * @param {Element} element
-   * @returns {string[]}
-   */
-  function getDependencies(element) {
-    var deps = (element.getAttribute("data-dependencies") || "").trim();
-    if (!deps) {
-      var parent = element.parentElement;
-      if (parent && parent.tagName.toLowerCase() === "pre") {
-        deps = (parent.getAttribute("data-dependencies") || "").trim();
-      }
-    }
-    return deps ? deps.split(/\s*,\s*/g) : [];
-  }
-
-  /**
-   * Returns whether the given language is currently loaded.
-   *
-   * @param {string} lang
-   * @returns {boolean}
-   */
-  function isLoaded(lang) {
-    if (lang.indexOf("!") >= 0) {
-      // forced reload
-      return false;
-    }
-
-    lang = lang_aliases[lang] || lang; // resolve alias
-
-    if (lang in Prism.languages) {
-      // the given language is already loaded
-      return true;
-    }
-
-    // this will catch extensions like CSS extras that don't add a grammar to Prism.languages
-    var data = lang_data[lang];
-    return data && !data.error && data.loading === false;
-  }
-
-  /**
-   * Returns the path to a grammar, using the language_path and use_minified config keys.
-   *
-   * @param {string} lang
-   * @returns {string}
-   */
-  function getLanguagePath(lang) {
-    return (
-      config.languages_path +
-      "prism-" +
-      lang +
-      (config.use_minified ? ".min" : "") +
-      ".js"
-    );
-  }
-
-  /**
-   * Loads all given grammars concurrently.
-   *
-   * @param {string[]|string} languages
-   * @param {(languages: string[]) => void} [success]
-   * @param {(language: string) => void} [error] This callback will be invoked on the first language to fail.
-   */
-  function loadLanguages(languages, success, error) {
-    if (typeof languages === "string") {
-      languages = [languages];
-    }
-
-    var total = languages.length;
-    var completed = 0;
-    var failed = false;
-
-    if (total === 0) {
-      if (success) {
-        setTimeout(success, 0);
-      }
-      return;
-    }
-
-    function successCallback() {
-      if (failed) {
-        return;
-      }
-      completed++;
-      if (completed === total) {
-        success && success(languages);
-      }
-    }
-
-    languages.forEach(function (lang) {
-      loadLanguage(lang, successCallback, function () {
-        if (failed) {
-          return;
-        }
-        failed = true;
-        error && error(lang);
-      });
-    });
-  }
-
-  /**
-   * Loads a grammar with its dependencies.
-   *
-   * @param {string} lang
-   * @param {() => void} [success]
-   * @param {() => void} [error]
-   */
-  function loadLanguage(lang, success, error) {
-    var force = lang.indexOf("!") >= 0;
-
-    lang = lang.replace("!", "");
-    lang = lang_aliases[lang] || lang;
-
-    function load() {
-      var data = lang_data[lang];
-      if (!data) {
-        data = lang_data[lang] = {
-          callbacks: [],
-        };
-      }
-      data.callbacks.push({
-        success: success,
-        error: error,
-      });
-
-      if (!force && isLoaded(lang)) {
-        // the language is already loaded and we aren't forced to reload
-        languageCallback(lang, "success");
-      } else if (!force && data.error) {
-        // the language failed to load before and we don't reload
-        languageCallback(lang, "error");
-      } else if (force || !data.loading) {
-        // the language isn't currently loading and/or we are forced to reload
-        data.loading = true;
-        data.error = false;
-
-        addScript(
-          getLanguagePath(lang),
-          function () {
-            data.loading = false;
-            languageCallback(lang, "success");
-          },
-          function () {
-            data.loading = false;
-            data.error = true;
-            languageCallback(lang, "error");
-          }
-        );
-      }
-    }
-
-    var dependencies = lang_dependencies[lang];
-    if (dependencies && dependencies.length) {
-      loadLanguages(dependencies, load, error);
-    } else {
-      load();
-    }
-  }
-
-  /**
-   * Runs all callbacks of the given type for the given language.
-   *
-   * @param {string} lang
-   * @param {"success" | "error"} type
-   */
-  function languageCallback(lang, type) {
-    if (lang_data[lang]) {
-      var callbacks = lang_data[lang].callbacks;
-      for (var i = 0, l = callbacks.length; i < l; i++) {
-        var callback = callbacks[i][type];
-        if (callback) {
-          setTimeout(callback, 0);
-        }
-      }
-      callbacks.length = 0;
-    }
-  }
-
-  Prism.hooks.add("complete", function (env) {
-    var element = env.element;
-    var language = env.language;
-    if (!element || !language || language === ignored_language) {
-      return;
-    }
-
-    var deps = getDependencies(element);
-    if (/^diff-./i.test(language)) {
-      // the "diff-xxxx" format is used by the Diff Highlight plugin
-      deps.push("diff");
-      deps.push(language.substr("diff-".length));
-    } else {
-      deps.push(language);
-    }
-
-    if (!deps.every(isLoaded)) {
-      // the language or some dependencies aren't loaded
-      loadLanguages(deps, function () {
-        Prism.highlightElement(element);
-      });
-    }
-  });
-})();
-
-(function () {
-  if (typeof Prism === "undefined") {
-    return;
-  }
-
-  var assign =
-    Object.assign ||
-    function (obj1, obj2) {
-      for (var name in obj2) {
-        if (obj2.hasOwnProperty(name)) {
-          obj1[name] = obj2[name];
-        }
-      }
-      return obj1;
-    };
-
-  function NormalizeWhitespace(defaults) {
-    this.defaults = assign({}, defaults);
-  }
-
-  function toCamelCase(value) {
-    return value.replace(/-(\w)/g, function (match, firstChar) {
-      return firstChar.toUpperCase();
-    });
-  }
-
-  function tabLen(str) {
-    var res = 0;
-    for (var i = 0; i < str.length; ++i) {
-      if (str.charCodeAt(i) == "\t".charCodeAt(0)) {
-        res += 3;
-      }
-    }
-    return str.length + res;
-  }
-
-  var settingsConfig = {
-    "remove-trailing": "boolean",
-    "remove-indent": "boolean",
-    "left-trim": "boolean",
-    "right-trim": "boolean",
-    "break-lines": "number",
-    indent: "number",
-    "remove-initial-line-feed": "boolean",
-    "tabs-to-spaces": "number",
-    "spaces-to-tabs": "number",
-  };
-
-  NormalizeWhitespace.prototype = {
-    setDefaults: function (defaults) {
-      this.defaults = assign(this.defaults, defaults);
-    },
-    normalize: function (input, settings) {
-      settings = assign(this.defaults, settings);
-
-      for (var name in settings) {
-        var methodName = toCamelCase(name);
-        if (
-          name !== "normalize" &&
-          methodName !== "setDefaults" &&
-          settings[name] &&
-          this[methodName]
-        ) {
-          input = this[methodName].call(this, input, settings[name]);
-        }
-      }
-
-      return input;
-    },
-
-    /*
-     * Normalization methods
-     */
-    leftTrim: function (input) {
-      return input.replace(/^\s+/, "");
-    },
-    rightTrim: function (input) {
-      return input.replace(/\s+$/, "");
-    },
-    tabsToSpaces: function (input, spaces) {
-      spaces = spaces | 0 || 4;
-      return input.replace(/\t/g, new Array(++spaces).join(" "));
-    },
-    spacesToTabs: function (input, spaces) {
-      spaces = spaces | 0 || 4;
-      return input.replace(RegExp(" {" + spaces + "}", "g"), "\t");
-    },
-    removeTrailing: function (input) {
-      return input.replace(/\s*?$/gm, "");
-    },
-    // Support for deprecated plugin remove-initial-line-feed
-    removeInitialLineFeed: function (input) {
-      return input.replace(/^(?:\r?\n|\r)/, "");
-    },
-    removeIndent: function (input) {
-      var indents = input.match(/^[^\S\n\r]*(?=\S)/gm);
-
-      if (!indents || !indents[0].length) {
-        return input;
-      }
-
-      indents.sort(function (a, b) {
-        return a.length - b.length;
-      });
-
-      if (!indents[0].length) {
-        return input;
-      }
-
-      return input.replace(RegExp("^" + indents[0], "gm"), "");
-    },
-    indent: function (input, tabs) {
-      return input.replace(
-        /^[^\S\n\r]*(?=\S)/gm,
-        new Array(++tabs).join("\t") + "$&"
-      );
-    },
-    breakLines: function (input, characters) {
-      characters = characters === true ? 80 : characters | 0 || 80;
-
-      var lines = input.split("\n");
-      for (var i = 0; i < lines.length; ++i) {
-        if (tabLen(lines[i]) <= characters) {
-          continue;
-        }
-
-        var line = lines[i].split(/(\s+)/g);
-        var len = 0;
-
-        for (var j = 0; j < line.length; ++j) {
-          var tl = tabLen(line[j]);
-          len += tl;
-          if (len > characters) {
-            line[j] = "\n" + line[j];
-            len = tl;
-          }
-        }
-        lines[i] = line.join("");
-      }
-      return lines.join("\n");
-    },
-  };
-
-  // Support node modules
-  if (typeof module !== "undefined" && module.exports) {
-    module.exports = NormalizeWhitespace;
-  }
-
-  Prism.plugins.NormalizeWhitespace = new NormalizeWhitespace({
-    "remove-trailing": true,
-    "remove-indent": true,
-    "left-trim": true,
-    "right-trim": true,
-    /*'break-lines': 80,
-    'indent': 2,
-    'remove-initial-line-feed': false,
-    'tabs-to-spaces': 4,
-    'spaces-to-tabs': 4*/
-  });
-
-  Prism.hooks.add("before-sanity-check", function (env) {
-    var Normalizer = Prism.plugins.NormalizeWhitespace;
-
-    // Check settings
-    if (env.settings && env.settings["whitespace-normalization"] === false) {
-      return;
-    }
-
-    // Check classes
-    if (!Prism.util.isActive(env.element, "whitespace-normalization", true)) {
-      return;
-    }
-
-    // Simple mode if there is no env.element
-    if ((!env.element || !env.element.parentNode) && env.code) {
-      env.code = Normalizer.normalize(env.code, env.settings);
-      return;
-    }
-
-    // Normal mode
-    var pre = env.element.parentNode;
-    if (!env.code || !pre || pre.nodeName.toLowerCase() !== "pre") {
-      return;
-    }
-
-    if (env.settings == null) {
-      env.settings = {};
-    }
-
-    // Read settings from 'data-' attributes
-    for (var key in settingsConfig) {
-      if (Object.hasOwnProperty.call(settingsConfig, key)) {
-        var settingType = settingsConfig[key];
-        if (pre.hasAttribute("data-" + key)) {
-          try {
-            var value = JSON.parse(pre.getAttribute("data-" + key) || "true");
-            if (typeof value === settingType) {
-              env.settings[key] = value;
-            }
-          } catch (_error) {
-            // ignore error
-          }
-        }
-      }
-    }
-
-    var children = pre.childNodes;
-    var before = "";
-    var after = "";
-    var codeFound = false;
-
-    // Move surrounding whitespace from the <pre> tag into the <code> tag
-    for (var i = 0; i < children.length; ++i) {
-      var node = children[i];
-
-      if (node == env.element) {
-        codeFound = true;
-      } else if (node.nodeName === "#text") {
-        if (codeFound) {
-          after += node.nodeValue;
-        } else {
-          before += node.nodeValue;
-        }
-
-        pre.removeChild(node);
-        --i;
-      }
-    }
-
-    if (!env.element.children.length || !Prism.plugins.KeepMarkup) {
-      env.code = before + env.code + after;
-      env.code = Normalizer.normalize(env.code, env.settings);
-    } else {
-      // Preserve markup for keep-markup plugin
-      var html = before + env.element.innerHTML + after;
-      env.element.innerHTML = Normalizer.normalize(html, env.settings);
-      env.code = env.element.textContent;
-    }
-  });
-})();
-
-(function () {
-  if (typeof Prism === "undefined") {
-    return;
-  }
-
-  var LANGUAGE_REGEX = /^diff-([\w-]+)/i;
-  var HTML_TAG =
-    /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/g;
-  //this will match a line plus the line break while ignoring the line breaks HTML tags may contain.
-  var HTML_LINE = RegExp(
-    /(?:__|[^\r\n<])*(?:\r\n?|\n|(?:__|[^\r\n<])(?![^\r\n]))/.source.replace(
-      /__/g,
-      function () {
-        return HTML_TAG.source;
-      }
-    ),
-    "gi"
-  );
-
-  var warningLogged = false;
-
-  Prism.hooks.add("before-sanity-check", function (env) {
-    var lang = env.language;
-    if (LANGUAGE_REGEX.test(lang) && !env.grammar) {
-      env.grammar = Prism.languages[lang] = Prism.languages.diff;
-    }
-  });
-  Prism.hooks.add("before-tokenize", function (env) {
-    if (!warningLogged && !Prism.languages.diff && !Prism.plugins.autoloader) {
-      warningLogged = true;
-      console.warn(
-        "Prism's Diff Highlight plugin requires the Diff language definition (prism-diff.js)." +
-          "Make sure the language definition is loaded or use Prism's Autoloader plugin."
-      );
-    }
-
-    var lang = env.language;
-    if (LANGUAGE_REGEX.test(lang) && !Prism.languages[lang]) {
-      Prism.languages[lang] = Prism.languages.diff;
-    }
-  });
-
-  Prism.hooks.add("wrap", function (env) {
-    var diffLanguage;
-    var diffGrammar;
-
-    if (env.language !== "diff") {
-      var langMatch = LANGUAGE_REGEX.exec(env.language);
-      if (!langMatch) {
-        return; // not a language specific diff
-      }
-
-      diffLanguage = langMatch[1];
-      diffGrammar = Prism.languages[diffLanguage];
-    }
-
-    var PREFIXES = Prism.languages.diff && Prism.languages.diff.PREFIXES;
-
-    // one of the diff tokens without any nested tokens
-    if (PREFIXES && env.type in PREFIXES) {
-      /** @type {string} */
-      var content = env.content.replace(HTML_TAG, ""); // remove all HTML tags
-
-      /** @type {string} */
-      var decoded = content.replace(/&lt;/g, "<").replace(/&amp;/g, "&");
-
-      // remove any one-character prefix
-      var code = decoded.replace(/(^|[\r\n])./g, "$1");
-
-      // highlight, if possible
-      var highlighted;
-      if (diffGrammar) {
-        highlighted = Prism.highlight(code, diffGrammar, diffLanguage);
-      } else {
-        highlighted = Prism.util.encode(code);
-      }
-
-      // get the HTML source of the prefix token
-      var prefixToken = new Prism.Token("prefix", PREFIXES[env.type], [
-        /\w+/.exec(env.type)[0],
-      ]);
-      var prefix = Prism.Token.stringify(prefixToken, env.language);
-
-      // add prefix
-      var lines = [];
-      var m;
-      HTML_LINE.lastIndex = 0;
-      while ((m = HTML_LINE.exec(highlighted))) {
-        lines.push(prefix + m[0]);
-      }
-      if (/(?:^|[\r\n]).$/.test(decoded)) {
-        // because both "+a\n+" and "+a\n" will map to "a\n" after the line prefixes are removed
-        lines.push(prefix);
-      }
-      env.content = lines.join("");
-
-      if (diffGrammar) {
-        env.classes.push("language-" + diffLanguage);
-      }
-    }
-  });
-})();

new file
public/.deps/prismjs.production.min.disabled.js
@@ -0,0 +1,2 @@
+var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){var t=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,n=0,r={},a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(t){return t instanceof i?new i(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++n}),e.__id},clone:function e(t,n){var r,i;switch(n=n||{},a.util.type(t)){case"Object":if(i=a.util.objId(t),n[i])return n[i];for(var s in r={},n[i]=r,t)t.hasOwnProperty(s)&&(r[s]=e(t[s],n));return r;case"Array":return i=a.util.objId(t),n[i]?n[i]:(r=[],n[i]=r,t.forEach(function(t,a){r[a]=e(t,n)}),r);default:return t}},getLanguage:function(e){for(;e;){var n=t.exec(e.className);if(n)return n[1].toLowerCase();e=e.parentElement}return"none"},setLanguage:function(e,n){e.className=e.className.replace(RegExp(t,"gi"),""),e.classList.add("language-"+n)},currentScript:function(){if("undefined"==typeof document)return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(r){var e=(/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(r.stack)||[])[1];if(e){var t=document.getElementsByTagName("script");for(var n in t)if(t[n].src==e)return t[n]}return null}},isActive:function(e,t,n){for(var r="no-"+t;e;){var a=e.classList;if(a.contains(t))return!0;if(a.contains(r))return!1;e=e.parentElement}return!!n}},languages:{plain:r,plaintext:r,text:r,txt:r,extend:function(e,t){var n=a.util.clone(a.languages[e]);for(var r in t)n[r]=t[r];return n},insertBefore:function(e,t,n,r){var i=(r=r||a.languages)[e],s={};for(var l in i)if(i.hasOwnProperty(l)){if(l==t)for(var o in n)n.hasOwnProperty(o)&&(s[o]=n[o]);n.hasOwnProperty(l)||(s[l]=i[l])}var u=r[e];return r[e]=s,a.languages.DFS(a.languages,function(t,n){n===u&&t!=e&&(this[t]=s)}),s},DFS:function e(t,n,r,i){i=i||{};var s=a.util.objId;for(var l in t)if(t.hasOwnProperty(l)){n.call(t,l,t[l],r||l);var o=t[l],u=a.util.type(o);"Object"!==u||i[s(o)]?"Array"!==u||i[s(o)]||(i[s(o)]=!0,e(o,n,l,i)):(i[s(o)]=!0,e(o,n,null,i))}}},plugins:{},highlightAll:function(e,t){a.highlightAllUnder(document,e,t)},highlightAllUnder:function(e,t,n){var r={callback:n,container:e,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};a.hooks.run("before-highlightall",r),r.elements=Array.prototype.slice.apply(r.container.querySelectorAll(r.selector)),a.hooks.run("before-all-elements-highlight",r);for(var i,s=0;i=r.elements[s++];)a.highlightElement(i,!0===t,r.callback)},highlightElement:function(t,n,r){var i=a.util.getLanguage(t),s=a.languages[i];a.util.setLanguage(t,i);var l=t.parentElement;l&&"pre"===l.nodeName.toLowerCase()&&a.util.setLanguage(l,i);var o={element:t,language:i,grammar:s,code:t.textContent};function u(e){o.highlightedCode=e,a.hooks.run("before-insert",o),o.element.innerHTML=o.highlightedCode,a.hooks.run("after-highlight",o),a.hooks.run("complete",o),r&&r.call(o.element)}if(a.hooks.run("before-sanity-check",o),(l=o.element.parentElement)&&"pre"===l.nodeName.toLowerCase()&&!l.hasAttribute("tabindex")&&l.setAttribute("tabindex","0"),!o.code)return a.hooks.run("complete",o),void(r&&r.call(o.element));if(a.hooks.run("before-highlight",o),o.grammar)if(n&&e.Worker){var c=new Worker(a.filename);c.onmessage=function(e){u(e.data)},c.postMessage(JSON.stringify({language:o.language,code:o.code,immediateClose:!0}))}else u(a.highlight(o.code,o.grammar,o.language));else u(a.util.encode(o.code))},highlight:function(e,t,n){var r={code:e,grammar:t,language:n};if(a.hooks.run("before-tokenize",r),!r.grammar)throw new Error('The language "'+r.language+'" has no grammar.');return r.tokens=a.tokenize(r.code,r.grammar),a.hooks.run("after-tokenize",r),i.stringify(a.util.encode(r.tokens),r.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}var u=new function(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0};return l(u,u.head,e),function e(t,n,r,u,c,p){for(var g in r)if(r.hasOwnProperty(g)&&r[g]){var d=r[g];d=Array.isArray(d)?d:[d];for(var m=0;m<d.length;++m){if(p&&p.cause==g+","+m)return;var f=d[m],h=f.inside,v=!!f.lookbehind,b=!!f.greedy,k=f.alias;if(b&&!f.pattern.global){var y=f.pattern.toString().match(/[imsuy]*$/)[0];f.pattern=RegExp(f.pattern.source,y+"g")}for(var x=f.pattern||f,w=u.next,P=c;w!==n.tail&&!(p&&P>=p.reach);P+=w.value.length,w=w.next){var F=w.value;if(n.length>t.length)return;if(!(F instanceof i)){var A,j=1;if(b){if(!(A=s(x,P,t,v))||A.index>=t.length)break;var S=A.index,$=A.index+A[0].length,E=P;for(E+=w.value.length;S>=E;)w=w.next,E+=w.value.length;if(E-=w.value.length,P=E,w.value instanceof i)continue;for(var C=w;C!==n.tail&&(E<$||"string"==typeof C.value);C=C.next)j++,E+=C.value.length;j--,F=t.slice(P,E),A.index-=P}else if(!(A=s(x,0,F,v)))continue;var S=A.index,L=A[0],z=F.slice(0,S),_=F.slice(S+L.length),T=P+F.length;p&&T>p.reach&&(p.reach=T);var q=w.prev;z&&(q=l(n,q,z),P+=z.length),o(n,q,j);var N=new i(g,h?a.tokenize(L,h):L,k,L);if(w=l(n,q,N),_&&l(n,w,_),j>1){var O={cause:g+","+m,reach:T};e(t,n,r,w.prev,P,O),p&&O.reach>p.reach&&(p.reach=O.reach)}}}}}}(e,u,t,u.head,0),function(e){var t=[],n=e.head.next;for(;n!==e.tail;)t.push(n.value),n=n.next;return t}(u)},hooks:{all:{},add:function(e,t){var n=a.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=a.hooks.all[e];if(n&&n.length)for(var r,i=0;r=n[i++];)r(t)}},Token:i};function i(e,t,n,r){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length}function s(e,t,n,r){e.lastIndex=t;var a=e.exec(n);if(a&&r&&a[1]){var i=a[1].length;a.index+=i,a[0]=a[0].slice(i)}return a}function l(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function o(e,t,n){for(var r=t.next,a=0;a<n&&r!==e.tail;a++)r=r.next;t.next=r,r.prev=t,e.length-=a}if(e.Prism=a,i.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var r="";return t.forEach(function(t){r+=e(t,n)}),r}var i={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},s=t.alias;s&&(Array.isArray(s)?Array.prototype.push.apply(i.classes,s):i.classes.push(s)),a.hooks.run("wrap",i);var l="";for(var o in i.attributes)l+=" "+o+'="'+(i.attributes[o]||"").replace(/"/g,"&quot;")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'"'+l+">"+i.content+"</"+i.tag+">"},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",function(t){var n=JSON.parse(t.data),r=n.language,i=n.code,s=n.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),s&&e.close()},!1),a):a;var u=a.util.currentScript();function c(){a.manual||a.highlightAll()}if(u&&(a.filename=u.src,u.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var p=document.readyState;"loading"===p||"interactive"===p&&u&&u.defer?document.addEventListener("DOMContentLoaded",c):window.requestAnimationFrame?window.requestAnimationFrame(c):window.setTimeout(c,16)}return a}(_self);
+"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism),Prism.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&amp;/,"&"))}),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:Prism.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i;var r={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:Prism.languages[t]};var a={};a[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,function(){return e}),"i"),lookbehind:!0,greedy:!0,inside:r},Prism.languages.insertBefore("markup","cdata",a)}}),Object.defineProperty(Prism.languages.markup.tag,"addAttribute",{value:function(e,t){Prism.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:Prism.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml,function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+t.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(Prism),Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),Prism.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),Prism.languages.markup&&(Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),Prism.languages.js=Prism.languages.javascript,function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach(function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}}),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(Prism),function(){if(void 0!==Prism&&"undefined"!=typeof document&&document.querySelector){var e,t="linkable-line-numbers",n=/\n(?!$)/g,r=function(){if(void 0===e){var t=document.createElement("div");t.style.fontSize="13px",t.style.lineHeight="1.5",t.style.padding="0",t.style.border="0",t.innerHTML="&nbsp;<br />&nbsp;",document.body.appendChild(t),e=38===t.offsetHeight,document.body.removeChild(t)}return e},a=!0;Prism.plugins.lineHighlight={highlightLines:function(e,i,u){var c=(i="string"==typeof i?i:e.getAttribute("data-line")||"").replace(/\s+/g,"").split(",").filter(Boolean),p=+e.getAttribute("data-line-offset")||0,g=(r()?parseInt:parseFloat)(getComputedStyle(e).lineHeight),d=Prism.util.isActive(e,"line-numbers"),m=e.querySelector("code"),f=d?e:m||e,h=[],v=m.textContent.match(n),b=v?v.length+1:1,k=m&&f!=m?function(e,t){var n=getComputedStyle(e),r=getComputedStyle(t);function a(e){return+e.substr(0,e.length-2)}return t.offsetTop+a(r.borderTopWidth)+a(r.paddingTop)-a(n.paddingTop)}(e,m):0;c.forEach(function(t){var n=t.split("-"),r=+n[0],a=+n[1]||r;if(!((a=Math.min(b+p,a))<r)){var i=e.querySelector('.line-highlight[data-range="'+t+'"]')||document.createElement("div");if(h.push(function(){i.setAttribute("aria-hidden","true"),i.setAttribute("data-range",t),i.className=(u||"")+" line-highlight"}),d&&Prism.plugins.lineNumbers){var s=Prism.plugins.lineNumbers.getLine(e,r),l=Prism.plugins.lineNumbers.getLine(e,a);if(s){var o=s.offsetTop+k+"px";h.push(function(){i.style.top=o})}if(l){var c=l.offsetTop-s.offsetTop+l.offsetHeight+"px";h.push(function(){i.style.height=c})}}else h.push(function(){i.setAttribute("data-start",String(r)),a>r&&i.setAttribute("data-end",String(a)),i.style.top=(r-p-1)*g+k+"px",i.textContent=new Array(a-r+2).join(" \n")});h.push(function(){i.style.width=e.scrollWidth+"px"}),h.push(function(){f.appendChild(i)})}});var y=e.id;if(d&&Prism.util.isActive(e,t)&&y){l(e,t)||h.push(function(){e.classList.add(t)});var x=parseInt(e.getAttribute("data-start")||"1");s(".line-numbers-rows > span",e).forEach(function(e,t){var n=t+x;e.onclick=function(){var e=y+"."+n;a=!1,location.hash=e,setTimeout(function(){a=!0},1)}})}return function(){h.forEach(o)}}};var i=0;Prism.hooks.add("before-sanity-check",function(e){var t=e.element.parentElement;if(u(t)){var n=0;s(".line-highlight",t).forEach(function(e){n+=e.textContent.length,e.parentNode.removeChild(e)}),n&&/^(?: \n)+$/.test(e.code.slice(-n))&&(e.code=e.code.slice(0,-n))}}),Prism.hooks.add("complete",function e(t){var n=t.element.parentElement;if(u(n)){clearTimeout(i);var r=Prism.plugins.lineNumbers,a=t.plugins&&t.plugins.lineNumbers;if(l(n,"line-numbers")&&r&&!a)Prism.hooks.add("line-numbers",e);else Prism.plugins.lineHighlight.highlightLines(n)(),i=setTimeout(c,1)}}),window.addEventListener("hashchange",c),window.addEventListener("resize",function(){s("pre").filter(u).map(function(e){return Prism.plugins.lineHighlight.highlightLines(e)}).forEach(o)})}function s(e,t){return Array.prototype.slice.call((t||document).querySelectorAll(e))}function l(e,t){return e.classList.contains(t)}function o(e){e()}function u(e){return!(!e||!/pre/i.test(e.nodeName))&&(!!e.hasAttribute("data-line")||!(!e.id||!Prism.util.isActive(e,t)))}function c(){var e=location.hash.slice(1);s(".temporary.line-highlight").forEach(function(e){e.parentNode.removeChild(e)});var t=(e.match(/\.([\d,-]+)$/)||[,""])[1];if(t&&!document.getElementById(e)){var n=e.slice(0,e.lastIndexOf(".")),r=document.getElementById(n);if(r)r.hasAttribute("data-line")||r.setAttribute("data-line",""),Prism.plugins.lineHighlight.highlightLines(r,t,"temporary ")(),a&&document.querySelector(".temporary.line-highlight").scrollIntoView()}}}(),function(){if(void 0!==Prism&&"undefined"!=typeof document){var e=/\n(?!$)/g,t=Prism.plugins.lineNumbers={getLine:function(e,t){if("PRE"===e.tagName&&e.classList.contains("line-numbers")){var n=e.querySelector(".line-numbers-rows");if(n){var r=parseInt(e.getAttribute("data-start"),10)||1,a=r+(n.children.length-1);t<r&&(t=r),t>a&&(t=a);var i=t-r;return n.children[i]}}},resize:function(e){r([e])},assumeViewportIndependence:!0},n=void 0;window.addEventListener("resize",function(){t.assumeViewportIndependence&&n===window.innerWidth||(n=window.innerWidth,r(Array.prototype.slice.call(document.querySelectorAll("pre.line-numbers"))))}),Prism.hooks.add("complete",function(t){if(t.code){var n=t.element,a=n.parentNode;if(a&&/pre/i.test(a.nodeName)&&!n.querySelector(".line-numbers-rows")&&Prism.util.isActive(n,"line-numbers")){n.classList.remove("line-numbers"),a.classList.add("line-numbers");var i,s=t.code.match(e),l=s?s.length+1:1,o=new Array(l+1).join("<span></span>");(i=document.createElement("span")).setAttribute("aria-hidden","true"),i.className="line-numbers-rows",i.innerHTML=o,a.hasAttribute("data-start")&&(a.style.counterReset="linenumber "+(parseInt(a.getAttribute("data-start"),10)-1)),t.element.appendChild(i),r([a]),Prism.hooks.run("line-numbers",t)}}}),Prism.hooks.add("line-numbers",function(e){e.plugins=e.plugins||{},e.plugins.lineNumbers=!0})}function r(t){if(0!=(t=t.filter(function(e){var t=function(e){if(!e)return null;return window.getComputedStyle?getComputedStyle(e):e.currentStyle||null}(e)["white-space"];return"pre-wrap"===t||"pre-line"===t})).length){var n=t.map(function(t){var n=t.querySelector("code"),r=t.querySelector(".line-numbers-rows");if(n&&r){var a=t.querySelector(".line-numbers-sizer"),i=n.textContent.split(e);a||((a=document.createElement("span")).className="line-numbers-sizer",n.appendChild(a)),a.innerHTML="0",a.style.display="block";var s=a.getBoundingClientRect().height;return a.innerHTML="",{element:t,lines:i,lineHeights:[],oneLinerHeight:s,sizer:a}}}).filter(Boolean);n.forEach(function(e){var t=e.sizer,n=e.lines,r=e.lineHeights,a=e.oneLinerHeight;r[n.length-1]=void 0,n.forEach(function(e,n){if(e&&e.length>1){var i=t.appendChild(document.createElement("span"));i.style.display="block",i.textContent=e}else r[n]=a})}),n.forEach(function(e){for(var t=e.sizer,n=e.lineHeights,r=0,a=0;a<n.length;a++)void 0===n[a]&&(n[a]=t.children[r++].getBoundingClientRect().height)}),n.forEach(function(e){var t=e.sizer,n=e.element.querySelector(".line-numbers-rows");t.style.display="none",t.innerHTML="",e.lineHeights.forEach(function(e,t){n.children[t].style.height=e+"px"})})}}}(),function(){if(void 0!==Prism&&"undefined"!=typeof document){var e={javascript:"clike",actionscript:"javascript",apex:["clike","sql"],arduino:"cpp",aspnet:["markup","csharp"],birb:"clike",bison:"c",c:"clike",csharp:"clike",cpp:"c",cfscript:"clike",chaiscript:["clike","cpp"],cilkc:"c",cilkcpp:"cpp",coffeescript:"javascript",crystal:"ruby","css-extras":"css",d:"clike",dart:"clike",django:"markup-templating",ejs:["javascript","markup-templating"],etlua:["lua","markup-templating"],erb:["ruby","markup-templating"],fsharp:"clike","firestore-security-rules":"clike",flow:"javascript",ftl:"markup-templating",gml:"clike",glsl:"c",go:"clike",gradle:"clike",groovy:"clike",haml:"ruby",handlebars:"markup-templating",haxe:"clike",hlsl:"c",idris:"haskell",java:"clike",javadoc:["markup","java","javadoclike"],jolie:"clike",jsdoc:["javascript","javadoclike","typescript"],"js-extras":"javascript",json5:"json",jsonp:"json","js-templates":"javascript",kotlin:"clike",latte:["clike","markup-templating","php"],less:"css",lilypond:"scheme",liquid:"markup-templating",markdown:"markup","markup-templating":"markup",mongodb:"javascript",n4js:"javascript",objectivec:"c",opencl:"c",parser:"markup",php:"markup-templating",phpdoc:["php","javadoclike"],"php-extras":"php",plsql:"sql",processing:"clike",protobuf:"clike",pug:["markup","javascript"],purebasic:"clike",purescript:"haskell",qsharp:"clike",qml:"javascript",qore:"clike",racket:"scheme",cshtml:["markup","csharp"],jsx:["markup","javascript"],tsx:["jsx","typescript"],reason:"clike",ruby:"clike",sass:"css",scss:"css",scala:"java","shell-session":"bash",smarty:"markup-templating",solidity:"clike",soy:"markup-templating",sparql:"turtle",sqf:"clike",squirrel:"clike",stata:["mata","java","python"],"t4-cs":["t4-templating","csharp"],"t4-vb":["t4-templating","vbnet"],tap:"yaml",tt2:["clike","markup-templating"],textile:"markup",twig:"markup-templating",typescript:"javascript",v:"clike",vala:"clike",vbnet:"basic",velocity:"markup",wiki:"markup",xeora:"markup","xml-doc":"markup",xquery:"markup"},t={html:"markup",xml:"markup",svg:"markup",mathml:"markup",ssml:"markup",atom:"markup",rss:"markup",js:"javascript",g4:"antlr4",ino:"arduino","arm-asm":"armasm",art:"arturo",adoc:"asciidoc",avs:"avisynth",avdl:"avro-idl",gawk:"awk",sh:"bash",shell:"bash",shortcode:"bbcode",rbnf:"bnf",oscript:"bsl",cs:"csharp",dotnet:"csharp",cfc:"cfscript","cilk-c":"cilkc","cilk-cpp":"cilkcpp",cilk:"cilkcpp",coffee:"coffeescript",conc:"concurnas",jinja2:"django","dns-zone":"dns-zone-file",dockerfile:"docker",gv:"dot",eta:"ejs",xlsx:"excel-formula",xls:"excel-formula",gamemakerlanguage:"gml",po:"gettext",gni:"gn",ld:"linker-script","go-mod":"go-module",hbs:"handlebars",mustache:"handlebars",hs:"haskell",idr:"idris",gitignore:"ignore",hgignore:"ignore",npmignore:"ignore",webmanifest:"json",kt:"kotlin",kts:"kotlin",kum:"kumir",tex:"latex",context:"latex",ly:"lilypond",emacs:"lisp",elisp:"lisp","emacs-lisp":"lisp",md:"markdown",moon:"moonscript",n4jsd:"n4js",nani:"naniscript",objc:"objectivec",qasm:"openqasm",objectpascal:"pascal",px:"pcaxis",pcode:"peoplecode",plantuml:"plant-uml",pq:"powerquery",mscript:"powerquery",pbfasm:"purebasic",purs:"purescript",py:"python",qs:"qsharp",rkt:"racket",razor:"cshtml",rpy:"renpy",res:"rescript",robot:"robotframework",rb:"ruby","sh-session":"shell-session",shellsession:"shell-session",smlnj:"sml",sol:"solidity",sln:"solution-file",rq:"sparql",sclang:"supercollider",t4:"t4-cs",trickle:"tremor",troy:"tremor",trig:"turtle",ts:"typescript",tsconfig:"typoscript",uscript:"unrealscript",uc:"unrealscript",url:"uri",vb:"visual-basic",vba:"visual-basic",webidl:"web-idl",mathematica:"wolfram",nb:"wolfram",wl:"wolfram",xeoracube:"xeora",yml:"yaml"},n={},r=(Prism.util.currentScript(),Prism.plugins.autoloader={languages_path:"/public/assets/prism/components/",use_minified:!0,loadLanguages:i});Prism.hooks.add("complete",function(e){var t=e.element,n=e.language;if(t&&n&&"none"!==n){var r=function(e){var t=(e.getAttribute("data-dependencies")||"").trim();if(!t){var n=e.parentElement;n&&"pre"===n.tagName.toLowerCase()&&(t=(n.getAttribute("data-dependencies")||"").trim())}return t?t.split(/\s*,\s*/g):[]}(t);/^diff-./i.test(n)?(r.push("diff"),r.push(n.substr("diff-".length))):r.push(n),r.every(a)||i(r,function(){Prism.highlightElement(t)})}})}function a(e){if(e.indexOf("!")>=0)return!1;if((e=t[e]||e)in Prism.languages)return!0;var r=n[e];return r&&!r.error&&!1===r.loading}function i(l,o,u){"string"==typeof l&&(l=[l]);var c=l.length,p=0,g=!1;function d(){g||++p===c&&o&&o(l)}0!==c?l.forEach(function(l){!function(l,o,u){var c=l.indexOf("!")>=0;function p(){var e=n[l];e||(e=n[l]={callbacks:[]}),e.callbacks.push({success:o,error:u}),!c&&a(l)?s(l,"success"):!c&&e.error?s(l,"error"):!c&&e.loading||(e.loading=!0,e.error=!1,function(e,t,n){var r=document.createElement("script");r.src=e,r.async=!0,r.onload=function(){document.body.removeChild(r),t&&t()},r.onerror=function(){document.body.removeChild(r),n&&n()},document.body.appendChild(r)}(function(e){return r.languages_path+"prism-"+e+(r.use_minified?".min":"")+".js"}(l),function(){e.loading=!1,s(l,"success")},function(){e.loading=!1,e.error=!0,s(l,"error")}))}l=l.replace("!",""),l=t[l]||l;var g=e[l];g&&g.length?i(g,p,u):p()}(l,d,function(){g||(g=!0,u&&u(l))})}):o&&setTimeout(o,0)}function s(e,t){if(n[e]){for(var r=n[e].callbacks,a=0,i=r.length;a<i;a++){var s=r[a][t];s&&setTimeout(s,0)}r.length=0}}}(),function(){if(void 0!==Prism){var e=Object.assign||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e},t={"remove-trailing":"boolean","remove-indent":"boolean","left-trim":"boolean","right-trim":"boolean","break-lines":"number",indent:"number","remove-initial-line-feed":"boolean","tabs-to-spaces":"number","spaces-to-tabs":"number"};n.prototype={setDefaults:function(t){this.defaults=e(this.defaults,t)},normalize:function(t,n){for(var r in n=e(this.defaults,n)){var a=r.replace(/-(\w)/g,function(e,t){return t.toUpperCase()});"normalize"!==r&&"setDefaults"!==a&&n[r]&&this[a]&&(t=this[a].call(this,t,n[r]))}return t},leftTrim:function(e){return e.replace(/^\s+/,"")},rightTrim:function(e){return e.replace(/\s+$/,"")},tabsToSpaces:function(e,t){return t=0|t||4,e.replace(/\t/g,new Array(++t).join(" "))},spacesToTabs:function(e,t){return t=0|t||4,e.replace(RegExp(" {"+t+"}","g"),"\t")},removeTrailing:function(e){return e.replace(/\s*?$/gm,"")},removeInitialLineFeed:function(e){return e.replace(/^(?:\r?\n|\r)/,"")},removeIndent:function(e){var t=e.match(/^[^\S\n\r]*(?=\S)/gm);return t&&t[0].length?(t.sort(function(e,t){return e.length-t.length}),t[0].length?e.replace(RegExp("^"+t[0],"gm"),""):e):e},indent:function(e,t){return e.replace(/^[^\S\n\r]*(?=\S)/gm,new Array(++t).join("\t")+"$&")},breakLines:function(e,t){t=!0===t?80:0|t||80;for(var n=e.split("\n"),a=0;a<n.length;++a)if(!(r(n[a])<=t)){for(var i=n[a].split(/(\s+)/g),s=0,l=0;l<i.length;++l){var o=r(i[l]);(s+=o)>t&&(i[l]="\n"+i[l],s=o)}n[a]=i.join("")}return n.join("\n")}},"undefined"!=typeof module&&module.exports&&(module.exports=n),Prism.plugins.NormalizeWhitespace=new n({"remove-trailing":!0,"remove-indent":!0,"left-trim":!0,"right-trim":!0}),Prism.hooks.add("before-sanity-check",function(e){var n=Prism.plugins.NormalizeWhitespace;if((!e.settings||!1!==e.settings["whitespace-normalization"])&&Prism.util.isActive(e.element,"whitespace-normalization",!0))if(e.element&&e.element.parentNode||!e.code){var r=e.element.parentNode;if(e.code&&r&&"pre"===r.nodeName.toLowerCase()){for(var a in null==e.settings&&(e.settings={}),t)if(Object.hasOwnProperty.call(t,a)){var i=t[a];if(r.hasAttribute("data-"+a))try{var s=JSON.parse(r.getAttribute("data-"+a)||"true");typeof s===i&&(e.settings[a]=s)}catch(e){}}for(var l=r.childNodes,o="",u="",c=!1,p=0;p<l.length;++p){var g=l[p];g==e.element?c=!0:"#text"===g.nodeName&&(c?u+=g.nodeValue:o+=g.nodeValue,r.removeChild(g),--p)}if(e.element.children.length&&Prism.plugins.KeepMarkup){var d=o+e.element.innerHTML+u;e.element.innerHTML=n.normalize(d,e.settings),e.code=e.element.textContent}else e.code=o+e.code+u,e.code=n.normalize(e.code,e.settings)}}else e.code=n.normalize(e.code,e.settings)})}function n(t){this.defaults=e({},t)}function r(e){for(var t=0,n=0;n<e.length;++n)e.charCodeAt(n)=="\t".charCodeAt(0)&&(t+=3);return e.length+t}}(),function(){if(void 0!==Prism){var e=/^diff-([\w-]+)/i,t=/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/g,n=RegExp(/(?:__|[^\r\n<])*(?:\r\n?|\n|(?:__|[^\r\n<])(?![^\r\n]))/.source.replace(/__/g,function(){return t.source}),"gi"),r=!1;Prism.hooks.add("before-sanity-check",function(t){var n=t.language;e.test(n)&&!t.grammar&&(t.grammar=Prism.languages[n]=Prism.languages.diff)}),Prism.hooks.add("before-tokenize",function(t){r||Prism.languages.diff||Prism.plugins.autoloader||(r=!0,console.warn("Prism's Diff Highlight plugin requires the Diff language definition (prism-diff.js).Make sure the language definition is loaded or use Prism's Autoloader plugin."));var n=t.language;e.test(n)&&!Prism.languages[n]&&(Prism.languages[n]=Prism.languages.diff)}),Prism.hooks.add("wrap",function(r){var a,i;if("diff"!==r.language){var s=e.exec(r.language);if(!s)return;a=s[1],i=Prism.languages[a]}var l=Prism.languages.diff&&Prism.languages.diff.PREFIXES;if(l&&r.type in l){var o,u=r.content.replace(t,"").replace(/&lt;/g,"<").replace(/&amp;/g,"&"),c=u.replace(/(^|[\r\n])./g,"$1");o=i?Prism.highlight(c,i,a):Prism.util.encode(c);var p,g=new Prism.Token("prefix",l[r.type],[/\w+/.exec(r.type)[0]]),d=Prism.Token.stringify(g,r.language),m=[];for(n.lastIndex=0;p=n.exec(o);)m.push(d+p[0]);/(?:^|[\r\n]).$/.test(u)&&m.push(d),r.content=m.join(""),i&&r.classes.push("language-"+a)}})}}();

public/.deps/prismjs.production.min.js
@@ -1,2 +0,0 @@
-var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){var t=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,n=0,r={},a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(t){return t instanceof i?new i(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++n}),e.__id},clone:function e(t,n){var r,i;switch(n=n||{},a.util.type(t)){case"Object":if(i=a.util.objId(t),n[i])return n[i];for(var s in r={},n[i]=r,t)t.hasOwnProperty(s)&&(r[s]=e(t[s],n));return r;case"Array":return i=a.util.objId(t),n[i]?n[i]:(r=[],n[i]=r,t.forEach(function(t,a){r[a]=e(t,n)}),r);default:return t}},getLanguage:function(e){for(;e;){var n=t.exec(e.className);if(n)return n[1].toLowerCase();e=e.parentElement}return"none"},setLanguage:function(e,n){e.className=e.className.replace(RegExp(t,"gi"),""),e.classList.add("language-"+n)},currentScript:function(){if("undefined"==typeof document)return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(r){var e=(/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(r.stack)||[])[1];if(e){var t=document.getElementsByTagName("script");for(var n in t)if(t[n].src==e)return t[n]}return null}},isActive:function(e,t,n){for(var r="no-"+t;e;){var a=e.classList;if(a.contains(t))return!0;if(a.contains(r))return!1;e=e.parentElement}return!!n}},languages:{plain:r,plaintext:r,text:r,txt:r,extend:function(e,t){var n=a.util.clone(a.languages[e]);for(var r in t)n[r]=t[r];return n},insertBefore:function(e,t,n,r){var i=(r=r||a.languages)[e],s={};for(var l in i)if(i.hasOwnProperty(l)){if(l==t)for(var o in n)n.hasOwnProperty(o)&&(s[o]=n[o]);n.hasOwnProperty(l)||(s[l]=i[l])}var u=r[e];return r[e]=s,a.languages.DFS(a.languages,function(t,n){n===u&&t!=e&&(this[t]=s)}),s},DFS:function e(t,n,r,i){i=i||{};var s=a.util.objId;for(var l in t)if(t.hasOwnProperty(l)){n.call(t,l,t[l],r||l);var o=t[l],u=a.util.type(o);"Object"!==u||i[s(o)]?"Array"!==u||i[s(o)]||(i[s(o)]=!0,e(o,n,l,i)):(i[s(o)]=!0,e(o,n,null,i))}}},plugins:{},highlightAll:function(e,t){a.highlightAllUnder(document,e,t)},highlightAllUnder:function(e,t,n){var r={callback:n,container:e,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};a.hooks.run("before-highlightall",r),r.elements=Array.prototype.slice.apply(r.container.querySelectorAll(r.selector)),a.hooks.run("before-all-elements-highlight",r);for(var i,s=0;i=r.elements[s++];)a.highlightElement(i,!0===t,r.callback)},highlightElement:function(t,n,r){var i=a.util.getLanguage(t),s=a.languages[i];a.util.setLanguage(t,i);var l=t.parentElement;l&&"pre"===l.nodeName.toLowerCase()&&a.util.setLanguage(l,i);var o={element:t,language:i,grammar:s,code:t.textContent};function u(e){o.highlightedCode=e,a.hooks.run("before-insert",o),o.element.innerHTML=o.highlightedCode,a.hooks.run("after-highlight",o),a.hooks.run("complete",o),r&&r.call(o.element)}if(a.hooks.run("before-sanity-check",o),(l=o.element.parentElement)&&"pre"===l.nodeName.toLowerCase()&&!l.hasAttribute("tabindex")&&l.setAttribute("tabindex","0"),!o.code)return a.hooks.run("complete",o),void(r&&r.call(o.element));if(a.hooks.run("before-highlight",o),o.grammar)if(n&&e.Worker){var c=new Worker(a.filename);c.onmessage=function(e){u(e.data)},c.postMessage(JSON.stringify({language:o.language,code:o.code,immediateClose:!0}))}else u(a.highlight(o.code,o.grammar,o.language));else u(a.util.encode(o.code))},highlight:function(e,t,n){var r={code:e,grammar:t,language:n};if(a.hooks.run("before-tokenize",r),!r.grammar)throw new Error('The language "'+r.language+'" has no grammar.');return r.tokens=a.tokenize(r.code,r.grammar),a.hooks.run("after-tokenize",r),i.stringify(a.util.encode(r.tokens),r.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}var u=new function(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0};return l(u,u.head,e),function e(t,n,r,u,c,p){for(var g in r)if(r.hasOwnProperty(g)&&r[g]){var d=r[g];d=Array.isArray(d)?d:[d];for(var m=0;m<d.length;++m){if(p&&p.cause==g+","+m)return;var f=d[m],h=f.inside,v=!!f.lookbehind,b=!!f.greedy,k=f.alias;if(b&&!f.pattern.global){var y=f.pattern.toString().match(/[imsuy]*$/)[0];f.pattern=RegExp(f.pattern.source,y+"g")}for(var x=f.pattern||f,w=u.next,P=c;w!==n.tail&&!(p&&P>=p.reach);P+=w.value.length,w=w.next){var F=w.value;if(n.length>t.length)return;if(!(F instanceof i)){var A,j=1;if(b){if(!(A=s(x,P,t,v))||A.index>=t.length)break;var S=A.index,$=A.index+A[0].length,E=P;for(E+=w.value.length;S>=E;)w=w.next,E+=w.value.length;if(E-=w.value.length,P=E,w.value instanceof i)continue;for(var C=w;C!==n.tail&&(E<$||"string"==typeof C.value);C=C.next)j++,E+=C.value.length;j--,F=t.slice(P,E),A.index-=P}else if(!(A=s(x,0,F,v)))continue;var S=A.index,L=A[0],z=F.slice(0,S),_=F.slice(S+L.length),T=P+F.length;p&&T>p.reach&&(p.reach=T);var q=w.prev;z&&(q=l(n,q,z),P+=z.length),o(n,q,j);var N=new i(g,h?a.tokenize(L,h):L,k,L);if(w=l(n,q,N),_&&l(n,w,_),j>1){var O={cause:g+","+m,reach:T};e(t,n,r,w.prev,P,O),p&&O.reach>p.reach&&(p.reach=O.reach)}}}}}}(e,u,t,u.head,0),function(e){var t=[],n=e.head.next;for(;n!==e.tail;)t.push(n.value),n=n.next;return t}(u)},hooks:{all:{},add:function(e,t){var n=a.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=a.hooks.all[e];if(n&&n.length)for(var r,i=0;r=n[i++];)r(t)}},Token:i};function i(e,t,n,r){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length}function s(e,t,n,r){e.lastIndex=t;var a=e.exec(n);if(a&&r&&a[1]){var i=a[1].length;a.index+=i,a[0]=a[0].slice(i)}return a}function l(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function o(e,t,n){for(var r=t.next,a=0;a<n&&r!==e.tail;a++)r=r.next;t.next=r,r.prev=t,e.length-=a}if(e.Prism=a,i.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var r="";return t.forEach(function(t){r+=e(t,n)}),r}var i={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},s=t.alias;s&&(Array.isArray(s)?Array.prototype.push.apply(i.classes,s):i.classes.push(s)),a.hooks.run("wrap",i);var l="";for(var o in i.attributes)l+=" "+o+'="'+(i.attributes[o]||"").replace(/"/g,"&quot;")+'"';return"<"+i.tag+' class="'+i.classes.join(" ")+'"'+l+">"+i.content+"</"+i.tag+">"},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",function(t){var n=JSON.parse(t.data),r=n.language,i=n.code,s=n.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),s&&e.close()},!1),a):a;var u=a.util.currentScript();function c(){a.manual||a.highlightAll()}if(u&&(a.filename=u.src,u.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var p=document.readyState;"loading"===p||"interactive"===p&&u&&u.defer?document.addEventListener("DOMContentLoaded",c):window.requestAnimationFrame?window.requestAnimationFrame(c):window.setTimeout(c,16)}return a}(_self);
-"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism),Prism.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&amp;/,"&"))}),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:Prism.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i;var r={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:Prism.languages[t]};var a={};a[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,function(){return e}),"i"),lookbehind:!0,greedy:!0,inside:r},Prism.languages.insertBefore("markup","cdata",a)}}),Object.defineProperty(Prism.languages.markup.tag,"addAttribute",{value:function(e,t){Prism.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:Prism.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml,function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+t.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(Prism),Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),Prism.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),Prism.languages.markup&&(Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),Prism.languages.js=Prism.languages.javascript,function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach(function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}}),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(Prism),function(){if(void 0!==Prism&&"undefined"!=typeof document&&document.querySelector){var e,t="linkable-line-numbers",n=/\n(?!$)/g,r=function(){if(void 0===e){var t=document.createElement("div");t.style.fontSize="13px",t.style.lineHeight="1.5",t.style.padding="0",t.style.border="0",t.innerHTML="&nbsp;<br />&nbsp;",document.body.appendChild(t),e=38===t.offsetHeight,document.body.removeChild(t)}return e},a=!0;Prism.plugins.lineHighlight={highlightLines:function(e,i,u){var c=(i="string"==typeof i?i:e.getAttribute("data-line")||"").replace(/\s+/g,"").split(",").filter(Boolean),p=+e.getAttribute("data-line-offset")||0,g=(r()?parseInt:parseFloat)(getComputedStyle(e).lineHeight),d=Prism.util.isActive(e,"line-numbers"),m=e.querySelector("code"),f=d?e:m||e,h=[],v=m.textContent.match(n),b=v?v.length+1:1,k=m&&f!=m?function(e,t){var n=getComputedStyle(e),r=getComputedStyle(t);function a(e){return+e.substr(0,e.length-2)}return t.offsetTop+a(r.borderTopWidth)+a(r.paddingTop)-a(n.paddingTop)}(e,m):0;c.forEach(function(t){var n=t.split("-"),r=+n[0],a=+n[1]||r;if(!((a=Math.min(b+p,a))<r)){var i=e.querySelector('.line-highlight[data-range="'+t+'"]')||document.createElement("div");if(h.push(function(){i.setAttribute("aria-hidden","true"),i.setAttribute("data-range",t),i.className=(u||"")+" line-highlight"}),d&&Prism.plugins.lineNumbers){var s=Prism.plugins.lineNumbers.getLine(e,r),l=Prism.plugins.lineNumbers.getLine(e,a);if(s){var o=s.offsetTop+k+"px";h.push(function(){i.style.top=o})}if(l){var c=l.offsetTop-s.offsetTop+l.offsetHeight+"px";h.push(function(){i.style.height=c})}}else h.push(function(){i.setAttribute("data-start",String(r)),a>r&&i.setAttribute("data-end",String(a)),i.style.top=(r-p-1)*g+k+"px",i.textContent=new Array(a-r+2).join(" \n")});h.push(function(){i.style.width=e.scrollWidth+"px"}),h.push(function(){f.appendChild(i)})}});var y=e.id;if(d&&Prism.util.isActive(e,t)&&y){l(e,t)||h.push(function(){e.classList.add(t)});var x=parseInt(e.getAttribute("data-start")||"1");s(".line-numbers-rows > span",e).forEach(function(e,t){var n=t+x;e.onclick=function(){var e=y+"."+n;a=!1,location.hash=e,setTimeout(function(){a=!0},1)}})}return function(){h.forEach(o)}}};var i=0;Prism.hooks.add("before-sanity-check",function(e){var t=e.element.parentElement;if(u(t)){var n=0;s(".line-highlight",t).forEach(function(e){n+=e.textContent.length,e.parentNode.removeChild(e)}),n&&/^(?: \n)+$/.test(e.code.slice(-n))&&(e.code=e.code.slice(0,-n))}}),Prism.hooks.add("complete",function e(t){var n=t.element.parentElement;if(u(n)){clearTimeout(i);var r=Prism.plugins.lineNumbers,a=t.plugins&&t.plugins.lineNumbers;if(l(n,"line-numbers")&&r&&!a)Prism.hooks.add("line-numbers",e);else Prism.plugins.lineHighlight.highlightLines(n)(),i=setTimeout(c,1)}}),window.addEventListener("hashchange",c),window.addEventListener("resize",function(){s("pre").filter(u).map(function(e){return Prism.plugins.lineHighlight.highlightLines(e)}).forEach(o)})}function s(e,t){return Array.prototype.slice.call((t||document).querySelectorAll(e))}function l(e,t){return e.classList.contains(t)}function o(e){e()}function u(e){return!(!e||!/pre/i.test(e.nodeName))&&(!!e.hasAttribute("data-line")||!(!e.id||!Prism.util.isActive(e,t)))}function c(){var e=location.hash.slice(1);s(".temporary.line-highlight").forEach(function(e){e.parentNode.removeChild(e)});var t=(e.match(/\.([\d,-]+)$/)||[,""])[1];if(t&&!document.getElementById(e)){var n=e.slice(0,e.lastIndexOf(".")),r=document.getElementById(n);if(r)r.hasAttribute("data-line")||r.setAttribute("data-line",""),Prism.plugins.lineHighlight.highlightLines(r,t,"temporary ")(),a&&document.querySelector(".temporary.line-highlight").scrollIntoView()}}}(),function(){if(void 0!==Prism&&"undefined"!=typeof document){var e=/\n(?!$)/g,t=Prism.plugins.lineNumbers={getLine:function(e,t){if("PRE"===e.tagName&&e.classList.contains("line-numbers")){var n=e.querySelector(".line-numbers-rows");if(n){var r=parseInt(e.getAttribute("data-start"),10)||1,a=r+(n.children.length-1);t<r&&(t=r),t>a&&(t=a);var i=t-r;return n.children[i]}}},resize:function(e){r([e])},assumeViewportIndependence:!0},n=void 0;window.addEventListener("resize",function(){t.assumeViewportIndependence&&n===window.innerWidth||(n=window.innerWidth,r(Array.prototype.slice.call(document.querySelectorAll("pre.line-numbers"))))}),Prism.hooks.add("complete",function(t){if(t.code){var n=t.element,a=n.parentNode;if(a&&/pre/i.test(a.nodeName)&&!n.querySelector(".line-numbers-rows")&&Prism.util.isActive(n,"line-numbers")){n.classList.remove("line-numbers"),a.classList.add("line-numbers");var i,s=t.code.match(e),l=s?s.length+1:1,o=new Array(l+1).join("<span></span>");(i=document.createElement("span")).setAttribute("aria-hidden","true"),i.className="line-numbers-rows",i.innerHTML=o,a.hasAttribute("data-start")&&(a.style.counterReset="linenumber "+(parseInt(a.getAttribute("data-start"),10)-1)),t.element.appendChild(i),r([a]),Prism.hooks.run("line-numbers",t)}}}),Prism.hooks.add("line-numbers",function(e){e.plugins=e.plugins||{},e.plugins.lineNumbers=!0})}function r(t){if(0!=(t=t.filter(function(e){var t=function(e){if(!e)return null;return window.getComputedStyle?getComputedStyle(e):e.currentStyle||null}(e)["white-space"];return"pre-wrap"===t||"pre-line"===t})).length){var n=t.map(function(t){var n=t.querySelector("code"),r=t.querySelector(".line-numbers-rows");if(n&&r){var a=t.querySelector(".line-numbers-sizer"),i=n.textContent.split(e);a||((a=document.createElement("span")).className="line-numbers-sizer",n.appendChild(a)),a.innerHTML="0",a.style.display="block";var s=a.getBoundingClientRect().height;return a.innerHTML="",{element:t,lines:i,lineHeights:[],oneLinerHeight:s,sizer:a}}}).filter(Boolean);n.forEach(function(e){var t=e.sizer,n=e.lines,r=e.lineHeights,a=e.oneLinerHeight;r[n.length-1]=void 0,n.forEach(function(e,n){if(e&&e.length>1){var i=t.appendChild(document.createElement("span"));i.style.display="block",i.textContent=e}else r[n]=a})}),n.forEach(function(e){for(var t=e.sizer,n=e.lineHeights,r=0,a=0;a<n.length;a++)void 0===n[a]&&(n[a]=t.children[r++].getBoundingClientRect().height)}),n.forEach(function(e){var t=e.sizer,n=e.element.querySelector(".line-numbers-rows");t.style.display="none",t.innerHTML="",e.lineHeights.forEach(function(e,t){n.children[t].style.height=e+"px"})})}}}(),function(){if(void 0!==Prism&&"undefined"!=typeof document){var e={javascript:"clike",actionscript:"javascript",apex:["clike","sql"],arduino:"cpp",aspnet:["markup","csharp"],birb:"clike",bison:"c",c:"clike",csharp:"clike",cpp:"c",cfscript:"clike",chaiscript:["clike","cpp"],cilkc:"c",cilkcpp:"cpp",coffeescript:"javascript",crystal:"ruby","css-extras":"css",d:"clike",dart:"clike",django:"markup-templating",ejs:["javascript","markup-templating"],etlua:["lua","markup-templating"],erb:["ruby","markup-templating"],fsharp:"clike","firestore-security-rules":"clike",flow:"javascript",ftl:"markup-templating",gml:"clike",glsl:"c",go:"clike",gradle:"clike",groovy:"clike",haml:"ruby",handlebars:"markup-templating",haxe:"clike",hlsl:"c",idris:"haskell",java:"clike",javadoc:["markup","java","javadoclike"],jolie:"clike",jsdoc:["javascript","javadoclike","typescript"],"js-extras":"javascript",json5:"json",jsonp:"json","js-templates":"javascript",kotlin:"clike",latte:["clike","markup-templating","php"],less:"css",lilypond:"scheme",liquid:"markup-templating",markdown:"markup","markup-templating":"markup",mongodb:"javascript",n4js:"javascript",objectivec:"c",opencl:"c",parser:"markup",php:"markup-templating",phpdoc:["php","javadoclike"],"php-extras":"php",plsql:"sql",processing:"clike",protobuf:"clike",pug:["markup","javascript"],purebasic:"clike",purescript:"haskell",qsharp:"clike",qml:"javascript",qore:"clike",racket:"scheme",cshtml:["markup","csharp"],jsx:["markup","javascript"],tsx:["jsx","typescript"],reason:"clike",ruby:"clike",sass:"css",scss:"css",scala:"java","shell-session":"bash",smarty:"markup-templating",solidity:"clike",soy:"markup-templating",sparql:"turtle",sqf:"clike",squirrel:"clike",stata:["mata","java","python"],"t4-cs":["t4-templating","csharp"],"t4-vb":["t4-templating","vbnet"],tap:"yaml",tt2:["clike","markup-templating"],textile:"markup",twig:"markup-templating",typescript:"javascript",v:"clike",vala:"clike",vbnet:"basic",velocity:"markup",wiki:"markup",xeora:"markup","xml-doc":"markup",xquery:"markup"},t={html:"markup",xml:"markup",svg:"markup",mathml:"markup",ssml:"markup",atom:"markup",rss:"markup",js:"javascript",g4:"antlr4",ino:"arduino","arm-asm":"armasm",art:"arturo",adoc:"asciidoc",avs:"avisynth",avdl:"avro-idl",gawk:"awk",sh:"bash",shell:"bash",shortcode:"bbcode",rbnf:"bnf",oscript:"bsl",cs:"csharp",dotnet:"csharp",cfc:"cfscript","cilk-c":"cilkc","cilk-cpp":"cilkcpp",cilk:"cilkcpp",coffee:"coffeescript",conc:"concurnas",jinja2:"django","dns-zone":"dns-zone-file",dockerfile:"docker",gv:"dot",eta:"ejs",xlsx:"excel-formula",xls:"excel-formula",gamemakerlanguage:"gml",po:"gettext",gni:"gn",ld:"linker-script","go-mod":"go-module",hbs:"handlebars",mustache:"handlebars",hs:"haskell",idr:"idris",gitignore:"ignore",hgignore:"ignore",npmignore:"ignore",webmanifest:"json",kt:"kotlin",kts:"kotlin",kum:"kumir",tex:"latex",context:"latex",ly:"lilypond",emacs:"lisp",elisp:"lisp","emacs-lisp":"lisp",md:"markdown",moon:"moonscript",n4jsd:"n4js",nani:"naniscript",objc:"objectivec",qasm:"openqasm",objectpascal:"pascal",px:"pcaxis",pcode:"peoplecode",plantuml:"plant-uml",pq:"powerquery",mscript:"powerquery",pbfasm:"purebasic",purs:"purescript",py:"python",qs:"qsharp",rkt:"racket",razor:"cshtml",rpy:"renpy",res:"rescript",robot:"robotframework",rb:"ruby","sh-session":"shell-session",shellsession:"shell-session",smlnj:"sml",sol:"solidity",sln:"solution-file",rq:"sparql",sclang:"supercollider",t4:"t4-cs",trickle:"tremor",troy:"tremor",trig:"turtle",ts:"typescript",tsconfig:"typoscript",uscript:"unrealscript",uc:"unrealscript",url:"uri",vb:"visual-basic",vba:"visual-basic",webidl:"web-idl",mathematica:"wolfram",nb:"wolfram",wl:"wolfram",xeoracube:"xeora",yml:"yaml"},n={},r=(Prism.util.currentScript(),Prism.plugins.autoloader={languages_path:"/public/assets/prism/components/",use_minified:!0,loadLanguages:i});Prism.hooks.add("complete",function(e){var t=e.element,n=e.language;if(t&&n&&"none"!==n){var r=function(e){var t=(e.getAttribute("data-dependencies")||"").trim();if(!t){var n=e.parentElement;n&&"pre"===n.tagName.toLowerCase()&&(t=(n.getAttribute("data-dependencies")||"").trim())}return t?t.split(/\s*,\s*/g):[]}(t);/^diff-./i.test(n)?(r.push("diff"),r.push(n.substr("diff-".length))):r.push(n),r.every(a)||i(r,function(){Prism.highlightElement(t)})}})}function a(e){if(e.indexOf("!")>=0)return!1;if((e=t[e]||e)in Prism.languages)return!0;var r=n[e];return r&&!r.error&&!1===r.loading}function i(l,o,u){"string"==typeof l&&(l=[l]);var c=l.length,p=0,g=!1;function d(){g||++p===c&&o&&o(l)}0!==c?l.forEach(function(l){!function(l,o,u){var c=l.indexOf("!")>=0;function p(){var e=n[l];e||(e=n[l]={callbacks:[]}),e.callbacks.push({success:o,error:u}),!c&&a(l)?s(l,"success"):!c&&e.error?s(l,"error"):!c&&e.loading||(e.loading=!0,e.error=!1,function(e,t,n){var r=document.createElement("script");r.src=e,r.async=!0,r.onload=function(){document.body.removeChild(r),t&&t()},r.onerror=function(){document.body.removeChild(r),n&&n()},document.body.appendChild(r)}(function(e){return r.languages_path+"prism-"+e+(r.use_minified?".min":"")+".js"}(l),function(){e.loading=!1,s(l,"success")},function(){e.loading=!1,e.error=!0,s(l,"error")}))}l=l.replace("!",""),l=t[l]||l;var g=e[l];g&&g.length?i(g,p,u):p()}(l,d,function(){g||(g=!0,u&&u(l))})}):o&&setTimeout(o,0)}function s(e,t){if(n[e]){for(var r=n[e].callbacks,a=0,i=r.length;a<i;a++){var s=r[a][t];s&&setTimeout(s,0)}r.length=0}}}(),function(){if(void 0!==Prism){var e=Object.assign||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e},t={"remove-trailing":"boolean","remove-indent":"boolean","left-trim":"boolean","right-trim":"boolean","break-lines":"number",indent:"number","remove-initial-line-feed":"boolean","tabs-to-spaces":"number","spaces-to-tabs":"number"};n.prototype={setDefaults:function(t){this.defaults=e(this.defaults,t)},normalize:function(t,n){for(var r in n=e(this.defaults,n)){var a=r.replace(/-(\w)/g,function(e,t){return t.toUpperCase()});"normalize"!==r&&"setDefaults"!==a&&n[r]&&this[a]&&(t=this[a].call(this,t,n[r]))}return t},leftTrim:function(e){return e.replace(/^\s+/,"")},rightTrim:function(e){return e.replace(/\s+$/,"")},tabsToSpaces:function(e,t){return t=0|t||4,e.replace(/\t/g,new Array(++t).join(" "))},spacesToTabs:function(e,t){return t=0|t||4,e.replace(RegExp(" {"+t+"}","g"),"\t")},removeTrailing:function(e){return e.replace(/\s*?$/gm,"")},removeInitialLineFeed:function(e){return e.replace(/^(?:\r?\n|\r)/,"")},removeIndent:function(e){var t=e.match(/^[^\S\n\r]*(?=\S)/gm);return t&&t[0].length?(t.sort(function(e,t){return e.length-t.length}),t[0].length?e.replace(RegExp("^"+t[0],"gm"),""):e):e},indent:function(e,t){return e.replace(/^[^\S\n\r]*(?=\S)/gm,new Array(++t).join("\t")+"$&")},breakLines:function(e,t){t=!0===t?80:0|t||80;for(var n=e.split("\n"),a=0;a<n.length;++a)if(!(r(n[a])<=t)){for(var i=n[a].split(/(\s+)/g),s=0,l=0;l<i.length;++l){var o=r(i[l]);(s+=o)>t&&(i[l]="\n"+i[l],s=o)}n[a]=i.join("")}return n.join("\n")}},"undefined"!=typeof module&&module.exports&&(module.exports=n),Prism.plugins.NormalizeWhitespace=new n({"remove-trailing":!0,"remove-indent":!0,"left-trim":!0,"right-trim":!0}),Prism.hooks.add("before-sanity-check",function(e){var n=Prism.plugins.NormalizeWhitespace;if((!e.settings||!1!==e.settings["whitespace-normalization"])&&Prism.util.isActive(e.element,"whitespace-normalization",!0))if(e.element&&e.element.parentNode||!e.code){var r=e.element.parentNode;if(e.code&&r&&"pre"===r.nodeName.toLowerCase()){for(var a in null==e.settings&&(e.settings={}),t)if(Object.hasOwnProperty.call(t,a)){var i=t[a];if(r.hasAttribute("data-"+a))try{var s=JSON.parse(r.getAttribute("data-"+a)||"true");typeof s===i&&(e.settings[a]=s)}catch(e){}}for(var l=r.childNodes,o="",u="",c=!1,p=0;p<l.length;++p){var g=l[p];g==e.element?c=!0:"#text"===g.nodeName&&(c?u+=g.nodeValue:o+=g.nodeValue,r.removeChild(g),--p)}if(e.element.children.length&&Prism.plugins.KeepMarkup){var d=o+e.element.innerHTML+u;e.element.innerHTML=n.normalize(d,e.settings),e.code=e.element.textContent}else e.code=o+e.code+u,e.code=n.normalize(e.code,e.settings)}}else e.code=n.normalize(e.code,e.settings)})}function n(t){this.defaults=e({},t)}function r(e){for(var t=0,n=0;n<e.length;++n)e.charCodeAt(n)=="\t".charCodeAt(0)&&(t+=3);return e.length+t}}(),function(){if(void 0!==Prism){var e=/^diff-([\w-]+)/i,t=/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/g,n=RegExp(/(?:__|[^\r\n<])*(?:\r\n?|\n|(?:__|[^\r\n<])(?![^\r\n]))/.source.replace(/__/g,function(){return t.source}),"gi"),r=!1;Prism.hooks.add("before-sanity-check",function(t){var n=t.language;e.test(n)&&!t.grammar&&(t.grammar=Prism.languages[n]=Prism.languages.diff)}),Prism.hooks.add("before-tokenize",function(t){r||Prism.languages.diff||Prism.plugins.autoloader||(r=!0,console.warn("Prism's Diff Highlight plugin requires the Diff language definition (prism-diff.js).Make sure the language definition is loaded or use Prism's Autoloader plugin."));var n=t.language;e.test(n)&&!Prism.languages[n]&&(Prism.languages[n]=Prism.languages.diff)}),Prism.hooks.add("wrap",function(r){var a,i;if("diff"!==r.language){var s=e.exec(r.language);if(!s)return;a=s[1],i=Prism.languages[a]}var l=Prism.languages.diff&&Prism.languages.diff.PREFIXES;if(l&&r.type in l){var o,u=r.content.replace(t,"").replace(/&lt;/g,"<").replace(/&amp;/g,"&"),c=u.replace(/(^|[\r\n])./g,"$1");o=i?Prism.highlight(c,i,a):Prism.util.encode(c);var p,g=new Prism.Token("prefix",l[r.type],[/\w+/.exec(r.type)[0]]),d=Prism.Token.stringify(g,r.language),m=[];for(n.lastIndex=0;p=n.exec(o);)m.push(d+p[0]);/(?:^|[\r\n]).$/.test(u)&&m.push(d),r.content=m.join(""),i&&r.classes.push("language-"+a)}})}}();

new file
types/himalaya.d.ts
@@ -0,0 +1,22 @@
+declare module "himalaya";
+
+interface TextNode {
+  type: "text";
+  content: string;
+}
+
+interface RealNode {
+  type: "element";
+  tagName: keyof HTMLElementTagNameMap;
+  attributes: Array<{
+    key: string;
+    value: string;
+  }>;
+  children: Array<RealNode | TextNode>;
+}
+
+export declare type ParseResult = (TextNode | RealNode)[];
+
+export declare function parse<T = ParseResult>(html: string): T;
+
+export default parse;

@@ -2539,6 +2539,10 @@ has@^1.0.3:
   dependencies:
     function-bind "^1.1.1"
 
+himalaya@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/himalaya/-/himalaya-1.1.0.tgz#31724ae9d35714cd7c6f4be94888953f3604606a"
+
 hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0:
   version "3.3.2"
   resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"