chunk-match
Version:
NodeJS library that semantically chunks text and matches it against a user query using cosine similarity for precise and relevant text retrieval
956 lines (820 loc) • 17.6 kB
CSS
:root {
--primary-color: #009432;
--primary-color-hover: #007a28;
--background-color: #2f3640;
--container-bg: #242424;
--border-color: #333;
--text-color: #e0e0e0;
--text-color-muted: #ffffff76;
--section-bg: #2a2a2a;
--input-bg: #333;
--input-text: #e0e0e0;
--pre-bg: #1e1e1e;
--switch-bg: #444;
--font-primary: 'Open Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
--font-mono: 'Roboto Mono', monospace;
}
html * {
box-sizing: border-box;
}
body {
font-family: var(--font-primary);
line-height: 1.6;
margin: 0;
padding: 20px;
background-color: var(--background-color);
color: var(--text-color);
height: 100vh;
box-sizing: border-box;
overflow: hidden;
display: grid;
}
.container {
display: flex;
flex-direction: column;
height: calc(100vh - 40px);
background-color: var(--container-bg);
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
padding: 20px;
position: relative;
opacity: 0;
animation: fadeInContent 0.3s ease-out forwards;
width: min(1440px, 100%);
justify-self: center;
}
@keyframes fadeInContent {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
h1.title {
margin-top: -15px;
}
h1.title > a > #version {
font-size: 0.5em;
filter: brightness(0.7);
}
.subtitle {
font-size: 0.8em;
color: var(--text-color);
opacity: 0.8;
text-align: center;
margin-top: -5px;
margin-bottom: 10px;
}
.content-wrapper {
display: grid;
gap: 2rem;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
margin: 2rem 0 0;
min-height: 0;
}
/* media query for smaller screens */
/* stacked layout, hide top links */
@media screen and (max-width: 800px) {
body {
padding: 10px;
height: 170vh;
overflow-y: auto;
display: block;
}
.container {
height: calc(170vh - 20px);
}
.content-wrapper {
grid-template-columns: 1fr;
gap: 1rem;
/* Take up remaining space and split equally between children */
flex: 1;
display: flex;
flex-direction: column;
}
.form-wrapper, .results-wrapper {
flex: 1; /* Make both containers take equal space */
min-height: 0; /* Allow containers to shrink */
}
.form-content, .results-content {
padding: 15px;
}
.form-footer, .results-footer {
padding: 15px;
}
.equillabs-logo {
display: none;
}
.top-links {
display: none ;
}
#downloadButton {
font-size: 0; /* Hide the original text */
}
#downloadButton::after {
content: 'Download';
font-size: 16px; /* Restore font size for new text */
}
#processingTime {
display: none;
}
}
@media screen and (max-width: 1115px) {
#processingTime, #avgTokenLength {
display: none;
}
}
@media screen and (max-width: 1115px) and (min-width: 923px) {
#downloadButton {
font-size: 0; /* Hide the original text */
}
#downloadButton::after {
content: 'Download Results';
font-size: 16px; /* Restore font size for new text */
}
}
@media screen and (max-width: 923px) {
#downloadButton {
font-size: 0; /* Hide the original text */
}
#downloadButton::after {
content: 'Download';
font-size: 16px; /* Restore font size for new text */
}
}
.form-wrapper, .results-wrapper {
display: flex;
flex-direction: column;
background-color: var(--section-bg);
border-radius: 8px;
border: 1px solid var(--border-color);
overflow: hidden;
min-height: 0;
}
form {
display: flex;
flex-direction: column;
height: 100%;
}
.form-content, .results-content {
flex: 1;
display: flex;
flex-direction: column;
padding: 20px;
min-height: 0;
overflow: hidden;
user-select: none;
}
.form-content {
overflow-y: auto;
}
.form-content h2, .results-content h2 {
margin-top: 0;
margin-bottom: 20px;
flex-shrink: 0;
}
.form-footer, .results-footer {
padding: 20px;
background-color: var(--container-bg);
border-top: 1px solid var(--border-color);
}
.results-footer {
display: block; /* Always show footer */
background-color: var(--container-bg);
border-top: 1px solid var(--border-color);
}
.results-footer.visible {
display: block;
}
h1 {
margin: 0;
text-align: center;
}
h1 a {
color: var(--primary-color);
text-decoration: none;
transition: color 0.2s;
}
h1 a:hover {
color: var(--primary-color-hover);
}
h1, h2, h3 {
color: var(--primary-color);
}
.form-section {
margin-bottom: 30px;
padding-bottom: 20px;
border-bottom: 1px solid var(--border-color);
}
.form-section:last-child {
margin-bottom: 0;
padding-bottom: 0;
border-bottom: none;
}
.form-section h3 {
margin-top: 0;
margin-bottom: 20px;
color: var(--primary-color);
}
.form-group {
margin-bottom: 20px;
}
.form-group:last-child {
margin-bottom: 0;
}
.form-row {
display: flex;
gap: 20px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: 500;
color: var(--text-color);
}
label.sub-label {
margin-top: -7px;
font-size: 0.8em;
color: var(--text-color);
opacity: 0.8;
}
textarea, select, input[type="text"] {
width: 100%;
padding: 10px;
background-color: var(--input-bg);
border: 1px solid var(--border-color);
border-radius: 4px;
color: var(--input-text);
}
textarea {
width: 100%;
min-height: 200px;
resize: vertical;
background-color: var(--input-bg);
color: var(--input-text);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 10px;
font-family: var(--font-mono);
margin-top: 8px;
}
textarea#query {
min-height: 35px;
max-height: 70px;
}
textarea:focus, select:focus, input[type="text"]:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 2px rgba(33, 150, 243, 0.2);
}
input[type="range"] {
width: 100%;
margin: 10px 0;
background: var(--input-bg);
height: 6px;
border-radius: 3px;
-webkit-appearance: none;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 18px;
height: 18px;
background: var(--primary-color);
border-radius: 50%;
cursor: pointer;
}
.value-display {
display: flex;
align-items: center;
gap: 8px;
}
.value-display .number {
min-width: 40px;
}
.value-display .description {
font-size: 0.85em;
font-style: italic;
}
/* Similarity level colors */
.similarity-low { color: #ff6b6b; }
.similarity-moderate { color: #ffd93d; }
.similarity-high { color: #6bff84; }
/* Precision level colors */
.precision-full { color: #4CAF50; }
.precision-half { color: #2196F3; }
.precision-q8 { color: #FF9800; }
.precision-q4 { color: #f44336; }
/* Switch styling */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--switch-bg);
transition: .4s;
border-radius: 34px;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: var(--text-color);
transition: .4s;
border-radius: 50%;
}
input:checked + .slider {
background-color: var(--primary-color);
}
input:checked + .slider:before {
transform: translateX(26px);
}
select {
width: 100%;
padding: 8px 12px;
background-color: var(--input-bg);
border: 1px solid var(--border-color);
border-radius: 4px;
color: var(--input-text);
font-size: 14px;
cursor: pointer;
}
select:focus {
outline: none;
border-color: var(--primary-color);
}
select option {
background-color: var(--container-bg);
color: var(--text-color);
padding: 8px;
}
button {
background-color: var(--primary-color);
color: white;
padding: 12px 24px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
width: 100%;
transition: background-color 0.2s;
}
button:hover {
background-color: var(--primary-color-hover);
}
button:disabled {
opacity: 0.5;
cursor: not-allowed;
background-color: var(--section-bg);
}
button:disabled:hover {
background-color: var(--section-bg);
}
.results-container {
display: flex;
flex-direction: column;
height: 100%;
margin: 0;
padding: 0;
}
.results-container.hidden {
display: none;
}
.label-with-info {
display: flex;
align-items: center;
gap: 8px;
}
.info-icon {
cursor: pointer;
color: var(--primary-color);
opacity: 0.7;
transition: opacity 0.2s;
font-size: 18px;
position: relative;
top: -2px;
}
.info-icon:hover {
opacity: 1;
}
pre {
margin: 0;
background-color: var(--pre-bg);
padding: 15px;
border-radius: 4px;
overflow-y: auto;
white-space: pre-wrap;
color: var(--text-color);
border: 1px solid var(--border-color);
flex: 1;
font-family: var(--font-mono);
}
/* Scrollbar styling */
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-track {
background: var(--container-bg);
}
::-webkit-scrollbar-thumb {
background: var(--primary-color);
border-radius: 5px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--primary-color-hover);
}
/* spinner styles */
.spinner {
display: none;
justify-content: center;
align-items: center;
height: 100%;
}
.spinner::after {
content: '';
width: 50px;
height: 50px;
border: 4px solid var(--border-color);
border-top: 4px solid var(--primary-color);
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.spinner.visible {
display: flex;
}
:not(.form-section).depends-on-combine-chunks {
max-height: 1000px; /* Large enough to contain content */
opacity: 1;
margin: inherit;
padding: inherit;
transition: all 0.3s ease;
overflow: hidden;
}
:not(.form-section).depends-on-combine-chunks.hidden {
max-height: 0;
opacity: 0;
margin: 0;
padding: 0;
}
.white-space--nowrap {
white-space: nowrap;
}
.results-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
flex-shrink: 0;
}
.results-header h2 {
margin: 0;
}
.results-stats {
display: flex;
gap: 15px;
font-size: 0.75em;
color: var(--text-color);
opacity: 0.8;
align-items: center;
}
.results-stats span {
padding: 4px 8px;
background: var(--container-bg);
border-radius: 4px;
white-space: nowrap;
}
.document-name-group {
margin-bottom: 20px;
}
.input-with-buttons {
display: flex;
gap: 10px;
align-items: center;
}
.document-buttons {
display: flex;
gap: 5px;
}
.secondary-button {
position: relative;
padding: 6px 12px;
background: var(--section-bg);
border: 1px solid var(--border-color);
border-radius: 4px;
color: var(--text-color);
cursor: pointer;
font-size: 0.9em;
white-space: nowrap;
opacity: 0.1;
transition: opacity 0.2s;
}
.secondary-button:hover {
background: var(--container-bg);
opacity: 1;
}
.secondary-button::after {
content: attr(data-tooltip);
position: absolute;
bottom: calc(100% + 5px);
left: 50%;
transform: translateX(-50%);
padding: 4px 8px;
background-color: var(--container-bg);
color: var(--text-color);
font-size: 0.8em;
border-radius: 4px;
white-space: nowrap;
opacity: 0;
visibility: hidden;
transition: opacity 0.2s, visibility 0.2s;
border: 1px solid var(--border-color);
z-index: 1000;
width: max-content;
max-width: 200px;
white-space: normal;
text-align: center;
}
/* Ensure tooltip stays within viewport */
.secondary-button:hover::after {
opacity: 1;
visibility: visible;
/* Adjust position if tooltip would overflow container */
left: 50%;
transform: translateX(-50%);
right: auto;
}
/* Special handling for rightmost button */
.document-buttons .secondary-button:last-child::after {
left: auto;
right: 0;
transform: none;
}
.button-group {
display: flex;
gap: 10px;
}
.button-group button {
flex: 1;
}
.modal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
overflow: hidden;
}
.modal-content {
background-color: var(--container-bg);
margin: 2vh auto;
padding: 20px;
border: 1px solid var(--border-color);
border-radius: 8px;
width: 90%;
max-width: 1000px;
max-height: 96vh;
position: relative;
display: flex;
flex-direction: column;
overflow: hidden;
user-select: none;
}
.modal-content h2 {
margin: 0 0 20px 0;
padding-right: 30px;
}
.close {
position: absolute;
right: 20px;
top: 20px;
color: var(--text-color);
font-size: 28px;
font-weight: bold;
cursor: pointer;
line-height: 1;
}
.close:hover {
color: var(--primary-color);
}
#codeExample {
margin: 0;
padding: 15px;
background-color: var(--pre-bg);
border: 1px solid var(--border-color);
border-radius: 4px;
overflow-y: auto;
flex: 1;
min-height: 0; /* Allow flex item to shrink */
font-family: var(--font-mono);
user-select: text;
white-space: pre;
}
.modal-footer {
display: flex;
gap: 10px;
margin-top: 20px;
}
.modal-footer .button-group {
flex: 1;
}
.modal-footer button {
flex: 1;
min-width: 100px;
}
.default-message {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
color: var(--text-color-muted);
text-align: center;
padding: 20px;
}
.default-message a {
color: var(--primary-color);
text-decoration: none;
}
#resultsJson {
display: none; /* Hide by default */
user-select: text;
}
/* Update toast styles */
.toast-container {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 2000;
display: none; /* Hide by default */
align-items: center;
justify-content: center;
}
/* Add blur effect only when toast container is visible */
.toast-container.visible {
display: flex;
background-color: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(4px);
}
.toast {
background-color: var(--container-bg);
color: var(--text-color);
padding: 16px 32px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
display: flex;
align-items: center;
border: 1px solid var(--border-color);
animation: fadeIn 0.3s ease-out forwards;
font-size: 1.1em;
max-width: 80%;
text-align: center;
}
.toast.error {
border-left: 4px solid #ff4444;
}
.toast.success {
border-left: 4px solid #00C851;
}
.toast.info {
border-left: 4px solid var(--primary-color);
}
@keyframes fadeIn {
from {
opacity: 0;
transform: scale(0.9);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes fadeOut {
from {
opacity: 1;
transform: scale(1);
}
to {
opacity: 0;
transform: scale(0.9);
}
}
.equillabs-logo {
position: absolute;
top: 25px;
left: 20px;
}
.equillabs-logo img {
height: 20px;
}
.top-links {
position: absolute;
top: 15px;
right: 20px;
display: flex;
gap: 3px;
flex-direction: column;
align-items: flex-end;
}
.top-link {
color: var(--text-color);
text-decoration: none;
opacity: 0.7;
transition: opacity 0.2s;
display: flex;
align-items: center;
gap: 8px;
font-size: 14px;
z-index: 1;
}
.top-link svg {
transition: all 0.2s ease-in-out;
}
.top-link:hover {
opacity: 1;
}
.top-link.-github:hover svg {
fill: #0984e3;
transform: scale(1.1);
}
.top-link.-support:hover svg {
fill: #fd79a8;
transform: scale(1.3);
}
.top-link svg {
width: 20px;
height: 20px;
fill: currentColor;
}
.container {
position: relative;
}
#resultsJson code {
font-family: var(--font-mono);
background: transparent;
padding: 0;
}
.hljs {
background: var(--pre-bg) ;
color: var(--text-color) ;
}
.resize-toggle {
background: var(--primary-color);
border: none;
width: 28px;
height: 28px;
border-radius: 4px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
margin-left: 8px;
transition: background-color 0.2s;
padding: 0;
}
.resize-toggle:hover {
background-color: var(--primary-color-hover);
}
.resize-toggle svg {
width: 20px;
height: 20px;
transition: transform 0.2s;
}
.resize-toggle.wrapped svg {
transform: rotate(90deg);
}
.resize-toggle svg path {
stroke-width: 1.5;
}
#resultsJson {
white-space: pre;
transition: white-space 0s;
}
#resultsJson.wrapped {
white-space: pre-wrap;
}