@promptbook/core 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 +200 -45
- 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 +1 -1
- package/umd/index.umd.js +200 -45
- 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
|
@@ -11,6 +11,11 @@ import type { CliAgentThinkingLevel } from '../book-3.0/CliAgent';
|
|
|
11
11
|
import type { CliAgentRunOptions } from '../book-3.0/CliAgent';
|
|
12
12
|
import type { CliAgentOptions } from '../book-3.0/CliAgent';
|
|
13
13
|
import { CliAgent } from '../book-3.0/CliAgent';
|
|
14
|
+
import { CLI_AGENT_HARNESS_NAMES } from '../book-3.0/cliAgentEnv';
|
|
15
|
+
import { CLI_AGENT_THINKING_LEVEL_VALUES } from '../book-3.0/cliAgentEnv';
|
|
16
|
+
import { PTBK_HARNESS_ENV } from '../book-3.0/cliAgentEnv';
|
|
17
|
+
import { PTBK_MODEL_ENV } from '../book-3.0/cliAgentEnv';
|
|
18
|
+
import { PTBK_THINKING_LEVEL_ENV } from '../book-3.0/cliAgentEnv';
|
|
14
19
|
import type { LiteAgentOptions } from '../book-3.0/LiteAgent';
|
|
15
20
|
import type { LiteAgentRunOptions } from '../book-3.0/LiteAgent';
|
|
16
21
|
import { LiteAgent } from '../book-3.0/LiteAgent';
|
|
@@ -39,6 +44,11 @@ export type { CliAgentThinkingLevel };
|
|
|
39
44
|
export type { CliAgentRunOptions };
|
|
40
45
|
export type { CliAgentOptions };
|
|
41
46
|
export { CliAgent };
|
|
47
|
+
export { CLI_AGENT_HARNESS_NAMES };
|
|
48
|
+
export { CLI_AGENT_THINKING_LEVEL_VALUES };
|
|
49
|
+
export { PTBK_HARNESS_ENV };
|
|
50
|
+
export { PTBK_MODEL_ENV };
|
|
51
|
+
export { PTBK_THINKING_LEVEL_ENV };
|
|
42
52
|
export type { LiteAgentOptions };
|
|
43
53
|
export type { LiteAgentRunOptions };
|
|
44
54
|
export { LiteAgent };
|
|
@@ -15,7 +15,7 @@ export type BookNodeAgentSource = Book | string_book;
|
|
|
15
15
|
*/
|
|
16
16
|
export type BookNodeAgentSourceOptions = {
|
|
17
17
|
readonly agentPath?: string;
|
|
18
|
-
readonly book?: BookNodeAgentSource;
|
|
18
|
+
readonly book?: string | BookNodeAgentSource;
|
|
19
19
|
readonly currentWorkingDirectory?: string;
|
|
20
20
|
};
|
|
21
21
|
/**
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import type { BookNodeAgentSourceOptions } from './BookNodeAgentSource';
|
|
2
|
+
import { CLI_AGENT_HARNESS_NAMES, CLI_AGENT_THINKING_LEVEL_VALUES } from './cliAgentEnv';
|
|
2
3
|
/**
|
|
3
4
|
* CLI harness names supported by `ptbk agent exec`.
|
|
4
5
|
*
|
|
5
6
|
* @public exported from `@promptbook/node`
|
|
6
7
|
*/
|
|
7
|
-
export type CliAgentHarness =
|
|
8
|
+
export type CliAgentHarness = (typeof CLI_AGENT_HARNESS_NAMES)[number];
|
|
8
9
|
/**
|
|
9
10
|
* Thinking levels supported by CLI coding harnesses.
|
|
10
11
|
*
|
|
11
12
|
* @public exported from `@promptbook/node`
|
|
12
13
|
*/
|
|
13
|
-
export type CliAgentThinkingLevel =
|
|
14
|
+
export type CliAgentThinkingLevel = (typeof CLI_AGENT_THINKING_LEVEL_VALUES)[number];
|
|
14
15
|
/**
|
|
15
16
|
* Per-run CLI options exposed by `CliAgent`.
|
|
16
17
|
*
|
|
@@ -22,6 +23,7 @@ export type CliAgentRunOptions = {
|
|
|
22
23
|
readonly allowCredits?: boolean;
|
|
23
24
|
readonly context?: string;
|
|
24
25
|
readonly harness?: CliAgentHarness;
|
|
26
|
+
readonly isVerbose?: boolean;
|
|
25
27
|
readonly model?: string;
|
|
26
28
|
readonly noUi?: boolean;
|
|
27
29
|
readonly thinkingLevel?: CliAgentThinkingLevel;
|
|
@@ -38,6 +40,9 @@ export type CliAgentOptions = BookNodeAgentSourceOptions & CliAgentRunOptions;
|
|
|
38
40
|
* It uses the same harnesses and execution path as `ptbk agent exec`, running the runner
|
|
39
41
|
* in-process instead of spawning a separate CLI process.
|
|
40
42
|
*
|
|
43
|
+
* When no `harness` is provided in the constructor or per-run options, `CliAgent` falls back
|
|
44
|
+
* to the `PTBK_HARNESS` environment variable, mirroring `ptbk agent exec` behavior.
|
|
45
|
+
*
|
|
41
46
|
* @public exported from `@promptbook/node`
|
|
42
47
|
*/
|
|
43
48
|
export declare class CliAgent {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* All CLI harness names supported by `CliAgent` and `ptbk agent exec`.
|
|
3
|
+
*
|
|
4
|
+
* @public exported from `@promptbook/node`
|
|
5
|
+
*/
|
|
6
|
+
export declare const CLI_AGENT_HARNESS_NAMES: readonly ["openai-codex", "github-copilot", "cline", "claude-code", "opencode", "gemini"];
|
|
7
|
+
/**
|
|
8
|
+
* All supported thinking-level values for CLI coding-agent runners.
|
|
9
|
+
*
|
|
10
|
+
* @public exported from `@promptbook/node`
|
|
11
|
+
*/
|
|
12
|
+
export declare const CLI_AGENT_THINKING_LEVEL_VALUES: readonly ["low", "medium", "high", "xhigh"];
|
|
13
|
+
/**
|
|
14
|
+
* Environment variable used as the default runner identifier when `--harness` is omitted or not set in `CliAgent`.
|
|
15
|
+
*
|
|
16
|
+
* Set this to one of the harness names (`openai-codex`, `github-copilot`, `cline`, `claude-code`, `opencode`, `gemini`)
|
|
17
|
+
* so that `CliAgent` and `ptbk agent exec` can run without an explicit `harness` option.
|
|
18
|
+
*
|
|
19
|
+
* @public exported from `@promptbook/node`
|
|
20
|
+
*/
|
|
21
|
+
export declare const PTBK_HARNESS_ENV = "PTBK_HARNESS";
|
|
22
|
+
/**
|
|
23
|
+
* Environment variable used as the default runner model when `--model` is omitted or not set in `CliAgent`.
|
|
24
|
+
*
|
|
25
|
+
* @public exported from `@promptbook/node`
|
|
26
|
+
*/
|
|
27
|
+
export declare const PTBK_MODEL_ENV = "PTBK_MODEL";
|
|
28
|
+
/**
|
|
29
|
+
* Environment variable used as the default thinking level when `--thinking-level` is omitted or not set in `CliAgent`.
|
|
30
|
+
*
|
|
31
|
+
* @public exported from `@promptbook/node`
|
|
32
|
+
*/
|
|
33
|
+
export declare const PTBK_THINKING_LEVEL_ENV = "PTBK_THINKING_LEVEL";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CSSProperties } from 'react';
|
|
1
|
+
import { type CSSProperties } from 'react';
|
|
2
2
|
import type { Promisable } from 'type-fest';
|
|
3
3
|
import type { string_book } from '../../book-2.0/agent-source/string_book';
|
|
4
4
|
import type { number_percent } from '../../types/number_percent';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Props for the citation iframe preview component.
|
|
3
|
+
*
|
|
4
|
+
* @private component of `<ChatCitationModal/>`
|
|
5
|
+
*/
|
|
6
|
+
export type CitationIframePreviewProps = {
|
|
7
|
+
src: string;
|
|
8
|
+
title: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Renders a citation URL preview as an iframe when the target page allows embedding,
|
|
12
|
+
* or falls back to a server-side screenshot with an "Open in new tab" link when it
|
|
13
|
+
* does not (e.g. X-Frame-Options: DENY / SAMEORIGIN).
|
|
14
|
+
*
|
|
15
|
+
* Embedding capability is determined by `GET /api/page-preview/check?url=<url>`.
|
|
16
|
+
* If that endpoint is unavailable the component falls back to the iframe directly.
|
|
17
|
+
*
|
|
18
|
+
* @private component of `<ChatCitationModal/>`
|
|
19
|
+
*/
|
|
20
|
+
export declare function CitationIframePreview({ src, title }: CitationIframePreviewProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,29 +1,13 @@
|
|
|
1
1
|
import { Command as Program } from 'commander';
|
|
2
2
|
import type { ThinkingLevel } from '../coder/ThinkingLevel';
|
|
3
|
+
import { PTBK_HARNESS_ENV, PTBK_MODEL_ENV, PTBK_THINKING_LEVEL_ENV } from '../../../book-3.0/cliAgentEnv';
|
|
4
|
+
export { PTBK_HARNESS_ENV, PTBK_MODEL_ENV, PTBK_THINKING_LEVEL_ENV };
|
|
3
5
|
/**
|
|
4
6
|
* Runner identifiers supported by Promptbook CLI agent orchestration commands.
|
|
5
7
|
*
|
|
6
8
|
* @private internal utility of `promptbookCli`
|
|
7
9
|
*/
|
|
8
10
|
export declare const PROMPT_RUNNER_HARNESS_NAMES: readonly ["openai-codex", "github-copilot", "cline", "claude-code", "opencode", "gemini"];
|
|
9
|
-
/**
|
|
10
|
-
* Environment variable used as the default runner identifier when `--harness` is omitted.
|
|
11
|
-
*
|
|
12
|
-
* @private internal utility of `promptbookCli`
|
|
13
|
-
*/
|
|
14
|
-
export declare const PTBK_HARNESS_ENV = "PTBK_HARNESS";
|
|
15
|
-
/**
|
|
16
|
-
* Environment variable used as the default runner model when `--model` is omitted.
|
|
17
|
-
*
|
|
18
|
-
* @private internal utility of `promptbookCli`
|
|
19
|
-
*/
|
|
20
|
-
export declare const PTBK_MODEL_ENV = "PTBK_MODEL";
|
|
21
|
-
/**
|
|
22
|
-
* Environment variable used as the default runner thinking level when `--thinking-level` is omitted.
|
|
23
|
-
*
|
|
24
|
-
* @private internal utility of `promptbookCli`
|
|
25
|
-
*/
|
|
26
|
-
export declare const PTBK_THINKING_LEVEL_ENV = "PTBK_THINKING_LEVEL";
|
|
27
11
|
/**
|
|
28
12
|
* Runner identifier supported by Promptbook CLI agent orchestration commands.
|
|
29
13
|
*
|
package/esm/src/version.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export declare const BOOK_LANGUAGE_VERSION: string_semantic_version;
|
|
|
15
15
|
export declare const PROMPTBOOK_ENGINE_VERSION: string_promptbook_version;
|
|
16
16
|
/**
|
|
17
17
|
* Represents the version string of the Promptbook engine.
|
|
18
|
-
* It follows semantic versioning (e.g., `0.112.0-
|
|
18
|
+
* It follows semantic versioning (e.g., `0.112.0-118`).
|
|
19
19
|
*
|
|
20
20
|
* @generated
|
|
21
21
|
*/
|
package/package.json
CHANGED
package/umd/index.umd.js
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* @generated
|
|
30
30
|
* @see https://github.com/webgptorg/promptbook
|
|
31
31
|
*/
|
|
32
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
32
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-119';
|
|
33
33
|
/**
|
|
34
34
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
35
35
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -13064,21 +13064,22 @@
|
|
|
13064
13064
|
* @private helper of `fractalAvatarVisual`
|
|
13065
13065
|
*/
|
|
13066
13066
|
function drawDragonCurveLayer(context, points, options) {
|
|
13067
|
-
const {
|
|
13067
|
+
const { primaryColor, secondaryColor, tertiaryColor, shadowColor, strokeWidth, timeMs, layerIndex } = options;
|
|
13068
13068
|
const firstPoint = points[0];
|
|
13069
13069
|
const lastPoint = points[points.length - 1];
|
|
13070
13070
|
const ribbonGradient = context.createLinearGradient(firstPoint.x, firstPoint.y, lastPoint.x, lastPoint.y);
|
|
13071
13071
|
ribbonGradient.addColorStop(0, `${primaryColor}f2`);
|
|
13072
13072
|
ribbonGradient.addColorStop(0.5, `${secondaryColor}e6`);
|
|
13073
13073
|
ribbonGradient.addColorStop(1, `${tertiaryColor}f2`);
|
|
13074
|
+
// Approximate the blurred shadow stroke with a wider semi-transparent stroke instead of
|
|
13075
|
+
// context.filter blur, which triggers a costly software rasterization pass every frame.
|
|
13074
13076
|
context.save();
|
|
13075
13077
|
context.beginPath();
|
|
13076
13078
|
tracePolyline(context, points);
|
|
13077
|
-
context.strokeStyle = `${shadowColor}
|
|
13078
|
-
context.lineWidth = strokeWidth *
|
|
13079
|
+
context.strokeStyle = `${shadowColor}48`;
|
|
13080
|
+
context.lineWidth = strokeWidth * 4.5;
|
|
13079
13081
|
context.lineJoin = 'round';
|
|
13080
13082
|
context.lineCap = 'round';
|
|
13081
|
-
context.filter = `blur(${size * 0.022}px)`;
|
|
13082
13083
|
context.stroke();
|
|
13083
13084
|
context.restore();
|
|
13084
13085
|
context.beginPath();
|
|
@@ -13662,11 +13663,23 @@
|
|
|
13662
13663
|
* @private helper of `minecraft2AvatarVisual`
|
|
13663
13664
|
*/
|
|
13664
13665
|
function drawMinecraftShadow(context, size, palette, interaction, timeMs) {
|
|
13666
|
+
const cx = size * 0.5 + interaction.gazeX * size * 0.03;
|
|
13667
|
+
const cy = size * 0.85 + Math.sin(timeMs / 880) * size * 0.01;
|
|
13668
|
+
const rx = size * (0.16 + interaction.intensity * 0.015);
|
|
13669
|
+
const ry = size * 0.055;
|
|
13670
|
+
// Radial gradient approximates the blurry ellipse shadow without context.filter blur.
|
|
13665
13671
|
context.save();
|
|
13666
|
-
context.
|
|
13667
|
-
context.
|
|
13672
|
+
context.translate(cx, cy);
|
|
13673
|
+
context.scale(1, ry / rx);
|
|
13674
|
+
const blurRadius = rx * 1.4;
|
|
13675
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
13676
|
+
shadowGradient.addColorStop(0, `${palette.shadow}7a`);
|
|
13677
|
+
shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
|
|
13678
|
+
shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
|
|
13679
|
+
shadowGradient.addColorStop(1, `${palette.shadow}00`);
|
|
13680
|
+
context.fillStyle = shadowGradient;
|
|
13668
13681
|
context.beginPath();
|
|
13669
|
-
context.
|
|
13682
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
13670
13683
|
context.fill();
|
|
13671
13684
|
context.restore();
|
|
13672
13685
|
}
|
|
@@ -13890,13 +13903,27 @@
|
|
|
13890
13903
|
spotlight.addColorStop(1, `${palette.highlight}00`);
|
|
13891
13904
|
context.fillStyle = spotlight;
|
|
13892
13905
|
context.fillRect(0, 0, size, size);
|
|
13893
|
-
|
|
13894
|
-
|
|
13895
|
-
|
|
13896
|
-
|
|
13897
|
-
|
|
13898
|
-
|
|
13899
|
-
|
|
13906
|
+
{
|
|
13907
|
+
// Radial gradient approximates the blurry ellipse shadow without context.filter blur.
|
|
13908
|
+
const cx = size * 0.5;
|
|
13909
|
+
const cy = size * 0.86;
|
|
13910
|
+
const rx = size * 0.2;
|
|
13911
|
+
const ry = size * 0.06;
|
|
13912
|
+
const blurRadius = rx * 1.4;
|
|
13913
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
13914
|
+
shadowGradient.addColorStop(0, 'rgba(0,0,0,0.28)');
|
|
13915
|
+
shadowGradient.addColorStop(0.45, 'rgba(0,0,0,0.14)');
|
|
13916
|
+
shadowGradient.addColorStop(0.8, 'rgba(0,0,0,0.05)');
|
|
13917
|
+
shadowGradient.addColorStop(1, 'rgba(0,0,0,0)');
|
|
13918
|
+
context.save();
|
|
13919
|
+
context.translate(cx, cy);
|
|
13920
|
+
context.scale(1, ry / rx);
|
|
13921
|
+
context.fillStyle = shadowGradient;
|
|
13922
|
+
context.beginPath();
|
|
13923
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
13924
|
+
context.fill();
|
|
13925
|
+
context.restore();
|
|
13926
|
+
}
|
|
13900
13927
|
drawVoxelCuboid(context, {
|
|
13901
13928
|
x: bodyX,
|
|
13902
13929
|
y: bodyY,
|
|
@@ -14948,6 +14975,35 @@
|
|
|
14948
14975
|
y: -0.62,
|
|
14949
14976
|
z: 0.94,
|
|
14950
14977
|
});
|
|
14978
|
+
/**
|
|
14979
|
+
* Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
|
|
14980
|
+
*
|
|
14981
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
14982
|
+
*/
|
|
14983
|
+
const octopus3dStableStateCache = new WeakMap();
|
|
14984
|
+
/**
|
|
14985
|
+
* Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
|
|
14986
|
+
*
|
|
14987
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
14988
|
+
*/
|
|
14989
|
+
function getOctopus3dStableState(createRandom) {
|
|
14990
|
+
const cached = octopus3dStableStateCache.get(createRandom);
|
|
14991
|
+
if (cached !== undefined) {
|
|
14992
|
+
return cached;
|
|
14993
|
+
}
|
|
14994
|
+
const animationRandom = createRandom('octopus3d-animation-profile');
|
|
14995
|
+
const eyeRandom = createRandom('octopus3d-eye-profile');
|
|
14996
|
+
const leftEyePhaseOffset = eyeRandom() * 0.6;
|
|
14997
|
+
const rightEyePhaseOffset = eyeRandom() * 0.6;
|
|
14998
|
+
const state = {
|
|
14999
|
+
morphologyProfile: createOctopus3MorphologyProfile(createRandom),
|
|
15000
|
+
animationPhase: animationRandom() * Math.PI * 2,
|
|
15001
|
+
leftEyePhaseOffset,
|
|
15002
|
+
rightEyePhaseOffset,
|
|
15003
|
+
};
|
|
15004
|
+
octopus3dStableStateCache.set(createRandom, state);
|
|
15005
|
+
return state;
|
|
15006
|
+
}
|
|
14951
15007
|
/**
|
|
14952
15008
|
* Proper 3D Octopus visual built from projected organic meshes and tentacles.
|
|
14953
15009
|
*
|
|
@@ -14960,10 +15016,7 @@
|
|
|
14960
15016
|
isAnimated: true,
|
|
14961
15017
|
supportsPointerTracking: true,
|
|
14962
15018
|
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
14963
|
-
const morphologyProfile =
|
|
14964
|
-
const animationRandom = createRandom('octopus3d-animation-profile');
|
|
14965
|
-
const eyeRandom = createRandom('octopus3d-eye-profile');
|
|
14966
|
-
const animationPhase = animationRandom() * Math.PI * 2;
|
|
15019
|
+
const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3dStableState(createRandom);
|
|
14967
15020
|
const sceneCenterX = size * 0.5;
|
|
14968
15021
|
const sceneCenterY = size * 0.56;
|
|
14969
15022
|
const bob = Math.sin(timeMs / 920 + animationPhase) * size * 0.014;
|
|
@@ -15060,12 +15113,12 @@
|
|
|
15060
15113
|
x: -faceEyeSpacing,
|
|
15061
15114
|
y: faceEyeYOffset,
|
|
15062
15115
|
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -faceEyeSpacing, faceEyeYOffset),
|
|
15063
|
-
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase +
|
|
15116
|
+
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
15064
15117
|
drawProjectedOrganicEye(context, {
|
|
15065
15118
|
x: faceEyeSpacing,
|
|
15066
15119
|
y: faceEyeYOffset,
|
|
15067
15120
|
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, faceEyeSpacing, faceEyeYOffset),
|
|
15068
|
-
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 +
|
|
15121
|
+
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
15069
15122
|
drawProjectedOrganicMouth(context, [
|
|
15070
15123
|
{
|
|
15071
15124
|
x: -mouthHalfWidth,
|
|
@@ -15109,14 +15162,28 @@
|
|
|
15109
15162
|
/**
|
|
15110
15163
|
* Draws the soft ground shadow below the octopus.
|
|
15111
15164
|
*
|
|
15165
|
+
* Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
|
|
15166
|
+
* blurry ellipse without triggering a costly software rasterization pass on every frame.
|
|
15167
|
+
*
|
|
15112
15168
|
* @private helper of `octopus3dAvatarVisual`
|
|
15113
15169
|
*/
|
|
15114
15170
|
function drawOctopus3dShadow(context, size, palette, interaction, timeMs) {
|
|
15171
|
+
const cx = size * 0.5 + interaction.gazeX * size * 0.04;
|
|
15172
|
+
const cy = size * 0.87 + Math.sin(timeMs / 920) * size * 0.008;
|
|
15173
|
+
const rx = size * (0.18 + interaction.intensity * 0.02);
|
|
15174
|
+
const ry = size * 0.06;
|
|
15115
15175
|
context.save();
|
|
15116
|
-
context.
|
|
15117
|
-
context.
|
|
15176
|
+
context.translate(cx, cy);
|
|
15177
|
+
context.scale(1, ry / rx);
|
|
15178
|
+
const blurRadius = rx * 1.4;
|
|
15179
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
15180
|
+
shadowGradient.addColorStop(0, `${palette.shadow}7a`);
|
|
15181
|
+
shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
|
|
15182
|
+
shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
|
|
15183
|
+
shadowGradient.addColorStop(1, `${palette.shadow}00`);
|
|
15184
|
+
context.fillStyle = shadowGradient;
|
|
15118
15185
|
context.beginPath();
|
|
15119
|
-
context.
|
|
15186
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
15120
15187
|
context.fill();
|
|
15121
15188
|
context.restore();
|
|
15122
15189
|
}
|
|
@@ -15347,6 +15414,35 @@
|
|
|
15347
15414
|
y: -0.6,
|
|
15348
15415
|
z: 0.98,
|
|
15349
15416
|
});
|
|
15417
|
+
/**
|
|
15418
|
+
* Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
|
|
15419
|
+
*
|
|
15420
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
15421
|
+
*/
|
|
15422
|
+
const octopus3d2StableStateCache = new WeakMap();
|
|
15423
|
+
/**
|
|
15424
|
+
* Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
|
|
15425
|
+
*
|
|
15426
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
15427
|
+
*/
|
|
15428
|
+
function getOctopus3d2StableState(createRandom) {
|
|
15429
|
+
const cached = octopus3d2StableStateCache.get(createRandom);
|
|
15430
|
+
if (cached !== undefined) {
|
|
15431
|
+
return cached;
|
|
15432
|
+
}
|
|
15433
|
+
const animationRandom = createRandom('octopus3d2-animation-profile');
|
|
15434
|
+
const eyeRandom = createRandom('octopus3d2-eye-profile');
|
|
15435
|
+
const leftEyePhaseOffset = eyeRandom() * 0.7;
|
|
15436
|
+
const rightEyePhaseOffset = eyeRandom() * 0.7;
|
|
15437
|
+
const state = {
|
|
15438
|
+
morphologyProfile: createOctopus3MorphologyProfile(createRandom),
|
|
15439
|
+
animationPhase: animationRandom() * Math.PI * 2,
|
|
15440
|
+
leftEyePhaseOffset,
|
|
15441
|
+
rightEyePhaseOffset,
|
|
15442
|
+
};
|
|
15443
|
+
octopus3d2StableStateCache.set(createRandom, state);
|
|
15444
|
+
return state;
|
|
15445
|
+
}
|
|
15350
15446
|
/**
|
|
15351
15447
|
* Octopus 3D 2 avatar visual.
|
|
15352
15448
|
*
|
|
@@ -15359,10 +15455,7 @@
|
|
|
15359
15455
|
isAnimated: true,
|
|
15360
15456
|
supportsPointerTracking: true,
|
|
15361
15457
|
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
15362
|
-
const morphologyProfile =
|
|
15363
|
-
const animationRandom = createRandom('octopus3d2-animation-profile');
|
|
15364
|
-
const eyeRandom = createRandom('octopus3d2-eye-profile');
|
|
15365
|
-
const animationPhase = animationRandom() * Math.PI * 2;
|
|
15458
|
+
const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3d2StableState(createRandom);
|
|
15366
15459
|
const sceneCenterX = size * 0.5;
|
|
15367
15460
|
const sceneCenterY = size * 0.575;
|
|
15368
15461
|
const bob = Math.sin(timeMs / 940 + animationPhase) * size * 0.013;
|
|
@@ -15415,8 +15508,8 @@
|
|
|
15415
15508
|
const rightEyeLocalCenter = sampleBlobbyOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude);
|
|
15416
15509
|
const eyeRadiusX = size * morphologyProfile.face.eyeRadiusXRatio * 0.78;
|
|
15417
15510
|
const eyeRadiusY = eyeRadiusX * morphologyProfile.face.eyeHeightRatio * 0.92;
|
|
15418
|
-
drawProjectedOrganicEye(context, leftEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase +
|
|
15419
|
-
drawProjectedOrganicEye(context, rightEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.9 +
|
|
15511
|
+
drawProjectedOrganicEye(context, leftEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
15512
|
+
drawProjectedOrganicEye(context, rightEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.9 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
15420
15513
|
drawProjectedOrganicMouth(context, [
|
|
15421
15514
|
sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude - mouthHalfLongitude),
|
|
15422
15515
|
sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthCurveLatitude, mouthCenterLongitude),
|
|
@@ -15445,14 +15538,28 @@
|
|
|
15445
15538
|
/**
|
|
15446
15539
|
* Draws the soft floor shadow that anchors the single mesh in the frame.
|
|
15447
15540
|
*
|
|
15541
|
+
* Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
|
|
15542
|
+
* blurry ellipse without triggering a costly software rasterization pass on every frame.
|
|
15543
|
+
*
|
|
15448
15544
|
* @private helper of `octopus3d2AvatarVisual`
|
|
15449
15545
|
*/
|
|
15450
15546
|
function drawBlobbyOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile) {
|
|
15547
|
+
const cx = size * 0.5 + interaction.gazeX * size * 0.045;
|
|
15548
|
+
const cy = size * 0.88 + Math.sin(timeMs / 940) * size * 0.008;
|
|
15549
|
+
const rx = size * (0.18 + (morphologyProfile.body.horizontalStretch - 1) * 0.04 + interaction.intensity * 0.018);
|
|
15550
|
+
const ry = size * 0.062;
|
|
15451
15551
|
context.save();
|
|
15452
|
-
context.
|
|
15453
|
-
context.
|
|
15552
|
+
context.translate(cx, cy);
|
|
15553
|
+
context.scale(1, ry / rx);
|
|
15554
|
+
const blurRadius = rx * 1.4;
|
|
15555
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
15556
|
+
shadowGradient.addColorStop(0, `${palette.shadow}7a`);
|
|
15557
|
+
shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
|
|
15558
|
+
shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
|
|
15559
|
+
shadowGradient.addColorStop(1, `${palette.shadow}00`);
|
|
15560
|
+
context.fillStyle = shadowGradient;
|
|
15454
15561
|
context.beginPath();
|
|
15455
|
-
context.
|
|
15562
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
15456
15563
|
context.fill();
|
|
15457
15564
|
context.restore();
|
|
15458
15565
|
}
|
|
@@ -15608,6 +15715,40 @@
|
|
|
15608
15715
|
* @private helper of `octopus3d3AvatarVisual`
|
|
15609
15716
|
*/
|
|
15610
15717
|
const OCTOPUS_TENTACLE_COUNT = 8;
|
|
15718
|
+
/**
|
|
15719
|
+
* Cache keyed by the `createRandom` factory reference, which is stable for the lifetime of one
|
|
15720
|
+
* mounted `<Avatar/>` component (created inside `resolveAvatarRenderDefinition` and held in a
|
|
15721
|
+
* React `useMemo`). Using a `WeakMap` ensures the entry is collected when the component unmounts.
|
|
15722
|
+
*
|
|
15723
|
+
* @private helper of `octopus3d3AvatarVisual`
|
|
15724
|
+
*/
|
|
15725
|
+
const stableStateCache = new WeakMap();
|
|
15726
|
+
/**
|
|
15727
|
+
* Returns the stable per-avatar state, computing it on first access and returning the cached
|
|
15728
|
+
* result on every subsequent call within the same `<Avatar/>` mount.
|
|
15729
|
+
*
|
|
15730
|
+
* @private helper of `octopus3d3AvatarVisual`
|
|
15731
|
+
*/
|
|
15732
|
+
function getOctopus3d3StableState(createRandom) {
|
|
15733
|
+
const cached = stableStateCache.get(createRandom);
|
|
15734
|
+
if (cached !== undefined) {
|
|
15735
|
+
return cached;
|
|
15736
|
+
}
|
|
15737
|
+
const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
|
|
15738
|
+
const animationRandom = createRandom('octopus3d3-animation-profile');
|
|
15739
|
+
const eyeRandom = createRandom('octopus3d3-eye-profile');
|
|
15740
|
+
const leftEyePhaseOffset = eyeRandom() * 0.7;
|
|
15741
|
+
const rightEyePhaseOffset = eyeRandom() * 0.7;
|
|
15742
|
+
const state = {
|
|
15743
|
+
morphologyProfile,
|
|
15744
|
+
animationPhase: animationRandom() * Math.PI * 2,
|
|
15745
|
+
leftEyePhaseOffset,
|
|
15746
|
+
rightEyePhaseOffset,
|
|
15747
|
+
tentacleProfiles: createContinuousTentacleProfiles(createRandom, morphologyProfile),
|
|
15748
|
+
};
|
|
15749
|
+
stableStateCache.set(createRandom, state);
|
|
15750
|
+
return state;
|
|
15751
|
+
}
|
|
15611
15752
|
/**
|
|
15612
15753
|
* Octopus 3D 3 avatar visual.
|
|
15613
15754
|
*
|
|
@@ -15620,11 +15761,7 @@
|
|
|
15620
15761
|
isAnimated: true,
|
|
15621
15762
|
supportsPointerTracking: true,
|
|
15622
15763
|
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
15623
|
-
const morphologyProfile =
|
|
15624
|
-
const animationRandom = createRandom('octopus3d3-animation-profile');
|
|
15625
|
-
const eyeRandom = createRandom('octopus3d3-eye-profile');
|
|
15626
|
-
const animationPhase = animationRandom() * Math.PI * 2;
|
|
15627
|
-
const tentacleProfiles = createContinuousTentacleProfiles(createRandom, morphologyProfile);
|
|
15764
|
+
const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset, tentacleProfiles } = getOctopus3d3StableState(createRandom);
|
|
15628
15765
|
const sceneCenterX = size * 0.5;
|
|
15629
15766
|
const sceneCenterY = size * 0.535;
|
|
15630
15767
|
const bob = Math.sin(timeMs / 960 + animationPhase) * size * 0.012;
|
|
@@ -15701,8 +15838,8 @@
|
|
|
15701
15838
|
size,
|
|
15702
15839
|
palette,
|
|
15703
15840
|
});
|
|
15704
|
-
drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, -eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase +
|
|
15705
|
-
drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.85 +
|
|
15841
|
+
drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, -eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
15842
|
+
drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.85 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
15706
15843
|
drawProjectedOrganicMouth(context, [
|
|
15707
15844
|
sampleContinuousOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude - mouthHalfLongitude),
|
|
15708
15845
|
sampleContinuousOctopusSurfacePoint(surfaceOptions, mouthCurveLatitude, mouthCenterLongitude),
|
|
@@ -15753,14 +15890,30 @@
|
|
|
15753
15890
|
/**
|
|
15754
15891
|
* Draws the soft lower shadow that anchors the octopus in the avatar frame.
|
|
15755
15892
|
*
|
|
15893
|
+
* Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
|
|
15894
|
+
* blurry ellipse without triggering a costly software rasterization pass on every frame.
|
|
15895
|
+
*
|
|
15756
15896
|
* @private helper of `octopus3d3AvatarVisual`
|
|
15757
15897
|
*/
|
|
15758
15898
|
function drawContinuousOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile) {
|
|
15899
|
+
const cx = size * 0.5 + interaction.gazeX * size * 0.045;
|
|
15900
|
+
const cy = size * 0.9 + Math.sin(timeMs / 980) * size * 0.007;
|
|
15901
|
+
const rx = size * (0.19 + morphologyProfile.tentacles.rootSpreadScale * 0.022 + interaction.intensity * 0.02);
|
|
15902
|
+
const ry = size * 0.06;
|
|
15903
|
+
// Scale the context so that drawing a circle produces the correct ellipse aspect ratio,
|
|
15904
|
+
// then fill with a radial gradient that approximates the blurry edge without context.filter.
|
|
15759
15905
|
context.save();
|
|
15760
|
-
context.
|
|
15761
|
-
context.
|
|
15906
|
+
context.translate(cx, cy);
|
|
15907
|
+
context.scale(1, ry / rx);
|
|
15908
|
+
const blurRadius = rx * 1.4;
|
|
15909
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
15910
|
+
shadowGradient.addColorStop(0, `${palette.shadow}7a`);
|
|
15911
|
+
shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
|
|
15912
|
+
shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
|
|
15913
|
+
shadowGradient.addColorStop(1, `${palette.shadow}00`);
|
|
15914
|
+
context.fillStyle = shadowGradient;
|
|
15762
15915
|
context.beginPath();
|
|
15763
|
-
context.
|
|
15916
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
15764
15917
|
context.fill();
|
|
15765
15918
|
context.restore();
|
|
15766
15919
|
}
|
|
@@ -29165,7 +29318,9 @@
|
|
|
29165
29318
|
* @private internal utility of `Book`
|
|
29166
29319
|
*/
|
|
29167
29320
|
function parseCommitmentHeader(line) {
|
|
29168
|
-
|
|
29321
|
+
// Require at least 2 characters in the first keyword word to avoid treating common
|
|
29322
|
+
// single-letter words (e.g. "V" in Czech, "I" or "A" in English) as commitment headers.
|
|
29323
|
+
const match = /^([A-Z][A-Z0-9]+(?: [A-Z0-9]+)*)(?:\s+(.*))?$/u.exec(line);
|
|
29169
29324
|
if (!match) {
|
|
29170
29325
|
return null;
|
|
29171
29326
|
}
|
|
@@ -39356,7 +39511,7 @@
|
|
|
39356
39511
|
return { skippedReason: 'invalid_data_url' };
|
|
39357
39512
|
}
|
|
39358
39513
|
return {
|
|
39359
|
-
file: new File([parsed.buffer], parsed.filename, {
|
|
39514
|
+
file: new File([new Uint8Array(parsed.buffer)], parsed.filename, {
|
|
39360
39515
|
type: parsed.mimeType,
|
|
39361
39516
|
}),
|
|
39362
39517
|
sizeBytes: parsed.buffer.length,
|