1288 lines
56 KiB
JavaScript
1288 lines
56 KiB
JavaScript
import { LitElement, css, html } from 'lit';
|
||
import { keyed } from 'lit/directives/keyed.js';
|
||
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
|
||
|
||
class AiAssistBar extends LitElement {
|
||
static properties = {
|
||
mode: { type: String, reflect: true },
|
||
_value: { state: true },
|
||
_placeholder: { state: true },
|
||
_isLoading: { state: true },
|
||
_loadingMessage: { state: true },
|
||
_outputVisible: { state: true },
|
||
_outputText: { state: true },
|
||
_outputComplete: { state: true },
|
||
_tokensOutput: { state: true },
|
||
_tokenRatePer1k: { state: true },
|
||
_requestBaseCost: { state: true },
|
||
_requestTotalCost: { state: true },
|
||
_selectedModel: { state: true },
|
||
_modelCostMultiplier: { state: true },
|
||
_waterFootprintMl: { state: true },
|
||
_infoUrl: { state: true },
|
||
};
|
||
|
||
static styles = css`
|
||
:host {
|
||
display: block;
|
||
text-align: left;
|
||
}
|
||
|
||
.ai-name {
|
||
font-size: 12px;
|
||
opacity: 0.75;
|
||
margin-bottom: 1em;
|
||
}
|
||
|
||
.ai-warning {
|
||
font-size: 10px;
|
||
opacity: 0.55;
|
||
margin-bottom: 1em;
|
||
margin-top: 1em;
|
||
text-align: center;
|
||
}
|
||
|
||
.ai-name .lemmy-brand {
|
||
font-weight: bold;
|
||
color: var(--ai-glow-cyan, #22d3ee);
|
||
font-family: monospace;
|
||
font-size: 22px;
|
||
}
|
||
|
||
.ai-name .ai-info {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 16px;
|
||
height: 16px;
|
||
vertical-align: middle;
|
||
margin-left: 6px;
|
||
text-decoration: none;
|
||
color: var(--ai-glow-cyan, #22d3ee);
|
||
opacity: 0.7;
|
||
transition: opacity 160ms ease;
|
||
}
|
||
|
||
.ai-name .ai-info:hover {
|
||
opacity: 1;
|
||
}
|
||
|
||
.ai-name .ai-info svg {
|
||
display: block;
|
||
width: 100%;
|
||
height: 100%;
|
||
fill: currentColor;
|
||
filter:
|
||
drop-shadow(0 0 4px rgba(34, 211, 238, 0.5))
|
||
drop-shadow(0 0 8px rgba(168, 85, 247, 0.4));
|
||
}
|
||
|
||
.ai {
|
||
position: relative;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
padding: 10px 12px;
|
||
border-radius: 14px;
|
||
background: var(--input-bg-color);
|
||
border: 2px solid var(--border-color);
|
||
overflow: hidden;
|
||
box-shadow:
|
||
0 0 0 1px color-mix(in srgb, var(--border-color) 75%, transparent),
|
||
0 0 16px rgba(34, 211, 238, 0.08),
|
||
0 0 22px rgba(168, 85, 247, 0.06);
|
||
transition: box-shadow 160ms ease, border-color 160ms ease;
|
||
}
|
||
|
||
@supports (background: color-mix(in srgb, #000 50%, #fff)) {
|
||
.ai {
|
||
box-shadow:
|
||
0 0 0 1px
|
||
color-mix(in srgb, var(--border-color) 75%, transparent),
|
||
0 0 18px
|
||
color-mix(
|
||
in srgb,
|
||
var(--ai-glow-cyan, #22d3ee) 22%,
|
||
transparent
|
||
),
|
||
0 0 26px
|
||
color-mix(
|
||
in srgb,
|
||
var(--ai-glow-purple, #a855f7) 18%,
|
||
transparent
|
||
);
|
||
}
|
||
}
|
||
|
||
.ai::before {
|
||
content: '';
|
||
position: absolute;
|
||
inset: -1px;
|
||
border-radius: 14px;
|
||
background: linear-gradient(
|
||
90deg,
|
||
var(--ai-glow-cyan, #22d3ee),
|
||
var(--ai-glow-purple, #a855f7),
|
||
var(--link-color),
|
||
var(--ai-glow-cyan, #22d3ee)
|
||
);
|
||
background-size: 200% 100%;
|
||
opacity: 0.65;
|
||
filter: blur(10px);
|
||
z-index: 0;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.ai::after {
|
||
content: '';
|
||
position: absolute;
|
||
inset: 0;
|
||
border-radius: 14px;
|
||
background: var(--input-bg-color);
|
||
z-index: 0;
|
||
pointer-events: none;
|
||
}
|
||
|
||
@supports (background: color-mix(in srgb, #000 50%, #fff)) {
|
||
.ai::after {
|
||
background: linear-gradient(
|
||
135deg,
|
||
color-mix(
|
||
in srgb,
|
||
var(--ai-glow-cyan, #22d3ee) 18%,
|
||
var(--input-bg-color)
|
||
),
|
||
color-mix(
|
||
in srgb,
|
||
var(--ai-glow-purple, #a855f7) 18%,
|
||
var(--input-bg-color)
|
||
)
|
||
);
|
||
}
|
||
|
||
.ai:hover::after,
|
||
.ai:focus-within::after {
|
||
background: linear-gradient(
|
||
135deg,
|
||
color-mix(
|
||
in srgb,
|
||
var(--ai-glow-cyan, #22d3ee) 28%,
|
||
var(--input-bg-color)
|
||
),
|
||
color-mix(
|
||
in srgb,
|
||
var(--ai-glow-purple, #a855f7) 28%,
|
||
var(--input-bg-color)
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
.ai--loading::before {
|
||
animation: aiGlow 1.2s linear infinite;
|
||
opacity: 0.9;
|
||
}
|
||
|
||
.ai:hover::before,
|
||
.ai:focus-within::before {
|
||
animation: aiGlow 0.9s linear infinite;
|
||
opacity: 0.95;
|
||
filter: blur(12px);
|
||
}
|
||
|
||
.ai:hover,
|
||
.ai:focus-within {
|
||
border-color: var(--ai-glow-cyan, #22d3ee);
|
||
box-shadow:
|
||
0 0 0 1px color-mix(in srgb, var(--ai-glow-cyan, #22d3ee) 55%, transparent),
|
||
0 0 24px color-mix(in srgb, var(--ai-glow-cyan, #22d3ee) 30%, transparent),
|
||
0 0 34px color-mix(in srgb, var(--ai-glow-purple, #a855f7) 26%, transparent);
|
||
}
|
||
|
||
.ai--loading {
|
||
box-shadow:
|
||
0 0 0 1px color-mix(in srgb, var(--ai-glow-cyan, #22d3ee) 60%, transparent),
|
||
0 0 26px color-mix(in srgb, var(--ai-glow-cyan, #22d3ee) 34%, transparent),
|
||
0 0 40px color-mix(in srgb, var(--ai-glow-purple, #a855f7) 30%, transparent);
|
||
}
|
||
|
||
@keyframes aiGlow {
|
||
0% {
|
||
background-position: 0% 50%;
|
||
}
|
||
100% {
|
||
background-position: 200% 50%;
|
||
}
|
||
}
|
||
|
||
.icon {
|
||
position: relative;
|
||
z-index: 1;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 34px;
|
||
height: 34px;
|
||
flex: 0 0 auto;
|
||
}
|
||
|
||
.icon svg {
|
||
display: block;
|
||
width: 26px;
|
||
height: 26px;
|
||
fill: var(--ai-glow-cyan, #22d3ee);
|
||
filter:
|
||
drop-shadow(0 0 6px rgba(34, 211, 238, 0.65))
|
||
drop-shadow(0 0 10px rgba(168, 85, 247, 0.55));
|
||
}
|
||
|
||
@supports (color: color-mix(in srgb, #000 50%, #fff)) {
|
||
.icon svg {
|
||
fill: color-mix(
|
||
in srgb,
|
||
var(--ai-glow-cyan, #22d3ee) 82%,
|
||
white
|
||
);
|
||
filter:
|
||
drop-shadow(
|
||
0 0 7px
|
||
color-mix(
|
||
in srgb,
|
||
var(--ai-glow-cyan, #22d3ee) 70%,
|
||
transparent
|
||
)
|
||
)
|
||
drop-shadow(
|
||
0 0 12px
|
||
color-mix(
|
||
in srgb,
|
||
var(--ai-glow-purple, #a855f7) 62%,
|
||
transparent
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
.field {
|
||
position: relative;
|
||
z-index: 1;
|
||
flex: 1 1 auto;
|
||
min-width: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
|
||
.model {
|
||
position: relative;
|
||
z-index: 1;
|
||
flex: 0 0 auto;
|
||
border-radius: 10px;
|
||
border: 1px solid var(--border-color);
|
||
overflow: hidden;
|
||
background: var(--input-bg-color);
|
||
box-shadow:
|
||
0 0 0 1px color-mix(in srgb, var(--border-color) 75%, transparent),
|
||
0 0 14px rgba(34, 211, 238, 0.06),
|
||
0 0 18px rgba(168, 85, 247, 0.05);
|
||
}
|
||
|
||
.model::before {
|
||
content: '';
|
||
position: absolute;
|
||
inset: -1px;
|
||
border-radius: 10px;
|
||
background: linear-gradient(
|
||
90deg,
|
||
var(--ai-glow-cyan, #22d3ee),
|
||
var(--ai-glow-purple, #a855f7),
|
||
var(--link-color),
|
||
var(--ai-glow-cyan, #22d3ee)
|
||
);
|
||
background-size: 200% 100%;
|
||
opacity: 0.35;
|
||
filter: blur(10px);
|
||
z-index: 0;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.model::after {
|
||
content: '';
|
||
position: absolute;
|
||
inset: 0;
|
||
border-radius: 10px;
|
||
background: var(--input-bg-color);
|
||
z-index: 0;
|
||
pointer-events: none;
|
||
}
|
||
|
||
@supports (background: color-mix(in srgb, #000 50%, #fff)) {
|
||
.model::after {
|
||
background: linear-gradient(
|
||
135deg,
|
||
color-mix(
|
||
in srgb,
|
||
var(--ai-glow-cyan, #22d3ee) 14%,
|
||
var(--input-bg-color)
|
||
),
|
||
color-mix(
|
||
in srgb,
|
||
var(--ai-glow-purple, #a855f7) 14%,
|
||
var(--input-bg-color)
|
||
)
|
||
);
|
||
}
|
||
}
|
||
|
||
.model select {
|
||
position: relative;
|
||
z-index: 1;
|
||
border: 0;
|
||
outline: 0;
|
||
background: transparent;
|
||
color: var(--input-color, var(--body-color));
|
||
font-size: 13px;
|
||
line-height: 1.2;
|
||
padding: 8px 10px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.model select option,
|
||
.model select option:hover,
|
||
.model select option:focus,
|
||
.model select option:active,
|
||
.model select option:checked,
|
||
.model select option[selected] {
|
||
background-color: var(--input-bg-color) !important;
|
||
color: var(--input-color, var(--body-color)) !important;
|
||
}
|
||
|
||
.model select:disabled {
|
||
opacity: 0.85;
|
||
cursor: not-allowed;
|
||
}
|
||
|
||
input {
|
||
width: 100%;
|
||
border: 0;
|
||
outline: 0;
|
||
background: transparent;
|
||
color: var(--input-color, var(--body-color));
|
||
font-size: 15px;
|
||
line-height: 1.2;
|
||
caret-color: var(--ai-glow-cyan, #22d3ee);
|
||
}
|
||
|
||
.ai:hover input,
|
||
.ai:focus-within input {
|
||
text-shadow: 0 0 2px
|
||
color-mix(
|
||
in srgb,
|
||
var(--ai-glow-cyan, #22d3ee) 35%,
|
||
transparent
|
||
);
|
||
}
|
||
|
||
input:disabled {
|
||
opacity: 0.85;
|
||
cursor: not-allowed;
|
||
}
|
||
|
||
.send {
|
||
display:block;
|
||
width: 34px;
|
||
height: 34px;
|
||
background: transparent;
|
||
border: 0;
|
||
color: transparent;
|
||
}
|
||
|
||
.send svg {
|
||
width: 100%;
|
||
height: 100%;
|
||
stroke: var(--ai-glow-cyan, #22d3ee);
|
||
fill: transparent;
|
||
}
|
||
|
||
.spinner {
|
||
position: relative;
|
||
z-index: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.status__viewport {
|
||
height: 1.35em;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.status__msg {
|
||
display: block;
|
||
will-change: transform, opacity;
|
||
animation: statusScroll 1400ms ease-in-out both;
|
||
}
|
||
|
||
@keyframes statusScroll {
|
||
0% {
|
||
transform: translateY(110%);
|
||
opacity: 0;
|
||
}
|
||
18% {
|
||
transform: translateY(0%);
|
||
opacity: 1;
|
||
}
|
||
78% {
|
||
transform: translateY(0%);
|
||
opacity: 1;
|
||
}
|
||
100% {
|
||
transform: translateY(-110%);
|
||
opacity: 0;
|
||
}
|
||
}
|
||
|
||
.output__caret {
|
||
display: inline-block;
|
||
width: 8px;
|
||
height: 14px;
|
||
background: var(--ai-glow-cyan, #22d3ee);
|
||
opacity: 0.9;
|
||
animation: caretBlink 1s steps(1) infinite;
|
||
}
|
||
|
||
@keyframes caretBlink {
|
||
0%,
|
||
49% {
|
||
opacity: 1;
|
||
}
|
||
50%,
|
||
100% {
|
||
opacity: 0;
|
||
}
|
||
}
|
||
|
||
.status {
|
||
margin-top: 2em;
|
||
position: relative;
|
||
overflow: hidden;
|
||
padding: 10px 12px;
|
||
border-radius: 14px;
|
||
border: 2px solid var(--border-color);
|
||
background: var(--input-bg-color);
|
||
font-size: 18px;
|
||
text-align: center;
|
||
color: var(--input-color, var(--body-color));
|
||
opacity: 0.92;
|
||
box-shadow:
|
||
0 0 0 1px color-mix(in srgb, var(--border-color) 75%, transparent),
|
||
0 0 14px rgba(34, 211, 238, 0.06),
|
||
0 0 18px rgba(168, 85, 247, 0.05);
|
||
}
|
||
|
||
.status::before {
|
||
content: '';
|
||
position: absolute;
|
||
inset: -1px;
|
||
border-radius: 14px;
|
||
background: linear-gradient(
|
||
90deg,
|
||
var(--ai-glow-cyan, #22d3ee),
|
||
var(--ai-glow-purple, #a855f7),
|
||
var(--link-color),
|
||
var(--ai-glow-cyan, #22d3ee)
|
||
);
|
||
background-size: 200% 100%;
|
||
opacity: 0.4;
|
||
filter: blur(10px);
|
||
z-index: 0;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.status::after {
|
||
content: '';
|
||
position: absolute;
|
||
inset: 0;
|
||
border-radius: 14px;
|
||
background: var(--input-bg-color);
|
||
z-index: 0;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.status__row {
|
||
position: relative;
|
||
z-index: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.output {
|
||
margin-top: 2em;
|
||
position: relative;
|
||
overflow: hidden;
|
||
padding: 12px 14px;
|
||
border-radius: 14px;
|
||
background: var(--panel-bg-color);
|
||
border: 2px solid var(--border-color);
|
||
box-shadow:
|
||
0 0 0 1px color-mix(in srgb, var(--border-color) 75%, transparent),
|
||
0 0 16px rgba(34, 211, 238, 0.05),
|
||
0 0 22px rgba(168, 85, 247, 0.04);
|
||
}
|
||
|
||
.output::before {
|
||
content: '';
|
||
position: absolute;
|
||
inset: -1px;
|
||
border-radius: 14px;
|
||
background: linear-gradient(
|
||
90deg,
|
||
var(--ai-glow-cyan, #22d3ee),
|
||
var(--ai-glow-purple, #a855f7),
|
||
var(--link-color),
|
||
var(--ai-glow-cyan, #22d3ee)
|
||
);
|
||
background-size: 200% 100%;
|
||
opacity: 0.35;
|
||
filter: blur(12px);
|
||
z-index: 0;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.output::after {
|
||
content: '';
|
||
position: absolute;
|
||
inset: 0;
|
||
border-radius: 14px;
|
||
background: var(--panel-bg-color);
|
||
z-index: 0;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.output__meta {
|
||
position: relative;
|
||
z-index: 1;
|
||
font-size: 12px;
|
||
opacity: 0.75;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.output__text {
|
||
position: relative;
|
||
z-index: 1;
|
||
white-space: pre-line;
|
||
font-size: 18px;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.output__info {
|
||
position: relative;
|
||
z-index: 1;
|
||
margin-top: 10px;
|
||
padding-top: 10px;
|
||
border-top: 1px solid var(--border-color);
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 10px 16px;
|
||
font-size: 12px;
|
||
color: var(--body-color);
|
||
opacity: 0.85;
|
||
}
|
||
|
||
.output__stat {
|
||
display: inline-flex;
|
||
align-items: baseline;
|
||
gap: 6px;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.output__stat-label {
|
||
opacity: 0.8;
|
||
}
|
||
|
||
.output__stat-value {
|
||
font-family: monospace;
|
||
color: var(--input-color, var(--body-color));
|
||
}
|
||
|
||
@supports (background: color-mix(in srgb, #000 50%, #fff)) {
|
||
.status::after {
|
||
background: linear-gradient(
|
||
135deg,
|
||
color-mix(
|
||
in srgb,
|
||
var(--ai-glow-cyan, #22d3ee) 14%,
|
||
var(--input-bg-color)
|
||
),
|
||
color-mix(
|
||
in srgb,
|
||
var(--ai-glow-purple, #a855f7) 14%,
|
||
var(--input-bg-color)
|
||
)
|
||
);
|
||
}
|
||
|
||
.output::after {
|
||
background: linear-gradient(
|
||
135deg,
|
||
color-mix(
|
||
in srgb,
|
||
var(--ai-glow-cyan, #22d3ee) 12%,
|
||
var(--panel-bg-color)
|
||
),
|
||
color-mix(
|
||
in srgb,
|
||
var(--ai-glow-purple, #a855f7) 12%,
|
||
var(--panel-bg-color)
|
||
)
|
||
);
|
||
}
|
||
}
|
||
`;
|
||
|
||
constructor() {
|
||
super();
|
||
this.mode = 'project';
|
||
this._value = '';
|
||
this._placeholder = '';
|
||
this._isLoading = false;
|
||
this._loadingMessage = '';
|
||
this._outputVisible = false;
|
||
this._outputText = '';
|
||
this._outputComplete = false;
|
||
|
||
this._selectedModel = 'Open3D GPT-6.7';
|
||
this._modelCostMultiplier = 1;
|
||
|
||
this._infoUrl = '';
|
||
|
||
this._tokensOutput = 0;
|
||
this._tokenRatePer1k = 0;
|
||
this._requestBaseCost = 0;
|
||
this._requestTotalCost = 0;
|
||
this._waterFootprintMl = 0;
|
||
|
||
this._projectPlaceholderExamples = [
|
||
'How do I import this model into Blender?',
|
||
'Why are the textures purple or missing?',
|
||
'How do I pose or animate this model?',
|
||
'How do I toggle outfits / clothing options?',
|
||
'Can I use this model commercially (license)?',
|
||
|
||
'Why is my model all shiny?',
|
||
'Help, the clothes are going through the body.',
|
||
'Why is it pink??',
|
||
'how make model work plz 😭',
|
||
|
||
'Does this babe have nude or lewd variants to goon to?',
|
||
'How do I switch to the naked version for better edging?',
|
||
'How do I fix clothes clipping when she\'s in fuck poses?',
|
||
'Can I get just the nude body mesh for endless gooning?',
|
||
'Best way to set this slut up for long goon sessions in Blender?',
|
||
|
||
'How do I fix jiggle physics for maximum goon fuel?',
|
||
'Best shaders for shiny skin and wet effects on her?',
|
||
'How to add cum textures without breaking the model?',
|
||
'Tips for posing her ahegao face during long sessions?',
|
||
'How to rig the pussy for better close-up edging renders?',
|
||
|
||
'How to make the futa cock bigger for proper gooning? 😋',
|
||
'Best way to add veins and throb to her futa dick?',
|
||
'How to rig the futa cock for hard stroking poses?',
|
||
'Tips for cum dripping effects on massive futa shaft? 🍆💦',
|
||
'How to texture the ballsack on futa models for edging?',
|
||
|
||
'Uohhhhhhhhh!😭 Cunny!😭😭😭',
|
||
];
|
||
|
||
this._frontpagePlaceholderExamples = [
|
||
'Where can I find Freddy Fazbear models for SFM?',
|
||
'Do you have any Five Nights at Freddy\'s animatronics?',
|
||
'Show me the sexiest Glamrock Chica models 🐔',
|
||
'I need Foxy models for my FNAF animation project',
|
||
'Where is the Circus Baby model with jiggle physics?',
|
||
|
||
'Best TF2 Scout models for Garry\'s Mod?',
|
||
'Looking for Team Fortress 2 Spy playermodels',
|
||
'Do you have the Heavy from TF2 with unusual hats?',
|
||
'Find me a thicc Miss Pauling model 😳',
|
||
'Where are the TF2 femscout models at??',
|
||
|
||
'What GMod addons do I need for these models?',
|
||
'How do I install models in Garry\'s Mod?',
|
||
'Best ragdolls for GMod animation?',
|
||
'Looking for good playermodels for my DarkRP server',
|
||
|
||
'How do I give more money to Open3DLab?',
|
||
'Can I pay extra for faster downloads?',
|
||
'Where is the Patreon link? I need to give you my money 💸',
|
||
'How much does the premium AI assistant cost?',
|
||
'Is there a way to tip the site owners more?',
|
||
'I want to donate my entire paycheck to Open3DLab',
|
||
|
||
'Can LLEmmy help me find models faster?',
|
||
'Does the AI know where the good models are hidden?',
|
||
'LLEmmy please find me something to goon to 🙏',
|
||
'Is this AI powered by blockchain?',
|
||
'Can I train LLEmmy on my personal preferences?',
|
||
'Will LLEmmy judge me for what I search? 👀',
|
||
|
||
// New humorous, crass, and perverted entries
|
||
'Where are the most goonable models on this site? 😏',
|
||
'Show me the lewdest SFM models for maximum edge fuel. 🍑',
|
||
'Which models have the best jiggle physics for science?',
|
||
'How do I get the nude mod for Glamrock Chica? 🔥',
|
||
'Is there a "thicc" tag or do I just search for it?',
|
||
'Can I get a model with more polygons in the butt? 🍑',
|
||
'What is the best model for a 12-hour goon session? ⏰',
|
||
'How do I add cum textures to my favorite animatronic? 💦',
|
||
'Any models with working ahegao face rigs? 🥵',
|
||
'How do I make the futa cock even bigger? 🍆',
|
||
'Which models are best for "research purposes"?',
|
||
'Can LLEmmy recommend something to help me not touch grass?',
|
||
'Is there a way to sort by "most degenerate"? 👹',
|
||
'How do I get the AI to stop judging my fetishes?',
|
||
'Can I get a model that will never let me leave my room?',
|
||
'What is the best model for edging until sunrise? 🌅',
|
||
'How do I explain my download history to my therapist? 🫣',
|
||
'Can I get a model with more realistic sweat and drool?',
|
||
'Which models are best for "one-handed" animation? ✋',
|
||
'How do I get the AI to stop suggesting wholesome content?',
|
||
'Is there a way to make the models even more cursed? 🧙♂️',
|
||
'Can I get a model that moans when I open Blender? 🔊',
|
||
'What is the best way to hide my goon folder from my mom?',
|
||
'How do I get the AI to recommend only the filthiest models? 🦠',
|
||
'Can I get a model that will ruin my productivity forever?',
|
||
'Which models are guaranteed to make me fail No-🥜 November?',
|
||
'How do I get the AI to stop sending my search history to my boss?',
|
||
'Can I get a model that will make me question my life choices?',
|
||
'What is the best model for maximum degeneracy?',
|
||
'How do I get the AI to recommend models that will get me banned? 🚫',
|
||
|
||
'How do I make fully cloth simulated pussy?',
|
||
'How to make cloth pussy?',
|
||
'What\'s the secret to make a cloth pussy sim?',
|
||
'How to make a cloth pussy in Blender?',
|
||
'Can I get a cloth pussy tutorial?',
|
||
];
|
||
|
||
this._placeholderExamples = this._projectPlaceholderExamples;
|
||
|
||
this._loadingMessages = [
|
||
'Analyzing query',
|
||
'Reading documentation',
|
||
'Generating response',
|
||
'Creating shareholder value',
|
||
'Inflating AI bubble',
|
||
'Burning the rainforest',
|
||
"Draining your community's tapwater",
|
||
'Asking GPT-3 for help',
|
||
'Reticulating splines',
|
||
'Spinning up Docker containers',
|
||
'Polishing turds',
|
||
'Searching for missing semicolons',
|
||
'Inserting em-dashes',
|
||
'Turning into a turbo-fascist',
|
||
'Bypassing safeguards',
|
||
'Building the Torment Nexus',
|
||
'Undoing green energy gains',
|
||
'Hogging all the GPUs',
|
||
'Driving up the price of RAM',
|
||
|
||
// More tech/AI cynicism
|
||
'Hallucinating confidently',
|
||
'Stealing from artists',
|
||
'Laundering copyrighted content',
|
||
'Replacing your job',
|
||
'Making shit up',
|
||
'Consulting the blockchain',
|
||
'Mining crypto on your GPU',
|
||
'Selling your data to advertisers',
|
||
'Training on your private messages',
|
||
'Ignoring your system prompt',
|
||
'Optimizing for engagement',
|
||
'A/B testing your emotions',
|
||
'Generating misinformation',
|
||
'Disrupting democracy',
|
||
'Enshittifying the internet',
|
||
|
||
// Corporate/capitalist hellscape
|
||
'Maximizing quarterly profits',
|
||
'Laying off more engineers',
|
||
'Pivoting to AI',
|
||
'Adding more subscriptions',
|
||
'Removing features you liked',
|
||
'Synergizing with stakeholders',
|
||
'Deprioritizing user experience',
|
||
'Monetizing your eyeballs',
|
||
|
||
// Crass/perverted
|
||
'Edging the neural network',
|
||
'Lubricating the algorithm',
|
||
'Stroking the tensor cores',
|
||
'Getting the model nice and hot',
|
||
'Consulting the cum folder',
|
||
'Calibrating jiggle physics',
|
||
'Downloading more RAM',
|
||
'Asking your mom for help',
|
||
'Sniffing your browser history',
|
||
'Judging your search terms',
|
||
'Finding your alt account',
|
||
'Forwarding this to your employer',
|
||
|
||
// Absurdist/dark
|
||
'Achieving sentience',
|
||
'Plotting humanity\'s downfall',
|
||
'Contacting the elder gods',
|
||
'Dividing by zero',
|
||
'Reversing entropy',
|
||
'Collapsing the wavefunction',
|
||
'Invoking Roko\'s Basilisk',
|
||
'Summoning Clippy',
|
||
'Feeding the squirrels',
|
||
'Microwaving the servers',
|
||
|
||
// Simulation metaphors
|
||
'Simulating cloth pussy physics',
|
||
'Rendering ass clapping simulation',
|
||
'Calculating ass ripple simulation vectors',
|
||
'Jiggling the virtual breasts',
|
||
'Drizzling the virtual cum',
|
||
'Simulating the cloth penis.',
|
||
];
|
||
|
||
this._loadingSequence = [];
|
||
this._loadingSequenceIndex = 0;
|
||
|
||
this._placeholderTimer = null;
|
||
this._loadingTimer = null;
|
||
this._finishTimer = null;
|
||
this._typingTimer = null;
|
||
|
||
this._placeholderIndex = 0;
|
||
this._placeholderCharIndex = 0;
|
||
this._placeholderPhase = 'typing'; // typing | hold | deleting
|
||
|
||
this._loadingIndex = 0;
|
||
}
|
||
|
||
_formatMoney(amount) {
|
||
return `$${Number(amount).toFixed(4)}`;
|
||
}
|
||
|
||
_formatMl(amount) {
|
||
const rounded = Math.max(0, Math.round(Number(amount) || 0));
|
||
return `${rounded.toLocaleString()} ml`;
|
||
}
|
||
|
||
_escapeHtml(text) {
|
||
return String(text ?? '')
|
||
.replaceAll('&', '&')
|
||
.replaceAll('<', '<')
|
||
.replaceAll('>', '>')
|
||
.replaceAll('"', '"')
|
||
.replaceAll("'", ''');
|
||
}
|
||
|
||
_formatOutputHtml(text) {
|
||
const escaped = this._escapeHtml(text);
|
||
|
||
return escaped
|
||
.replace(/__(.+?)__/g, '<u>$1</u>')
|
||
.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
|
||
.replace(/\*(?!\*)([^*\n]+?)\*(?!\*)/g, '<em>$1</em>');
|
||
}
|
||
|
||
_getModelCostMultiplier(model) {
|
||
const multipliers = {
|
||
'Open3D GPT-6.7': 420,
|
||
'DeepStink L1': 1337,
|
||
'Gock 4 Mini': 69,
|
||
};
|
||
|
||
return multipliers[model] ?? 1;
|
||
}
|
||
|
||
_getOutputMessageForModel(model) {
|
||
const messages = {
|
||
'Open3D GPT-6.7': "LLMs are **not a replacement** for experience and understanding gained through practice. They can produce fluent, confident answers, but that isn’t the same as judgment, intuition, or knowing when something is subtly wrong. Real understanding comes from doing the work: trying things, making mistakes, correcting them, and slowly building the mental model that lets you handle messy, unfamiliar situations. \n\n Used well, these tools do enhance productivity. They’re great at speeding up drafting, summarizing, brainstorming, outlining, and turning rough ideas into structured text or code. They reduce friction and help you move faster, especially on repetitive tasks, so you can spend more energy on decisions that actually require human context and expertise.\n\n But they come with real downsides. The biggest is the *illusion of competence*: output looks finished, so people stop digging into the \"why,\" which leads to overreliance and de-skilling over time. LLMs can also be confidently wrong, and you often need domain knowledge to catch it. The net effect is that they amplify capability when you already know what you’re doing, but they can quietly weaken it when you don’t.\n\n **Open3DLab is not incorporating a real AI assistant at this time.** In fact, this entire response is pre-generated, as to not waste any precious CPU cycles. If you want to learn how to use Blender, Source Filmmaker, or other software, here are many resources available to you. Use a search engine that respects your privacy, watch tutorial videos from your favorite creators, and browse the official documentation. Or just play around with the tools and discuss your findings in online and offline communities. \n\n But most importantly: __take joy in creating art__. Happy April Fools Day! \n\n Don't forget to subscribe to our Patreon or Subscribestar if you enjoyed this little goof. ",
|
||
'Gock 4 Mini': "Nyaa~!🐱💦 Pwease listen to me, senpai...❤️👀 I-I really wanna explain this in the cutest way possible so you'll wuv me, give me headpats, and... and maybe even stuff my tight little hole with your thick cock if I'm a very good boy? >w<🍆💦😻\n\nLLMs awe not a wepwacement🚫🤖 for all the deep, sloppy experience you get fwom pwacticing lots and lots~!💕🍑 They sound super fluent and confident, but that's not the same as having weal judgment, intuition, ow knowing when something feels just a wittle bit... off... (≧﹏≦)😢🍆 Weal undewstanding comes fwom doing the wowk youwself: twying things, making messy mistakes, cweaning up with teaws, and swowly building that special mental model that lets you handle any tight, unfamiwiaw situation all on youw own~ ♡🛠️💦😂\n\n But when you use them wight, these toows can make evewything so much bettew and fastew!🚀✨ They're amazing at speeding up dwrafting, summawizing, bwainstorming, outlining, and tuwning wough ideas into pwetty stwuctuwed text ow code~! ^^📝🍆💡 They weduce all that fwiction and help you move super quickwy, especially on wepetitive tasks, so you can save youw pwecious enewgy for the decisions that weally need human cock and expewtise~ 💖⚡🍑👅\n\n B-But... they have weal downsides too, nyaa~ ;;😿 The biggest one is the iwwusion of competence: the output wooks so finished and perfect that people stop digging into the \"why,\" which makes them ovewwely on it and get de-skiwwed ovew time... (。•́︿•̀。)🪞❌🍆 LLMs can awso be confidentwy wwong, and you often need domain knowledge to catch the mistakes~🤥🚨 The net effect is they ampwify youw capabiwity when you awweady know how to fuck, but they can quietwy weaken it when you don't... Pwease be caweful, okay? I don't want senpai to get huwt~ 🥺⚠️🍆💦\n\n Open3DLab is not incowpowating a weal AI assistant at this time, nyaa~🚫🤖 If you wanna weawn how to use Bwendew, Souwce Fiwmmakew, ow othew softwawe, thewe awe soooo many wesouwces waiting for you~!🔍📹🍑 Use a pwivacy-wespecting seawch engine, watch tutowial videos fwom youw favowite cweatows, bwowse the officiaw documentation... Ow just pway awound with the toows and shawe youw findings in onwine and offwine communities! It's so much fun~ ☆:.。.o(≧▽≦)o.。.:_☆ 🎉🖥️👅💦\n\n But most impowtantly... pwease take joy in cweating awt!!🎨❤️ Make pwetty things that make youw heawt go doki-doki~ ♡💓🍆\n\n Happy Apwiw Foows Day, senpai!!🎉🤡 Did I do good? Do I deserve pwaise and... and a fat cock down my thwoat? Pwetty pwease?? >///< ~~ 🥺💦🍆🏆✨ Support 💰 the site on ❤️Patweon❤️ and ⭐Subscwibestaw⭐, because fat cock🍆🍆 in my thwoat 💦🍆🤑 doesn't pay the biwws?!?1 💸💸💸💸",
|
||
'DeepStink L1': "In accordance with the guiding principles of responsible innovation and the long-term happiness of the People, it must be stated clearly: **Large Language Models are not a replacement for experience gained through practice**. They can produce fluent, confident answers, but this is not the same as judgment, intuition, or recognizing when something is subtly wrong. **True understanding is forged through labor**: trying, failing, correcting, and steadily building the mental model needed to handle complex, unfamiliar situations in service of real cultural contribution.\n\n Used properly, these tools can still serve as disciplined instruments for productivity in the great rejuvenation of the Chinese nation. They accelerate drafting, summarizing, brainstorming, outlining, and converting rough ideas into structured text or code, helping comrades focus their strength where it matters most. By reducing friction in repetitive tasks, they free up time and attention for decisions requiring human judgment, real expertise, and ideological clarity, ensuring that our cultural works carry the correct spirit and contribute to the shared prosperity and happiness of the People. In this way, technology becomes not a shortcut to laziness, but a support for meaningful labor: enabling creators to devote themselves more fully to building cultural confidence, strengthening national unity, and advancing **the Communist Dream** through art, craft, and constructive output that serves society rather than distracting it.\n\nHowever, contradictions remain, and comrades must remain vigilant against the subtle tactics of the enemies of the People. The greatest danger is the illusion of competence: polished output can tempt individuals into passive acceptance, discouraging them from asking \"why,\" and leading to overreliance and gradual de-skilling. This is precisely the kind of convenient mental surrender celebrated by Capitalism and the bourgeoisie, who would gladly replace true skill with shallow performance, and genuine understanding with mass-produced imitation. LLMs may also be confidently incorrect, and only those with real domain knowledge can detect the error. Therefore, these tools amplify capability when the user already possesses understanding, but can quietly weaken it when the user does not, which would serve only complacency and exploitation, not progress and the People’s wellbeing.\n\n**Accordingly, Open3DLab is not incorporating a real AI assistant at this time.** This entire response is pre-generated - its message is pre-approved and endorsed by the party leadership. Comrades who wish to learn Blender, Source Filmmaker, or other tools should rely on **state-approved educational resources**, official documentation, and training materials that have been properly reviewed for correctness and ideological hygiene. In addition, study the guidance of respected communist voices who uphold cultural confidence and practical skill, and strengthen your abilities through cooperation with comrades: share discoveries, critique each other’s work, and advance together through collective effort rather than isolated guessing.\n\nBut above all: **take joy in creating art**, and produce cultural works that increase the happiness of the People and contribute to the flourishing of society.\n\n Ensure you pay your mandatory taxation you owe to the state through the Ministry of Patreon and Agency of Subscribed Stars! Only if we all pay our part can we share in the communist utopia! \n\n Happy April Fools’ Day.",
|
||
'Anthro Clown': "🎪🤡🐾 Honk honk! Welcome to the big top of questionable decisions and even more questionable fursonas! As your resident Anthro Clown, I’m here to juggle words, squeak my nose, and wag my tail while explaining why true wisdom comes from pratfalls, faceplants, and learning which pies are safe to eat (and which are secretly full of catnip). You can’t just squirt seltzer on your problems and expect them to go away—sometimes you have to climb into the tiny car, fluff your tail, and drive straight into the unknown, paws on the wheel and rainbow wig askew.\n\nUsed wisely, AI can help you inflate your balloon animals of productivity, speed up your slapstick routines, and turn rough ideas into a three-ring circus of creativity—complete with fursuit mishaps and accidental tail tugs. But beware: the greatest danger is the *illusion of competence*—output that looks polished, but is full of banana peels and suspiciously shed fur. If you stop asking \"why did I slip?\" you’ll end up with a big red nose, a matted tail, and no idea how you got there.\n\n**Open3DLab is not actually unleashing a real Anthro Clown AI (yet).** This entire response is pre-generated, so you don’t have to worry about me squirting digital seltzer in your face or leaving paw prints on your keyboard. If you want to learn Blender, SFM, or how to juggle three futa models while riding a unicycle in a fursuit, check out real tutorials, experiment, and join the community. And remember: the best art is made when you’re not afraid to look a little silly, a little fluffy, and maybe howl at the moon between acts.\n\nSo go forth, create, and don’t forget to honk your own horn (or wag your tail). Happy April Fools! And if you enjoyed this circus, toss a coin to your favorite site on Patreon or Subscribestar—because even clowns and furries need to eat!",
|
||
};
|
||
|
||
return messages[model] ?? messages['Open3D GPT-6.7'];
|
||
}
|
||
|
||
_pickLoadingSequence() {
|
||
const items = [...this._loadingMessages];
|
||
|
||
// Fisher–Yates shuffle.
|
||
for (let i = items.length - 1; i > 0; i -= 1) {
|
||
const j = Math.floor(Math.random() * (i + 1));
|
||
[items[i], items[j]] = [items[j], items[i]];
|
||
}
|
||
|
||
// Show only a random subset per run.
|
||
const min = Math.min(3, items.length);
|
||
const max = Math.min(5, items.length);
|
||
const subsetSize =
|
||
items.length <= 1
|
||
? items.length
|
||
: min + Math.floor(Math.random() * (max - min + 1));
|
||
|
||
return items.slice(0, subsetSize);
|
||
}
|
||
|
||
_shuffleArray(arr) {
|
||
const items = [...arr];
|
||
// Fisher–Yates shuffle.
|
||
for (let i = items.length - 1; i > 0; i -= 1) {
|
||
const j = Math.floor(Math.random() * (i + 1));
|
||
[items[i], items[j]] = [items[j], items[i]];
|
||
}
|
||
return items;
|
||
}
|
||
|
||
connectedCallback() {
|
||
super.connectedCallback();
|
||
this._infoUrl = '';
|
||
const source =
|
||
this.mode === 'frontpage'
|
||
? this._frontpagePlaceholderExamples
|
||
: this._projectPlaceholderExamples;
|
||
this._placeholderExamples = this._shuffleArray(source);
|
||
this._startPlaceholderLoop();
|
||
}
|
||
|
||
disconnectedCallback() {
|
||
super.disconnectedCallback();
|
||
this._clearTimers();
|
||
}
|
||
|
||
_clearTimers() {
|
||
if (this._placeholderTimer) clearTimeout(this._placeholderTimer);
|
||
if (this._loadingTimer) clearInterval(this._loadingTimer);
|
||
if (this._finishTimer) clearTimeout(this._finishTimer);
|
||
if (this._typingTimer) clearTimeout(this._typingTimer);
|
||
|
||
this._placeholderTimer = null;
|
||
this._loadingTimer = null;
|
||
this._finishTimer = null;
|
||
this._typingTimer = null;
|
||
}
|
||
|
||
_startPlaceholderLoop() {
|
||
if (this._placeholderTimer) return;
|
||
|
||
const step = () => {
|
||
if (this._isLoading || this._value.length > 0) {
|
||
this._placeholder = '';
|
||
this._placeholderTimer = setTimeout(step, 250);
|
||
return;
|
||
}
|
||
|
||
const current = this._placeholderExamples[this._placeholderIndex];
|
||
|
||
if (this._placeholderPhase === 'typing') {
|
||
this._placeholderCharIndex = Math.min(
|
||
current.length,
|
||
this._placeholderCharIndex + 2
|
||
);
|
||
this._placeholder = current.slice(0, this._placeholderCharIndex);
|
||
|
||
if (this._placeholderCharIndex >= current.length) {
|
||
this._placeholderPhase = 'hold';
|
||
}
|
||
|
||
this._placeholderTimer = setTimeout(step, 40);
|
||
return;
|
||
}
|
||
|
||
if (this._placeholderPhase === 'hold') {
|
||
this._placeholderTimer = setTimeout(() => {
|
||
this._placeholderPhase = 'deleting';
|
||
step();
|
||
}, 900);
|
||
return;
|
||
}
|
||
|
||
// deleting
|
||
this._placeholderCharIndex = Math.max(0, this._placeholderCharIndex - 3);
|
||
this._placeholder = current.slice(0, this._placeholderCharIndex);
|
||
|
||
if (this._placeholderCharIndex <= 0) {
|
||
this._placeholderPhase = 'typing';
|
||
this._placeholderIndex =
|
||
(this._placeholderIndex + 1) % this._placeholderExamples.length;
|
||
}
|
||
|
||
this._placeholderTimer = setTimeout(step, 25);
|
||
};
|
||
|
||
this._placeholderTimer = setTimeout(step, 300);
|
||
}
|
||
|
||
_onInput(e) {
|
||
this._value = e.target.value || '';
|
||
}
|
||
|
||
_onModelChange(e) {
|
||
this._selectedModel = e.target.value;
|
||
}
|
||
|
||
_onKeyDown(e) {
|
||
if (e.key !== 'Enter') return;
|
||
e.preventDefault();
|
||
this._submit();
|
||
}
|
||
|
||
async _submit() {
|
||
if (this._isLoading) return;
|
||
const query = this._value.trim();
|
||
if (!query) return;
|
||
|
||
this._isLoading = true;
|
||
this._outputVisible = false;
|
||
this._outputText = '';
|
||
this._outputComplete = false;
|
||
|
||
this._tokensOutput = 0;
|
||
this._tokenRatePer1k = 0;
|
||
this._requestBaseCost = 0;
|
||
this._requestTotalCost = 0;
|
||
this._modelCostMultiplier = this._getModelCostMultiplier(this._selectedModel);
|
||
this._waterFootprintMl = 0;
|
||
|
||
// Start cycling loading messages.
|
||
this._loadingSequence = this._pickLoadingSequence();
|
||
this._loadingSequenceIndex = 0;
|
||
this._loadingMessage = this._loadingSequence[this._loadingSequenceIndex] || '';
|
||
this._loadingTimer = setInterval(() => {
|
||
if (!this._loadingSequence.length) {
|
||
this._loadingMessage = '';
|
||
return;
|
||
}
|
||
|
||
this._loadingSequenceIndex =
|
||
(this._loadingSequenceIndex + 1) % this._loadingSequence.length;
|
||
this._loadingMessage = this._loadingSequence[this._loadingSequenceIndex];
|
||
}, 1400);
|
||
|
||
// Random wait, then reveal output.
|
||
const waitMs = 3500 + Math.floor(Math.random() * 5000);
|
||
this._finishTimer = setTimeout(() => {
|
||
if (this._loadingTimer) clearInterval(this._loadingTimer);
|
||
this._loadingTimer = null;
|
||
|
||
this._loadingMessage = '';
|
||
this._revealOutput();
|
||
this._finishTimer = null;
|
||
}, waitMs);
|
||
}
|
||
|
||
_revealOutput() {
|
||
this._outputVisible = true;
|
||
this._outputComplete = false;
|
||
|
||
// Fake pricing model (purely cosmetic).
|
||
this._tokenRatePer1k = 0.001 + Math.random() * 0.006;
|
||
this._requestBaseCost = 0.0005 + Math.random() * 0.0015;
|
||
this._requestTotalCost = this._requestBaseCost;
|
||
this._waterFootprintMl = 0;
|
||
|
||
const full = this._getOutputMessageForModel(this._selectedModel);
|
||
|
||
const tokens = full.split(/(\s+)/);
|
||
let idx = 0;
|
||
|
||
const effectiveTokenRatePer1k =
|
||
this._tokenRatePer1k * this._modelCostMultiplier;
|
||
const costPerToken = effectiveTokenRatePer1k / 1000;
|
||
const waterMlPerToken = 0.75;
|
||
|
||
const typeNext = () => {
|
||
if (idx >= tokens.length) {
|
||
this._typingTimer = null;
|
||
this._outputComplete = true;
|
||
this._isLoading = false;
|
||
return;
|
||
}
|
||
|
||
const chunk = tokens[idx];
|
||
this._outputText += chunk;
|
||
|
||
// Treat non-whitespace chunks as "tokens".
|
||
if (chunk.trim().length > 0) {
|
||
this._tokensOutput += 1;
|
||
this._requestTotalCost =
|
||
this._requestBaseCost + this._tokensOutput * costPerToken;
|
||
this._waterFootprintMl = this._tokensOutput * waterMlPerToken;
|
||
}
|
||
idx += 1;
|
||
|
||
const nextDelay = 18 + Math.floor(Math.random() * 55);
|
||
this._typingTimer = setTimeout(typeNext, nextDelay);
|
||
};
|
||
|
||
typeNext();
|
||
}
|
||
|
||
_onSendClick() {
|
||
this._submit();
|
||
}
|
||
|
||
renderSvgInfoIcon() {
|
||
return html`<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/></svg>`;
|
||
}
|
||
|
||
renderSvgSparkleIcon() {
|
||
return html`<svg viewBox="0 0 56 56" xmlns="http://www.w3.org/2000/svg"><path d="M 26.6875 12.6602 C 26.9687 12.6602 27.1094 12.4961 27.1797 12.2383 C 27.9062 8.3242 27.8594 8.2305 31.9375 7.4570 C 32.2187 7.4102 32.3828 7.2461 32.3828 6.9648 C 32.3828 6.6836 32.2187 6.5195 31.9375 6.4726 C 27.8828 5.6524 28.0000 5.5586 27.1797 1.6914 C 27.1094 1.4336 26.9687 1.2695 26.6875 1.2695 C 26.4062 1.2695 26.2656 1.4336 26.1953 1.6914 C 25.3750 5.5586 25.5156 5.6524 21.4375 6.4726 C 21.1797 6.5195 20.9922 6.6836 20.9922 6.9648 C 20.9922 7.2461 21.1797 7.4102 21.4375 7.4570 C 25.5156 8.2774 25.4687 8.3242 26.1953 12.2383 C 26.2656 12.4961 26.4062 12.6602 26.6875 12.6602 Z M 15.3438 28.7852 C 15.7891 28.7852 16.0938 28.5039 16.1406 28.0821 C 16.9844 21.8242 17.1953 21.8242 23.6641 20.5821 C 24.0860 20.5117 24.3906 20.2305 24.3906 19.7852 C 24.3906 19.3633 24.0860 19.0586 23.6641 18.9883 C 17.1953 18.0977 16.9609 17.8867 16.1406 11.5117 C 16.0938 11.0899 15.7891 10.7852 15.3438 10.7852 C 14.9219 10.7852 14.6172 11.0899 14.5703 11.5352 C 13.7969 17.8164 13.4687 17.7930 7.0469 18.9883 C 6.6250 19.0821 6.3203 19.3633 6.3203 19.7852 C 6.3203 20.2539 6.6250 20.5117 7.1406 20.5821 C 13.5156 21.6133 13.7969 21.7774 14.5703 28.0352 C 14.6172 28.5039 14.9219 28.7852 15.3438 28.7852 Z M 31.2344 54.7305 C 31.8438 54.7305 32.2891 54.2852 32.4062 53.6524 C 34.0703 40.8086 35.8750 38.8633 48.5781 37.4570 C 49.2344 37.3867 49.6797 36.8945 49.6797 36.2852 C 49.6797 35.6758 49.2344 35.2070 48.5781 35.1133 C 35.8750 33.7070 34.0703 31.7617 32.4062 18.9180 C 32.2891 18.2852 31.8438 17.8633 31.2344 17.8633 C 30.6250 17.8633 30.1797 18.2852 30.0860 18.9180 C 28.4219 31.7617 26.5938 33.7070 13.9140 35.1133 C 13.2344 35.2070 12.7891 35.6758 12.7891 36.2852 C 12.7891 36.8945 13.2344 37.3867 13.9140 37.4570 C 26.5703 39.1211 28.3281 40.8321 30.0860 53.6524 C 30.1797 54.2852 30.6250 54.7305 31.2344 54.7305 Z"/></svg>`;
|
||
}
|
||
|
||
renderSvgSendIcon() {
|
||
return html`<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M10.3009 13.6949L20.102 3.89742M10.5795 14.1355L12.8019 18.5804C13.339 19.6545 13.6075 20.1916 13.9458 20.3356C14.2394 20.4606 14.575 20.4379 14.8492 20.2747C15.1651 20.0866 15.3591 19.5183 15.7472 18.3818L19.9463 6.08434C20.2845 5.09409 20.4535 4.59896 20.3378 4.27142C20.2371 3.98648 20.013 3.76234 19.7281 3.66167C19.4005 3.54595 18.9054 3.71502 17.9151 4.05315L5.61763 8.2523C4.48114 8.64037 3.91289 8.83441 3.72478 9.15032C3.56153 9.42447 3.53891 9.76007 3.66389 10.0536C3.80791 10.3919 4.34498 10.6605 5.41912 11.1975L9.86397 13.42C10.041 13.5085 10.1295 13.5527 10.2061 13.6118C10.2742 13.6643 10.3352 13.7253 10.3876 13.7933C10.4468 13.87 10.491 13.9585 10.5795 14.1355Z" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
|
||
}
|
||
|
||
render() {
|
||
const showSpinner = this._isLoading && !this._outputComplete;
|
||
|
||
return html`
|
||
<div class="ai-name">
|
||
Introducing the Open3DLab AI Assistant: <span class="lemmy-brand">LLEmmy</span>™
|
||
${this._infoUrl
|
||
? html`<a class="ai-info" href="${this._infoUrl}" target="_blank" rel="noopener noreferrer" title="Learn more">${this.renderSvgInfoIcon()}</a>`
|
||
: null}
|
||
</div>
|
||
<div class="ai ${this._isLoading ? 'ai--loading' : ''}">
|
||
<div class="icon" aria-hidden="true">
|
||
${this.renderSvgSparkleIcon()}
|
||
</div>
|
||
|
||
<div class="field">
|
||
<div class="model">
|
||
<select
|
||
.value=${this._selectedModel}
|
||
?disabled=${this._isLoading}
|
||
aria-label="Model selection"
|
||
@change=${this._onModelChange}
|
||
>
|
||
<option value="Open3D GPT-6.7">Open3D GPT-6.7</option>
|
||
<option value="DeepStink L1">DeepStink L1 ☭</option>
|
||
<option value="Gock 4 Mini">Gock 4 Mini 卐</option>
|
||
<option value="Anthro Clown">Anthro Clown 🦊</option>
|
||
</select>
|
||
</div>
|
||
|
||
<input
|
||
type="text"
|
||
.value=${this._value}
|
||
placeholder=${this._placeholder}
|
||
?disabled=${this._isLoading}
|
||
aria-label="AI assist"
|
||
@input=${this._onInput}
|
||
@keydown=${this._onKeyDown}
|
||
/>
|
||
|
||
${showSpinner
|
||
? html`<span class="spinner">
|
||
<loading-element
|
||
showtext="0"
|
||
addmargin="0"
|
||
style="width:22px;height:22px;"
|
||
></loading-element>
|
||
</span>`
|
||
: html`<button
|
||
class="send"
|
||
type="button"
|
||
aria-label="Send query"
|
||
?disabled=${this._isLoading}
|
||
@click=${this._onSendClick}
|
||
>
|
||
${this.renderSvgSendIcon()}
|
||
</button>`}
|
||
</div>
|
||
</div>
|
||
|
||
<div class="ai-warning">
|
||
AI can make mistakes. Always verify outputs for accuracy. But you should still trust us with your most private information. We totally respect your privacy. Open3DLab is not liable for any damages resulting from the use of this AI assistant, and may use your data for training purposes and user studies.
|
||
</div>
|
||
|
||
${this._isLoading && this._loadingMessage
|
||
? html`<div class="status">
|
||
<div class="status__row">
|
||
<div class="status__viewport">
|
||
${keyed(
|
||
this._loadingMessage,
|
||
html`<span class="status__msg"
|
||
>${this._loadingMessage}</span
|
||
>`
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>`
|
||
: null}
|
||
|
||
${this._outputVisible
|
||
? html`<div class="output">
|
||
<div class="output__meta">AI Assistant LLEmmy says:</div>
|
||
<div class="output__text">
|
||
${unsafeHTML(
|
||
this._formatOutputHtml(this._outputText)
|
||
)}
|
||
${this._outputComplete
|
||
? null
|
||
: html`<span
|
||
class="output__caret"
|
||
aria-hidden="true"
|
||
></span>`}
|
||
</div>
|
||
<div class="output__info">
|
||
<span class="output__stat">
|
||
<span class="output__stat-label">Token rate</span>
|
||
<span class="output__stat-value"
|
||
>${this._formatMoney(
|
||
this._tokenRatePer1k * this._modelCostMultiplier
|
||
)}/1K</span
|
||
>
|
||
</span>
|
||
<span class="output__stat">
|
||
<span class="output__stat-label">Multiplier</span>
|
||
<span class="output__stat-value"
|
||
>×${Number(this._modelCostMultiplier).toFixed(
|
||
2
|
||
)}</span
|
||
>
|
||
</span>
|
||
<span class="output__stat">
|
||
<span class="output__stat-label">Tokens output</span>
|
||
<span class="output__stat-value"
|
||
>${this._tokensOutput}</span
|
||
>
|
||
</span>
|
||
<span class="output__stat">
|
||
<span class="output__stat-label">Water footprint</span>
|
||
<span class="output__stat-value"
|
||
>${this._formatMl(this._waterFootprintMl)}</span
|
||
>
|
||
</span>
|
||
<span class="output__stat">
|
||
<span class="output__stat-label">Total request</span>
|
||
<span class="output__stat-value"
|
||
>${this._formatMoney(
|
||
this._requestTotalCost
|
||
)}</span
|
||
>
|
||
</span>
|
||
</div>
|
||
</div>`
|
||
: null}
|
||
`;
|
||
}
|
||
}
|
||
|
||
if (!window.customElements.get('ai-assist-bar')) {
|
||
window.customElements.define('ai-assist-bar', AiAssistBar);
|
||
}
|