From 98b463b94b3c34ac59217109a30ccc8f9b365476 Mon Sep 17 00:00:00 2001 From: Hk-Gosuto Date: Wed, 8 Jan 2025 23:06:58 +0800 Subject: [PATCH] feat: optimize animation --- app/components/chat.module.scss | 31 + app/components/chat.tsx | 24 + .../openai-voice-visualizer/index.ts | 1 + .../openai-voice-visualizer.module.scss | 9 + .../openai-voice-visualizer.tsx | 372 +++++ .../realtime-chat/realtime-chat.module.scss | 18 +- .../realtime-chat/realtime-chat.tsx | 17 +- app/global.d.ts | 5 + app/lib/audio.ts | 79 + app/shaders/fragment.glsl | 1326 +++++++++++++++++ app/shaders/vertex.glsl | 20 + app/store/chat.ts | 223 ++- app/utils/webgl.ts | 95 ++ next.config.mjs | 5 +- package.json | 22 +- public/noise-texture.webp | Bin 0 -> 33578 bytes yarn.lock | 230 ++- 17 files changed, 2374 insertions(+), 103 deletions(-) create mode 100644 app/components/openai-voice-visualizer/index.ts create mode 100644 app/components/openai-voice-visualizer/openai-voice-visualizer.module.scss create mode 100644 app/components/openai-voice-visualizer/openai-voice-visualizer.tsx create mode 100644 app/shaders/fragment.glsl create mode 100644 app/shaders/vertex.glsl create mode 100644 app/utils/webgl.ts create mode 100644 public/noise-texture.webp diff --git a/app/components/chat.module.scss b/app/components/chat.module.scss index 9e901e27b..f272d1d2a 100644 --- a/app/components/chat.module.scss +++ b/app/components/chat.module.scss @@ -815,3 +815,34 @@ } } } + +.chat-message-checkmark { + display: inline-block; + margin-right: 5px; + height: 12px; + width: 12px; + color: #13a10e; + fill: #13a10e; + user-select: none; + backface-visibility: hidden; + transform: translateZ(0px); +} + +.chat-message-tools-status { + display: flex; + justify-content: center; + align-items: center; + font-size: 12px; + margin-top: 5px; + line-height: 1.5; +} + +.chat-message-tools-name { + color: #aaa; +} + +.chat-message-tools-details { + margin-left: 5px; + font-weight: bold; + color: #999; +} \ No newline at end of file diff --git a/app/components/chat.tsx b/app/components/chat.tsx index 3a045936d..8697c00ba 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -2039,6 +2039,30 @@ function _Chat() { )} + {!isUser && + message.toolMessages && + message.toolMessages.map((tool, index) => ( +
+
+ + {tool.toolName}: + + {tool.toolInput} + +
+
+ ))} {message?.tools?.length == 0 && showTyping && (
{Locale.Chat.Typing} diff --git a/app/components/openai-voice-visualizer/index.ts b/app/components/openai-voice-visualizer/index.ts new file mode 100644 index 000000000..b7d2d1042 --- /dev/null +++ b/app/components/openai-voice-visualizer/index.ts @@ -0,0 +1 @@ +export * from "./openai-voice-visualizer"; diff --git a/app/components/openai-voice-visualizer/openai-voice-visualizer.module.scss b/app/components/openai-voice-visualizer/openai-voice-visualizer.module.scss new file mode 100644 index 000000000..d6ea660bb --- /dev/null +++ b/app/components/openai-voice-visualizer/openai-voice-visualizer.module.scss @@ -0,0 +1,9 @@ +.openai-voice-visualizer { + width: 100%; + height: 100%; + + canvas { + width: 100%; + height: 100%; + } +} diff --git a/app/components/openai-voice-visualizer/openai-voice-visualizer.tsx b/app/components/openai-voice-visualizer/openai-voice-visualizer.tsx new file mode 100644 index 000000000..5c4f56cae --- /dev/null +++ b/app/components/openai-voice-visualizer/openai-voice-visualizer.tsx @@ -0,0 +1,372 @@ +import { useEffect, useRef, useCallback, useState } from "react"; +import styles from "./openai-voice-visualizer.module.scss"; +import { initWebGL } from "../../utils/webgl"; +import vertexShaderSource from "../../shaders/vertex.glsl"; +import fragmentShaderSource from "../../shaders/fragment.glsl"; +import { loadImage } from "canvas"; + +const CANVAS_SIZE = 208; +const DEFAULT_VIEWPORT_SIZE: [number, number] = [300, 300]; +const NOISE_TEXTURE_OPTIONS = { + format: "webp", + width: 512, + height: 512, + space: "srgb", + channels: 3, + depth: "uchar", + density: 72, + isProgressive: false, + paletteBitDepth: 8, + hasProfile: false, + hasAlpha: false, + src: "./noise-texture.webp", +} as const; + +interface ColorTheme { + bloopColorMain: Float32Array; + bloopColorLow: Float32Array; + bloopColorMid: Float32Array; + bloopColorHigh: Float32Array; +} + +export interface AudioData { + avgMag: Float32Array; + micLevel: number; + cumulativeAudio: Float32Array; +} + +const hexToFloatArray = (hex: string): Float32Array => { + const hexWithoutHash = hex.replace("#", ""); + const red = parseInt(hexWithoutHash.substring(0, 2), 16) / 255; + const green = parseInt(hexWithoutHash.substring(2, 4), 16) / 255; + const blue = parseInt(hexWithoutHash.substring(4, 6), 16) / 255; + return new Float32Array([red, green, blue]); +}; + +const colorThemes = { + BLUE: { + bloopColorMain: hexToFloatArray("#DCF7FF"), + bloopColorLow: hexToFloatArray("#0181FE"), + bloopColorMid: hexToFloatArray("#A4EFFF"), + bloopColorHigh: hexToFloatArray("#FFFDEF"), + }, + DARK_BLUE: { + bloopColorMain: hexToFloatArray("#DAF5FF"), + bloopColorLow: hexToFloatArray("#0066CC"), + bloopColorMid: hexToFloatArray("#2EC6F5"), + bloopColorHigh: hexToFloatArray("#72EAF5"), + }, + GREYSCALE: { + bloopColorMain: hexToFloatArray("#D7D7D7"), + bloopColorLow: hexToFloatArray("#303030"), + bloopColorMid: hexToFloatArray("#989898"), + bloopColorHigh: hexToFloatArray("#FFFFFF"), + }, + WHITE: { + bloopColorMain: hexToFloatArray("#FFFFFF"), + bloopColorLow: hexToFloatArray("#FFFFFF"), + bloopColorMid: hexToFloatArray("#FFFFFF"), + bloopColorHigh: hexToFloatArray("#FFFFFF"), + }, + BLACK: { + bloopColorMain: hexToFloatArray("#000000"), + bloopColorLow: hexToFloatArray("#000000"), + bloopColorMid: hexToFloatArray("#000000"), + bloopColorHigh: hexToFloatArray("#000000"), + }, +} as const; + +interface OpenAIVoiceVisualizerProps { + audioData?: AudioData; + isActive?: boolean; +} + +export class NormalBlorpUniformsSetter { + static uniformBlockName = "BlorbUniformsObject"; + private gl: WebGL2RenderingContext; + private uniformBuffer: WebGLBuffer; + private uniformNames: string[]; + private uniformOffsets: { [key: string]: number }; + private dataBuffer: ArrayBuffer; + private floatView: Float32Array; + private intView: Int32Array; + + constructor(gl: WebGL2RenderingContext, program: WebGLProgram) { + this.gl = gl; + const uniformBlockIndex = gl.getUniformBlockIndex( + program, + NormalBlorpUniformsSetter.uniformBlockName, + ); + const uniformBlockSize = gl.getActiveUniformBlockParameter( + program, + uniformBlockIndex, + gl.UNIFORM_BLOCK_DATA_SIZE, + ); + + this.uniformBuffer = gl.createBuffer()!; + gl.bindBuffer(gl.UNIFORM_BUFFER, this.uniformBuffer); + gl.bufferData(gl.UNIFORM_BUFFER, uniformBlockSize, gl.DYNAMIC_DRAW); + + const bindingPoint = 0; + gl.bindBufferBase(gl.UNIFORM_BUFFER, bindingPoint, this.uniformBuffer); + gl.uniformBlockBinding(program, uniformBlockIndex, bindingPoint); + + const uniformIndices = gl.getActiveUniformBlockParameter( + program, + uniformBlockIndex, + gl.UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, + ); + + this.uniformNames = []; + this.uniformOffsets = {}; + for (let i = 0; i < uniformIndices.length; i++) { + const uniformIndex = uniformIndices[i]; + const uniformInfo = gl.getActiveUniform(program, uniformIndex); + if (!uniformInfo) { + throw new Error("No uniformInfo for index " + uniformIndex); + } + let uniformName = uniformInfo.name; + uniformName = uniformName.replace(/\[0\]$/, ""); + const uniformOffset = gl.getActiveUniforms( + program, + [uniformIndex], + gl.UNIFORM_OFFSET, + )[0]; + this.uniformNames.push(uniformName); + this.uniformOffsets[uniformName] = uniformOffset; + } + + this.dataBuffer = new ArrayBuffer(uniformBlockSize); + this.floatView = new Float32Array(this.dataBuffer); + this.intView = new Int32Array(this.dataBuffer); + } + + setVariablesAndRender(variables: { + [key: string]: number | boolean | number[]; + }) { + for (const uniformName of this.uniformNames) { + const [, name] = uniformName.split("."); + const offset = this.uniformOffsets[uniformName] / 4; + const value = variables[name]; + + if (typeof value === "number") { + this.floatView[offset] = value; + } else if (typeof value === "boolean") { + this.intView[offset] = value ? 1 : 0; + } else if (Array.isArray(value)) { + this.floatView.set(value, offset); + } + } + + this.gl.bindBuffer(this.gl.UNIFORM_BUFFER, this.uniformBuffer); + this.gl.bufferSubData(this.gl.UNIFORM_BUFFER, 0, this.dataBuffer); + this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 6); + } +} + +export function OpenAIVoiceVisualizer({ + audioData, + isActive, +}: OpenAIVoiceVisualizerProps) { + const canvasRef = useRef(null); + const glRef = useRef(null); + const programRef = useRef(null); + const animationFrameRef = useRef(0); + const uniformSetterRef = useRef(null); + const startTimeRef = useRef(performance.now() / 1000); + const readyTimeRef = useRef(performance.now() / 1000); + + const variablesRef = useRef({ + time: 0, + micLevel: 0, + stateListen: 0, + listenTimestamp: 0, + stateThink: 0.0, + thinkTimestamp: 0.0, + stateSpeak: 1, + speakTimestamp: 0, + readyTimestamp: 0, + stateHalt: 0.0, + haltTimestamp: 0.0, + touchDownTimestamp: 0.0, + touchUpTimestamp: 0.0, + stateFailedToConnect: 0.0, + failedToConnectTimestamp: 0.0, + avgMag: new Array(4).fill(0), + cumulativeAudio: new Array(4).fill(0), + isNewBloop: true, + isAdvancedBloop: true, + bloopColorMain: [0, 0, 0], + bloopColorLow: [0, 0, 0], + bloopColorMid: [0, 0, 0], + bloopColorHigh: [0, 0, 0], + isDarkMode: false, + screenScaleFactor: 1.0, + viewport: DEFAULT_VIEWPORT_SIZE, + silenceAmount: 0.0, + silenceTimestamp: 0.0, + fadeBloopWhileListening: false, + }); + + const audioDataRef = useRef({ + avgMag: new Float32Array(4), + micLevel: 0, + cumulativeAudio: new Float32Array(4), + }); + + const handleAudioData = useCallback((data: AudioData) => { + audioDataRef.current = data; + }, []); + + const [viewportSize] = useState<[number, number]>(DEFAULT_VIEWPORT_SIZE); + const [noiseTextureImage, setNoiseTextureImage] = + useState(null); + const getColorTheme = useCallback((isAdvanced: boolean): ColorTheme => { + return colorThemes.BLUE; + }, []); + + const initializeWebGL = useCallback(() => { + if (!canvasRef.current) return; + + canvasRef.current.width = CANVAS_SIZE; + canvasRef.current.height = CANVAS_SIZE; + + const { gl, program } = initWebGL( + canvasRef.current, + vertexShaderSource, + fragmentShaderSource, + ); + + if (!gl || !program) { + console.error("WebGL 初始化失败"); + return; + } + + glRef.current = gl; + programRef.current = program; + uniformSetterRef.current = new NormalBlorpUniformsSetter(gl, program); + + return { gl, program }; + }, []); + + const initializeNoiseTexture = useCallback( + (gl: WebGL2RenderingContext, program: WebGLProgram) => { + const noiseTexture = gl.createTexture(); + if (!noiseTexture) { + console.error("创建噪声纹理失败"); + return; + } + + gl.bindTexture(gl.TEXTURE_2D, noiseTexture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + + if (noiseTextureImage) { + gl.texImage2D( + gl.TEXTURE_2D, + 0, + gl.RGBA, + gl.RGBA, + gl.UNSIGNED_BYTE, + noiseTextureImage, + ); + } + + const location = gl.getUniformLocation(program, "uTextureNoise"); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, noiseTexture); + gl.uniform1i(location, 0); + + return noiseTexture; + }, + [noiseTextureImage], + ); + + const renderFrame = useCallback(() => { + if (!glRef.current || !uniformSetterRef.current) return; + + if (!audioData) { + handleAudioData({ + avgMag: new Float32Array(4), + micLevel: 0, + cumulativeAudio: new Float32Array(4), + }); + // return; + } else { + handleAudioData(audioData); + } + + const currentFrameTime = performance.now() / 1000; + const colorTheme = getColorTheme(true); + + const variables = variablesRef.current; + variables.time = currentFrameTime; + variables.micLevel = audioDataRef.current.micLevel; + variables.speakTimestamp = readyTimeRef.current; + variables.readyTimestamp = startTimeRef.current; + variables.avgMag = Array.from(audioDataRef.current.avgMag); + variables.cumulativeAudio = Array.from( + audioDataRef.current.cumulativeAudio, + ); + variables.bloopColorMain = Array.from(colorTheme.bloopColorMain); + variables.bloopColorLow = Array.from(colorTheme.bloopColorLow); + variables.bloopColorMid = Array.from(colorTheme.bloopColorMid); + variables.bloopColorHigh = Array.from(colorTheme.bloopColorHigh); + variables.screenScaleFactor = window.devicePixelRatio || 1.0; + variables.viewport = viewportSize; + + uniformSetterRef.current.setVariablesAndRender(variables); + animationFrameRef.current = requestAnimationFrame(renderFrame); + }, [audioData, getColorTheme, handleAudioData, viewportSize]); + + useEffect(() => { + const loadNoiseTexture = async () => { + try { + const image = await loadImage(NOISE_TEXTURE_OPTIONS.src); + setNoiseTextureImage(image as unknown as HTMLImageElement); + } catch (error) { + console.error("加载噪声纹理失败:", error); + } + }; + loadNoiseTexture(); + }, []); + + useEffect(() => { + const canvas = canvasRef.current; + if (!canvas) return; + + const webglContext = initializeWebGL(); + if (!webglContext) return; + + const { gl, program } = webglContext; + const noiseTexture = initializeNoiseTexture(gl, program); + + renderFrame(); + + return () => { + if (animationFrameRef.current) { + cancelAnimationFrame(animationFrameRef.current); + } + if (gl) { + if (noiseTexture) { + gl.deleteTexture(noiseTexture); + } + gl.deleteProgram(program); + } + }; + }, [ + initializeWebGL, + initializeNoiseTexture, + renderFrame, + audioData, + isActive, + ]); + + return ( +
+ +
+ ); +} diff --git a/app/components/realtime-chat/realtime-chat.module.scss b/app/components/realtime-chat/realtime-chat.module.scss index ef58bebb6..7df7016f8 100644 --- a/app/components/realtime-chat/realtime-chat.module.scss +++ b/app/components/realtime-chat/realtime-chat.module.scss @@ -8,15 +8,15 @@ height: 100%; padding: 20px; box-sizing: border-box; - .circle-mic { - width: 150px; - height: 150px; - border-radius: 50%; - background: linear-gradient(to bottom right, #a0d8ef, #f0f8ff); - display: flex; - justify-content: center; - align-items: center; - } + // .circle-mic { + // width: 150px; + // height: 150px; + // border-radius: 50%; + // background: linear-gradient(to bottom right, #a0d8ef, #f0f8ff); + // display: flex; + // justify-content: center; + // align-items: center; + // } .icon-center { font-size: 24px; } diff --git a/app/components/realtime-chat/realtime-chat.tsx b/app/components/realtime-chat/realtime-chat.tsx index faa36373a..ffbab0f3b 100644 --- a/app/components/realtime-chat/realtime-chat.tsx +++ b/app/components/realtime-chat/realtime-chat.tsx @@ -21,6 +21,10 @@ import { import { AudioHandler } from "@/app/lib/audio"; import { uploadImage } from "@/app/utils/chat"; import { VoicePrint } from "@/app/components/voice-print"; +import { + OpenAIVoiceVisualizer, + AudioData, +} from "../openai-voice-visualizer/openai-voice-visualizer"; interface RealtimeChatProps { onClose?: () => void; @@ -43,6 +47,7 @@ export function RealtimeChat({ const [modality, setModality] = useState("audio"); const [useVAD, setUseVAD] = useState(true); const [frequencies, setFrequencies] = useState(); + const [audioData, setAudioData] = useState(); const clientRef = useRef(null); const audioHandlerRef = useRef(null); @@ -292,6 +297,9 @@ export function RealtimeChat({ if (audioHandlerRef.current) { const freqData = audioHandlerRef.current.getByteFrequencyData(); setFrequencies(freqData); + + const audioData = audioHandlerRef.current.getAudioData(); + setAudioData(audioData); } animationFrameId = requestAnimationFrame(animationFrame); }; @@ -299,6 +307,7 @@ export function RealtimeChat({ animationFrameId = requestAnimationFrame(animationFrame); } else { setFrequencies(undefined); + setAudioData(undefined); } return () => { @@ -327,11 +336,11 @@ export function RealtimeChat({ return (
- +
diff --git a/app/global.d.ts b/app/global.d.ts index 897871fec..d76510ab6 100644 --- a/app/global.d.ts +++ b/app/global.d.ts @@ -10,6 +10,11 @@ declare module "*.scss" { declare module "*.svg"; +declare module "*.glsl" { + const content: string; + export default content; +} + declare interface Window { __TAURI__?: { writeText(text: string): Promise; diff --git a/app/lib/audio.ts b/app/lib/audio.ts index a4937d773..0fbb865e6 100644 --- a/app/lib/audio.ts +++ b/app/lib/audio.ts @@ -21,6 +21,9 @@ export class AudioHandler { this.analyser = new AnalyserNode(this.context, { fftSize: 256 }); this.analyserData = new Uint8Array(this.analyser.frequencyBinCount); this.mergeNode.connect(this.analyser); + + this.dataArray = new Float32Array(this.analyser.frequencyBinCount); + this.initializeBands(this.analyser.frequencyBinCount); } getByteFrequencyData() { @@ -94,6 +97,7 @@ export class AudioHandler { this.source.disconnect(); this.stream.getTracks().forEach((track) => track.stop()); } + startStreamingPlayback() { this.isPlaying = true; this.nextPlayTime = this.context.currentTime; @@ -148,6 +152,7 @@ export class AudioHandler { this.nextPlayTime = this.context.currentTime; } } + _saveData(data: Int16Array, bytesPerSample = 16): Blob { const headerLength = 44; const numberOfChannels = 1; @@ -171,10 +176,12 @@ export class AudioHandler { // using data.buffer, so no need to setUint16 to view. return new Blob([view, data.buffer], { type: "audio/mpeg" }); } + savePlayFile() { // @ts-ignore return this._saveData(new Int16Array(this.playBuffer)); } + saveRecordFile( audioStartMillis: number | undefined, audioEndMillis: number | undefined, @@ -190,6 +197,7 @@ export class AudioHandler { new Int16Array(this.recordBuffer.slice(startIndex, endIndex)), ); } + async close() { this.recordBuffer = []; this.workletNode?.disconnect(); @@ -197,4 +205,75 @@ export class AudioHandler { this.stream?.getTracks().forEach((track) => track.stop()); await this.context.close(); } + + private readonly NUM_BANDS = 4; + private avgMag: Float32Array = new Float32Array(this.NUM_BANDS); + private dataArray: Float32Array | null = null; + private cumulativeAudio: Float32Array = new Float32Array(this.NUM_BANDS); + private binSize: number = 0; + + private initializeBands = (frequencyBinCount: number) => { + this.binSize = Math.floor(frequencyBinCount / this.NUM_BANDS); + }; + + private createMagnitudeLookupTable = () => { + const GAIN_MULTIPLIER = 1.2; + const table = new Float32Array(100); + for (let i = 0; i < 100; i++) { + const db = -100 + i; + let magnitude = 1 - (Math.max(-100, Math.min(-10, db)) * -1) / 100; + magnitude = Math.pow(magnitude, 0.7) * GAIN_MULTIPLIER; + table[i] = Math.min(1, magnitude); + } + return table; + }; + + private magnitudeLookupTable = this.createMagnitudeLookupTable(); + + decibelToMagnitude = (db: number): number => { + if (db === -Infinity) return 0; + const index = Math.floor(db + 100); + if (index < 0) return 0; + if (index >= 100) return 1; + return this.magnitudeLookupTable[index]; + }; + + getAudioData() { + if (!this.analyser || !this.dataArray) return; + + const SMOOTHING_FACTOR = 0.2; + const FREQUENCY_WEIGHTS = [1.2, 1.0, 0.8, 0.6]; + + this.analyser.getFloatFrequencyData(this.dataArray); + + let totalMagnitude = 0; + + for (let i = 0; i < this.NUM_BANDS; i++) { + const startBin = i * this.binSize; + const endBin = startBin + this.binSize; + let sum = 0; + + const bandData = this.dataArray.subarray(startBin, endBin); + for (let j = 0; j < bandData.length; j++) { + const magnitude = + this.decibelToMagnitude(bandData[j]) * FREQUENCY_WEIGHTS[i]; + sum += magnitude; + } + + this.avgMag[i] = sum / this.binSize; + totalMagnitude += this.avgMag[i]; + + this.cumulativeAudio[i] = + this.cumulativeAudio[i] * (1 - SMOOTHING_FACTOR) + + this.avgMag[i] * SMOOTHING_FACTOR; + } + + const micLevel = Math.min(1, (totalMagnitude / this.NUM_BANDS) * 1.2); + + return { + avgMag: this.avgMag, + micLevel, + cumulativeAudio: this.cumulativeAudio, + }; + } } diff --git a/app/shaders/fragment.glsl b/app/shaders/fragment.glsl new file mode 100644 index 000000000..b240fd3d6 --- /dev/null +++ b/app/shaders/fragment.glsl @@ -0,0 +1,1326 @@ +#version 300 es +#define E (2.71828182846) +#define pi (3.14159265358979323844) +#define NUM_OCTAVES (4) + +precision highp float; + +struct ColoredSDF { + float distance; + vec4 color; +}; + +struct SDFArgs { + vec2 st; + float amount; + float duration; + float time; + float mainRadius; +}; + +float triangle(float t, float p) { + return 2.0 * abs(t / p - floor(t / p + 0.5)); +} + +float spring(float t, float d) { + return 1.0 - exp(-E * 2.0 * t) * cos((1.0 - d) * 115.0 * t); +} + +float silkySmooth(float t, float k) { + return atan(k * sin((t - 0.5) * pi)) / atan(k) * 0.5 + 0.5; +} + +float scaled(float edge0, float edge1, float x) { + return clamp((x - edge0) / (edge1 - edge0), float(0), float(1)); +} + +float fixedSpring(float t, float d) { + float s = mix( + 1.0 - exp(-E * 2.0 * t) * cos((1.0 - d) * 115.0 * t), + 1.0, + scaled(0.0, 1.0, t) + ); + return s * (1.0 - t) + t; +} + +float bounce(float t, float d) { + return -sin(pi * (1.0 - d) * t) * + (1.0 - t) * + exp(-2.71828182846 * 2.0 * t) * + t * + 10.0; +} + +float random(vec2 st) { + return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123); +} + +float random(ivec2 st) { + return random(vec2(st)); +} + +float random(float p) { + return random(vec2(p)); +} + +float opSmoothUnion(float d1, float d2, float k) { + if (k <= 0.0) { + k = 0.000001; + } + float h = clamp(0.5 + 0.5 * (d2 - d1) / k, 0.0, 1.0); + return mix(d2, d1, h) - k * h * (1.0 - h); +} + +float opSmoothSubtraction(float d1, float d2, float k) { + if (k <= 0.0) { + k = 0.000001; + } + float h = clamp(0.5 - 0.5 * (d2 + d1) / k, 0.0, 1.0); + return mix(d2, -d1, h) + k * h * (1.0 - h); +} + +float opSmoothIntersection(float d1, float d2, float k) { + if (k <= 0.0) { + k = 0.000001; + } + float h = clamp(0.5 - 0.5 * (d2 - d1) / k, 0.0, 1.0); + return mix(d2, d1, h) + k * h * (1.0 - h); +} + +float sdRoundedBox(vec2 p, vec2 b, vec4 r) { + r.xy = p.x > 0.0 ? r.xy : r.zw; + r.x = p.y > 0.0 ? r.x : r.y; + vec2 q = abs(p) - b + r.x; + return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r.x; +} + +float sdSegment(vec2 p, vec2 a, vec2 b) { + vec2 pa = p - a; + vec2 ba = b - a; + float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0); + return length(pa - ba * h); +} + +float sdArc(vec2 p, vec2 sca, vec2 scb, float ra, float rb) { + p *= mat2(sca.x, sca.y, -sca.y, sca.x); + p.x = abs(p.x); + return scb.y * p.x > scb.x * p.y + ? length(p - ra * scb) - rb + : abs(length(p) - ra) - rb; +} + +float arc(vec2 st, float startAngle, float length, float radius, float width) { + return sdArc( + st, + vec2(sin(startAngle), cos(startAngle)), + vec2(sin(length), cos(length)), + radius, + width + ); +} + +vec2 rotate(vec2 v, float a) { + float s = sin(a); + float c = cos(a); + mat2 m = mat2(c, s, -s, c); + return m * v; +} + +vec3 blendLinearBurn_13_5(vec3 base, vec3 blend) { + + return max(base + blend - vec3(1.0), vec3(0.0)); +} + +vec3 blendLinearBurn_13_5(vec3 base, vec3 blend, float opacity) { + return blendLinearBurn_13_5(base, blend) * opacity + base * (1.0 - opacity); +} + +float blendScreen_21_19(float base, float blend) { + return 1.0 - (1.0 - base) * (1.0 - blend); +} + +vec3 blendScreen_21_19(vec3 base, vec3 blend) { + return vec3( + blendScreen_21_19(base.r, blend.r), + blendScreen_21_19(base.g, blend.g), + blendScreen_21_19(base.b, blend.b) + ); +} + +vec3 blendScreen_21_19(vec3 base, vec3 blend, float opacity) { + return blendScreen_21_19(base, blend) * opacity + base * (1.0 - opacity); +} + +vec4 permute(vec4 x) { + return mod((x * 34.0 + 1.0) * x, 289.0); +} +vec4 taylorInvSqrt(vec4 r) { + return 1.79284291400159 - 0.85373472095314 * r; +} +vec3 fade(vec3 t) { + return t * t * t * (t * (t * 6.0 - 15.0) + 10.0); +} + +float cnoise(vec3 P) { + vec3 Pi0 = floor(P); + vec3 Pi1 = Pi0 + vec3(1.0); + Pi0 = mod(Pi0, 289.0); + Pi1 = mod(Pi1, 289.0); + vec3 Pf0 = fract(P); + vec3 Pf1 = Pf0 - vec3(1.0); + vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); + vec4 iy = vec4(Pi0.yy, Pi1.yy); + vec4 iz0 = vec4(Pi0.z); + vec4 iz1 = vec4(Pi1.z); + + vec4 ixy = permute(permute(ix) + iy); + vec4 ixy0 = permute(ixy + iz0); + vec4 ixy1 = permute(ixy + iz1); + + vec4 gx0 = ixy0 / 7.0; + vec4 gy0 = fract(floor(gx0) / 7.0) - 0.5; + gx0 = fract(gx0); + vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0); + vec4 sz0 = step(gz0, vec4(0.0)); + gx0 -= sz0 * (step(vec4(0.0), gx0) - 0.5); + gy0 -= sz0 * (step(vec4(0.0), gy0) - 0.5); + + vec4 gx1 = ixy1 / 7.0; + vec4 gy1 = fract(floor(gx1) / 7.0) - 0.5; + gx1 = fract(gx1); + vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1); + vec4 sz1 = step(gz1, vec4(0.0)); + gx1 -= sz1 * (step(vec4(0.0), gx1) - 0.5); + gy1 -= sz1 * (step(vec4(0.0), gy1) - 0.5); + + vec3 g000 = vec3(gx0.x, gy0.x, gz0.x); + vec3 g100 = vec3(gx0.y, gy0.y, gz0.y); + vec3 g010 = vec3(gx0.z, gy0.z, gz0.z); + vec3 g110 = vec3(gx0.w, gy0.w, gz0.w); + vec3 g001 = vec3(gx1.x, gy1.x, gz1.x); + vec3 g101 = vec3(gx1.y, gy1.y, gz1.y); + vec3 g011 = vec3(gx1.z, gy1.z, gz1.z); + vec3 g111 = vec3(gx1.w, gy1.w, gz1.w); + + vec4 norm0 = taylorInvSqrt( + vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)) + ); + g000 *= norm0.x; + g010 *= norm0.y; + g100 *= norm0.z; + g110 *= norm0.w; + vec4 norm1 = taylorInvSqrt( + vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)) + ); + g001 *= norm1.x; + g011 *= norm1.y; + g101 *= norm1.z; + g111 *= norm1.w; + + float n000 = dot(g000, Pf0); + float n100 = dot(g100, vec3(Pf1.x, Pf0.yz)); + float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)); + float n110 = dot(g110, vec3(Pf1.xy, Pf0.z)); + float n001 = dot(g001, vec3(Pf0.xy, Pf1.z)); + float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)); + float n011 = dot(g011, vec3(Pf0.x, Pf1.yz)); + float n111 = dot(g111, Pf1); + + vec3 fade_xyz = fade(Pf0); + vec4 n_z = mix( + vec4(n000, n100, n010, n110), + vec4(n001, n101, n011, n111), + fade_xyz.z + ); + vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); + float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); + return 2.2 * n_xyz; +} + +float rand(vec2 n) { + return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 43758.5453); +} + +float noise(vec2 p) { + vec2 ip = floor(p); + vec2 u = fract(p); + u = u * u * (3.0 - 2.0 * u); + + float res = mix( + mix(rand(ip), rand(ip + vec2(1.0, 0.0)), u.x), + mix(rand(ip + vec2(0.0, 1.0)), rand(ip + vec2(1.0, 1.0)), u.x), + u.y + ); + return res * res; +} + +float fbm(vec2 x) { + float v = 0.0; + float a = 0.5; + vec2 shift = vec2(100.0); + + mat2 rot = mat2(cos(0.5), sin(0.5), -sin(0.5), cos(0.5)); + for (int i = 0; i < NUM_OCTAVES; ++i) { + v += a * noise(x); + x = rot * x * 2.0 + shift; + a *= 0.5; + } + return v; +} + +#define HASHSCALE1 (0.1031) +#define HASHSCALE3 (vec3(0.1031, 0.103, 0.0973)) +#define HASHSCALE4 (vec3(0.1031, 0.103, 0.0973, 0.1099)) + +float Hash11(float p) { + vec3 p3 = fract(vec3(p) * HASHSCALE1); + p3 += dot(p3, p3.yzx + 19.19); + return fract((p3.x + p3.y) * p3.z); +} + +vec2 Hash22(vec2 p) { + vec3 p3 = fract(vec3(p.xyx) * HASHSCALE3); + p3 += dot(p3, p3.yzx + 19.19); + return fract((p3.xx + p3.yz) * p3.zy); +} + +vec2 Rand22(vec2 co) { + float x = fract(sin(dot(co.xy, vec2(122.9898, 783.233))) * 43758.5453); + float y = fract(sin(dot(co.xy, vec2(457.6537, 537.2793))) * 37573.5913); + return vec2(x, y); +} + +vec3 SnowSingleLayer( + vec2 uv, + float layer, + vec2 speed, + vec4 uCumulativeAudio, + float uTime +) { + uv = uv * (1.5 + layer); + float size = 0.01; + + float xOffset = + uv.y * (((Hash11(layer) * 2.0 - 1.0) * 0.5 + 1.0) * speed.x) + + sin( + layer * 2963.0 + uCumulativeAudio.y * 0.05625 + uCumulativeAudio.z * 0.075 + ); + float yOffset = + speed.y + uTime * 1.75 + uCumulativeAudio.x * 0.07125 + cos(uTime) * 0.1; + xOffset += sin(uTime * 2.0 + uv.x + layer * 2938.0) * 0.25; + uv += vec2(xOffset, yOffset); + + vec2 rgrid = Hash22(floor(uv) + 31.1759 * layer); + uv = fract(uv); + uv -= (rgrid * 2.0 - 1.0) * 0.35; + uv -= 0.5; + + float r = length(uv); + + float circleSize = 0.05 * (1.0 + 0.2 * sin(uTime * size + layer)); + float val = smoothstep(circleSize, -circleSize, r); + val = smoothstep(0.0, 0.2, val); + + vec3 col = vec3(val, val, val) * rgrid.x; + return col; + +} + +/** + * End new code for colored orb + */ + +ColoredSDF applyIdleState( + ColoredSDF sdf, + SDFArgs args, + bool isDarkMode /** + * new bool + */ +) { + float midRadius = 0.12; + float maxRadius = 0.3; + float t1 = 1.0; + float gamma = 3.0; + float omega = pi / 2.0; + + + float k = exp(-gamma) * omega; + + float radius; + if (args.time <= t1) { + + float t_prime = args.time / t1; + + float springValue = 1.0 - exp(-gamma * t_prime) * cos(omega * t_prime); + radius = midRadius * springValue; + } else { + + float adjustedTime = args.time - t1; + + radius = + midRadius + (maxRadius - midRadius) * (1.0 - exp(-k * adjustedTime)); + } + + + float distance = length(args.st) - radius; + + + sdf.distance = mix(sdf.distance, distance, args.amount); + + + + float alpha = sin(pi / 0.7 * args.time) * 0.3 + 0.7; + vec4 color = vec4(isDarkMode ? vec3(1.0) : vec3(0.0), alpha); + + + sdf.color = mix(sdf.color, color, args.amount); + + return sdf; +} + +ColoredSDF applyIdleStateLegacy(ColoredSDF sdf, SDFArgs args, bool isDarkMode) { + float connectedLinearAnimation = scaled(0.0, 2.0, args.duration); + float connectedAnimation = fixedSpring(connectedLinearAnimation, 0.96); + float circleSize = + mix( + pow(scaled(0.0, 3.0, args.time), 2.0) * 0.75 + 0.1, + 1.0, + connectedAnimation + ) * + 0.33; + vec2 rotatedCoords = rotate( + args.st, + -args.time * pi - + connectedAnimation * pi * 2.0 - + pi * 2.0 * 5.0 * silkySmooth(scaled(0.0, 5.0, args.time), 2.0) + ); + + float strokeWidth = mix(circleSize / 2.0, circleSize, connectedAnimation); + float connecting = abs(length(args.st) - circleSize) - strokeWidth; + + float connected = length(args.st) - circleSize; + float idleDist = mix(connecting, connected, connectedAnimation); + + float d = min(sdf.distance, idleDist); + sdf.distance = mix(sdf.distance, d, args.amount); + float angle = atan(rotatedCoords.y, rotatedCoords.x); + float alpha = mix( + min(1.0, scaled(-pi, pi, angle)), + 1.0, + connectedLinearAnimation + ); + + float spinningCircleDist = + length( + rotatedCoords - + vec2(-mix(circleSize, strokeWidth, connectedAnimation), 0.0) + ) - + strokeWidth; + + alpha = min( + 1.0, + max( + alpha, + smoothstep(0.005, 0.0, spinningCircleDist) + connectedAnimation * 4.0 + ) + ); + + sdf.color = mix( + sdf.color, + vec4(isDarkMode ? vec3(1.0) : vec3(0.0), alpha), + args.amount + ); + return sdf; +} + +ColoredSDF applyListenState( + ColoredSDF sdf, + SDFArgs args, + float micLevel, + float listenTimestamp, /* new */ + float touchDownTimestamp, /* new */ + float touchUpTimestamp, /* new */ + bool fadeBloopWhileListening /* new */ +) { + float breathingSequence = sin(args.time) * 0.5 + 0.5; + float entryAnimation = fixedSpring(scaled(0.0, 3.0, args.duration), 0.9); + + float touch = + fixedSpring(scaled(0.0, 1.0, args.time - touchDownTimestamp), 0.99) - + fixedSpring(scaled(0.0, 0.8, args.time - touchUpTimestamp), 1.0); + + float listenAnimation = clamp( + spring(scaled(0.0, 0.9, args.duration), 1.0), + 0.0, + 1.0 + ); + float radius = 0.0; + float smoothlevel = micLevel; + float l1 = smoothlevel; + radius = 0.38 + l1 * 0.05 + breathingSequence * 0.03; + radius *= 1.0 - (1.0 - entryAnimation) * 0.25; + + float ring = 10000.0; + + + if (touch > 0.0) { + touch = min(touch, listenAnimation); + float arcWidth = radius * 0.1; + + + radius -= touch * arcWidth * 2.3; + + radius = min( + radius, + mix(radius, args.mainRadius - arcWidth * 2.3 - l1 * 0.01, touch) + ); + + float startAngle = 0.0; + float arcLengthTouch = + smoothstep(0.04, 1.0, touch) * pi * (1.0 - arcWidth / 3.0 / radius); + + float arcLength = 0.0; + float radiusTouch = + radius * fixedSpring(scaled(0.0, 1.0, args.duration), 1.0) * args.amount + + l1 * 0.01; + + radiusTouch += + arcWidth * 1.3 * mix(-1.0, 1.0, smoothstep(0.0, 0.12, touch)); + + float ringRadius = 0.0; + arcLength = arcLengthTouch; + ringRadius = radiusTouch; + startAngle = pi / 2.0 - (args.time - touchDownTimestamp) / 2.0; + + ring = arc(args.st, startAngle, arcLength, ringRadius, arcWidth); + } + + float d = length(args.st) - radius; + + d = min(d, ring); + + sdf.distance = mix(sdf.distance, d, args.amount); + + if (fadeBloopWhileListening) { + + sdf.color.a = mix( + sdf.color.a, + mix(1.0, 1.0 - l1 * 0.6, listenAnimation), + args.amount + ); + } else { + sdf.color.a = 1.0; + } + + return sdf; +} + +ColoredSDF applyThinkState(ColoredSDF sdf, SDFArgs args) { + float d = 1000.0; + int count = 5; + float entryAnimation = spring(scaled(0.0, 1.0, args.duration), 1.0); + + float thinkingDotEntryAnimation = spring( + scaled(0.1, 1.1, args.duration), + 1.0 + ); + float thinkingDotRadius = + mix(0.2, 0.06, thinkingDotEntryAnimation) * args.amount; + + + args.st.x -= thinkingDotRadius * 0.5 * thinkingDotEntryAnimation; + + for (int i = 0; i < count; i++) { + float f = float(float(i) + 0.5) / float(count); + float a = + -f * pi * 2.0 + + args.time / 3.0 + + spring(scaled(0.0, 10.0, args.duration), 1.0) * pi / 2.0; + float ringRadi = args.mainRadius * 0.45 * entryAnimation; + + + ringRadi -= + (sin( + entryAnimation * pi * 4.0 + + a * pi * 2.0 + + args.time * 3.0 - + silkySmooth(args.time / 4.0, 2.0) * pi * 1.0 + ) * + 0.5 + + 0.5) * + args.mainRadius * + 0.1; + + vec2 pos = vec2(cos(a), sin(a)) * ringRadi; + float dd = length(args.st - pos) - args.mainRadius * 0.5; + + + d = opSmoothUnion( + d, + dd, + 0.03 * scaled(0.0, 10.0, args.duration) + 0.8 * (1.0 - entryAnimation) + ); + + + float dotAngle = f * pi * 2.0; + float dotRingRadius = + (sin( + thinkingDotEntryAnimation * pi * 4.0 + + a * pi * 2.0 + + args.time * 0.1 * pi * 4.0 + ) * + 0.5 + + 0.5) * + thinkingDotRadius * + 0.3; + vec2 dotPos = + vec2(-args.mainRadius, args.mainRadius) * 0.8 * thinkingDotEntryAnimation; + vec2 dotOffset = + vec2(cos(dotAngle + args.time), sin(dotAngle + args.time)) * + dotRingRadius; + float dotD = length(args.st - dotPos - dotOffset) - thinkingDotRadius * 0.8; + d = opSmoothUnion( + d, + dotD, + (1.0 - min(thinkingDotEntryAnimation, args.amount)) * thinkingDotRadius + ); + } + sdf.distance = mix(sdf.distance, d, args.amount); + sdf.color.a = 1.0; + return sdf; +} + +ColoredSDF applySpeakState( + ColoredSDF sdf, + SDFArgs args, + vec4 avgMag, + float silenceAmount, + float silenceDuration +) { + float d = 1000.0; + int barCount = 4; + for (int i = 0; i < barCount; i++) { + float f = float(float(i) + 0.5) / float(barCount); + + + float w = 1.0 / float(barCount) * 0.44; + float h = w; + + + float wave = sin(f * pi * 0.8 + args.time) * 0.5 + 0.5; + float entryAnimation = spring( + scaled(0.1 + wave * 0.4, 1.0 + wave * 0.4, args.duration), + 0.98 + ); + vec2 pos = vec2(f - 0.5, 0.0) * args.mainRadius * 1.9; + pos.y = 0.25 * (1.0 - entryAnimation); + + + if (silenceAmount > 0.0) { + float bounceStagger = f / 5.0; + float bounceDelay = 0.6; + float bounceTimer = scaled( + bounceDelay, + bounceDelay + 1.0, + fract((silenceDuration + bounceStagger) / 2.0) * 2.0 + ); + pos.y += + bounce(bounceTimer, 6.0) * + w * + 0.25 * + silenceAmount * + pow(entryAnimation, 4.0) * + pow(args.amount, 4.0); + } + + + h += avgMag[i] * (0.1 + (1.0 - abs(f - 0.5) * 2.0) * 0.1); + + float dd = sdRoundedBox(args.st - pos, vec2(w, h), vec4(w)); + d = opSmoothUnion(d, dd, 0.2 * (1.0 - args.amount)); + + } + + sdf.distance = mix(sdf.distance, d, args.amount); + sdf.color.a = 1.0; + return sdf; +} + +ColoredSDF applyListenAndSpeakState( + ColoredSDF sdf, + SDFArgs args, + float micLevel, + vec4 avgMag, + vec4 cumulativeAudio, + int binCount, + vec3 bloopColorMain, + vec3 bloopColorLow, + vec3 bloopColorMid, + vec3 bloopColorHigh, + sampler2D uTextureNoise, + bool listening, + bool isAdvancedBloop, + float xmassMode +) { + float entryAnimation = fixedSpring(scaled(0.0, 2.0, args.duration), 0.92); + + + + float radius = + (listening ? 0.37 : 0.43) * (1.0 - (1.0 - entryAnimation) * 0.25) + + micLevel * 0.065; + + + + + float maxDisplacement = 0.01; + + + float oscillationPeriod = 4.0; + + float displacementOffset = + maxDisplacement * sin(2.0 * pi / oscillationPeriod * args.time); + + vec2 adjusted_st = args.st - vec2(0.0, displacementOffset); + + + if (!isAdvancedBloop) { + sdf.color = mix(sdf.color, vec4(bloopColorMain, 1.0), args.amount); + sdf.distance = mix(sdf.distance, length(adjusted_st) - radius, args.amount); + return sdf; + } + + + + vec4 uAudioAverage = avgMag; + vec4 uCumulativeAudio = cumulativeAudio; + + + float scaleFactor = 1.0 / (2.0 * radius); + vec2 uv = adjusted_st * scaleFactor + 0.5; + uv.y = 1.0 - uv.y; + vec3 color; + + + float noiseScale = 1.25; + float windSpeed = 0.075; + float warpPower = 0.19; + float waterColorNoiseScale = 18.0; + float waterColorNoiseStrength = 0.01; + float textureNoiseScale = 1.0; + float textureNoiseStrength = 0.08; + float verticalOffset = 0.09; + float waveSpread = 1.0; + float layer1Amplitude = 1.0; + float layer1Frequency = 1.0; + float layer2Amplitude = 1.0; + float layer2Frequency = 1.0; + float layer3Amplitude = 1.0; + float layer3Frequency = 1.0; + float fbmStrength = 1.0; + float fbmPowerDamping = 0.55; + float overallSoundScale = 1.0; + float blurRadius = 1.0; + float timescale = 1.0; + + + float time = args.time * timescale * 0.85; + + + noiseScale = mix(1.25, 2.0, xmassMode); + waterColorNoiseStrength = mix(0.01, 0.005, xmassMode); + textureNoiseStrength = mix(0.03, 0.01, xmassMode); + blurRadius = mix(0.9, 0.7, xmassMode); + verticalOffset = mix(0.09, 0.0, xmassMode); + layer1Amplitude = mix(1.0, 0.5, xmassMode); + layer1Frequency = mix(1.0, 0.5, xmassMode); + layer2Amplitude = mix(1.0, 0.5, xmassMode); + layer2Frequency = mix(1.0, 0.5, xmassMode); + layer3Amplitude = mix(1.0, 0.5, xmassMode); + layer3Frequency = mix(1.0, 0.5, xmassMode); + waveSpread = mix(1.0, 0.25, xmassMode); + overallSoundScale = mix(1.0, 1.2, xmassMode); + + vec3 sinOffsets = vec3( + uCumulativeAudio.x * 0.15 * overallSoundScale, + -uCumulativeAudio.y * 0.5 * overallSoundScale, + uCumulativeAudio.z * 1.5 * overallSoundScale + ); + verticalOffset += 1.0 - waveSpread; + + + vec3 sinOffsetsXmass = vec3( + uCumulativeAudio.x * 0.15 * overallSoundScale * 0.9, + -uCumulativeAudio.y * 0.5 * overallSoundScale * 0.1875, + uCumulativeAudio.z * 1.5 * overallSoundScale * 0.45 + ); + sinOffsets = mix(sinOffsets, sinOffsetsXmass, xmassMode); + + + float noiseX = cnoise( + vec3( + uv * 1.0 + vec2(0.0, 74.8572), + (time + uCumulativeAudio.x * 0.05 * overallSoundScale) * 0.3 + ) + ); + float noiseY = cnoise( + vec3( + uv * 1.0 + vec2(203.91282, 10.0), + (time + uCumulativeAudio.z * 0.05 * overallSoundScale) * 0.3 + ) + ); + + vec2 uvBis = uv + vec2(noiseX * 2.0, noiseY) * warpPower * 0.25; + uv += vec2(noiseX * 2.0, noiseY) * warpPower; + + + float noiseA = + cnoise(vec3(uv * waterColorNoiseScale + vec2(344.91282, 0.0), time * 0.3)) + + cnoise( + vec3(uv * waterColorNoiseScale * 2.2 + vec2(723.937, 0.0), time * 0.4) + ) * + 0.5; + uv += noiseA * waterColorNoiseStrength; + uv.y -= verticalOffset; + + + vec2 textureUv = uv * textureNoiseScale; + float textureSampleR0 = texture(uTextureNoise, textureUv).r; + float textureSampleG0 = texture( + uTextureNoise, + vec2(textureUv.x, 1.0 - textureUv.y) + ).g; + float textureNoiseDisp0 = + mix( + textureSampleR0 - 0.5, + textureSampleG0 - 0.5, + (sin(time + uCumulativeAudio.a * 2.0) + 1.0) * 0.5 + ) * + textureNoiseStrength; + textureUv += vec2(63.861 + uCumulativeAudio.x * 0.05, 368.937); + float textureSampleR1 = texture(uTextureNoise, textureUv).r; + float textureSampleG1 = texture( + uTextureNoise, + vec2(textureUv.x, 1.0 - textureUv.y) + ).g; + float textureNoiseDisp1 = + mix( + textureSampleR1 - 0.5, + textureSampleG1 - 0.5, + (sin(time + uCumulativeAudio.a * 2.0) + 1.0) * 0.5 + ) * + textureNoiseStrength; + textureUv += vec2(272.861, 829.937 + uCumulativeAudio.y * 0.1); + textureUv += vec2(180.302 - uCumulativeAudio.z * 0.1, 819.871); + float textureSampleR3 = texture(uTextureNoise, textureUv).r; + float textureSampleG3 = texture( + uTextureNoise, + vec2(textureUv.x, 1.0 - textureUv.y) + ).g; + float textureNoiseDisp3 = + mix( + textureSampleR3 - 0.5, + textureSampleG3 - 0.5, + (sin(time + uCumulativeAudio.a * 2.0) + 1.0) * 0.5 + ) * + textureNoiseStrength; + uv += textureNoiseDisp0; + + + vec2 st = uv * noiseScale; + + vec2 q = vec2(0.0); + q.x = fbm( + st * 0.5 + + windSpeed * (time + uCumulativeAudio.a * 0.175 * overallSoundScale) + ); + q.y = fbm( + st * 0.5 + + windSpeed * (time + uCumulativeAudio.x * 0.136 * overallSoundScale) + ); + + vec2 r = vec2(0.0); + r.x = fbm( + st + + 1.0 * q + + vec2(0.3, 9.2) + + 0.15 * (time + uCumulativeAudio.y * 0.234 * overallSoundScale) + ); + r.y = fbm( + st + + 1.0 * q + + vec2(8.3, 0.8) + + 0.126 * (time + uCumulativeAudio.z * 0.165 * overallSoundScale) + ); + + float f = fbm(st + r - q); + float fullFbm = (f + 0.6 * f * f + 0.7 * f + 0.5) * 0.5; + fullFbm = pow(fullFbm, fbmPowerDamping); + fullFbm *= fbmStrength; + + + blurRadius = blurRadius * 1.5; + vec2 snUv = + (uv + vec2((fullFbm - 0.5) * 1.2) + vec2(0.0, 0.025) + textureNoiseDisp0) * + vec2(layer1Frequency, 1.0); + float sn = + noise( + snUv * 2.0 + vec2(sin(sinOffsets.x * 0.25), time * 0.5 + sinOffsets.x) + ) * + 2.0 * + layer1Amplitude; + float sn2 = smoothstep( + sn - 1.2 * blurRadius, + sn + 1.2 * blurRadius, + (snUv.y - 0.5 * waveSpread) * + (5.0 - uAudioAverage.x * 0.1 * overallSoundScale * 0.5) + + 0.5 + ); + + vec2 snUvBis = + (uv + vec2((fullFbm - 0.5) * 0.85) + vec2(0.0, 0.025) + textureNoiseDisp1) * + vec2(layer2Frequency, 1.0); + float snBis = + noise( + snUvBis * 4.0 + + vec2( + sin(sinOffsets.y * 0.15) * 2.4 + 293.0, + time * 1.0 + sinOffsets.y * 0.5 + ) + ) * + 2.0 * + layer2Amplitude; + float sn2Bis = smoothstep( + snBis - (0.9 + uAudioAverage.y * 0.4 * overallSoundScale) * blurRadius, + snBis + (0.9 + uAudioAverage.y * 0.8 * overallSoundScale) * blurRadius, + (snUvBis.y - 0.6 * waveSpread) * (5.0 - uAudioAverage.y * 0.75) + 0.5 + ); + + vec2 snUvThird = + (uv + vec2((fullFbm - 0.5) * 1.1) + textureNoiseDisp3) * + vec2(layer3Frequency, 1.0); + float snThird = + noise( + snUvThird * 6.0 + + vec2( + sin(sinOffsets.z * 0.1) * 2.4 + 153.0, + time * 1.2 + sinOffsets.z * 0.8 + ) + ) * + 2.0 * + layer3Amplitude; + float sn2Third = smoothstep( + snThird - 0.7 * blurRadius, + snThird + 0.7 * blurRadius, + (snUvThird.y - 0.9 * waveSpread) * 6.0 + 0.5 + ); + + sn2 = pow(sn2, 0.8); + sn2Bis = pow(sn2Bis, 0.9); + + + vec3 sinColor; + sinColor = blendLinearBurn_13_5(bloopColorMain, bloopColorLow, 1.0 - sn2); + sinColor = blendLinearBurn_13_5( + sinColor, + mix(bloopColorMain, bloopColorMid, 1.0 - sn2Bis), + sn2 + ); + sinColor = mix( + sinColor, + mix(bloopColorMain, bloopColorHigh, 1.0 - sn2Third), + sn2 * sn2Bis + ); + + + color = sinColor; + + + float XSPEED = noise(vec2(time * 0.5, time * 0.1)) * 0.75; + float YSPEED = cos(time + uCumulativeAudio.y * 0.05) * 0.75; + + vec2 wind = vec2(XSPEED, YSPEED); + + vec3 acc = vec3(0, 0, 0); + for (float i = 0.0; i < 9.0; i++) { + acc += SnowSingleLayer( + uvBis, + i * 0.85 + 0.75, + wind, + uCumulativeAudio, + time + ); + } + vec3 xmassColor; + xmassColor = mix( + vec3(0.004, 0.506, 0.996), + vec3(0.973, 0.984, 1.0), + 1.0 - sn2 + ); + xmassColor = mix( + xmassColor, + mix(vec3(0.004, 0.506, 0.996), vec3(1.0), 1.0 - sn2Bis), + sn2 + ); + xmassColor = mix( + xmassColor, + mix(vec3(0.004, 0.506, 0.996), vec3(1.0), 1.0 - sn2Third), + sn2 * sn2Bis + ); + xmassColor = mix(xmassColor, vec3(1.0), acc); + + + color.rgb = mix(color, xmassColor, xmassMode); + + + sdf.color = mix(sdf.color, vec4(color, 1), args.amount); + + + sdf.distance = mix(sdf.distance, length(adjusted_st) - radius, args.amount); + + return sdf; +} + +float micSdf(vec2 st, float muted) { + float d = 100.0; + float strokeWidth = 0.03; + vec2 elementSize = vec2(0.12, 0.26); + vec2 elementPos = vec2(0.0, elementSize.y * 0.585); + float element = sdRoundedBox( + st - elementPos, + elementSize, + vec4(min(elementSize.x, elementSize.y)) + ); + element = element - strokeWidth; + d = min(d, element); + + vec2 standSize = elementSize * 2.2; + vec2 standPos = vec2(elementPos.x, elementPos.y - 0.05); + st.y += 0.08; + float ta = -pi / 2.0; + float tb = pi / 2.0; + float w = 0.0; + float stand = sdArc( + st - standPos, + vec2(sin(ta), cos(ta)), + vec2(sin(tb), cos(tb)), + standSize.x, + w + ); + stand = min( + stand, + sdSegment(st - standPos, vec2(standSize.x, 0.06), vec2(standSize.x, 0.0)) + ); + stand = min( + stand, + sdSegment(st - standPos, vec2(-standSize.x, 0.06), vec2(-standSize.x, 0.0)) + ); + + float foot = sdSegment( + st - standPos, + vec2(0.0, -standSize.x), + vec2(0.0, -standSize.x * 1.66) + ); + foot = min( + foot, + sdSegment( + st - standPos, + vec2(-standSize.x * 0.68, -standSize.x * 1.66), + vec2(standSize.x * 0.68, -standSize.x * 1.66) + ) + ); + stand = min(stand, foot); + + d = min(d, abs(stand) - strokeWidth); + + return d; +} + +ColoredSDF applyBottomAlignedBarsAndMicState( + ColoredSDF sdf, + SDFArgs args, + vec4 avgMag, + float micLevel, + bool isDarkMode +) { + float d = 1000.0; + int barCount = 5; + int loopCount = barCount; + if (args.amount == 0.0) { + loopCount = 1; + } + for (int i = 0; i < loopCount; i++) { + float f = float(float(i) + 0.5) / float(barCount); + + + float w = 1.0 / float(barCount) * 0.42; + float h = w; + + + float entryDuration = 1.8; + float entryAnimation = + fixedSpring(scaled(0.0, entryDuration, args.duration), 0.94) * + args.amount; + vec2 pos = vec2(f - 0.5, 0.0) * args.mainRadius * 1.9; + pos.x *= entryAnimation; + + if (i == 0) { + float micScale = mix(6.0 - micLevel * 2.0, 6.0, args.amount); + float yOffset = w * 2.0; + d = + micSdf( + (args.st - pos + vec2(-w * 0.15 * args.amount, yOffset)) * micScale, + 1.0 - args.amount + ) / + micScale; + } else { + + h += avgMag[i - 1] * (0.1 + (1.0 - abs(f - 0.5) * 2.0) * 0.1) * 0.7; + h = mix(w, h, smoothstep(0.8, 1.0, entryAnimation)); + + float bubbleInDur = 0.5; + float bubbleOutDur = 0.4; + + + float bubbleEffect = + fixedSpring( + scaled( + f / 4.0, + f / 4.0 + bubbleInDur, + args.duration - entryDuration / 8.0 + ), + 1.0 + ) * + pow( + 1.0 - + scaled( + f / 8.0 + bubbleInDur / 8.0, + f / 4.0 + bubbleInDur / 8.0 + bubbleOutDur, + args.duration - entryDuration / 8.0 + ), + 2.0 + ); + + h += bubbleEffect * min(h, w); + + + w *= args.amount; + h *= args.amount; + + h = min(h, 0.23); + + pos.y -= 0.25; + pos.y += h; + pos.y += bubbleEffect * w * 0.5; + + float dd = sdRoundedBox(args.st - pos, vec2(w, h), vec4(w)); + d = min(d, dd); + } + } + + sdf.distance = d; + sdf.color = mix( + sdf.color, + isDarkMode + ? vec4(1.0) + : vec4(0.0, 0.0, 0.0, 1.0), + args.amount + ); + return sdf; +} + +ColoredSDF applyHaltState(ColoredSDF sdf, SDFArgs args) { + + float radius = mix( + 0.4, + mix(0.4, 0.45, args.amount), + sin(args.time * 0.25) * 0.5 + 0.5 + ); + float strokeWidth = mix(radius / 2.0, 0.02, args.amount); + + + radius -= strokeWidth; + + radius *= mix(0.7, 1.0, args.amount); + float circle = abs(length(args.st) - radius) - strokeWidth; + + sdf.distance = mix(sdf.distance, circle, args.amount); + sdf.color.a = mix(sdf.color.a, pow(0.8, 2.2), scaled(0.5, 1.0, args.amount)); + return sdf; +} + +vec3 blendNormal(vec3 base, vec3 blend) { + return blend; +} + +vec3 blendNormal(vec3 base, vec3 blend, float opacity) { + return blendNormal(base, blend) * opacity + base * (1.0 - opacity); +} + +in vec2 out_uv; +out vec4 fragColor; + +layout(std140) uniform BlorbUniformsObject { + float time; + float micLevel; + float touchDownTimestamp; + float touchUpTimestamp; + float stateListen; + float listenTimestamp; + float stateThink; + float thinkTimestamp; + float stateSpeak; + float speakTimestamp; + float readyTimestamp; + float stateHalt; + float haltTimestamp; + float stateFailedToConnect; + float failedToConnectTimestamp; + vec4 avgMag; + vec4 cumulativeAudio; + vec2 viewport; + float screenScaleFactor; + float silenceAmount; + float silenceTimestamp; + float xmassMode; + bool isDarkMode; + bool fadeBloopWhileListening; + bool isNewBloop; + bool isAdvancedBloop; + vec3 bloopColorMain; + vec3 bloopColorLow; + vec3 bloopColorMid; + vec3 bloopColorHigh; +} ubo; + +uniform sampler2D uTextureNoise; + +void main() { + vec2 st = out_uv - 0.5; + float viewRatio = ubo.viewport.y / ubo.viewport.x; + st.y *= viewRatio; + + ColoredSDF sdf; + sdf.distance = 1000.0; + sdf.color = vec4(1.0); + + SDFArgs args; + args.st = st; + args.time = ubo.time; + args.mainRadius = 0.49; + + SDFArgs idleArgs = args; + SDFArgs listenArgs = args; + SDFArgs thinkArgs = args; + SDFArgs speakArgs = args; + SDFArgs haltArgs = args; + SDFArgs failedToConnectArgs = args; + + idleArgs.amount = 1.0; + listenArgs.amount = ubo.stateListen; + thinkArgs.amount = ubo.stateThink; + speakArgs.amount = ubo.stateSpeak; + haltArgs.amount = ubo.stateHalt; + failedToConnectArgs.amount = ubo.stateFailedToConnect; + + idleArgs.duration = ubo.time - ubo.readyTimestamp; + listenArgs.duration = ubo.time - ubo.listenTimestamp; + thinkArgs.duration = ubo.time - ubo.thinkTimestamp; + speakArgs.duration = ubo.time - ubo.speakTimestamp; + haltArgs.duration = ubo.time - ubo.haltTimestamp; + failedToConnectArgs.duration = ubo.time - ubo.failedToConnectTimestamp; + + if (ubo.isNewBloop) { + sdf = applyIdleState(sdf, idleArgs, ubo.isDarkMode); + } else { + sdf = applyIdleStateLegacy(sdf, idleArgs, ubo.isDarkMode); + } + + if (failedToConnectArgs.amount > 0.0) { + sdf = applyHaltState(sdf, failedToConnectArgs); + } + + if (listenArgs.amount > 0.0) { + if (ubo.isAdvancedBloop) { + if (speakArgs.amount > 0.0) { + listenArgs.amount = 1.0; + } + + + int binCount = 1; + sdf = applyListenAndSpeakState( + sdf, + listenArgs, + ubo.micLevel, + ubo.avgMag, + ubo.cumulativeAudio, + binCount, + ubo.bloopColorMain, + ubo.bloopColorLow, + ubo.bloopColorMid, + ubo.bloopColorHigh, + uTextureNoise, + true, + ubo.isAdvancedBloop, + ubo.xmassMode + ); + } else { + sdf = applyListenState( + sdf, + listenArgs, + ubo.micLevel, + ubo.listenTimestamp, + ubo.touchDownTimestamp, + ubo.touchUpTimestamp, + ubo.fadeBloopWhileListening + ); + } + } + + if (thinkArgs.amount > 0.0) { + sdf = applyThinkState(sdf, thinkArgs); + } + + if (speakArgs.amount > 0.0) { + if (ubo.isAdvancedBloop) { + int binCount = 1; + sdf = applyListenAndSpeakState( + sdf, + speakArgs, + ubo.micLevel, + ubo.avgMag, + ubo.cumulativeAudio, + binCount, + ubo.bloopColorMain, + ubo.bloopColorLow, + ubo.bloopColorMid, + ubo.bloopColorHigh, + uTextureNoise, + false, + ubo.isAdvancedBloop, + ubo.xmassMode + ); + } else { + float silenceDuration = ubo.time - ubo.silenceTimestamp; + sdf = applySpeakState( + sdf, + speakArgs, + ubo.avgMag, + ubo.silenceAmount, + silenceDuration + ); + } + } + + if (haltArgs.amount > 0.0) { + sdf = applyHaltState(sdf, haltArgs); + } + + float clampingTolerance = 0.0075 / ubo.screenScaleFactor; + float clampedShape = smoothstep(clampingTolerance, 0.0, sdf.distance); + float alpha = sdf.color.a * clampedShape; + if (!ubo.isNewBloop) { + alpha *= scaled(0.0, 1.0, ubo.time); + } + fragColor = vec4(sdf.color.rgb * alpha, alpha); +} \ No newline at end of file diff --git a/app/shaders/vertex.glsl b/app/shaders/vertex.glsl new file mode 100644 index 000000000..f8e79d449 --- /dev/null +++ b/app/shaders/vertex.glsl @@ -0,0 +1,20 @@ +#version 300 es + +out vec4 out_position; +out vec2 out_uv; + +const vec4 blitFullscreenTrianglePositions[6] = vec4[]( + vec4(-1.0, -1.0, 0.0, 1.0), + vec4(3.0, -1.0, 0.0, 1.0), + vec4(-1.0, 3.0, 0.0, 1.0), + vec4(-1.0, -1.0, 0.0, 1.0), + vec4(3.0, -1.0, 0.0, 1.0), + vec4(-1.0, 3.0, 0.0, 1.0) +); + +void main() { + out_position = blitFullscreenTrianglePositions[gl_VertexID]; + out_uv = out_position.xy * 0.5 + 0.5; + out_uv.y = 1.0 - out_uv.y; + gl_Position = out_position; +} \ No newline at end of file diff --git a/app/store/chat.ts b/app/store/chat.ts index 0835d7519..910769c7d 100644 --- a/app/store/chat.ts +++ b/app/store/chat.ts @@ -1,4 +1,8 @@ -import { getMessageTextContent, trimTopic } from "../utils"; +import { + getMessageTextContent, + isFunctionCallModel, + trimTopic, +} from "../utils"; import { indexedDBStorage } from "@/app/utils/indexedDB-storage"; import { nanoid } from "nanoid"; @@ -448,74 +452,157 @@ export const useChatStore = createPersistStore( }); const api: ClientApi = getClientApi(modelConfig.providerName); - // make request - api.llm.chat({ - messages: sendMessages, - config: { ...modelConfig, stream: true }, - onUpdate(message) { - botMessage.streaming = true; - if (message) { - botMessage.content = message; - } - get().updateTargetSession(session, (session) => { - session.messages = session.messages.concat(); - }); - }, - onFinish(message) { - botMessage.streaming = false; - if (message) { - botMessage.content = message; - botMessage.date = new Date().toLocaleString(); - get().onNewMessage(botMessage, session); - } - ChatControllerPool.remove(session.id, botMessage.id); - }, - onBeforeTool(tool: ChatMessageTool) { - (botMessage.tools = botMessage?.tools || []).push(tool); - get().updateTargetSession(session, (session) => { - session.messages = session.messages.concat(); - }); - }, - onAfterTool(tool: ChatMessageTool) { - botMessage?.tools?.forEach((t, i, tools) => { - if (tool.id == t.id) { - tools[i] = { ...tool }; - } - }); - get().updateTargetSession(session, (session) => { - session.messages = session.messages.concat(); - }); - }, - onError(error) { - const isAborted = error.message?.includes?.("aborted"); - botMessage.content += - "\n\n" + - prettyObject({ - error: true, - message: error.message, - }); - botMessage.streaming = false; - userMessage.isError = !isAborted; - botMessage.isError = !isAborted; - get().updateTargetSession(session, (session) => { - session.messages = session.messages.concat(); - }); - ChatControllerPool.remove( - session.id, - botMessage.id ?? messageIndex, - ); + if ( + config.pluginConfig.enable && + session.mask.usePlugins && + (allPlugins.length > 0 || isEnableRAG) && + isFunctionCallModel(modelConfig.model) + ) { + console.log("[ToolAgent] start"); + let pluginToolNames = allPlugins.map((m) => m.toolName); + if (isEnableRAG) { + // other plugins will affect rag + // clear existing plugins here + pluginToolNames = []; + pluginToolNames.push("myfiles_browser"); + } + const agentCall = () => { + api.llm.toolAgentChat({ + chatSessionId: session.id, + messages: sendMessages, + config: { ...modelConfig, stream: true }, + agentConfig: { ...pluginConfig, useTools: pluginToolNames }, + onUpdate(message) { + botMessage.streaming = true; + if (message) { + botMessage.content = message; + } + get().updateTargetSession(session, (session) => { + session.messages = session.messages.concat(); + }); + }, + onToolUpdate(toolName, toolInput) { + botMessage.streaming = true; + if (toolName && toolInput) { + botMessage.toolMessages!.push({ + toolName, + toolInput, + }); + } + get().updateTargetSession(session, (session) => { + session.messages = session.messages.concat(); + }); + }, + onFinish(message) { + botMessage.streaming = false; + if (message) { + botMessage.content = message; + get().onNewMessage(botMessage, session); + } + ChatControllerPool.remove(session.id, botMessage.id); + }, + onError(error) { + const isAborted = error.message.includes("aborted"); + botMessage.content += + "\n\n" + + prettyObject({ + error: true, + message: error.message, + }); + botMessage.streaming = false; + userMessage.isError = !isAborted; + botMessage.isError = !isAborted; + get().updateTargetSession(session, (session) => { + session.messages = session.messages.concat(); + }); + ChatControllerPool.remove( + session.id, + botMessage.id ?? messageIndex, + ); - console.error("[Chat] failed ", error); - }, - onController(controller) { - // collect controller for stop/retry - ChatControllerPool.addController( - session.id, - botMessage.id ?? messageIndex, - controller, - ); - }, - }); + console.error("[Chat] failed ", error); + }, + onController(controller) { + // collect controller for stop/retry + ChatControllerPool.addController( + session.id, + botMessage.id ?? messageIndex, + controller, + ); + }, + }); + }; + agentCall(); + } else { + // make request + api.llm.chat({ + messages: sendMessages, + config: { ...modelConfig, stream: true }, + onUpdate(message) { + botMessage.streaming = true; + if (message) { + botMessage.content = message; + } + get().updateTargetSession(session, (session) => { + session.messages = session.messages.concat(); + }); + }, + onFinish(message) { + botMessage.streaming = false; + if (message) { + botMessage.content = message; + botMessage.date = new Date().toLocaleString(); + get().onNewMessage(botMessage, session); + } + ChatControllerPool.remove(session.id, botMessage.id); + }, + onBeforeTool(tool: ChatMessageTool) { + (botMessage.tools = botMessage?.tools || []).push(tool); + get().updateTargetSession(session, (session) => { + session.messages = session.messages.concat(); + }); + }, + onAfterTool(tool: ChatMessageTool) { + botMessage?.tools?.forEach((t, i, tools) => { + if (tool.id == t.id) { + tools[i] = { ...tool }; + } + }); + get().updateTargetSession(session, (session) => { + session.messages = session.messages.concat(); + }); + }, + onError(error) { + const isAborted = error.message?.includes?.("aborted"); + botMessage.content += + "\n\n" + + prettyObject({ + error: true, + message: error.message, + }); + botMessage.streaming = false; + userMessage.isError = !isAborted; + botMessage.isError = !isAborted; + get().updateTargetSession(session, (session) => { + session.messages = session.messages.concat(); + }); + ChatControllerPool.remove( + session.id, + botMessage.id ?? messageIndex, + ); + + console.error("[Chat] failed ", error); + }, + onController(controller) { + // collect controller for stop/retry + ChatControllerPool.addController( + session.id, + botMessage.id ?? messageIndex, + controller, + ); + }, + }); + } }, getMemoryPrompt() { diff --git a/app/utils/webgl.ts b/app/utils/webgl.ts new file mode 100644 index 000000000..f06d19eae --- /dev/null +++ b/app/utils/webgl.ts @@ -0,0 +1,95 @@ +export function initWebGL( + canvas: HTMLCanvasElement, + vertexShaderSource: string, + fragmentShaderSource: string, +) { + // 获取WebGL上下文 + const gl = canvas.getContext("webgl2", { + premultipliedAlpha: true, + }); + if (!gl) { + console.error("无法初始化WebGL2上下文"); + return { gl: null, program: null }; + } + + // 创建着色器程序 + const program = createShaderProgram( + gl, + vertexShaderSource, + fragmentShaderSource, + ); + if (!program) { + console.error("无法创建着色器程序"); + return { gl: null, program: null }; + } + + // 设置视口 + gl.viewport(0, 0, canvas.width, canvas.height); + + // 使用着色器程序 + gl.useProgram(program); + + return { gl, program }; +} + +function createShaderProgram( + gl: WebGL2RenderingContext, + vertexShaderSource: string, + fragmentShaderSource: string, +): WebGLProgram | null { + // 创建顶点着色器 + const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource); + if (!vertexShader) return null; + + // 创建片段着色器 + const fragmentShader = createShader( + gl, + gl.FRAGMENT_SHADER, + fragmentShaderSource, + ); + if (!fragmentShader) return null; + + // 创建着色器程序 + const program = gl.createProgram(); + if (!program) return null; + + // 附加着色器 + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + + // 链接程序 + gl.linkProgram(program); + + // 检查链接状态 + if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { + console.error("无法初始化着色器程序:", gl.getProgramInfoLog(program)); + return null; + } + + return program; +} + +function createShader( + gl: WebGL2RenderingContext, + type: number, + source: string, +): WebGLShader | null { + // 创建着色器 + const shader = gl.createShader(type); + if (!shader) return null; + + // 设置着色器源代码 + gl.shaderSource(shader, source); + + // 编译着色器 + gl.compileShader(shader); + + // 检查编译状态 + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + console.error("着色器编译错误:", gl.getShaderInfoLog(shader)); + gl.deleteShader(shader); + return null; + } + + return shader; +} diff --git a/next.config.mjs b/next.config.mjs index 74c6782d2..73e8913f0 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -13,7 +13,10 @@ const nextConfig = { test: /\.svg$/, use: ["@svgr/webpack"], }); - + config.module.rules.push({ + test: /\.(glsl|vs|fs|vert|frag)$/, + use: ["raw-loader"] + }); if (disableChunk) { config.plugins.push( new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }) diff --git a/package.json b/package.json index c6011d4eb..235b3c34a 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,6 @@ "@langchain/langgraph": "^0.0.33", "@langchain/ollama": "^0.0.4", "@langchain/openai": "^0.2.6", - "langchain": "0.2.15", "@next/third-parties": "^14.1.0", "@pinecone-database/pinecone": "^2.2.0", "@qdrant/js-client-rest": "^1.8.2", @@ -38,8 +37,9 @@ "@vercel/analytics": "^0.1.11", "@vercel/speed-insights": "^1.0.2", "axios": "^1.7.5", - "clsx": "^2.1.1", + "canvas": "^3.0.1", "cheerio": "^1.0.0-rc.12", + "clsx": "^2.1.1", "d3-dsv": "2", "duck-duck-scrape": "^2.2.4", "emoji-picker-react": "^4.9.2", @@ -49,9 +49,10 @@ "heic2any": "^0.0.4", "html-entities": "^2.4.0", "html-to-image": "^1.11.11", - "idb-keyval": "^6.2.1", "html-to-text": "^9.0.5", "https-proxy-agent": "^7.0.2", + "idb-keyval": "^6.2.1", + "langchain": "0.2.15", "mammoth": "^1.7.1", "markdown-to-txt": "^2.0.1", "md5": "^2.3.0", @@ -60,8 +61,8 @@ "nanoid": "^5.0.3", "next": "^14.1.1", "node-fetch": "^3.3.1", - "openapi-client-axios": "^7.5.5", "officeparser": "^4.0.8", + "openapi-client-axios": "^7.5.5", "pdf-parse": "^1.1.1", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -72,13 +73,13 @@ "remark-breaks": "^3.0.2", "remark-gfm": "^3.0.1", "remark-math": "^5.1.1", + "rt-client": "https://github.com/Azure-Samples/aoai-realtime-audio-sdk/releases/download/js/v0.5.0/rt-client-0.5.0.tgz", "sass": "^1.59.2", "sharp": "^0.33.3", "spark-md5": "^3.0.2", "srt-parser-2": "^1.2.3", "use-debounce": "^9.0.4", - "zustand": "^4.3.8", - "rt-client": "https://github.com/Azure-Samples/aoai-realtime-audio-sdk/releases/download/js/v0.5.0/rt-client-0.5.0.tgz" + "zustand": "^4.3.8" }, "devDependencies": { "@tauri-apps/api": "^1.6.0", @@ -86,16 +87,16 @@ "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.2", "@testing-library/react": "^16.0.1", + "@types/html-to-text": "^9.0.1", "@types/jest": "^29.5.14", "@types/js-yaml": "4.0.9", "@types/lodash-es": "^4.17.12", + "@types/md5": "^2.3.5", "@types/node": "^20.11.30", "@types/react": "^18.2.70", "@types/react-dom": "^18.2.7", "@types/react-katex": "^3.0.0", "@types/spark-md5": "^3.0.4", - "@types/html-to-text": "^9.0.1", - "@types/md5": "^2.3.5", "concurrently": "^8.2.2", "cross-env": "^7.0.3", "eslint": "^8.49.0", @@ -112,11 +113,12 @@ "tsx": "^4.16.0", "typescript": "5.2.2", "watch": "^1.0.2", - "webpack": "^5.88.1" + "webpack": "^5.88.1", + "raw-loader": "^4.0.2" }, "resolutions": { "lint-staged/yaml": "^2.2.2", "@langchain/core": "0.2.23" }, "packageManager": "yarn@1.22.19" -} \ No newline at end of file +} diff --git a/public/noise-texture.webp b/public/noise-texture.webp new file mode 100644 index 0000000000000000000000000000000000000000..f987e2f54b4dd12dd6ce56ea4f2ea7c46879053d GIT binary patch literal 33578 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 G00021_du2a literal 0 HcmV?d00001 diff --git a/yarn.lock b/yarn.lock index 3ffe192aa..0a45f4b4c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4446,6 +4446,11 @@ bath-es5@^3.0.3: resolved "https://registry.yarnpkg.com/bath-es5/-/bath-es5-3.0.3.tgz#4e2808e8b33b4a5e3328ec1e9032f370f042193d" integrity sha512-PdCioDToH3t84lP40kUFCKWCOCH389Dl1kbC8FGoqOwamxsmqxxnJSXdkTOsPoNHXjem4+sJ+bbNoQm5zeCqxg== +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + binary-extensions@^2.0.0, binary-extensions@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" @@ -4464,6 +4469,15 @@ bl@^1.0.0: readable-stream "^2.3.5" safe-buffer "^5.1.1" +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + bluebird@^3.7.2: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" @@ -4561,7 +4575,7 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer@^5.2.1: +buffer@^5.2.1, buffer@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -4612,6 +4626,15 @@ caniuse-lite@^1.0.30001669: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz#27c2e2c637e007cfa864a16f7dfe7cde66b38b5f" integrity sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog== +canvas@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/canvas/-/canvas-3.0.1.tgz#b536df1d5c8c33c64f7752c499b3ff96a43eaf27" + integrity sha512-PcpVF4f8RubAeN/jCQQ/UymDKzOiLmRPph8fOTzDnlsUihkO/AUlxuhaa7wGRc3vMcCbV1fzuvyu5cWZlIcn1w== + dependencies: + node-addon-api "^7.0.0" + prebuild-install "^7.1.1" + simple-get "^3.0.3" + ccount@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" @@ -4702,6 +4725,11 @@ cheerio@^1.0.0-rc.12: optionalDependencies: fsevents "~2.3.2" +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + chrome-trace-event@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" @@ -5423,6 +5451,20 @@ decode-named-character-reference@^1.0.0: dependencies: character-entities "^2.0.0" +decompress-response@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" + integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== + dependencies: + mimic-response "^2.0.0" + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" @@ -5512,6 +5554,11 @@ deep-equal@^2.0.5: which-collection "^1.0.1" which-typed-array "^1.1.13" +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -5562,7 +5609,7 @@ dereference-json-schema@^0.2.1: resolved "https://registry.yarnpkg.com/dereference-json-schema/-/dereference-json-schema-0.2.1.tgz#fcad3c98e0116f7124b0989d39d947fa318cae09" integrity sha512-uzJsrg225owJyRQ8FNTPHIuBOdSzIZlHhss9u6W8mp7jJldHqGuLv9cULagP/E26QVJDnjtG8U7Dw139mM1ydA== -detect-libc@^2.0.3: +detect-libc@^2.0.0, detect-libc@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== @@ -5747,6 +5794,11 @@ emoji-regex@^9.2.2: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + encoding@^0.1.13: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" @@ -5754,7 +5806,7 @@ encoding@^0.1.13: dependencies: iconv-lite "^0.6.2" -end-of-stream@^1.0.0: +end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== @@ -6317,6 +6369,11 @@ exit@^0.1.2: resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + expect@^29.0.0, expect@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" @@ -6643,6 +6700,11 @@ get-tsconfig@^4.5.0, get-tsconfig@^4.7.5: dependencies: resolve-pkg-maps "^1.0.0" +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -7058,11 +7120,16 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.3, inherits@~2.0.3: +inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + inline-style-parser@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" @@ -7908,7 +7975,7 @@ json5@^1.0.2: dependencies: minimist "^1.2.0" -json5@^2.2.3: +json5@^2.1.2, json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -8123,6 +8190,15 @@ loader-runner@^4.2.0: resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== +loader-utils@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" + integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -8825,6 +8901,16 @@ mimic-fn@^4.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== +mimic-response@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" + integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + min-indent@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" @@ -8844,11 +8930,16 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + ml-array-mean@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/ml-array-mean/-/ml-array-mean-1.1.6.tgz#d951a700dc8e3a17b3e0a583c2c64abd0c619c56" @@ -8915,6 +9006,11 @@ nanoid@^5.0.3: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-5.0.7.tgz#6452e8c5a816861fd9d2b898399f7e5fd6944cc6" integrity sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ== +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -8956,6 +9052,18 @@ next@^14.1.1: "@next/swc-win32-ia32-msvc" "14.2.5" "@next/swc-win32-x64-msvc" "14.2.5" +node-abi@^3.3.0: + version "3.71.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.71.0.tgz#52d84bbcd8575efb71468fbaa1f9a49b2c242038" + integrity sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw== + dependencies: + semver "^7.3.5" + +node-addon-api@^7.0.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.1.1.tgz#1aba6693b0f255258a049d621329329322aad558" + integrity sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ== + node-domexception@1.0.0, node-domexception@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" @@ -9126,7 +9234,7 @@ ollama@^0.5.6: dependencies: whatwg-fetch "^3.6.20" -once@^1.3.0, once@^1.4.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -9438,6 +9546,24 @@ postcss@8.4.31: picocolors "^1.0.0" source-map-js "^1.0.2" +prebuild-install@^7.1.1: + version "7.1.2" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.2.tgz#a5fd9986f5a6251fbc47e1e5c65de71e68c0a056" + integrity sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -9510,6 +9636,14 @@ psl@^1.1.33: resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== +pump@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.2.tgz#836f3edd6bc2ee599256c924ffe0d88573ddcbf8" + integrity sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + punycode@^2.1.0, punycode@^2.1.1: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" @@ -9542,6 +9676,24 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" +raw-loader@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6" + integrity sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + react-dom@^18.2.0: version "18.3.1" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" @@ -9633,7 +9785,7 @@ readable-stream@^2.3.0, readable-stream@^2.3.5, readable-stream@~2.3.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.6.0: +readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -9952,7 +10104,7 @@ safe-array-concat@^1.1.2: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.2.0: +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -10004,7 +10156,7 @@ scheduler@^0.23.2: dependencies: loose-envify "^1.1.0" -schema-utils@^3.1.1, schema-utils@^3.2.0: +schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== @@ -10032,7 +10184,7 @@ semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.3: +semver@^7.3.5, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.3: version "7.6.3" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== @@ -10132,6 +10284,29 @@ signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.1.tgz#cc7ba77cfbe761036fbfce3d021af25fc5584d55" + integrity sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA== + dependencies: + decompress-response "^4.2.0" + once "^1.3.1" + simple-concat "^1.0.0" + +simple-get@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" @@ -10392,6 +10567,11 @@ strip-json-comments@^3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + strnum@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" @@ -10486,6 +10666,16 @@ tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +tar-fs@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + tar-stream@^1.5.2: version "1.6.2" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" @@ -10499,6 +10689,17 @@ tar-stream@^1.5.2: to-buffer "^1.1.1" xtend "^4.0.0" +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + terser-webpack-plugin@^5.3.10: version "5.3.10" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" @@ -10684,6 +10885,13 @@ tsx@^4.16.0: optionalDependencies: fsevents "~2.3.3" +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"