diff --git a/analytics/husky.analytics.ts b/analytics/husky.analytics.ts
index af63747d..2983b854 100644
--- a/analytics/husky.analytics.ts
+++ b/analytics/husky.analytics.ts
@@ -59,8 +59,8 @@ export const useHuskyAnalytics = () => {
captureEvent(events.husky_action_card_clicked, {...action})
}
- function trackSharedBlog(blogId: string, mode: string) {
- captureEvent(events.husky_open_shared_blog, {blogId, mode });
+ function trackSharedBlog(blogId: string, mode: string, question: string) {
+ captureEvent(events.husky_open_shared_blog, {blogId, mode, question });
}
function trackFollowupQuestionClick(mode: string, question: string, blogId?: string | null) {
@@ -75,12 +75,12 @@ export const useHuskyAnalytics = () => {
captureEvent(events.husky_user_feedback_clicked, { question, answer });
}
- function trackFeedbackStatus( status: string) {
- captureEvent(events.husky_user_feedback_status, { status });
+ function trackFeedbackStatus( status: string, rating: string, question: string) {
+ captureEvent(events.husky_user_feedback_status, { feedbackStatus: status, rating, question });
}
- function trackAiResponse(status: string, mode: string) {
- captureEvent(events.husky_ai_response, { status, mode, });
+ function trackAiResponse(status: string, mode: string, isBlog: boolean, question: string) {
+ captureEvent(events.husky_ai_response, { huskyResponse: status, mode, isBlog, question });
}
function trackRegenerate() {
diff --git a/components/core/husky/husky-ai.tsx b/components/core/husky/husky-ai.tsx
index 86145829..df262ec6 100644
--- a/components/core/husky/husky-ai.tsx
+++ b/components/core/husky/husky-ai.tsx
@@ -107,7 +107,7 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose
const onPromptClicked = async (question: string) => {
try {
- const { authToken } = await getUserCredentials();
+ const { authToken, userInfo } = await getUserCredentials();
if (!authToken) {
return;
}
@@ -116,19 +116,19 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose
setAnswerLoadingStatus(true);
setActiveTab(DEFAULT_TAB_ITEMS[0].key);
setChats([]);
- trackAiResponse('initiated', 'prompt');
- const result = await getHuskyResponse(authToken, question, selectedSource, chatUid, null, null, mode === 'blog'); // Fixed function name
+ trackAiResponse('initiated', 'prompt', mode === 'blog', question);
+ const result = await getHuskyResponse(userInfo, authToken, question, selectedSource, chatUid, null, null, mode === 'blog'); // Fixed function name
setAskingQuestion('');
setAnswerLoadingStatus(false);
if (result.isError) {
- trackAiResponse('error', 'prompt');
+ trackAiResponse('error', 'prompt', mode === 'blog', question);
setChats((prevChats) => [...prevChats, { question, answer: '', isError: true }]);
return;
}
- trackAiResponse('success', 'prompt');
+ trackAiResponse('success', 'prompt', mode === 'blog', question);
setChats(result.data ? [{ ...result.data, isError: false }] : []);
} catch (error) {
- trackAiResponse('error', 'prompt');
+ trackAiResponse('error', 'prompt', mode === 'blog', question);
}
};
@@ -149,7 +149,7 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose
const onFollowupClicked = async (question: string) => {
try {
- const { authToken } = await getUserCredentials();
+ const { authToken, userInfo } = await getUserCredentials();
if (!authToken) {
return;
}
@@ -158,23 +158,23 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose
return;
}
trackFollowupQuestionClick(mode, question, blogId);
- trackAiResponse('initiated', 'followup');
+ trackAiResponse('initiated', 'followup', mode === 'blog', question);
const chatUid = checkAndSetPromptId();
setAskingQuestion(question);
setAnswerLoadingStatus(true);
- const result = await getHuskyResponse(authToken, question, selectedSource, chatUid, mode === 'blog' && chats.length === 1 ? chats[0].question : null, mode === 'blog' && chats.length === 1 ? chats[0].answer : null, mode === 'blog'); // Fixed function name
+ const result = await getHuskyResponse(userInfo, authToken, question, selectedSource, chatUid, mode === 'blog' && chats.length === 1 ? chats[0].question : null, mode === 'blog' && chats.length === 1 ? chats[0].answer : null, mode === 'blog'); // Fixed function name
setAskingQuestion('');
setAnswerLoadingStatus(false);
if (result.isError) {
- trackAiResponse('error', 'followup');
+ trackAiResponse('error', 'followup', mode === 'blog', question);
setChats((prevChats) => [...prevChats, { question, answer: '', isError: true }]);
return;
}
- trackAiResponse('success', 'followup');
+ trackAiResponse('success', 'followup', mode === 'blog', question);
setChats((prevChats) => result.data ? [...prevChats, { ...result.data, isError: false }] : prevChats);
} catch (error) {
- trackAiResponse('error', 'followup');
+ trackAiResponse('error', 'followup', mode === 'blog', question);
}
};
@@ -199,7 +199,7 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose
const onHuskyInput = async (query: string) => {
try {
- const { authToken } = await getUserCredentials();
+ const { authToken, userInfo } = await getUserCredentials();
if (!authToken) {
return;
}
@@ -216,19 +216,19 @@ function HuskyAi({ mode = 'chat', initialChats = [], isLoggedIn, blogId, onClose
trackUserPrompt(query);
setAskingQuestion(query);
setAnswerLoadingStatus(true);
- trackAiResponse('initiated', 'user-input');
- const result = await getHuskyResponse(authToken, query, selectedSource, chatUid);
+ trackAiResponse('initiated', 'user-input', mode === 'blog', query);
+ const result = await getHuskyResponse(userInfo, authToken, query, selectedSource, chatUid);
setAskingQuestion('');
setAnswerLoadingStatus(false);
if (result.isError) {
- trackAiResponse('error', 'user-input');
+ trackAiResponse('error', 'user-input', mode === 'blog', query);
setChats((prevChats) => [...prevChats, { question: query, answer: '', isError: true }]);
return;
}
- trackAiResponse('success', 'user-input');
+ trackAiResponse('success', 'user-input', mode === 'blog', query);
setChats((prevChats) => result.data ? [...prevChats, { ...result.data, isError: false }] : prevChats);
} catch (error) {
- trackAiResponse('error', 'user-input');
+ trackAiResponse('error', 'user-input', mode === 'blog', query);
}
};
diff --git a/components/core/husky/husky-chat-answer.tsx b/components/core/husky/husky-chat-answer.tsx
index 489e2552..48ff054a 100644
--- a/components/core/husky/husky-chat-answer.tsx
+++ b/components/core/husky/husky-chat-answer.tsx
@@ -1,7 +1,6 @@
import Markdown from 'markdown-to-jsx';
-import { useRef, useState } from 'react';
-
import CopyText from '../copy-text';
+import HuskyCodeBlock from './husky-code-block';
interface HuskyChatAnswerProps {
mode: 'blog' | 'chat';
@@ -29,22 +28,24 @@ function HuskyChatAnswer({ mode, answer, isLastIndex, question, onCopyAnswer, on
{mode !== 'blog' && (
-
+
Answer
)}
@@ -95,6 +96,11 @@ function HuskyChatAnswer({ mode, answer, isLastIndex, question, onCopyAnswer, on
gap: 8px;
padding: 14px;
border-radius: 8px;
+ max-width: 100%;
+ }
+
+ .chat__ans__text div:first-child {
+ max-width: 100%;
}
.chat__ans__text--blog {
@@ -138,4 +144,4 @@ function HuskyChatAnswer({ mode, answer, isLastIndex, question, onCopyAnswer, on
);
}
-export default HuskyChatAnswer;
+export default HuskyChatAnswer;
\ No newline at end of file
diff --git a/components/core/husky/husky-code-block.tsx b/components/core/husky/husky-code-block.tsx
new file mode 100644
index 00000000..67c88498
--- /dev/null
+++ b/components/core/husky/husky-code-block.tsx
@@ -0,0 +1,354 @@
+import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
+import { a11yDark } from 'react-syntax-highlighter/dist/esm/styles/prism';
+import CopyText from '../copy-text';
+
+function HuskyCodeBlock(props: any) {
+ const languages = new Set([
+ 'abap',
+ 'abnf',
+ 'actionscript',
+ 'ada',
+ 'agda',
+ 'al',
+ 'antlr4',
+ 'apacheconf',
+ 'apex',
+ 'apl',
+ 'applescript',
+ 'aql',
+ 'arduino',
+ 'arff',
+ 'asciidoc',
+ 'asm6502',
+ 'asmatmel',
+ 'aspnet',
+ 'autohotkey',
+ 'autoit',
+ 'avisynth',
+ 'avroIdl',
+ 'bash',
+ 'basic',
+ 'batch',
+ 'bbcode',
+ 'bicep',
+ 'birb',
+ 'bison',
+ 'bnf',
+ 'brainfuck',
+ 'brightscript',
+ 'bro',
+ 'bsl',
+ 'c',
+ 'cfscript',
+ 'chaiscript',
+ 'cil',
+ 'clike',
+ 'clojure',
+ 'cmake',
+ 'cobol',
+ 'coffeescript',
+ 'concurnas',
+ 'coq',
+ 'cpp',
+ 'crystal',
+ 'csharp',
+ 'cshtml',
+ 'csp',
+ 'cssExtras',
+ 'css',
+ 'csv',
+ 'cypher',
+ 'd',
+ 'dart',
+ 'dataweave',
+ 'dax',
+ 'dhall',
+ 'diff',
+ 'django',
+ 'dnsZoneFile',
+ 'docker',
+ 'dot',
+ 'ebnf',
+ 'editorconfig',
+ 'eiffel',
+ 'ejs',
+ 'elixir',
+ 'elm',
+ 'erb',
+ 'erlang',
+ 'etlua',
+ 'excelFormula',
+ 'factor',
+ 'falselang',
+ 'firestoreSecurityRules',
+ 'flow',
+ 'fortran',
+ 'fsharp',
+ 'ftl',
+ 'gap',
+ 'gcode',
+ 'gdscript',
+ 'gedcom',
+ 'gherkin',
+ 'git',
+ 'glsl',
+ 'gml',
+ 'gn',
+ 'goModule',
+ 'go',
+ 'graphql',
+ 'groovy',
+ 'haml',
+ 'handlebars',
+ 'haskell',
+ 'haxe',
+ 'hcl',
+ 'hlsl',
+ 'hoon',
+ 'hpkp',
+ 'hsts',
+ 'http',
+ 'ichigojam',
+ 'icon',
+ 'icuMessageFormat',
+ 'idris',
+ 'iecst',
+ 'ignore',
+ 'inform7',
+ 'ini',
+ 'io',
+ 'j',
+ 'java',
+ 'javadoc',
+ 'javadoclike',
+ 'javascript',
+ 'javastacktrace',
+ 'jexl',
+ 'jolie',
+ 'jq',
+ 'jsExtras',
+ 'jsTemplates',
+ 'jsdoc',
+ 'json',
+ 'json5',
+ 'jsonp',
+ 'jsstacktrace',
+ 'jsx',
+ 'julia',
+ 'keepalived',
+ 'keyman',
+ 'kotlin',
+ 'kumir',
+ 'kusto',
+ 'latex',
+ 'latte',
+ 'less',
+ 'lilypond',
+ 'liquid',
+ 'lisp',
+ 'livescript',
+ 'llvm',
+ 'log',
+ 'lolcode',
+ 'lua',
+ 'magma',
+ 'makefile',
+ 'markdown',
+ 'markupTemplating',
+ 'markup',
+ 'matlab',
+ 'maxscript',
+ 'mel',
+ 'mermaid',
+ 'mizar',
+ 'mongodb',
+ 'monkey',
+ 'moonscript',
+ 'n1ql',
+ 'n4js',
+ 'nand2tetrisHdl',
+ 'naniscript',
+ 'nasm',
+ 'neon',
+ 'nevod',
+ 'nginx',
+ 'nim',
+ 'nix',
+ 'nsis',
+ 'objectivec',
+ 'ocaml',
+ 'opencl',
+ 'openqasm',
+ 'oz',
+ 'parigp',
+ 'parser',
+ 'pascal',
+ 'pascaligo',
+ 'pcaxis',
+ 'peoplecode',
+ 'perl',
+ 'phpExtras',
+ 'php',
+ 'phpdoc',
+ 'plsql',
+ 'powerquery',
+ 'powershell',
+ 'processing',
+ 'prolog',
+ 'promql',
+ 'properties',
+ 'protobuf',
+ 'psl',
+ 'pug',
+ 'puppet',
+ 'pure',
+ 'purebasic',
+ 'purescript',
+ 'python',
+ 'q',
+ 'qml',
+ 'qore',
+ 'qsharp',
+ 'r',
+ 'racket',
+ 'reason',
+ 'regex',
+ 'rego',
+ 'renpy',
+ 'rest',
+ 'rip',
+ 'roboconf',
+ 'robotframework',
+ 'ruby',
+ 'rust',
+ 'sas',
+ 'sass',
+ 'scala',
+ 'scheme',
+ 'scss',
+ 'shellSession',
+ 'smali',
+ 'smalltalk',
+ 'smarty',
+ 'sml',
+ 'solidity',
+ 'solutionFile',
+ 'soy',
+ 'sparql',
+ 'splunkSpl',
+ 'sqf',
+ 'sql',
+ 'squirrel',
+ 'stan',
+ 'stylus',
+ 'swift',
+ 'systemd',
+ 't4Cs',
+ 't4Templating',
+ 't4Vb',
+ 'tap',
+ 'tcl',
+ 'textile',
+ 'toml',
+ 'tremor',
+ 'tsx',
+ 'tt2',
+ 'turtle',
+ 'twig',
+ 'typescript',
+ 'typoscript',
+ 'unrealscript',
+ 'uorazor',
+ 'uri',
+ 'v',
+ 'vala',
+ 'vbnet',
+ 'velocity',
+ 'verilog',
+ 'vhdl',
+ 'vim',
+ 'visualBasic',
+ 'warpscript',
+ 'wasm',
+ 'webIdl',
+ 'wiki',
+ 'wolfram',
+ 'wren',
+ 'xeora',
+ 'xmlDoc',
+ 'xojo',
+ 'xquery',
+ 'yaml',
+ 'yang',
+ 'zig',
+ ]);
+
+ let codeText = props.children.trim();
+ let language = 'bash';
+
+ const firstLineEndIndex = codeText.indexOf('\n');
+ if (firstLineEndIndex !== -1) {
+ const firstWord = codeText.substring(0, firstLineEndIndex).trim();
+ if (languages.has(firstWord)) {
+ language = firstWord;
+ codeText = codeText.substring(firstLineEndIndex + 1).trim();
+ }
+ }
+
+ return (
+ <>
+
+
+
{language}
+
+
+ Copy Code
+
+
+
+
+ {codeText}
+
+
+
+ >
+ );
+}
+
+export default HuskyCodeBlock
\ No newline at end of file
diff --git a/components/core/husky/husky-empty-chat.tsx b/components/core/husky/husky-empty-chat.tsx
index ec41437b..119b1160 100644
--- a/components/core/husky/husky-empty-chat.tsx
+++ b/components/core/husky/husky-empty-chat.tsx
@@ -12,6 +12,10 @@ function HuskyEmptyChat({ onPromptClicked }: HuskyEmptyChatProps) {
{ text: 'What initiatives or programs does Protocol Labs offer to foster innovation in decentralized technologies?', icon: '/icons/send-black.svg' },
];
+ const isMobileDevice = () => {
+ return /Mobi|Android/i.test(navigator.userAgent);
+ };
+
const { trackExplorationPromptSelection } = useHuskyAnalytics();
const textareaRef = useRef(null);
@@ -33,12 +37,22 @@ function HuskyEmptyChat({ onPromptClicked }: HuskyEmptyChatProps) {
await onPromptClicked(ques);
};
+ const handleKeyDown = (e: React.KeyboardEvent) => {
+ const isMobileOrTablet = /Mobi|Android|iPad|iPhone/i.test(navigator.userAgent);
+ if (!isMobileOrTablet && window.innerWidth >= 1024) {
+ if (e.key === 'Enter' && !e.shiftKey) {
+ e.preventDefault(); // Prevents adding a new line
+ handlePromptSubmission(); // Submits the form
+ }
+ }
+ };
+
return (
<>
-
+
What is Husky?
@@ -49,26 +63,38 @@ function HuskyEmptyChat({ onPromptClicked }: HuskyEmptyChatProps) {
-
+
Traverse the Protocol Labs with Husky
-
-
+
+
+ {!isMobileDevice() && (
+
+
+ Shift + Enter for new line
+
+
+ )}
-
+
Try asking or searching for
{initialPrompts.map((prompt, index) => (
onExplorationPromptClicked(prompt.text)}>
-
+
{prompt.text}
))}
@@ -76,7 +102,7 @@ function HuskyEmptyChat({ onPromptClicked }: HuskyEmptyChatProps) {
-
+
Want Husky to be able to fetch results for your teams, projects and members too?
Upload data
@@ -163,6 +189,7 @@ function HuskyEmptyChat({ onPromptClicked }: HuskyEmptyChatProps) {
align-items: center;
padding: 0 16px;
gap: 8px;
+ position: relative;
}
.hec__content__box__search__input {
flex: 1;
@@ -242,6 +269,16 @@ function HuskyEmptyChat({ onPromptClicked }: HuskyEmptyChatProps) {
font-weight: 400;
}
+ .hec__content__box__search__instruction {
+ display: none;
+ }
+
+ .hec__content__box__search__instruction__tag {
+ border: 1px solid #CBD5E1;
+ padding: 2px 4px;
+ border-radius: 4px;
+ }
+
@media (min-width: 1024px) {
.hec__content__box {
width: 600px;
@@ -263,6 +300,26 @@ function HuskyEmptyChat({ onPromptClicked }: HuskyEmptyChatProps) {
margin: 30px 0;
line-height: 36px;
}
+
+ .hec__content__box__search__instruction {
+ position: absolute;
+ top: 0px;
+ right: 68px;
+ width: auto;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 10px;
+ color: #adadad;
+ }
+
+ .hec__content__box__search__input:placeholder-shown + .hec__content__box__search__instruction {
+ display: flex;
+ }
+ .hec__content__box__search__input:not(:placeholder-shown) + .hec__content__box__search__instruction {
+ display: none;
+ }
}
`}
>
diff --git a/components/core/husky/husky-feedback.tsx b/components/core/husky/husky-feedback.tsx
index a5459da1..7d8d92fb 100644
--- a/components/core/husky/husky-feedback.tsx
+++ b/components/core/husky/husky-feedback.tsx
@@ -32,7 +32,7 @@ const HuskyFeedback = (props: any) => {
forceUserLogin()
}
if (userInfo) {
- trackFeedbackStatus('initiated')
+ trackFeedbackStatus('initiated', ratingInfo.rating, question)
const memberInfo = await getMemberInfo(userInfo.uid);
const memberDetails = memberInfo.data;
const payload = {
@@ -50,15 +50,15 @@ const HuskyFeedback = (props: any) => {
const response = await saveFeedback(newAuthToken, payload);
setLoadingStatus(false);
if(response.isSaved) {
- trackFeedbackStatus('success')
+ trackFeedbackStatus('success', ratingInfo.rating, question)
setStep('success')
} else {
- trackFeedbackStatus('error')
+ trackFeedbackStatus('error', ratingInfo.rating, question)
setStep('error');
}
}
} catch (error) {
- trackFeedbackStatus('error')
+ trackFeedbackStatus('error', ratingInfo.rating, question)
setStep('error');
}
};
diff --git a/components/core/husky/husky-input-box.tsx b/components/core/husky/husky-input-box.tsx
index 6042aeda..01623831 100644
--- a/components/core/husky/husky-input-box.tsx
+++ b/components/core/husky/husky-input-box.tsx
@@ -41,17 +41,39 @@ function HuskyInputBox(props: any) {
onSourceSelected(value);
};
+ const isMobileDevice = () => {
+ return /Mobi|Android/i.test(navigator.userAgent);
+ };
+
useEffect(() => {
- function handler(e: any) {
+ const handleKeyDown = (event: KeyboardEvent) => {
if (inputRef.current) {
- inputRef.current.innerText = e?.detail;
+ const isMobile = isMobileDevice();
+ if (event.key === 'Enter') {
+ if (isMobile || event.shiftKey) {
+ // Allow new line on mobile or with Shift + Enter on desktop
+ document.execCommand('insertLineBreak');
+ event.preventDefault();
+ } else {
+ // Submit on Enter on desktop
+ event.preventDefault();
+ onTextSubmit();
+ }
+ }
}
+ };
+
+ const inputElement = inputRef.current;
+ if (inputElement) {
+ inputElement.addEventListener('keydown', handleKeyDown);
}
- document.addEventListener('husky-ai-input', handler);
- return function () {
- document.removeEventListener('husky-ai-input', handler);
+
+ return () => {
+ if (inputElement) {
+ inputElement.removeEventListener('keydown', handleKeyDown);
+ }
};
- }, []);
+ }, [isAnswerLoading]);
return (
<>
@@ -59,6 +81,13 @@ function HuskyInputBox(props: any) {
+ {!isMobileDevice() && (
+
+
+ Shift + Enter for new line
+
+
+ )}
@@ -97,6 +126,7 @@ function HuskyInputBox(props: any) {
display: flex;
gap: 8px;
align-items: center;
+ position: relative;
}
.huskyinput::before {
@@ -146,6 +176,16 @@ function HuskyInputBox(props: any) {
display: flex;
gap: 8px;
align-items: center;
+ position: relative;
+ }
+ .huskyinput__itemcn__instruction {
+ display: none;
+ }
+
+ .huskyinput__itemcn__instruction__tag {
+ border: 1px solid #CBD5E1;
+ padding: 2px 4px;
+ border-radius: 4px;
}
.huskyinput__action__menu {
@@ -231,6 +271,24 @@ function HuskyInputBox(props: any) {
height: 30px;
margin-left: -3px;
}
+ .huskyinput__itemcn__instruction {
+ position: absolute;
+ top: 0px;
+ right: 188px;
+ width: 180px;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 11px;
+ color: #64748b;
+ }
+ .huskyinput__itemcn__instruction {
+ display: none;
+ }
+ .huskyinput__itemcn__textbox:empty + .huskyinput__itemcn__instruction {
+ display: flex;
+ }
}
`}
diff --git a/components/page/home/husky-discover.tsx b/components/page/home/husky-discover.tsx
index 75b4defe..217e2bb0 100644
--- a/components/page/home/husky-discover.tsx
+++ b/components/page/home/husky-discover.tsx
@@ -59,7 +59,8 @@ function HuskyDiscover(props: any) {
function dialogHandler(e: any) {
if (dialogRef.current) {
increaseViewAndShow(e?.detail)
- trackSharedBlog(e?.detail?.slug, 'discover')
+ console.log(e?.detail);
+ trackSharedBlog(e?.detail?.slug, 'discover', e?.detail?.question)
}
}
document.addEventListener('open-husky-discover', dialogHandler);
@@ -75,8 +76,9 @@ function HuskyDiscover(props: any) {
.then(result => {
if(result.data && dialogRef.current) {
setInitialChats([result.data]);
+ console.log(result.data)
if(!huskyRecorded) {
- trackSharedBlog(huskyShareId, 'shareurl')
+ trackSharedBlog(huskyShareId, 'shareurl', result.data?.question)
}
huskyRecorded = true;
dialogRef.current.showModal();
diff --git a/package-lock.json b/package-lock.json
index f0c69d0f..ed376c1b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,8 +18,11 @@
"md-editor-rt": "^4.17.0",
"next": "14.2.3",
"posthog-js": "^1.139.2",
+ "prismjs": "^1.29.0",
"react": "^18",
+ "react-copy-to-clipboard": "^5.1.0",
"react-dom": "^18",
+ "react-syntax-highlighter": "^15.5.0",
"react-toastify": "^10.0.5",
"text-clipper": "^2.2.0",
"zod": "^3.23.8"
@@ -31,8 +34,10 @@
"@types/js-cookie": "^3.0.6",
"@types/jsonwebtoken": "^9.0.6",
"@types/node": "^20",
+ "@types/prismjs": "^1.26.4",
"@types/react": "^18",
"@types/react-dom": "^18",
+ "@types/react-syntax-highlighter": "^15.5.13",
"eslint": "^8",
"eslint-config-next": "14.2.3",
"jest": "^29.7.0",
@@ -618,7 +623,6 @@
"version": "7.25.6",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz",
"integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==",
- "dev": true,
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -4290,6 +4294,14 @@
"@types/node": "*"
}
},
+ "node_modules/@types/hast": {
+ "version": "2.3.10",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz",
+ "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==",
+ "dependencies": {
+ "@types/unist": "^2"
+ }
+ },
"node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
@@ -4378,6 +4390,12 @@
"undici-types": "~5.26.4"
}
},
+ "node_modules/@types/prismjs": {
+ "version": "1.26.4",
+ "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.4.tgz",
+ "integrity": "sha512-rlAnzkW2sZOjbqZ743IHUhFcvzaGbqijwOu8QZnZCjfQzBqFE3s4lOTJEsxikImav9uzz/42I+O7YUs1mWgMlg==",
+ "dev": true
+ },
"node_modules/@types/prop-types": {
"version": "15.7.12",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz",
@@ -4403,6 +4421,15 @@
"@types/react": "*"
}
},
+ "node_modules/@types/react-syntax-highlighter": {
+ "version": "15.5.13",
+ "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.13.tgz",
+ "integrity": "sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==",
+ "dev": true,
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
"node_modules/@types/stack-utils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
@@ -4420,6 +4447,11 @@
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="
},
+ "node_modules/@types/unist": {
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="
+ },
"node_modules/@types/yargs": {
"version": "17.0.33",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
@@ -5721,6 +5753,33 @@
"node": ">=10"
}
},
+ "node_modules/character-entities": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
+ "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-legacy": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
+ "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-reference-invalid": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
+ "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/charenc": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
@@ -5924,6 +5983,15 @@
"node": ">= 0.8"
}
},
+ "node_modules/comma-separated-tokens": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz",
+ "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -7621,6 +7689,18 @@
"reusify": "^1.0.4"
}
},
+ "node_modules/fault": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz",
+ "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==",
+ "dependencies": {
+ "format": "^0.2.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/fb-watchman": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
@@ -7774,6 +7854,14 @@
"node": ">= 6"
}
},
+ "node_modules/format": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
+ "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==",
+ "engines": {
+ "node": ">=0.4.x"
+ }
+ },
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -8149,6 +8237,31 @@
"node": ">= 0.4"
}
},
+ "node_modules/hast-util-parse-selector": {
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
+ "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hastscript": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz",
+ "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==",
+ "dependencies": {
+ "@types/hast": "^2.0.0",
+ "comma-separated-tokens": "^1.0.0",
+ "hast-util-parse-selector": "^2.0.0",
+ "property-information": "^5.0.0",
+ "space-separated-tokens": "^1.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
"node_modules/help-me": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz",
@@ -8159,6 +8272,14 @@
"resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz",
"integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q=="
},
+ "node_modules/highlight.js": {
+ "version": "10.7.3",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
+ "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==",
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
@@ -8380,6 +8501,28 @@
"url": "https://github.com/sponsors/brc-dd"
}
},
+ "node_modules/is-alphabetical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
+ "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-alphanumerical": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
+ "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
+ "dependencies": {
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/is-arguments": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
@@ -8532,6 +8675,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-decimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
+ "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/is-docker": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
@@ -8617,6 +8769,15 @@
"npm": ">=3"
}
},
+ "node_modules/is-hexadecimal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
+ "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/is-inside-container": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
@@ -10786,6 +10947,19 @@
"loose-envify": "cli.js"
}
},
+ "node_modules/lowlight": {
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz",
+ "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==",
+ "dependencies": {
+ "fault": "^1.0.0",
+ "highlight.js": "~10.7.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/lru-cache": {
"version": "10.3.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.1.tgz",
@@ -11296,7 +11470,6 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -11553,6 +11726,23 @@
"node": ">=6"
}
},
+ "node_modules/parse-entities": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
+ "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
+ "dependencies": {
+ "character-entities": "^1.0.0",
+ "character-entities-legacy": "^1.0.0",
+ "character-reference-invalid": "^1.0.0",
+ "is-alphanumerical": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-hexadecimal": "^1.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/parse-json": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
@@ -11949,6 +12139,14 @@
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
"dev": true
},
+ "node_modules/prismjs": {
+ "version": "1.29.0",
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
+ "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
@@ -11979,7 +12177,6 @@
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
- "dev": true,
"dependencies": {
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
@@ -11989,8 +12186,19 @@
"node_modules/prop-types/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
- "dev": true
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
+ "node_modules/property-information": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz",
+ "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==",
+ "dependencies": {
+ "xtend": "^4.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
},
"node_modules/proxy-compare": {
"version": "2.5.1",
@@ -12131,6 +12339,18 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-copy-to-clipboard": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz",
+ "integrity": "sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==",
+ "dependencies": {
+ "copy-to-clipboard": "^3.3.1",
+ "prop-types": "^15.8.1"
+ },
+ "peerDependencies": {
+ "react": "^15.3.0 || 16 || 17 || 18"
+ }
+ },
"node_modules/react-device-detect": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/react-device-detect/-/react-device-detect-2.2.3.tgz",
@@ -12160,6 +12380,21 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
},
+ "node_modules/react-syntax-highlighter": {
+ "version": "15.5.0",
+ "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz",
+ "integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==",
+ "dependencies": {
+ "@babel/runtime": "^7.3.1",
+ "highlight.js": "^10.4.1",
+ "lowlight": "^1.17.0",
+ "prismjs": "^1.27.0",
+ "refractor": "^3.6.0"
+ },
+ "peerDependencies": {
+ "react": ">= 0.14.0"
+ }
+ },
"node_modules/react-toastify": {
"version": "10.0.5",
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-10.0.5.tgz",
@@ -12246,11 +12481,32 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/refractor": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz",
+ "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==",
+ "dependencies": {
+ "hastscript": "^6.0.0",
+ "parse-entities": "^2.0.0",
+ "prismjs": "~1.27.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/refractor/node_modules/prismjs": {
+ "version": "1.27.0",
+ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz",
+ "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/regenerator-runtime": {
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
- "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
- "dev": true
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
},
"node_modules/regexp.prototype.flags": {
"version": "1.5.2",
@@ -12696,6 +12952,15 @@
"source-map": "^0.6.0"
}
},
+ "node_modules/space-separated-tokens": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz",
+ "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/split-on-first": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
@@ -14431,6 +14696,14 @@
"node": ">= 0.10.0"
}
},
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
"node_modules/y18n": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
diff --git a/package.json b/package.json
index 57808634..dea3967d 100644
--- a/package.json
+++ b/package.json
@@ -21,8 +21,11 @@
"md-editor-rt": "^4.17.0",
"next": "14.2.3",
"posthog-js": "^1.139.2",
+ "prismjs": "^1.29.0",
"react": "^18",
+ "react-copy-to-clipboard": "^5.1.0",
"react-dom": "^18",
+ "react-syntax-highlighter": "^15.5.0",
"react-toastify": "^10.0.5",
"text-clipper": "^2.2.0",
"zod": "^3.23.8"
@@ -34,8 +37,10 @@
"@types/js-cookie": "^3.0.6",
"@types/jsonwebtoken": "^9.0.6",
"@types/node": "^20",
+ "@types/prismjs": "^1.26.4",
"@types/react": "^18",
"@types/react-dom": "^18",
+ "@types/react-syntax-highlighter": "^15.5.13",
"eslint": "^8",
"eslint-config-next": "14.2.3",
"jest": "^29.7.0",
diff --git a/public/icons/copy-grey.svg b/public/icons/copy-grey.svg
new file mode 100644
index 00000000..de511ee3
--- /dev/null
+++ b/public/icons/copy-grey.svg
@@ -0,0 +1,10 @@
+
diff --git a/public/icons/copy-white.svg b/public/icons/copy-white.svg
new file mode 100644
index 00000000..3a0a1f7f
--- /dev/null
+++ b/public/icons/copy-white.svg
@@ -0,0 +1,3 @@
+
diff --git a/services/husky.service.ts b/services/husky.service.ts
index 6ec10c25..79abdbf4 100644
--- a/services/husky.service.ts
+++ b/services/husky.service.ts
@@ -90,13 +90,16 @@ export const getHuskyAugmentedInfo = async (authToken: string, query: string, an
}
};
-export const getHuskyResponse = async (authToken: string, query: string, source: string, chatUid: string, previousQues?: string | null, previousAns?: string | null, isBlog = false) => {
+export const getHuskyResponse = async (userInfo: any,authToken: string, query: string, source: string, chatUid: string, previousQues?: string | null, previousAns?: string | null, isBlog = false) => {
const payload = {
query,
UID: chatUid,
source,
...(previousQues && { promptHistory: previousQues }),
...(previousAns && { answerHistory: previousAns }),
+ ...(userInfo?.name && { name: userInfo?.name }),
+ ...(userInfo?.email && { email: userInfo?.email }),
+ ...(userInfo?.uid && { directoryId: userInfo?.uid }),
};
const queryResponse = await fetch(`${process.env.HUSKY_API_URL}/retrieve`, {
cache: 'no-store',