Add OpenAI chat integration and dependencies

- Add OpenAI library and related dependencies to package files
- Implement chat functionality with custom OpenAI API endpoint
- Update app.ts and create new chat.ts module for AI chat interface
- Modify results template to support AI chat container
- Add new font dependencies for Inter and Vazirmatn
- Update package-lock.json with new package versions
This commit is contained in:
Gnkalk 2025-02-21 01:09:43 +03:30
parent aa9ea20c0f
commit bdd25f7a6b
40 changed files with 9693 additions and 150 deletions

View file

@ -3,7 +3,7 @@
font-style: normal;
font-display: swap;
font-weight: 100 900;
src: url("inter-cyrillic-ext-standard-normal.fc62596d.woff2") format("woff2-variations");
src: url("inter-cyrillic-ext-standard-normal.ad8a30de.woff2") format("woff2-variations");
unicode-range: U+460-52F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@ -12,7 +12,7 @@
font-style: normal;
font-display: swap;
font-weight: 100 900;
src: url("inter-cyrillic-standard-normal.ea7e923a.woff2") format("woff2-variations");
src: url("inter-cyrillic-standard-normal.edf2e0c8.woff2") format("woff2-variations");
unicode-range: U+301, U+400-45F, U+490-491, U+4B0-4B1, U+2116;
}
@ -21,7 +21,7 @@
font-style: normal;
font-display: swap;
font-weight: 100 900;
src: url("inter-greek-ext-standard-normal.e10982a0.woff2") format("woff2-variations");
src: url("inter-greek-ext-standard-normal.f6de5c8f.woff2") format("woff2-variations");
unicode-range: U+1F??;
}
@ -30,7 +30,7 @@
font-style: normal;
font-display: swap;
font-weight: 100 900;
src: url("inter-greek-standard-normal.0caa17e7.woff2") format("woff2-variations");
src: url("inter-greek-standard-normal.caf6d48e.woff2") format("woff2-variations");
unicode-range: U+370-377, U+37A-37F, U+384-38A, U+38C, U+38E-3A1, U+3A3-3FF;
}
@ -39,7 +39,7 @@
font-style: normal;
font-display: swap;
font-weight: 100 900;
src: url("inter-vietnamese-standard-normal.2aec2804.woff2") format("woff2-variations");
src: url("inter-vietnamese-standard-normal.02f2e048.woff2") format("woff2-variations");
unicode-range: U+102-103, U+110-111, U+128-129, U+168-169, U+1A0-1A1, U+1AF-1B0, U+300-301, U+303-304, U+308-309, U+323, U+329, U+1EA0-1EF9, U+20AB;
}
@ -48,7 +48,7 @@
font-style: normal;
font-display: swap;
font-weight: 100 900;
src: url("inter-latin-ext-standard-normal.a7641455.woff2") format("woff2-variations");
src: url("inter-latin-ext-standard-normal.c3e326ee.woff2") format("woff2-variations");
unicode-range: U+100-2BA, U+2BD-2C5, U+2C7-2CC, U+2CE-2D7, U+2DD-2FF, U+304, U+308, U+329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@ -57,7 +57,7 @@
font-style: normal;
font-display: swap;
font-weight: 100 900;
src: url("inter-latin-standard-normal.2d8fdd01.woff2") format("woff2-variations");
src: url("inter-latin-standard-normal.9d95bac0.woff2") format("woff2-variations");
unicode-range: U+??, U+131, U+152-153, U+2BB-2BC, U+2C6, U+2DA, U+2DC, U+304, U+308, U+329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@ -66,7 +66,7 @@
font-style: normal;
font-display: swap;
font-weight: 400;
src: url("inter-cyrillic-ext-400-normal.a48d4e19.woff2") format("woff2"), url("inter-cyrillic-ext-400-normal.8938e3ac.woff") format("woff");
src: url("inter-cyrillic-ext-400-normal.5b5b757f.woff2") format("woff2"), url("inter-cyrillic-ext-400-normal.2cb5dc0c.woff") format("woff");
unicode-range: U+460-52F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@ -75,7 +75,7 @@
font-style: normal;
font-display: swap;
font-weight: 400;
src: url("inter-cyrillic-400-normal.cb9ef530.woff2") format("woff2"), url("inter-cyrillic-400-normal.be966a56.woff") format("woff");
src: url("inter-cyrillic-400-normal.4b5feba6.woff2") format("woff2"), url("inter-cyrillic-400-normal.36464be3.woff") format("woff");
unicode-range: U+301, U+400-45F, U+490-491, U+4B0-4B1, U+2116;
}
@ -84,7 +84,7 @@
font-style: normal;
font-display: swap;
font-weight: 400;
src: url("inter-greek-ext-400-normal.bfaa2c39.woff2") format("woff2"), url("inter-greek-ext-400-normal.50e73398.woff") format("woff");
src: url("inter-greek-ext-400-normal.5f623e11.woff2") format("woff2"), url("inter-greek-ext-400-normal.8c538869.woff") format("woff");
unicode-range: U+1F??;
}
@ -93,7 +93,7 @@
font-style: normal;
font-display: swap;
font-weight: 400;
src: url("inter-greek-400-normal.4515f19a.woff2") format("woff2"), url("inter-greek-400-normal.77684a9d.woff") format("woff");
src: url("inter-greek-400-normal.334c89a2.woff2") format("woff2"), url("inter-greek-400-normal.8f0b5c8d.woff") format("woff");
unicode-range: U+370-377, U+37A-37F, U+384-38A, U+38C, U+38E-3A1, U+3A3-3FF;
}
@ -102,7 +102,7 @@
font-style: normal;
font-display: swap;
font-weight: 400;
src: url("inter-vietnamese-400-normal.c9e40957.woff2") format("woff2"), url("inter-vietnamese-400-normal.6507846e.woff") format("woff");
src: url("inter-vietnamese-400-normal.cd378412.woff2") format("woff2"), url("inter-vietnamese-400-normal.1c764e18.woff") format("woff");
unicode-range: U+102-103, U+110-111, U+128-129, U+168-169, U+1A0-1A1, U+1AF-1B0, U+300-301, U+303-304, U+308-309, U+323, U+329, U+1EA0-1EF9, U+20AB;
}
@ -111,7 +111,7 @@
font-style: normal;
font-display: swap;
font-weight: 400;
src: url("inter-latin-ext-400-normal.a6024ce9.woff2") format("woff2"), url("inter-latin-ext-400-normal.fbc4849c.woff") format("woff");
src: url("inter-latin-ext-400-normal.9e6288f4.woff2") format("woff2"), url("inter-latin-ext-400-normal.3f4f9cd0.woff") format("woff");
unicode-range: U+100-2BA, U+2BD-2C5, U+2C7-2CC, U+2CE-2D7, U+2DD-2FF, U+304, U+308, U+329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@ -120,7 +120,7 @@
font-style: normal;
font-display: swap;
font-weight: 400;
src: url("inter-latin-400-normal.fcefd771.woff2") format("woff2"), url("inter-latin-400-normal.a22ac1fc.woff") format("woff");
src: url("inter-latin-400-normal.c257aa80.woff2") format("woff2"), url("inter-latin-400-normal.106646e8.woff") format("woff");
unicode-range: U+??, U+131, U+152-153, U+2BB-2BC, U+2C6, U+2DA, U+2DC, U+304, U+308, U+329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@ -1140,7 +1140,8 @@ main:has(.not-found) .button {
#results .results-container .message-container {
background-color: var(--background-color);
border-radius: 2rem;
padding: 1.5rem;
padding: 1.5rem 1.5rem 5rem;
position: relative;
}
#results .results-container .message-container .title {
@ -1164,12 +1165,12 @@ main:has(.not-found) .button {
border-radius: 1.5rem 1.5rem 1.5rem .5rem;
width: 80%;
max-width: 800px;
margin-bottom: 1rem;
padding: 1rem;
}
#results .results-container .message-container .message-box .reference {
color: var(--text-color);
margin-top: 1rem;
font-size: .8rem;
}
@ -1238,9 +1239,12 @@ main:has(.not-found) .button {
border-radius: 9999px;
align-items: center;
gap: .5rem;
width: calc(100% - 3rem);
margin-top: 1rem;
padding: 0 .5rem;
display: flex;
position: absolute;
bottom: 1.5rem;
}
#results .results-container .message-container .send-message input {
@ -1268,6 +1272,7 @@ main:has(.not-found) .button {
#results .results-container .message-container.ai.loading {
background-color: var(--primary-color);
color: var(--filled-text-color);
padding: 1.5rem;
}
#results .results-container .message-container.ai.loading svg {

View file

@ -1,6 +1,6 @@
@font-face {
font-family: Vazirmatn UI;
src: url("Vazirmatn-UI-Thin.37503ccd.woff2") format("woff2");
src: url("Vazirmatn-UI-Thin.7fd7be2d.woff2") format("woff2");
font-weight: 100;
font-style: normal;
font-display: swap;
@ -8,7 +8,7 @@
@font-face {
font-family: Vazirmatn UI;
src: url("Vazirmatn-UI-ExtraLight.cba2b231.woff2") format("woff2");
src: url("Vazirmatn-UI-ExtraLight.165c33b1.woff2") format("woff2");
font-weight: 200;
font-style: normal;
font-display: swap;
@ -16,7 +16,7 @@
@font-face {
font-family: Vazirmatn UI;
src: url("Vazirmatn-UI-Light.c77d6de0.woff2") format("woff2");
src: url("Vazirmatn-UI-Light.feccc9d1.woff2") format("woff2");
font-weight: 300;
font-style: normal;
font-display: swap;
@ -24,7 +24,7 @@
@font-face {
font-family: Vazirmatn UI;
src: url("Vazirmatn-UI-Regular.a3c99ff7.woff2") format("woff2");
src: url("Vazirmatn-UI-Regular.65a0d014.woff2") format("woff2");
font-weight: 400;
font-style: normal;
font-display: swap;
@ -32,7 +32,7 @@
@font-face {
font-family: Vazirmatn UI;
src: url("Vazirmatn-UI-Medium.972fdd22.woff2") format("woff2");
src: url("Vazirmatn-UI-Medium.9f10f335.woff2") format("woff2");
font-weight: 500;
font-style: normal;
font-display: swap;
@ -40,7 +40,7 @@
@font-face {
font-family: Vazirmatn UI;
src: url("Vazirmatn-UI-SemiBold.37d9c53d.woff2") format("woff2");
src: url("Vazirmatn-UI-SemiBold.f297b6f6.woff2") format("woff2");
font-weight: 600;
font-style: normal;
font-display: swap;
@ -48,7 +48,7 @@
@font-face {
font-family: Vazirmatn UI;
src: url("Vazirmatn-UI-Bold.b0065d44.woff2") format("woff2");
src: url("Vazirmatn-UI-Bold.bb01a60b.woff2") format("woff2");
font-weight: 700;
font-style: normal;
font-display: swap;
@ -56,7 +56,7 @@
@font-face {
font-family: Vazirmatn UI;
src: url("Vazirmatn-UI-ExtraBold.c431ea38.woff2") format("woff2");
src: url("Vazirmatn-UI-ExtraBold.b1556a2a.woff2") format("woff2");
font-weight: 800;
font-style: normal;
font-display: swap;
@ -64,7 +64,7 @@
@font-face {
font-family: Vazirmatn UI;
src: url("Vazirmatn-UI-Black.bc8837bc.woff2") format("woff2");
src: url("Vazirmatn-UI-Black.eebe1f15.woff2") format("woff2");
font-weight: 900;
font-style: normal;
font-display: swap;
@ -1086,7 +1086,8 @@ main:has(.not-found) .button {
#results .results-container .message-container {
background-color: var(--background-color);
border-radius: 2rem;
padding: 1.5rem;
padding: 1.5rem 1.5rem 5rem;
position: relative;
}
#results .results-container .message-container .title {
@ -1110,12 +1111,12 @@ main:has(.not-found) .button {
border-radius: 1.5rem 1.5rem 1.5rem .5rem;
width: 80%;
max-width: 800px;
margin-bottom: 1rem;
padding: 1rem;
}
#results .results-container .message-container .message-box .reference {
color: var(--text-color);
margin-top: 1rem;
font-size: .8rem;
}
@ -1184,9 +1185,12 @@ main:has(.not-found) .button {
border-radius: 9999px;
align-items: center;
gap: .5rem;
width: calc(100% - 3rem);
margin-top: 1rem;
padding: 0 .5rem;
display: flex;
position: absolute;
bottom: 1.5rem;
}
#results .results-container .message-container .send-message input {
@ -1214,6 +1218,7 @@ main:has(.not-found) .button {
#results .results-container .message-container.ai.loading {
background-color: var(--primary-color);
color: var(--filled-text-color);
padding: 1.5rem;
}
#results .results-container .message-container.ai.loading svg {

File diff suppressed because it is too large Load diff

View file

@ -5,15 +5,21 @@
"packages": {
"": {
"dependencies": {
"@fontsource-variable/inter": "^5.1.1",
"@fontsource/inter": "^5.1.1",
"ejs": "^3.1.10",
"nodemon": "^3.1.9",
"openai": "^4.85.3",
"remixicon": "^4.5.0",
"svgo": "^3.3.2"
"svgo": "^3.3.2",
"vazirmatn": "^33.0.3"
},
"devDependencies": {
"@parcel/transformer-sass": "^2.13.0",
"@parcel/transformer-sass": "2.13.0",
"buffer": "^6.0.3",
"concurrently": "^9.1.0",
"parcel": "^2.13.0"
"parcel": "^2.13.0",
"process": "^0.11.10"
}
},
"node_modules/@babel/code-frame": {
@ -41,6 +47,18 @@
"node": ">=6.9.0"
}
},
"node_modules/@fontsource-variable/inter": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@fontsource-variable/inter/-/inter-5.1.1.tgz",
"integrity": "sha512-OpXFTmiH6tHkYijMvQTycFKBLK4X+SRV6tet1m4YOUH7SzIIlMqDja+ocDtiCA72UthBH/vF+3ZtlMr2rN/wIw==",
"license": "OFL-1.1"
},
"node_modules/@fontsource/inter": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-5.1.1.tgz",
"integrity": "sha512-weN3E+rq0Xb3Z93VHJ+Rc7WOQX9ETJPTAJ+gDcaMHtjft67L58sfS65rAjC5tZUXQ2FdZ/V1/sSzCwZ6v05kJw==",
"license": "OFL-1.1"
},
"node_modules/@lezer/common": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz",
@ -1990,6 +2008,49 @@
"node": ">=10.13.0"
}
},
"node_modules/@types/node": {
"version": "18.19.76",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.76.tgz",
"integrity": "sha512-yvR7Q9LdPz2vGpmpJX5LolrgRdWvB67MJKDPSgIIzpFbaf9a1j/f5DnLp5VDyHGMR0QZHlTr1afsD87QCXFHKw==",
"license": "MIT",
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/@types/node-fetch": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz",
"integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==",
"license": "MIT",
"dependencies": {
"@types/node": "*",
"form-data": "^4.0.0"
}
},
"node_modules/abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
"license": "MIT",
"dependencies": {
"event-target-shim": "^5.0.0"
},
"engines": {
"node": ">=6.5"
}
},
"node_modules/agentkeepalive": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz",
"integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==",
"license": "MIT",
"dependencies": {
"humanize-ms": "^1.2.1"
},
"engines": {
"node": ">= 8.0.0"
}
},
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@ -2041,6 +2102,12 @@
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
"license": "MIT"
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@ -2057,6 +2124,27 @@
"safe-buffer": "^5.0.1"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT"
},
"node_modules/binary-extensions": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
@ -2130,6 +2218,44 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
"node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@ -2246,6 +2372,18 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "12.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
@ -2422,6 +2560,15 @@
}
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/detect-libc": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
@ -2519,6 +2666,20 @@
"url": "https://dotenvx.com"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/ejs": {
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
@ -2580,6 +2741,51 @@
"is-arrayish": "^0.2.1"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@ -2590,6 +2796,15 @@
"node": ">=6"
}
},
"node_modules/event-target-shim": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/filelist": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
@ -2632,6 +2847,40 @@
"node": ">=8"
}
},
"node_modules/form-data": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
"integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/form-data-encoder": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz",
"integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==",
"license": "MIT"
},
"node_modules/formdata-node": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz",
"integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==",
"license": "MIT",
"dependencies": {
"node-domexception": "1.0.0",
"web-streams-polyfill": "4.0.0-beta.3"
},
"engines": {
"node": ">= 12.20"
}
},
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@ -2646,6 +2895,15 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@ -2656,6 +2914,30 @@
"node": "6.* || 8.* || >= 10.*"
}
},
"node_modules/get-intrinsic": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz",
"integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.0.0",
"function-bind": "^1.1.2",
"get-proto": "^1.0.0",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-port": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/get-port/-/get-port-4.2.0.tgz",
@ -2666,6 +2948,19 @@
"node": ">=6"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
@ -2694,6 +2989,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@ -2703,6 +3010,45 @@
"node": ">=8"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/htmlnano": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/htmlnano/-/htmlnano-2.1.1.tgz",
@ -2771,6 +3117,36 @@
"entities": "^4.5.0"
}
},
"node_modules/humanize-ms": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
"integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
"license": "MIT",
"dependencies": {
"ms": "^2.0.0"
}
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "BSD-3-Clause"
},
"node_modules/ignore-by-default": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
@ -3211,6 +3587,15 @@
"dev": true,
"license": "MIT"
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/mdn-data": {
"version": "2.0.30",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
@ -3231,6 +3616,27 @@
"node": ">=8.6"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@ -3316,6 +3722,45 @@
"dev": true,
"license": "MIT"
},
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "github",
"url": "https://paypal.me/jimmywarting"
}
],
"license": "MIT",
"engines": {
"node": ">=10.5.0"
}
},
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/node-gyp-build-optional-packages": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz",
@ -3461,6 +3906,36 @@
"dev": true,
"license": "MIT"
},
"node_modules/openai": {
"version": "4.85.3",
"resolved": "https://registry.npmjs.org/openai/-/openai-4.85.3.tgz",
"integrity": "sha512-KTMXAK6FPd2IvsPtglMt0J1GyVrjMxCYzu/mVbCPabzzquSJoZlYpHtE0p0ScZPyt11XTc757xSO4j39j5g+Xw==",
"license": "Apache-2.0",
"dependencies": {
"@types/node": "^18.11.18",
"@types/node-fetch": "^2.6.4",
"abort-controller": "^3.0.0",
"agentkeepalive": "^4.2.1",
"form-data-encoder": "1.7.2",
"formdata-node": "^4.3.2",
"node-fetch": "^2.6.7"
},
"bin": {
"openai": "bin/cli"
},
"peerDependencies": {
"ws": "^8.18.0",
"zod": "^3.23.8"
},
"peerDependenciesMeta": {
"ws": {
"optional": true
},
"zod": {
"optional": true
}
}
},
"node_modules/ordered-binary": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.3.tgz",
@ -3701,6 +4176,16 @@
"node": ">=12"
}
},
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/pstree.remy": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
@ -3996,6 +4481,12 @@
"nodetouch": "bin/nodetouch.js"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"license": "MIT"
},
"node_modules/tree-kill": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
@ -4048,6 +4539,12 @@
"integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
"license": "MIT"
},
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"license": "MIT"
},
"node_modules/update-browserslist-db": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
@ -4089,6 +4586,12 @@
"node": ">= 4"
}
},
"node_modules/vazirmatn": {
"version": "33.0.3",
"resolved": "https://registry.npmjs.org/vazirmatn/-/vazirmatn-33.0.3.tgz",
"integrity": "sha512-fbjNc0CMjazZpIegWzz9OHGzI1APFboT+x7ZecXlUCtDe/nkyx7gtCTZnWS/+eeXG7fbfXymCPKJI8EsnM3iqw==",
"license": "OFL"
},
"node_modules/weak-lru-cache": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz",
@ -4096,6 +4599,31 @@
"dev": true,
"license": "MIT"
},
"node_modules/web-streams-polyfill": {
"version": "4.0.0-beta.3",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz",
"integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==",
"license": "MIT",
"engines": {
"node": ">= 14"
}
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"license": "BSD-2-Clause"
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"license": "MIT",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/wrap-ansi": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",

View file

@ -17,14 +17,17 @@
},
"devDependencies": {
"@parcel/transformer-sass": "2.13.0",
"buffer": "^6.0.3",
"concurrently": "^9.1.0",
"parcel": "^2.13.0"
"parcel": "^2.13.0",
"process": "^0.11.10"
},
"dependencies": {
"@fontsource-variable/inter": "^5.1.1",
"@fontsource/inter": "^5.1.1",
"ejs": "^3.1.10",
"nodemon": "^3.1.9",
"openai": "^4.85.3",
"remixicon": "^4.5.0",
"svgo": "^3.3.2",
"vazirmatn": "^33.0.3"

View file

@ -237,7 +237,8 @@ main:has(.not-found) {
.message-container {
background-color: var(--background-color);
padding: 1.5rem;
padding: 1.5rem 1.5rem 5rem;
position: relative;
@include mixin.rounded(lg);
.title {
@ -257,7 +258,6 @@ main:has(.not-found) {
.message {
background-color: var(--secondary-background-color);
margin-bottom: 1rem;
padding: 1rem;
border-radius: 1.5rem 1.5rem 1.5rem .5rem;
width: 80%;
@ -265,6 +265,7 @@ main:has(.not-found) {
}
.reference {
margin-top: 1rem;
font-size: .8rem;
color: var(--text-color);
@ -335,6 +336,9 @@ main:has(.not-found) {
border: 1px solid var(--border-color);
@include mixin.rounded(full);
padding: 0 .5rem;
position: absolute;
bottom: 1.5rem;
width: calc(100% - 3rem);
gap: .5rem;
align-items: center;
margin-top: 1rem;
@ -366,6 +370,7 @@ main:has(.not-found) {
&.ai.loading {
background-color: var(--primary-color);
color: var(--filled-text-color);
padding: 1.5rem;
svg {

View file

@ -1,3 +1,4 @@
import { setupChat } from "./chat";
import { checkImagePage } from "./images";
import { copyToClipboard, getFromClipboard } from "./utils";
@ -9,54 +10,57 @@ export function $$(selector: string) {
return document.querySelectorAll(selector);
}
function setupShareBtn() {
const shareBtn = $("#share-url-btn") as HTMLButtonElement;
if (!shareBtn) return;
shareBtn.addEventListener("click", function () {
const searchUrl = shareBtn.getAttribute("data-search-url");
if (!searchUrl) return;
copyToClipboard(searchUrl);
const copiedText = shareBtn.getAttribute("data-gitee-copied");
if (!copiedText) return;
shareBtn.setAttribute("tooltip", copiedText);
setTimeout(() => {
shareBtn.removeAttribute("tooltip");
}, 2000);
});
}
function setupPreferencesPage() {
// check for preferences hash
const hashInput = $("#preferences-hash") as HTMLInputElement;
if (!hashInput) return;
const copyBtn = $("#copy-preferences-hash") as HTMLButtonElement;
if (!copyBtn) return;
copyBtn.addEventListener("click", function () {
copyToClipboard(hashInput.value);
copyBtn.innerText = copyBtn.getAttribute("data-copied-text") as string;
setTimeout(() => {
copyBtn.innerText = copyBtn.getAttribute(
"data-copy-text"
) as string;
}, 2000);
});
const pasteBtn = $("#paste-preferences-hash") as HTMLButtonElement;
const pasteInput = $("#paste-preferences-hash-input") as HTMLInputElement;
if (!pasteBtn || !pasteInput) return;
pasteBtn.addEventListener("click", async function () {
const hash = await getFromClipboard();
pasteInput.value = hash;
});
}
checkImagePage();
function afterPageLoad() {
// preferences page
if ($("#preferences")) {
// check for preferences hash
const hashInput = $("#preferences-hash") as HTMLInputElement;
if (!hashInput) return;
const copyBtn = $("#copy-preferences-hash") as HTMLButtonElement;
if (!copyBtn) return;
copyBtn.addEventListener("click", function () {
copyToClipboard(hashInput.value);
copyBtn.innerText = copyBtn.getAttribute(
"data-copied-text"
) as string;
setTimeout(() => {
copyBtn.innerText = copyBtn.getAttribute(
"data-copy-text"
) as string;
}, 2000);
});
const pasteBtn = $("#paste-preferences-hash") as HTMLButtonElement;
const pasteInput = $(
"#paste-preferences-hash-input"
) as HTMLInputElement;
if (!pasteBtn || !pasteInput) return;
pasteBtn.addEventListener("click", async function () {
const hash = await getFromClipboard();
pasteInput.value = hash;
});
}
if ($("#preferences")) setupPreferencesPage();
// search page
if ($("#results")) {
const shareBtn = $("#share-url-btn") as HTMLButtonElement;
if (!shareBtn) return;
shareBtn.addEventListener("click", function () {
const searchUrl = shareBtn.getAttribute("data-search-url");
if (!searchUrl) return;
copyToClipboard(searchUrl);
const copiedText = shareBtn.getAttribute("data-gitee-copied");
if (!copiedText) return;
shareBtn.setAttribute("tooltip", copiedText);
setTimeout(() => {
shareBtn.removeAttribute("tooltip");
}, 2000);
});
}
if ($("#results")) setupShareBtn();
// chat
setupChat();
}
if (document.readyState === "loading") {

View file

@ -0,0 +1,103 @@
import { ChatCompletionMessageParam } from "openai/resources/index.mjs";
import { $ } from "./app";
import { OpenAI } from "openai";
let client: OpenAI;
let messages: ChatCompletionMessageParam[] = [
{
role: "system",
content:
"You are a Search Engine Assistant. You will answer questions about the search query.\
dont answer like previous message. try to summarize the answer little bit",
},
];
export function setupChat() {
const chatContainer = $("#ai-message-container") as HTMLDivElement;
if (!chatContainer) return;
const sendMessageForm = $("#send-message") as HTMLFormElement;
if (!sendMessageForm) return;
const messageInput = sendMessageForm.querySelector(
"input"
) as HTMLInputElement;
if (!messageInput) return;
const searchQuery = $("#search-query") as HTMLParagraphElement;
if (!searchQuery) return;
client = new OpenAI({
apiKey: "FAKE",
dangerouslyAllowBrowser: true,
baseURL: "https://openai.jabirproject.org/v1",
});
sendMessage(messageInput, chatContainer, searchQuery.innerText).then(() =>
chatContainer.classList.remove("loading")
);
sendMessageForm.addEventListener("submit", function (e) {
e.preventDefault();
sendMessage(messageInput, chatContainer);
});
}
function createMessage(
chatContainer: HTMLDivElement,
role: "user" | "ai",
refrence?: string
) {
const messageBox = document.createElement("div");
messageBox.classList.add("message-box");
messageBox.classList.add(role);
const messageElement = document.createElement("div");
messageElement.classList.add("message");
messageBox.appendChild(messageElement);
// TODO: improve this
if (refrence) {
const referenceElement = document.createElement("div");
referenceElement.classList.add("reference");
referenceElement.innerText = refrence;
messageBox.appendChild(referenceElement);
}
chatContainer.appendChild(messageBox);
return messageElement;
}
async function sendMessage(
messageInput: HTMLInputElement,
chatContainer: HTMLDivElement,
message?: string
) {
const userMessage = messageInput.value;
if (!userMessage && !message) return;
messages.push({
role: "user",
content: message || userMessage,
});
const stream = await client.chat.completions.create({
// @ts-ignore
model: "jabir-400b-online",
messages,
// do to some bugs right now i disabled it
// stream: true,
});
const messageElement = createMessage(chatContainer, "ai");
// for await (const chunk of stream) {
// const text = chunk.choices[0].delta.content || "";
// messageElement.innerText += text;
// }\
messageElement.innerText = stream.choices[0].message.content || "";
if (messageElement.innerText.length <= 0) {
messageElement.parentElement?.remove();
}
}

View file

@ -11,7 +11,7 @@
endif
%}
>
{% if favicon_resolver != "" %}
{% if favicon_resolver != "" and result.parsed_url.netloc %}
<div class="favicon">
<img
loading="lazy"
@ -44,8 +44,9 @@
<div class="result-meta">
<span class="result-url">
{{ result.parsed_url.netloc }}{{ result.parsed_url.path[:25] }} {%
if result.parsed_url.path|length > 25 %}... {% endif %}
{% if result.parsed_url.netloc %} {{ result.parsed_url.netloc }}{{
result.parsed_url.path[:25] }} {% if result.parsed_url.path|length >
25 %}... {% endif %} {% endif %}
</span>
<div class="engines">
{% for engine in result.engines %} {% if loop.index < 7 %}

View file

@ -27,8 +27,9 @@ block body %} {% include 'smart/madules/search_header.html' %}
</button>
</div>
<div class="user message-box">
<p class="message">{{ q|e }}</p>
<p class="message" id="search-query">{{ q|e }}</p>
</div>
{#
<div class="message-box">
<p class="message">temporary message</p>
<div class="reference">
@ -50,6 +51,7 @@ block body %} {% include 'smart/madules/search_header.html' %}
>
</div>
</div>
#}
<form class="send-message" id="send-message">
<input type="text" placeholder="{{ _('Ask Jabir anything...') }}" />
<button>{{ icon_small('send') }}</button>
@ -89,8 +91,8 @@ block body %} {% include 'smart/madules/search_header.html' %}
</div>
{%- endfor -%}
</div>
{% endif %} {% for result in results %} {% if result.open_group and not
is_image_page %}
{% endif %} {% if results %}{% for result in results %} {% if
result.open_group and not is_image_page %}
<div
class="{{ result['template']|replace('.html', '') }}_group result-group"
>
@ -99,7 +101,7 @@ block body %} {% include 'smart/madules/search_header.html' %}
result['template']) else get_result_template('smart', 'default.html') %}
{% include template %} {% if result.close_group and not is_image_page %}
</div>
{% endif %} {% endfor %}
{% endif %} {% endfor %} {% endif %}
</div>
<div class="info-panel">
{% if infoboxes %} {% include 'smart/madules/infoboxs.html' %} {% endif %}