@promptbook/browser 0.112.0-117 → 0.112.0-119
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/index.es.js +197 -44
- package/esm/index.es.js.map +1 -1
- package/esm/src/_packages/node.index.d.ts +10 -0
- package/esm/src/book-3.0/BookNodeAgentSource.d.ts +1 -1
- package/esm/src/book-3.0/CliAgent.d.ts +7 -2
- package/esm/src/book-3.0/cliAgentEnv.d.ts +33 -0
- package/esm/src/book-components/BookEditor/BookEditor.d.ts +1 -1
- package/esm/src/book-components/BookEditor/BookEditorForClient.d.ts +1 -1
- package/esm/src/book-components/Chat/Chat/CitationIframePreview.d.ts +20 -0
- package/esm/src/book-components/_common/Dropdown/Dropdown.d.ts +1 -1
- package/esm/src/book-components/_common/MenuHoisting/MenuHoistingContext.d.ts +1 -1
- package/esm/src/book-components/_common/Modal/Modal.d.ts +1 -1
- package/esm/src/book-components/icons/AboutIcon.d.ts +1 -1
- package/esm/src/book-components/icons/DownloadIcon.d.ts +1 -1
- package/esm/src/book-components/icons/ExitFullscreenIcon.d.ts +1 -1
- package/esm/src/book-components/icons/FullscreenIcon.d.ts +1 -1
- package/esm/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +2 -18
- package/esm/src/version.d.ts +1 -1
- package/package.json +2 -2
- package/umd/index.umd.js +197 -44
- package/umd/index.umd.js.map +1 -1
- package/umd/src/_packages/node.index.d.ts +10 -0
- package/umd/src/book-3.0/BookNodeAgentSource.d.ts +1 -1
- package/umd/src/book-3.0/CliAgent.d.ts +7 -2
- package/umd/src/book-3.0/cliAgentEnv.d.ts +33 -0
- package/umd/src/book-components/BookEditor/BookEditor.d.ts +1 -1
- package/umd/src/book-components/BookEditor/BookEditorForClient.d.ts +1 -1
- package/umd/src/book-components/Chat/Chat/CitationIframePreview.d.ts +20 -0
- package/umd/src/book-components/_common/Dropdown/Dropdown.d.ts +1 -1
- package/umd/src/book-components/_common/MenuHoisting/MenuHoistingContext.d.ts +1 -1
- package/umd/src/book-components/_common/Modal/Modal.d.ts +1 -1
- package/umd/src/book-components/icons/AboutIcon.d.ts +1 -1
- package/umd/src/book-components/icons/DownloadIcon.d.ts +1 -1
- package/umd/src/book-components/icons/ExitFullscreenIcon.d.ts +1 -1
- package/umd/src/book-components/icons/FullscreenIcon.d.ts +1 -1
- package/umd/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +2 -18
- package/umd/src/version.d.ts +1 -1
package/esm/index.es.js
CHANGED
|
@@ -28,7 +28,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
28
28
|
* @generated
|
|
29
29
|
* @see https://github.com/webgptorg/promptbook
|
|
30
30
|
*/
|
|
31
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
31
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-119';
|
|
32
32
|
/**
|
|
33
33
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
34
34
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -6160,21 +6160,22 @@ function getPointBounds(points) {
|
|
|
6160
6160
|
* @private helper of `fractalAvatarVisual`
|
|
6161
6161
|
*/
|
|
6162
6162
|
function drawDragonCurveLayer(context, points, options) {
|
|
6163
|
-
const {
|
|
6163
|
+
const { primaryColor, secondaryColor, tertiaryColor, shadowColor, strokeWidth, timeMs, layerIndex } = options;
|
|
6164
6164
|
const firstPoint = points[0];
|
|
6165
6165
|
const lastPoint = points[points.length - 1];
|
|
6166
6166
|
const ribbonGradient = context.createLinearGradient(firstPoint.x, firstPoint.y, lastPoint.x, lastPoint.y);
|
|
6167
6167
|
ribbonGradient.addColorStop(0, `${primaryColor}f2`);
|
|
6168
6168
|
ribbonGradient.addColorStop(0.5, `${secondaryColor}e6`);
|
|
6169
6169
|
ribbonGradient.addColorStop(1, `${tertiaryColor}f2`);
|
|
6170
|
+
// Approximate the blurred shadow stroke with a wider semi-transparent stroke instead of
|
|
6171
|
+
// context.filter blur, which triggers a costly software rasterization pass every frame.
|
|
6170
6172
|
context.save();
|
|
6171
6173
|
context.beginPath();
|
|
6172
6174
|
tracePolyline(context, points);
|
|
6173
|
-
context.strokeStyle = `${shadowColor}
|
|
6174
|
-
context.lineWidth = strokeWidth *
|
|
6175
|
+
context.strokeStyle = `${shadowColor}48`;
|
|
6176
|
+
context.lineWidth = strokeWidth * 4.5;
|
|
6175
6177
|
context.lineJoin = 'round';
|
|
6176
6178
|
context.lineCap = 'round';
|
|
6177
|
-
context.filter = `blur(${size * 0.022}px)`;
|
|
6178
6179
|
context.stroke();
|
|
6179
6180
|
context.restore();
|
|
6180
6181
|
context.beginPath();
|
|
@@ -6758,11 +6759,23 @@ function drawMinecraftBackdrop(context, size, palette, sceneCenterX, spotlightY,
|
|
|
6758
6759
|
* @private helper of `minecraft2AvatarVisual`
|
|
6759
6760
|
*/
|
|
6760
6761
|
function drawMinecraftShadow(context, size, palette, interaction, timeMs) {
|
|
6762
|
+
const cx = size * 0.5 + interaction.gazeX * size * 0.03;
|
|
6763
|
+
const cy = size * 0.85 + Math.sin(timeMs / 880) * size * 0.01;
|
|
6764
|
+
const rx = size * (0.16 + interaction.intensity * 0.015);
|
|
6765
|
+
const ry = size * 0.055;
|
|
6766
|
+
// Radial gradient approximates the blurry ellipse shadow without context.filter blur.
|
|
6761
6767
|
context.save();
|
|
6762
|
-
context.
|
|
6763
|
-
context.
|
|
6768
|
+
context.translate(cx, cy);
|
|
6769
|
+
context.scale(1, ry / rx);
|
|
6770
|
+
const blurRadius = rx * 1.4;
|
|
6771
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
6772
|
+
shadowGradient.addColorStop(0, `${palette.shadow}7a`);
|
|
6773
|
+
shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
|
|
6774
|
+
shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
|
|
6775
|
+
shadowGradient.addColorStop(1, `${palette.shadow}00`);
|
|
6776
|
+
context.fillStyle = shadowGradient;
|
|
6764
6777
|
context.beginPath();
|
|
6765
|
-
context.
|
|
6778
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
6766
6779
|
context.fill();
|
|
6767
6780
|
context.restore();
|
|
6768
6781
|
}
|
|
@@ -6986,13 +6999,27 @@ const minecraftAvatarVisual = {
|
|
|
6986
6999
|
spotlight.addColorStop(1, `${palette.highlight}00`);
|
|
6987
7000
|
context.fillStyle = spotlight;
|
|
6988
7001
|
context.fillRect(0, 0, size, size);
|
|
6989
|
-
|
|
6990
|
-
|
|
6991
|
-
|
|
6992
|
-
|
|
6993
|
-
|
|
6994
|
-
|
|
6995
|
-
|
|
7002
|
+
{
|
|
7003
|
+
// Radial gradient approximates the blurry ellipse shadow without context.filter blur.
|
|
7004
|
+
const cx = size * 0.5;
|
|
7005
|
+
const cy = size * 0.86;
|
|
7006
|
+
const rx = size * 0.2;
|
|
7007
|
+
const ry = size * 0.06;
|
|
7008
|
+
const blurRadius = rx * 1.4;
|
|
7009
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
7010
|
+
shadowGradient.addColorStop(0, 'rgba(0,0,0,0.28)');
|
|
7011
|
+
shadowGradient.addColorStop(0.45, 'rgba(0,0,0,0.14)');
|
|
7012
|
+
shadowGradient.addColorStop(0.8, 'rgba(0,0,0,0.05)');
|
|
7013
|
+
shadowGradient.addColorStop(1, 'rgba(0,0,0,0)');
|
|
7014
|
+
context.save();
|
|
7015
|
+
context.translate(cx, cy);
|
|
7016
|
+
context.scale(1, ry / rx);
|
|
7017
|
+
context.fillStyle = shadowGradient;
|
|
7018
|
+
context.beginPath();
|
|
7019
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
7020
|
+
context.fill();
|
|
7021
|
+
context.restore();
|
|
7022
|
+
}
|
|
6996
7023
|
drawVoxelCuboid(context, {
|
|
6997
7024
|
x: bodyX,
|
|
6998
7025
|
y: bodyY,
|
|
@@ -8044,6 +8071,35 @@ const LIGHT_DIRECTION$2 = normalizeVector3({
|
|
|
8044
8071
|
y: -0.62,
|
|
8045
8072
|
z: 0.94,
|
|
8046
8073
|
});
|
|
8074
|
+
/**
|
|
8075
|
+
* Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
|
|
8076
|
+
*
|
|
8077
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
8078
|
+
*/
|
|
8079
|
+
const octopus3dStableStateCache = new WeakMap();
|
|
8080
|
+
/**
|
|
8081
|
+
* Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
|
|
8082
|
+
*
|
|
8083
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
8084
|
+
*/
|
|
8085
|
+
function getOctopus3dStableState(createRandom) {
|
|
8086
|
+
const cached = octopus3dStableStateCache.get(createRandom);
|
|
8087
|
+
if (cached !== undefined) {
|
|
8088
|
+
return cached;
|
|
8089
|
+
}
|
|
8090
|
+
const animationRandom = createRandom('octopus3d-animation-profile');
|
|
8091
|
+
const eyeRandom = createRandom('octopus3d-eye-profile');
|
|
8092
|
+
const leftEyePhaseOffset = eyeRandom() * 0.6;
|
|
8093
|
+
const rightEyePhaseOffset = eyeRandom() * 0.6;
|
|
8094
|
+
const state = {
|
|
8095
|
+
morphologyProfile: createOctopus3MorphologyProfile(createRandom),
|
|
8096
|
+
animationPhase: animationRandom() * Math.PI * 2,
|
|
8097
|
+
leftEyePhaseOffset,
|
|
8098
|
+
rightEyePhaseOffset,
|
|
8099
|
+
};
|
|
8100
|
+
octopus3dStableStateCache.set(createRandom, state);
|
|
8101
|
+
return state;
|
|
8102
|
+
}
|
|
8047
8103
|
/**
|
|
8048
8104
|
* Proper 3D Octopus visual built from projected organic meshes and tentacles.
|
|
8049
8105
|
*
|
|
@@ -8056,10 +8112,7 @@ const octopus3dAvatarVisual = {
|
|
|
8056
8112
|
isAnimated: true,
|
|
8057
8113
|
supportsPointerTracking: true,
|
|
8058
8114
|
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
8059
|
-
const morphologyProfile =
|
|
8060
|
-
const animationRandom = createRandom('octopus3d-animation-profile');
|
|
8061
|
-
const eyeRandom = createRandom('octopus3d-eye-profile');
|
|
8062
|
-
const animationPhase = animationRandom() * Math.PI * 2;
|
|
8115
|
+
const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3dStableState(createRandom);
|
|
8063
8116
|
const sceneCenterX = size * 0.5;
|
|
8064
8117
|
const sceneCenterY = size * 0.56;
|
|
8065
8118
|
const bob = Math.sin(timeMs / 920 + animationPhase) * size * 0.014;
|
|
@@ -8156,12 +8209,12 @@ const octopus3dAvatarVisual = {
|
|
|
8156
8209
|
x: -faceEyeSpacing,
|
|
8157
8210
|
y: faceEyeYOffset,
|
|
8158
8211
|
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -faceEyeSpacing, faceEyeYOffset),
|
|
8159
|
-
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase +
|
|
8212
|
+
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
8160
8213
|
drawProjectedOrganicEye(context, {
|
|
8161
8214
|
x: faceEyeSpacing,
|
|
8162
8215
|
y: faceEyeYOffset,
|
|
8163
8216
|
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, faceEyeSpacing, faceEyeYOffset),
|
|
8164
|
-
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 +
|
|
8217
|
+
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
8165
8218
|
drawProjectedOrganicMouth(context, [
|
|
8166
8219
|
{
|
|
8167
8220
|
x: -mouthHalfWidth,
|
|
@@ -8205,14 +8258,28 @@ function drawOctopus3dAtmosphere(context, size, palette, sceneCenterX, sceneCent
|
|
|
8205
8258
|
/**
|
|
8206
8259
|
* Draws the soft ground shadow below the octopus.
|
|
8207
8260
|
*
|
|
8261
|
+
* Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
|
|
8262
|
+
* blurry ellipse without triggering a costly software rasterization pass on every frame.
|
|
8263
|
+
*
|
|
8208
8264
|
* @private helper of `octopus3dAvatarVisual`
|
|
8209
8265
|
*/
|
|
8210
8266
|
function drawOctopus3dShadow(context, size, palette, interaction, timeMs) {
|
|
8267
|
+
const cx = size * 0.5 + interaction.gazeX * size * 0.04;
|
|
8268
|
+
const cy = size * 0.87 + Math.sin(timeMs / 920) * size * 0.008;
|
|
8269
|
+
const rx = size * (0.18 + interaction.intensity * 0.02);
|
|
8270
|
+
const ry = size * 0.06;
|
|
8211
8271
|
context.save();
|
|
8212
|
-
context.
|
|
8213
|
-
context.
|
|
8272
|
+
context.translate(cx, cy);
|
|
8273
|
+
context.scale(1, ry / rx);
|
|
8274
|
+
const blurRadius = rx * 1.4;
|
|
8275
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
8276
|
+
shadowGradient.addColorStop(0, `${palette.shadow}7a`);
|
|
8277
|
+
shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
|
|
8278
|
+
shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
|
|
8279
|
+
shadowGradient.addColorStop(1, `${palette.shadow}00`);
|
|
8280
|
+
context.fillStyle = shadowGradient;
|
|
8214
8281
|
context.beginPath();
|
|
8215
|
-
context.
|
|
8282
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
8216
8283
|
context.fill();
|
|
8217
8284
|
context.restore();
|
|
8218
8285
|
}
|
|
@@ -8443,6 +8510,35 @@ const LIGHT_DIRECTION$1 = normalizeVector3({
|
|
|
8443
8510
|
y: -0.6,
|
|
8444
8511
|
z: 0.98,
|
|
8445
8512
|
});
|
|
8513
|
+
/**
|
|
8514
|
+
* Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
|
|
8515
|
+
*
|
|
8516
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
8517
|
+
*/
|
|
8518
|
+
const octopus3d2StableStateCache = new WeakMap();
|
|
8519
|
+
/**
|
|
8520
|
+
* Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
|
|
8521
|
+
*
|
|
8522
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
8523
|
+
*/
|
|
8524
|
+
function getOctopus3d2StableState(createRandom) {
|
|
8525
|
+
const cached = octopus3d2StableStateCache.get(createRandom);
|
|
8526
|
+
if (cached !== undefined) {
|
|
8527
|
+
return cached;
|
|
8528
|
+
}
|
|
8529
|
+
const animationRandom = createRandom('octopus3d2-animation-profile');
|
|
8530
|
+
const eyeRandom = createRandom('octopus3d2-eye-profile');
|
|
8531
|
+
const leftEyePhaseOffset = eyeRandom() * 0.7;
|
|
8532
|
+
const rightEyePhaseOffset = eyeRandom() * 0.7;
|
|
8533
|
+
const state = {
|
|
8534
|
+
morphologyProfile: createOctopus3MorphologyProfile(createRandom),
|
|
8535
|
+
animationPhase: animationRandom() * Math.PI * 2,
|
|
8536
|
+
leftEyePhaseOffset,
|
|
8537
|
+
rightEyePhaseOffset,
|
|
8538
|
+
};
|
|
8539
|
+
octopus3d2StableStateCache.set(createRandom, state);
|
|
8540
|
+
return state;
|
|
8541
|
+
}
|
|
8446
8542
|
/**
|
|
8447
8543
|
* Octopus 3D 2 avatar visual.
|
|
8448
8544
|
*
|
|
@@ -8455,10 +8551,7 @@ const octopus3d2AvatarVisual = {
|
|
|
8455
8551
|
isAnimated: true,
|
|
8456
8552
|
supportsPointerTracking: true,
|
|
8457
8553
|
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
8458
|
-
const morphologyProfile =
|
|
8459
|
-
const animationRandom = createRandom('octopus3d2-animation-profile');
|
|
8460
|
-
const eyeRandom = createRandom('octopus3d2-eye-profile');
|
|
8461
|
-
const animationPhase = animationRandom() * Math.PI * 2;
|
|
8554
|
+
const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3d2StableState(createRandom);
|
|
8462
8555
|
const sceneCenterX = size * 0.5;
|
|
8463
8556
|
const sceneCenterY = size * 0.575;
|
|
8464
8557
|
const bob = Math.sin(timeMs / 940 + animationPhase) * size * 0.013;
|
|
@@ -8511,8 +8604,8 @@ const octopus3d2AvatarVisual = {
|
|
|
8511
8604
|
const rightEyeLocalCenter = sampleBlobbyOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude);
|
|
8512
8605
|
const eyeRadiusX = size * morphologyProfile.face.eyeRadiusXRatio * 0.78;
|
|
8513
8606
|
const eyeRadiusY = eyeRadiusX * morphologyProfile.face.eyeHeightRatio * 0.92;
|
|
8514
|
-
drawProjectedOrganicEye(context, leftEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase +
|
|
8515
|
-
drawProjectedOrganicEye(context, rightEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.9 +
|
|
8607
|
+
drawProjectedOrganicEye(context, leftEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
8608
|
+
drawProjectedOrganicEye(context, rightEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.9 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
8516
8609
|
drawProjectedOrganicMouth(context, [
|
|
8517
8610
|
sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude - mouthHalfLongitude),
|
|
8518
8611
|
sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthCurveLatitude, mouthCenterLongitude),
|
|
@@ -8541,14 +8634,28 @@ function drawBlobbyOctopusAtmosphere(context, size, palette, sceneCenterX, scene
|
|
|
8541
8634
|
/**
|
|
8542
8635
|
* Draws the soft floor shadow that anchors the single mesh in the frame.
|
|
8543
8636
|
*
|
|
8637
|
+
* Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
|
|
8638
|
+
* blurry ellipse without triggering a costly software rasterization pass on every frame.
|
|
8639
|
+
*
|
|
8544
8640
|
* @private helper of `octopus3d2AvatarVisual`
|
|
8545
8641
|
*/
|
|
8546
8642
|
function drawBlobbyOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile) {
|
|
8643
|
+
const cx = size * 0.5 + interaction.gazeX * size * 0.045;
|
|
8644
|
+
const cy = size * 0.88 + Math.sin(timeMs / 940) * size * 0.008;
|
|
8645
|
+
const rx = size * (0.18 + (morphologyProfile.body.horizontalStretch - 1) * 0.04 + interaction.intensity * 0.018);
|
|
8646
|
+
const ry = size * 0.062;
|
|
8547
8647
|
context.save();
|
|
8548
|
-
context.
|
|
8549
|
-
context.
|
|
8648
|
+
context.translate(cx, cy);
|
|
8649
|
+
context.scale(1, ry / rx);
|
|
8650
|
+
const blurRadius = rx * 1.4;
|
|
8651
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
8652
|
+
shadowGradient.addColorStop(0, `${palette.shadow}7a`);
|
|
8653
|
+
shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
|
|
8654
|
+
shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
|
|
8655
|
+
shadowGradient.addColorStop(1, `${palette.shadow}00`);
|
|
8656
|
+
context.fillStyle = shadowGradient;
|
|
8550
8657
|
context.beginPath();
|
|
8551
|
-
context.
|
|
8658
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
8552
8659
|
context.fill();
|
|
8553
8660
|
context.restore();
|
|
8554
8661
|
}
|
|
@@ -8704,6 +8811,40 @@ const LIGHT_DIRECTION = normalizeVector3({
|
|
|
8704
8811
|
* @private helper of `octopus3d3AvatarVisual`
|
|
8705
8812
|
*/
|
|
8706
8813
|
const OCTOPUS_TENTACLE_COUNT = 8;
|
|
8814
|
+
/**
|
|
8815
|
+
* Cache keyed by the `createRandom` factory reference, which is stable for the lifetime of one
|
|
8816
|
+
* mounted `<Avatar/>` component (created inside `resolveAvatarRenderDefinition` and held in a
|
|
8817
|
+
* React `useMemo`). Using a `WeakMap` ensures the entry is collected when the component unmounts.
|
|
8818
|
+
*
|
|
8819
|
+
* @private helper of `octopus3d3AvatarVisual`
|
|
8820
|
+
*/
|
|
8821
|
+
const stableStateCache = new WeakMap();
|
|
8822
|
+
/**
|
|
8823
|
+
* Returns the stable per-avatar state, computing it on first access and returning the cached
|
|
8824
|
+
* result on every subsequent call within the same `<Avatar/>` mount.
|
|
8825
|
+
*
|
|
8826
|
+
* @private helper of `octopus3d3AvatarVisual`
|
|
8827
|
+
*/
|
|
8828
|
+
function getOctopus3d3StableState(createRandom) {
|
|
8829
|
+
const cached = stableStateCache.get(createRandom);
|
|
8830
|
+
if (cached !== undefined) {
|
|
8831
|
+
return cached;
|
|
8832
|
+
}
|
|
8833
|
+
const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
|
|
8834
|
+
const animationRandom = createRandom('octopus3d3-animation-profile');
|
|
8835
|
+
const eyeRandom = createRandom('octopus3d3-eye-profile');
|
|
8836
|
+
const leftEyePhaseOffset = eyeRandom() * 0.7;
|
|
8837
|
+
const rightEyePhaseOffset = eyeRandom() * 0.7;
|
|
8838
|
+
const state = {
|
|
8839
|
+
morphologyProfile,
|
|
8840
|
+
animationPhase: animationRandom() * Math.PI * 2,
|
|
8841
|
+
leftEyePhaseOffset,
|
|
8842
|
+
rightEyePhaseOffset,
|
|
8843
|
+
tentacleProfiles: createContinuousTentacleProfiles(createRandom, morphologyProfile),
|
|
8844
|
+
};
|
|
8845
|
+
stableStateCache.set(createRandom, state);
|
|
8846
|
+
return state;
|
|
8847
|
+
}
|
|
8707
8848
|
/**
|
|
8708
8849
|
* Octopus 3D 3 avatar visual.
|
|
8709
8850
|
*
|
|
@@ -8716,11 +8857,7 @@ const octopus3d3AvatarVisual = {
|
|
|
8716
8857
|
isAnimated: true,
|
|
8717
8858
|
supportsPointerTracking: true,
|
|
8718
8859
|
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
8719
|
-
const morphologyProfile =
|
|
8720
|
-
const animationRandom = createRandom('octopus3d3-animation-profile');
|
|
8721
|
-
const eyeRandom = createRandom('octopus3d3-eye-profile');
|
|
8722
|
-
const animationPhase = animationRandom() * Math.PI * 2;
|
|
8723
|
-
const tentacleProfiles = createContinuousTentacleProfiles(createRandom, morphologyProfile);
|
|
8860
|
+
const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset, tentacleProfiles } = getOctopus3d3StableState(createRandom);
|
|
8724
8861
|
const sceneCenterX = size * 0.5;
|
|
8725
8862
|
const sceneCenterY = size * 0.535;
|
|
8726
8863
|
const bob = Math.sin(timeMs / 960 + animationPhase) * size * 0.012;
|
|
@@ -8797,8 +8934,8 @@ const octopus3d3AvatarVisual = {
|
|
|
8797
8934
|
size,
|
|
8798
8935
|
palette,
|
|
8799
8936
|
});
|
|
8800
|
-
drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, -eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase +
|
|
8801
|
-
drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.85 +
|
|
8937
|
+
drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, -eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
8938
|
+
drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.85 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
8802
8939
|
drawProjectedOrganicMouth(context, [
|
|
8803
8940
|
sampleContinuousOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude - mouthHalfLongitude),
|
|
8804
8941
|
sampleContinuousOctopusSurfacePoint(surfaceOptions, mouthCurveLatitude, mouthCenterLongitude),
|
|
@@ -8849,14 +8986,30 @@ function drawContinuousOctopusAtmosphere(context, size, palette, sceneCenterX, s
|
|
|
8849
8986
|
/**
|
|
8850
8987
|
* Draws the soft lower shadow that anchors the octopus in the avatar frame.
|
|
8851
8988
|
*
|
|
8989
|
+
* Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
|
|
8990
|
+
* blurry ellipse without triggering a costly software rasterization pass on every frame.
|
|
8991
|
+
*
|
|
8852
8992
|
* @private helper of `octopus3d3AvatarVisual`
|
|
8853
8993
|
*/
|
|
8854
8994
|
function drawContinuousOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile) {
|
|
8995
|
+
const cx = size * 0.5 + interaction.gazeX * size * 0.045;
|
|
8996
|
+
const cy = size * 0.9 + Math.sin(timeMs / 980) * size * 0.007;
|
|
8997
|
+
const rx = size * (0.19 + morphologyProfile.tentacles.rootSpreadScale * 0.022 + interaction.intensity * 0.02);
|
|
8998
|
+
const ry = size * 0.06;
|
|
8999
|
+
// Scale the context so that drawing a circle produces the correct ellipse aspect ratio,
|
|
9000
|
+
// then fill with a radial gradient that approximates the blurry edge without context.filter.
|
|
8855
9001
|
context.save();
|
|
8856
|
-
context.
|
|
8857
|
-
context.
|
|
9002
|
+
context.translate(cx, cy);
|
|
9003
|
+
context.scale(1, ry / rx);
|
|
9004
|
+
const blurRadius = rx * 1.4;
|
|
9005
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
9006
|
+
shadowGradient.addColorStop(0, `${palette.shadow}7a`);
|
|
9007
|
+
shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
|
|
9008
|
+
shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
|
|
9009
|
+
shadowGradient.addColorStop(1, `${palette.shadow}00`);
|
|
9010
|
+
context.fillStyle = shadowGradient;
|
|
8858
9011
|
context.beginPath();
|
|
8859
|
-
context.
|
|
9012
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
8860
9013
|
context.fill();
|
|
8861
9014
|
context.restore();
|
|
8862
9015
|
}
|
|
@@ -33276,7 +33429,7 @@ class OpenAiVectorStoreKnowledgeSourcePreparer {
|
|
|
33276
33429
|
return { skippedReason: 'invalid_data_url' };
|
|
33277
33430
|
}
|
|
33278
33431
|
return {
|
|
33279
|
-
file: new File([parsed.buffer], parsed.filename, {
|
|
33432
|
+
file: new File([new Uint8Array(parsed.buffer)], parsed.filename, {
|
|
33280
33433
|
type: parsed.mimeType,
|
|
33281
33434
|
}),
|
|
33282
33435
|
sizeBytes: parsed.buffer.length,
|