diff --git a/assets/copyicon.svg b/assets/copyicon.svg
new file mode 100644
index 0000000..233c66f
--- /dev/null
+++ b/assets/copyicon.svg
@@ -0,0 +1,13 @@
+
+
+
diff --git a/index.html b/index.html
index b10bcb0..5f72716 100644
--- a/index.html
+++ b/index.html
@@ -13,7 +13,7 @@
diff --git a/package.json b/package.json
index d4bb019..3466bbc 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,7 @@
"react-router-dom": "^7.5.0",
"react-scripts": "^5.0.1",
"react-scroll": "^1.9.3",
+ "react-syntax-highlighter": "^16.1.0",
"react-turnstile": "^1.1.4",
"sass": "^1.86.3",
"simplebar": "^6.3.2",
diff --git a/src/components/CodeBlock.jsx b/src/components/CodeBlock.jsx
new file mode 100644
index 0000000..9460a61
--- /dev/null
+++ b/src/components/CodeBlock.jsx
@@ -0,0 +1,244 @@
+import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
+import { useTheme } from "../contexts/ThemeContext";
+import { useMemo, useState } from "react";
+import CopyIcon from "../icons/CopyIcon";
+import CheckIcon from "../icons/CheckIcon";
+
+// Helper function to parse hex color to RGB
+const hexToRgb = (hex) => {
+ const cleanHex = hex.replace("#", "");
+ return {
+ r: parseInt(cleanHex.slice(0, 2), 16),
+ g: parseInt(cleanHex.slice(2, 4), 16),
+ b: parseInt(cleanHex.slice(4, 6), 16),
+ };
+};
+
+// Helper function to blend two colors
+const blendColors = (color1, color2, ratio) => {
+ const rgb1 = hexToRgb(color1);
+ const rgb2 = hexToRgb(color2);
+ const r = Math.round(rgb1.r * ratio + rgb2.r * (1 - ratio));
+ const g = Math.round(rgb1.g * ratio + rgb2.g * (1 - ratio));
+ const b = Math.round(rgb1.b * ratio + rgb2.b * (1 - ratio));
+ return `#${[r, g, b].map((x) => x.toString(16).padStart(2, "0")).join("")}`;
+};
+
+// Helper function to create a custom theme based on app theme colors
+const createCustomTheme = (backgroundColor, textColor) => {
+ // Determine if theme is dark or light based on background color brightness
+ const bgRgb = hexToRgb(backgroundColor);
+ const brightness = (bgRgb.r * 299 + bgRgb.g * 587 + bgRgb.b * 114) / 1000;
+ const isDark = brightness < 128;
+
+ // Base colors
+ const bg = backgroundColor;
+ const fg = textColor;
+
+ // Create color variations by blending foreground and background
+ // For dark themes: use brighter accents
+ // For light themes: use darker accents
+ const accent1 = isDark ? blendColors(fg, bg, 0.8) : blendColors(fg, bg, 0.6);
+ const accent2 = isDark ? blendColors(fg, bg, 0.6) : blendColors(fg, bg, 0.4);
+
+ // Syntax highlighting colors
+ // Strings: slightly warmer tone
+ const stringColor = isDark ? "#f1fa8c" : "#8b6914";
+ // Keywords: slightly cooler tone
+ const keywordColor = isDark ? "#bd93f9" : "#6b46c1";
+ // Comments: muted
+ const commentColor = isDark ? "#6272a4" : "#6b7280";
+ // Numbers: accent color
+ const numberColor = isDark ? "#ff79c6" : "#c026d3";
+ // Functions: primary text color
+ const functionColor = isDark ? "#50fa7b" : "#059669";
+ // Operators: accent
+ const operatorColor = fg;
+
+ return {
+ 'code[class*="language-"]': {
+ color: fg,
+ background: bg,
+ textShadow: "none",
+ },
+ 'pre[class*="language-"]': {
+ color: fg,
+ background: bg,
+ textShadow: "none",
+ },
+ comment: {
+ color: commentColor,
+ fontStyle: "italic",
+ },
+ prolog: {
+ color: commentColor,
+ },
+ doctype: {
+ color: commentColor,
+ },
+ cdata: {
+ color: commentColor,
+ },
+ punctuation: {
+ color: accent2,
+ },
+ property: {
+ color: keywordColor,
+ },
+ tag: {
+ color: keywordColor,
+ },
+ boolean: {
+ color: keywordColor,
+ },
+ number: {
+ color: numberColor,
+ },
+ constant: {
+ color: numberColor,
+ },
+ symbol: {
+ color: numberColor,
+ },
+ deleted: {
+ color: numberColor,
+ },
+ selector: {
+ color: functionColor,
+ },
+ "attr-name": {
+ color: functionColor,
+ },
+ string: {
+ color: stringColor,
+ },
+ char: {
+ color: stringColor,
+ },
+ builtin: {
+ color: stringColor,
+ },
+ inserted: {
+ color: stringColor,
+ },
+ operator: {
+ color: operatorColor,
+ },
+ entity: {
+ color: accent1,
+ cursor: "help",
+ },
+ url: {
+ color: accent1,
+ },
+ ".language-css .token.string": {
+ color: accent1,
+ },
+ ".style .token.string": {
+ color: accent1,
+ },
+ variable: {
+ color: accent1,
+ },
+ atrule: {
+ color: keywordColor,
+ },
+ "attr-value": {
+ color: stringColor,
+ },
+ function: {
+ color: functionColor,
+ },
+ "class-name": {
+ color: functionColor,
+ },
+ keyword: {
+ color: keywordColor,
+ },
+ regex: {
+ color: stringColor,
+ },
+ important: {
+ color: keywordColor,
+ fontWeight: "bold",
+ },
+ bold: {
+ fontWeight: "bold",
+ },
+ italic: {
+ fontStyle: "italic",
+ },
+ };
+};
+
+export default function CodeBlock({ code, language }) {
+ const { theme } = useTheme();
+
+ // Create custom theme based on app theme
+ const customTheme = useMemo(() => {
+ const bg = theme?.backgroundColor || "#ffffff";
+ const text = theme?.textColor || "#000000";
+ return createCustomTheme(bg, text);
+ }, [theme?.backgroundColor, theme?.textColor]);
+
+ // Determine line number color based on theme
+ const lineNumberColor = useMemo(() => {
+ if (!theme?.backgroundColor || !theme?.textColor) {
+ return "#6272a4";
+ }
+ const bgRgb = hexToRgb(theme.backgroundColor);
+ const brightness = (bgRgb.r * 299 + bgRgb.g * 587 + bgRgb.b * 114) / 1000;
+ const isDark = brightness < 128;
+ // Use a muted version of the text color for line numbers
+ return isDark
+ ? blendColors(theme.textColor, theme.backgroundColor, 0.4)
+ : blendColors(theme.textColor, theme.backgroundColor, 0.3);
+ }, [theme?.backgroundColor, theme?.textColor]);
+
+ const [isCopied, setIsCopied] = useState(false);
+ const handleCopy = () => {
+ navigator.clipboard.writeText(code);
+ setIsCopied(true);
+ setTimeout(() => {
+ setIsCopied(false);
+ }, 2000);
+ };
+
+ return (
+
+
+
+
+ {code}
+
+
+ );
+}
diff --git a/src/components/ContentRenderer.jsx b/src/components/ContentRenderer.jsx
index a7ba61e..5c0a6d9 100644
--- a/src/components/ContentRenderer.jsx
+++ b/src/components/ContentRenderer.jsx
@@ -11,7 +11,8 @@ import RightIcon from "../icons/RightIcon";
import LeftIcon from "../icons/LeftIcon";
import Video from "./Video";
import VisitIcon from "../icons/VisitIcon";
-
+import CodeBlock from "./CodeBlock";
+import CopyIcon from "../icons/CopyIcon";
const gradientHeight = 60;
const renderAnnotation = (textObject = {}, navigate, index) => {
@@ -378,6 +379,14 @@ const renderContentElement = (
);
}
+ case "code": {
+ return (
+
+ );
+ }
default:
console.log("Unknown type:", type);
return (
diff --git a/src/icons/CopyIcon.jsx b/src/icons/CopyIcon.jsx
new file mode 100644
index 0000000..16a2340
--- /dev/null
+++ b/src/icons/CopyIcon.jsx
@@ -0,0 +1,6 @@
+import CopyIconSvg from "../../assets/copyicon.svg?react";
+const CopyIcon = () => {
+ return ;
+};
+
+export default CopyIcon;
diff --git a/src/styles/components.css b/src/styles/components.css
index 6f0e457..35e9b24 100644
--- a/src/styles/components.css
+++ b/src/styles/components.css
@@ -3308,3 +3308,22 @@ textarea.tb-form-input {
.tb-video-volume-button > .tb-icon-button > svg {
width: auto;
}
+
+.tb-code {
+ font-family: "Sono", sans-serif;
+ position: relative;
+ padding: 20px 65px 5px 10px;
+ border: 1px solid color-mix(in srgb, var(--tb-textColor) 15%, transparent);
+ border-radius: 22px;
+}
+
+.tb-code span {
+ font-family: "Sono", sans-serif;
+}
+
+.tb-code-copy-btn {
+ position: absolute;
+ top: 0;
+ right: 0;
+ margin: 9px 10px;
+}
diff --git a/yarn.lock b/yarn.lock
index a7b2f56..108a2f9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1161,7 +1161,7 @@
"@babel/plugin-transform-modules-commonjs" "^7.27.1"
"@babel/plugin-transform-typescript" "^7.27.1"
-"@babel/runtime@^7.10.1", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.16.7", "@babel/runtime@^7.18.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.0", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.22.5", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.6", "@babel/runtime@^7.23.9", "@babel/runtime@^7.24.4", "@babel/runtime@^7.24.7", "@babel/runtime@^7.24.8", "@babel/runtime@^7.25.7", "@babel/runtime@^7.26.0":
+"@babel/runtime@^7.10.1", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.16.7", "@babel/runtime@^7.18.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.0", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.22.5", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.6", "@babel/runtime@^7.23.9", "@babel/runtime@^7.24.4", "@babel/runtime@^7.24.7", "@babel/runtime@^7.24.8", "@babel/runtime@^7.25.7", "@babel/runtime@^7.26.0", "@babel/runtime@^7.28.4":
version "7.28.4"
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz"
integrity sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==
@@ -2882,6 +2882,13 @@
dependencies:
"@types/node" "*"
+"@types/hast@^3.0.0":
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/@types/hast/-/hast-3.0.4.tgz#1d6b39993b82cea6ad783945b0508c25903e15aa"
+ integrity sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==
+ dependencies:
+ "@types/unist" "*"
+
"@types/html-minifier-terser@^6.0.0":
version "6.1.0"
resolved "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz"
@@ -2957,6 +2964,11 @@
resolved "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz"
integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==
+"@types/prismjs@^1.0.0":
+ version "1.26.5"
+ resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.5.tgz#72499abbb4c4ec9982446509d2f14fb8483869d6"
+ integrity sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==
+
"@types/q@^1.5.1":
version "1.5.8"
resolved "https://registry.npmjs.org/@types/q/-/q-1.5.8.tgz"
@@ -3042,6 +3054,16 @@
resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz"
integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==
+"@types/unist@*":
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.3.tgz#acaab0f919ce69cce629c2d4ed2eb4adc1b6c20c"
+ integrity sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==
+
+"@types/unist@^2.0.0":
+ version "2.0.11"
+ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.11.tgz#11af57b127e32487774841f7a4e54eab166d03c4"
+ integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==
+
"@types/ws@^8.5.5":
version "8.18.1"
resolved "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz"
@@ -4124,6 +4146,21 @@ char-regex@^2.0.0:
resolved "https://registry.npmjs.org/char-regex/-/char-regex-2.0.2.tgz"
integrity sha512-cbGOjAptfM2LVmWhwRFHEKTPkLwNddVmuqYZQt895yXwAsWsXObCG+YN4DGQ/JBtT4GP1a1lPPdio2z413LmTg==
+character-entities-legacy@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz#76bc83a90738901d7bc223a9e93759fdd560125b"
+ integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==
+
+character-entities@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22"
+ integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==
+
+character-reference-invalid@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz#85c66b041e43b47210faf401278abf808ac45cb9"
+ integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==
+
check-types@^11.2.3:
version "11.2.3"
resolved "https://registry.npmjs.org/check-types/-/check-types-11.2.3.tgz"
@@ -4259,6 +4296,11 @@ combined-stream@^1.0.8:
dependencies:
delayed-stream "~1.0.0"
+comma-separated-tokens@^2.0.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz#4e89c9458acb61bc8fef19f4529973b2392839ee"
+ integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==
+
commander@^2.20.0:
version "2.20.3"
resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz"
@@ -4747,6 +4789,13 @@ decimal.js@^10.2.1:
resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz"
integrity sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==
+decode-named-character-reference@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz#25c32ae6dd5e21889549d40f676030e9514cc0ed"
+ integrity sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==
+ dependencies:
+ character-entities "^2.0.0"
+
dedent@^0.7.0:
version "0.7.0"
resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz"
@@ -5721,6 +5770,13 @@ fastq@^1.6.0:
dependencies:
reusify "^1.0.4"
+fault@^1.0.0:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13"
+ integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==
+ dependencies:
+ format "^0.2.0"
+
faye-websocket@^0.11.3:
version "0.11.4"
resolved "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz"
@@ -5894,6 +5950,11 @@ form-data@^4.0.4:
hasown "^2.0.2"
mime-types "^2.1.12"
+format@^0.2.0:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b"
+ integrity sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==
+
forwarded@0.2.0:
version "0.2.0"
resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz"
@@ -6199,11 +6260,39 @@ hasown@^2.0.2:
dependencies:
function-bind "^1.1.2"
+hast-util-parse-selector@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz#352879fa86e25616036037dd8931fb5f34cb4a27"
+ integrity sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==
+ dependencies:
+ "@types/hast" "^3.0.0"
+
+hastscript@^9.0.0:
+ version "9.0.1"
+ resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-9.0.1.tgz#dbc84bef6051d40084342c229c451cd9dc567dff"
+ integrity sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==
+ dependencies:
+ "@types/hast" "^3.0.0"
+ comma-separated-tokens "^2.0.0"
+ hast-util-parse-selector "^4.0.0"
+ property-information "^7.0.0"
+ space-separated-tokens "^2.0.0"
+
he@^1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
+highlight.js@^10.4.1, highlight.js@~10.7.0:
+ version "10.7.3"
+ resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531"
+ integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==
+
+highlightjs-vue@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/highlightjs-vue/-/highlightjs-vue-1.0.0.tgz#fdfe97fbea6354e70ee44e3a955875e114db086d"
+ integrity sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==
+
hoopy@^0.1.4:
version "0.1.4"
resolved "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz"
@@ -6462,6 +6551,19 @@ ipaddr.js@^2.0.1:
resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz"
integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==
+is-alphabetical@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz#01072053ea7c1036df3c7d19a6daaec7f19e789b"
+ integrity sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==
+
+is-alphanumerical@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz#7c03fbe96e3e931113e57f964b0a368cc2dfd875"
+ integrity sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==
+ dependencies:
+ is-alphabetical "^2.0.0"
+ is-decimal "^2.0.0"
+
is-array-buffer@^3.0.4, is-array-buffer@^3.0.5:
version "3.0.5"
resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz"
@@ -6538,6 +6640,11 @@ is-date-object@^1.0.5, is-date-object@^1.1.0:
call-bound "^1.0.2"
has-tostringtag "^1.0.2"
+is-decimal@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-2.0.1.tgz#9469d2dc190d0214fd87d78b78caecc0cc14eef7"
+ integrity sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==
+
is-docker@^2.0.0, is-docker@^2.1.1:
version "2.2.1"
resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz"
@@ -6582,6 +6689,11 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
dependencies:
is-extglob "^2.1.1"
+is-hexadecimal@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz#86b5bf668fca307498d319dfc03289d781a90027"
+ integrity sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==
+
is-map@^2.0.3:
version "2.0.3"
resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz"
@@ -7635,6 +7747,14 @@ lower-case@^2.0.2:
dependencies:
tslib "^2.0.3"
+lowlight@^1.17.0:
+ version "1.20.0"
+ resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.20.0.tgz#ddb197d33462ad0d93bf19d17b6c301aa3941888"
+ integrity sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==
+ dependencies:
+ fault "^1.0.0"
+ highlight.js "~10.7.0"
+
lru-cache@^10.2.0:
version "10.4.3"
resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz"
@@ -8191,6 +8311,19 @@ parent-module@^1.0.0:
dependencies:
callsites "^3.0.0"
+parse-entities@^4.0.0:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-4.0.2.tgz#61d46f5ed28e4ee62e9ddc43d6b010188443f159"
+ integrity sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==
+ dependencies:
+ "@types/unist" "^2.0.0"
+ character-entities-legacy "^3.0.0"
+ character-reference-invalid "^2.0.0"
+ decode-named-character-reference "^1.0.0"
+ is-alphanumerical "^2.0.0"
+ is-decimal "^2.0.0"
+ is-hexadecimal "^2.0.0"
+
parse-json@^5.0.0, parse-json@^5.2.0:
version "5.2.0"
resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz"
@@ -8918,6 +9051,11 @@ pretty-format@^28.1.3:
ansi-styles "^5.0.0"
react-is "^18.0.0"
+prismjs@^1.30.0:
+ version "1.30.0"
+ resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.30.0.tgz#d9709969d9d4e16403f6f348c63553b19f0975a9"
+ integrity sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==
+
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz"
@@ -8947,6 +9085,11 @@ prop-types@^15.6.1, prop-types@^15.7.2, prop-types@^15.8.1:
object-assign "^4.1.1"
react-is "^16.13.1"
+property-information@^7.0.0:
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/property-information/-/property-information-7.1.0.tgz#b622e8646e02b580205415586b40804d3e8bfd5d"
+ integrity sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==
+
proxy-addr@~2.0.7:
version "2.0.7"
resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz"
@@ -9563,6 +9706,18 @@ react-scroll@^1.9.3:
lodash.throttle "^4.1.1"
prop-types "^15.7.2"
+react-syntax-highlighter@^16.1.0:
+ version "16.1.0"
+ resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-16.1.0.tgz#ebe0bb5ae7a3540859212cedafd767f0189c516c"
+ integrity sha512-E40/hBiP5rCNwkeBN1vRP+xow1X0pndinO+z3h7HLsHyjztbyjfzNWNKuAsJj+7DLam9iT4AaaOZnueCU+Nplg==
+ dependencies:
+ "@babel/runtime" "^7.28.4"
+ highlight.js "^10.4.1"
+ highlightjs-vue "^1.0.0"
+ lowlight "^1.17.0"
+ prismjs "^1.30.0"
+ refractor "^5.0.0"
+
react-turnstile@^1.1.4:
version "1.1.4"
resolved "https://registry.npmjs.org/react-turnstile/-/react-turnstile-1.1.4.tgz"
@@ -9643,6 +9798,16 @@ reflect.getprototypeof@^1.0.6, reflect.getprototypeof@^1.0.9:
get-proto "^1.0.1"
which-builtin-type "^1.2.1"
+refractor@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/refractor/-/refractor-5.0.0.tgz#85daf0448a6d947f5361796eb22c31733d61d904"
+ integrity sha512-QXOrHQF5jOpjjLfiNk5GFnWhRXvxjUVnlFxkeDmewR5sXkr3iM46Zo+CnRR8B+MDVqkULW4EcLVcRBNOPXHosw==
+ dependencies:
+ "@types/hast" "^3.0.0"
+ "@types/prismjs" "^1.0.0"
+ hastscript "^9.0.0"
+ parse-entities "^4.0.0"
+
regenerate-unicode-properties@^10.2.2:
version "10.2.2"
resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz"
@@ -10295,6 +10460,11 @@ sourcemap-codec@^1.4.8:
resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz"
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
+space-separated-tokens@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f"
+ integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==
+
spdy-transport@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz"