@promptbook/components 0.112.0-115 → 0.112.0-118

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.
Files changed (31) hide show
  1. package/esm/index.es.js +577 -518
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/src/_packages/components.index.d.ts +2 -0
  4. package/esm/src/_packages/node.index.d.ts +20 -0
  5. package/esm/src/book-3.0/BookNodeAgentSource.d.ts +1 -1
  6. package/esm/src/book-3.0/CliAgent.d.ts +15 -17
  7. package/esm/src/book-3.0/agentFolderPaths.d.ts +30 -0
  8. package/esm/src/book-3.0/cliAgentEnv.d.ts +33 -0
  9. package/esm/src/book-components/BookEditor/BookEditorBrowserConfig.d.ts +2 -0
  10. package/esm/src/book-components/BookEditor/BookEditorForClient.d.ts +7 -0
  11. package/esm/src/book-components/BookEditor/createDeprecatedCommitmentDiagnostics.browser.d.ts +9 -0
  12. package/esm/src/cli/cli-commands/agent-folder/agentProjectPaths.d.ts +2 -30
  13. package/esm/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +2 -18
  14. package/esm/src/scrapers/website/utils/createShowdownConverter.d.ts +2 -2
  15. package/esm/src/version.d.ts +1 -1
  16. package/package.json +1 -3
  17. package/umd/index.umd.js +581 -516
  18. package/umd/index.umd.js.map +1 -1
  19. package/umd/src/_packages/components.index.d.ts +2 -0
  20. package/umd/src/_packages/node.index.d.ts +20 -0
  21. package/umd/src/book-3.0/BookNodeAgentSource.d.ts +1 -1
  22. package/umd/src/book-3.0/CliAgent.d.ts +15 -17
  23. package/umd/src/book-3.0/agentFolderPaths.d.ts +30 -0
  24. package/umd/src/book-3.0/cliAgentEnv.d.ts +33 -0
  25. package/umd/src/book-components/BookEditor/BookEditorBrowserConfig.d.ts +2 -0
  26. package/umd/src/book-components/BookEditor/BookEditorForClient.d.ts +7 -0
  27. package/umd/src/book-components/BookEditor/createDeprecatedCommitmentDiagnostics.browser.d.ts +9 -0
  28. package/umd/src/cli/cli-commands/agent-folder/agentProjectPaths.d.ts +2 -30
  29. package/umd/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +2 -18
  30. package/umd/src/scrapers/website/utils/createShowdownConverter.d.ts +2 -2
  31. package/umd/src/version.d.ts +1 -1
package/esm/index.es.js CHANGED
@@ -1,19 +1,17 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
2
  import { spaceTrim as spaceTrim$1 } from 'spacetrim';
3
3
  import { useMemo, useState, createContext, useContext, useEffect, useRef, useCallback, useId, memo, forwardRef } from 'react';
4
- import { SHA256 } from 'crypto-js';
4
+ import CryptoJS from 'crypto-js';
5
5
  import hexEncoder from 'crypto-js/enc-hex';
6
6
  import { basename, join, dirname, isAbsolute } from 'path';
7
7
  import moment from 'moment';
8
8
  import { lookup, extension } from 'mime-types';
9
- import { randomBytes } from 'crypto';
10
9
  import { createPortal } from 'react-dom';
11
10
  import MonacoEditor, { useMonaco } from '@monaco-editor/react';
12
- import { Registration } from 'destroyable';
13
11
  import { BehaviorSubject, Subject } from 'rxjs';
14
12
  import createDOMPurify from 'dompurify';
15
13
  import katex from 'katex';
16
- import { Converter } from 'showdown';
14
+ import showdown from 'showdown';
17
15
  import { toCanvas } from 'html-to-image';
18
16
  import { jsPDF } from 'jspdf';
19
17
  import { createRoot } from 'react-dom/client';
@@ -21,7 +19,7 @@ import { Maximize2, X, Reply, Pause, Play, Volume2Icon, VolumeXIcon, VibrateIcon
21
19
  import 'moment/locale/cs';
22
20
  import { forTime } from 'waitasecond';
23
21
  import sha256 from 'crypto-js/sha256';
24
- import { parse, unparse } from 'papaparse';
22
+ import papaparse from 'papaparse';
25
23
  import { fileSearchTool, tool, Agent as Agent$1, webSearchTool, run, setDefaultOpenAIClient, setDefaultOpenAIKey } from '@openai/agents';
26
24
  import colors from 'colors';
27
25
  import Bottleneck from 'bottleneck';
@@ -42,7 +40,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
42
40
  * @generated
43
41
  * @see https://github.com/webgptorg/promptbook
44
42
  */
45
- const PROMPTBOOK_ENGINE_VERSION = '0.112.0-115';
43
+ const PROMPTBOOK_ENGINE_VERSION = '0.112.0-118';
46
44
  /**
47
45
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
48
46
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -2778,21 +2776,22 @@ function getPointBounds(points) {
2778
2776
  * @private helper of `fractalAvatarVisual`
2779
2777
  */
2780
2778
  function drawDragonCurveLayer(context, points, options) {
2781
- const { size, primaryColor, secondaryColor, tertiaryColor, shadowColor, strokeWidth, timeMs, layerIndex } = options;
2779
+ const { primaryColor, secondaryColor, tertiaryColor, shadowColor, strokeWidth, timeMs, layerIndex } = options;
2782
2780
  const firstPoint = points[0];
2783
2781
  const lastPoint = points[points.length - 1];
2784
2782
  const ribbonGradient = context.createLinearGradient(firstPoint.x, firstPoint.y, lastPoint.x, lastPoint.y);
2785
2783
  ribbonGradient.addColorStop(0, `${primaryColor}f2`);
2786
2784
  ribbonGradient.addColorStop(0.5, `${secondaryColor}e6`);
2787
2785
  ribbonGradient.addColorStop(1, `${tertiaryColor}f2`);
2786
+ // Approximate the blurred shadow stroke with a wider semi-transparent stroke instead of
2787
+ // context.filter blur, which triggers a costly software rasterization pass every frame.
2788
2788
  context.save();
2789
2789
  context.beginPath();
2790
2790
  tracePolyline(context, points);
2791
- context.strokeStyle = `${shadowColor}82`;
2792
- context.lineWidth = strokeWidth * 1.8;
2791
+ context.strokeStyle = `${shadowColor}48`;
2792
+ context.lineWidth = strokeWidth * 4.5;
2793
2793
  context.lineJoin = 'round';
2794
2794
  context.lineCap = 'round';
2795
- context.filter = `blur(${size * 0.022}px)`;
2796
2795
  context.stroke();
2797
2796
  context.restore();
2798
2797
  context.beginPath();
@@ -3376,11 +3375,23 @@ function drawMinecraftBackdrop(context, size, palette, sceneCenterX, spotlightY,
3376
3375
  * @private helper of `minecraft2AvatarVisual`
3377
3376
  */
3378
3377
  function drawMinecraftShadow(context, size, palette, interaction, timeMs) {
3378
+ const cx = size * 0.5 + interaction.gazeX * size * 0.03;
3379
+ const cy = size * 0.85 + Math.sin(timeMs / 880) * size * 0.01;
3380
+ const rx = size * (0.16 + interaction.intensity * 0.015);
3381
+ const ry = size * 0.055;
3382
+ // Radial gradient approximates the blurry ellipse shadow without context.filter blur.
3379
3383
  context.save();
3380
- context.fillStyle = `${palette.shadow}66`;
3381
- context.filter = `blur(${size * 0.02}px)`;
3384
+ context.translate(cx, cy);
3385
+ context.scale(1, ry / rx);
3386
+ const blurRadius = rx * 1.4;
3387
+ const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
3388
+ shadowGradient.addColorStop(0, `${palette.shadow}7a`);
3389
+ shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
3390
+ shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
3391
+ shadowGradient.addColorStop(1, `${palette.shadow}00`);
3392
+ context.fillStyle = shadowGradient;
3382
3393
  context.beginPath();
3383
- context.ellipse(size * 0.5 + interaction.gazeX * size * 0.03, size * 0.85 + Math.sin(timeMs / 880) * size * 0.01, size * (0.16 + interaction.intensity * 0.015), size * 0.055, 0, 0, Math.PI * 2);
3394
+ context.arc(0, 0, blurRadius, 0, Math.PI * 2);
3384
3395
  context.fill();
3385
3396
  context.restore();
3386
3397
  }
@@ -3604,13 +3615,27 @@ const minecraftAvatarVisual = {
3604
3615
  spotlight.addColorStop(1, `${palette.highlight}00`);
3605
3616
  context.fillStyle = spotlight;
3606
3617
  context.fillRect(0, 0, size, size);
3607
- context.save();
3608
- context.fillStyle = 'rgba(0, 0, 0, 0.22)';
3609
- context.filter = `blur(${size * 0.018}px)`;
3610
- context.beginPath();
3611
- context.ellipse(size * 0.5, size * 0.86, size * 0.2, size * 0.06, 0, 0, Math.PI * 2);
3612
- context.fill();
3613
- context.restore();
3618
+ {
3619
+ // Radial gradient approximates the blurry ellipse shadow without context.filter blur.
3620
+ const cx = size * 0.5;
3621
+ const cy = size * 0.86;
3622
+ const rx = size * 0.2;
3623
+ const ry = size * 0.06;
3624
+ const blurRadius = rx * 1.4;
3625
+ const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
3626
+ shadowGradient.addColorStop(0, 'rgba(0,0,0,0.28)');
3627
+ shadowGradient.addColorStop(0.45, 'rgba(0,0,0,0.14)');
3628
+ shadowGradient.addColorStop(0.8, 'rgba(0,0,0,0.05)');
3629
+ shadowGradient.addColorStop(1, 'rgba(0,0,0,0)');
3630
+ context.save();
3631
+ context.translate(cx, cy);
3632
+ context.scale(1, ry / rx);
3633
+ context.fillStyle = shadowGradient;
3634
+ context.beginPath();
3635
+ context.arc(0, 0, blurRadius, 0, Math.PI * 2);
3636
+ context.fill();
3637
+ context.restore();
3638
+ }
3614
3639
  drawVoxelCuboid(context, {
3615
3640
  x: bodyX,
3616
3641
  y: bodyY,
@@ -4662,6 +4687,35 @@ const LIGHT_DIRECTION$2 = normalizeVector3({
4662
4687
  y: -0.62,
4663
4688
  z: 0.94,
4664
4689
  });
4690
+ /**
4691
+ * Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
4692
+ *
4693
+ * @private helper of `octopus3dAvatarVisual`
4694
+ */
4695
+ const octopus3dStableStateCache = new WeakMap();
4696
+ /**
4697
+ * Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
4698
+ *
4699
+ * @private helper of `octopus3dAvatarVisual`
4700
+ */
4701
+ function getOctopus3dStableState(createRandom) {
4702
+ const cached = octopus3dStableStateCache.get(createRandom);
4703
+ if (cached !== undefined) {
4704
+ return cached;
4705
+ }
4706
+ const animationRandom = createRandom('octopus3d-animation-profile');
4707
+ const eyeRandom = createRandom('octopus3d-eye-profile');
4708
+ const leftEyePhaseOffset = eyeRandom() * 0.6;
4709
+ const rightEyePhaseOffset = eyeRandom() * 0.6;
4710
+ const state = {
4711
+ morphologyProfile: createOctopus3MorphologyProfile(createRandom),
4712
+ animationPhase: animationRandom() * Math.PI * 2,
4713
+ leftEyePhaseOffset,
4714
+ rightEyePhaseOffset,
4715
+ };
4716
+ octopus3dStableStateCache.set(createRandom, state);
4717
+ return state;
4718
+ }
4665
4719
  /**
4666
4720
  * Proper 3D Octopus visual built from projected organic meshes and tentacles.
4667
4721
  *
@@ -4674,10 +4728,7 @@ const octopus3dAvatarVisual = {
4674
4728
  isAnimated: true,
4675
4729
  supportsPointerTracking: true,
4676
4730
  render({ context, size, palette, createRandom, timeMs, interaction }) {
4677
- const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
4678
- const animationRandom = createRandom('octopus3d-animation-profile');
4679
- const eyeRandom = createRandom('octopus3d-eye-profile');
4680
- const animationPhase = animationRandom() * Math.PI * 2;
4731
+ const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3dStableState(createRandom);
4681
4732
  const sceneCenterX = size * 0.5;
4682
4733
  const sceneCenterY = size * 0.56;
4683
4734
  const bob = Math.sin(timeMs / 920 + animationPhase) * size * 0.014;
@@ -4774,12 +4825,12 @@ const octopus3dAvatarVisual = {
4774
4825
  x: -faceEyeSpacing,
4775
4826
  y: faceEyeYOffset,
4776
4827
  z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -faceEyeSpacing, faceEyeYOffset),
4777
- }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + eyeRandom() * 0.6, interaction, morphologyProfile.face.eyeStyle);
4828
+ }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
4778
4829
  drawProjectedOrganicEye(context, {
4779
4830
  x: faceEyeSpacing,
4780
4831
  y: faceEyeYOffset,
4781
4832
  z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, faceEyeSpacing, faceEyeYOffset),
4782
- }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + eyeRandom() * 0.6, interaction, morphologyProfile.face.eyeStyle);
4833
+ }, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
4783
4834
  drawProjectedOrganicMouth(context, [
4784
4835
  {
4785
4836
  x: -mouthHalfWidth,
@@ -4823,14 +4874,28 @@ function drawOctopus3dAtmosphere(context, size, palette, sceneCenterX, sceneCent
4823
4874
  /**
4824
4875
  * Draws the soft ground shadow below the octopus.
4825
4876
  *
4877
+ * Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
4878
+ * blurry ellipse without triggering a costly software rasterization pass on every frame.
4879
+ *
4826
4880
  * @private helper of `octopus3dAvatarVisual`
4827
4881
  */
4828
4882
  function drawOctopus3dShadow(context, size, palette, interaction, timeMs) {
4883
+ const cx = size * 0.5 + interaction.gazeX * size * 0.04;
4884
+ const cy = size * 0.87 + Math.sin(timeMs / 920) * size * 0.008;
4885
+ const rx = size * (0.18 + interaction.intensity * 0.02);
4886
+ const ry = size * 0.06;
4829
4887
  context.save();
4830
- context.fillStyle = `${palette.shadow}66`;
4831
- context.filter = `blur(${size * 0.022}px)`;
4888
+ context.translate(cx, cy);
4889
+ context.scale(1, ry / rx);
4890
+ const blurRadius = rx * 1.4;
4891
+ const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
4892
+ shadowGradient.addColorStop(0, `${palette.shadow}7a`);
4893
+ shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
4894
+ shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
4895
+ shadowGradient.addColorStop(1, `${palette.shadow}00`);
4896
+ context.fillStyle = shadowGradient;
4832
4897
  context.beginPath();
4833
- context.ellipse(size * 0.5 + interaction.gazeX * size * 0.04, size * 0.87 + Math.sin(timeMs / 920) * size * 0.008, size * (0.18 + interaction.intensity * 0.02), size * 0.06, 0, 0, Math.PI * 2);
4898
+ context.arc(0, 0, blurRadius, 0, Math.PI * 2);
4834
4899
  context.fill();
4835
4900
  context.restore();
4836
4901
  }
@@ -5061,6 +5126,35 @@ const LIGHT_DIRECTION$1 = normalizeVector3({
5061
5126
  y: -0.6,
5062
5127
  z: 0.98,
5063
5128
  });
5129
+ /**
5130
+ * Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
5131
+ *
5132
+ * @private helper of `octopus3d2AvatarVisual`
5133
+ */
5134
+ const octopus3d2StableStateCache = new WeakMap();
5135
+ /**
5136
+ * Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
5137
+ *
5138
+ * @private helper of `octopus3d2AvatarVisual`
5139
+ */
5140
+ function getOctopus3d2StableState(createRandom) {
5141
+ const cached = octopus3d2StableStateCache.get(createRandom);
5142
+ if (cached !== undefined) {
5143
+ return cached;
5144
+ }
5145
+ const animationRandom = createRandom('octopus3d2-animation-profile');
5146
+ const eyeRandom = createRandom('octopus3d2-eye-profile');
5147
+ const leftEyePhaseOffset = eyeRandom() * 0.7;
5148
+ const rightEyePhaseOffset = eyeRandom() * 0.7;
5149
+ const state = {
5150
+ morphologyProfile: createOctopus3MorphologyProfile(createRandom),
5151
+ animationPhase: animationRandom() * Math.PI * 2,
5152
+ leftEyePhaseOffset,
5153
+ rightEyePhaseOffset,
5154
+ };
5155
+ octopus3d2StableStateCache.set(createRandom, state);
5156
+ return state;
5157
+ }
5064
5158
  /**
5065
5159
  * Octopus 3D 2 avatar visual.
5066
5160
  *
@@ -5073,10 +5167,7 @@ const octopus3d2AvatarVisual = {
5073
5167
  isAnimated: true,
5074
5168
  supportsPointerTracking: true,
5075
5169
  render({ context, size, palette, createRandom, timeMs, interaction }) {
5076
- const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
5077
- const animationRandom = createRandom('octopus3d2-animation-profile');
5078
- const eyeRandom = createRandom('octopus3d2-eye-profile');
5079
- const animationPhase = animationRandom() * Math.PI * 2;
5170
+ const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3d2StableState(createRandom);
5080
5171
  const sceneCenterX = size * 0.5;
5081
5172
  const sceneCenterY = size * 0.575;
5082
5173
  const bob = Math.sin(timeMs / 940 + animationPhase) * size * 0.013;
@@ -5129,8 +5220,8 @@ const octopus3d2AvatarVisual = {
5129
5220
  const rightEyeLocalCenter = sampleBlobbyOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude);
5130
5221
  const eyeRadiusX = size * morphologyProfile.face.eyeRadiusXRatio * 0.78;
5131
5222
  const eyeRadiusY = eyeRadiusX * morphologyProfile.face.eyeHeightRatio * 0.92;
5132
- drawProjectedOrganicEye(context, leftEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + eyeRandom() * 0.7, interaction, morphologyProfile.face.eyeStyle);
5133
- drawProjectedOrganicEye(context, rightEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.9 + eyeRandom() * 0.7, interaction, morphologyProfile.face.eyeStyle);
5223
+ drawProjectedOrganicEye(context, leftEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
5224
+ drawProjectedOrganicEye(context, rightEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.9 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
5134
5225
  drawProjectedOrganicMouth(context, [
5135
5226
  sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude - mouthHalfLongitude),
5136
5227
  sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthCurveLatitude, mouthCenterLongitude),
@@ -5159,14 +5250,28 @@ function drawBlobbyOctopusAtmosphere(context, size, palette, sceneCenterX, scene
5159
5250
  /**
5160
5251
  * Draws the soft floor shadow that anchors the single mesh in the frame.
5161
5252
  *
5253
+ * Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
5254
+ * blurry ellipse without triggering a costly software rasterization pass on every frame.
5255
+ *
5162
5256
  * @private helper of `octopus3d2AvatarVisual`
5163
5257
  */
5164
5258
  function drawBlobbyOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile) {
5259
+ const cx = size * 0.5 + interaction.gazeX * size * 0.045;
5260
+ const cy = size * 0.88 + Math.sin(timeMs / 940) * size * 0.008;
5261
+ const rx = size * (0.18 + (morphologyProfile.body.horizontalStretch - 1) * 0.04 + interaction.intensity * 0.018);
5262
+ const ry = size * 0.062;
5165
5263
  context.save();
5166
- context.fillStyle = `${palette.shadow}66`;
5167
- context.filter = `blur(${size * 0.024}px)`;
5264
+ context.translate(cx, cy);
5265
+ context.scale(1, ry / rx);
5266
+ const blurRadius = rx * 1.4;
5267
+ const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
5268
+ shadowGradient.addColorStop(0, `${palette.shadow}7a`);
5269
+ shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
5270
+ shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
5271
+ shadowGradient.addColorStop(1, `${palette.shadow}00`);
5272
+ context.fillStyle = shadowGradient;
5168
5273
  context.beginPath();
5169
- context.ellipse(size * 0.5 + interaction.gazeX * size * 0.045, size * 0.88 + Math.sin(timeMs / 940) * size * 0.008, size * (0.18 + (morphologyProfile.body.horizontalStretch - 1) * 0.04 + interaction.intensity * 0.018), size * 0.062, 0, 0, Math.PI * 2);
5274
+ context.arc(0, 0, blurRadius, 0, Math.PI * 2);
5170
5275
  context.fill();
5171
5276
  context.restore();
5172
5277
  }
@@ -5322,6 +5427,40 @@ const LIGHT_DIRECTION = normalizeVector3({
5322
5427
  * @private helper of `octopus3d3AvatarVisual`
5323
5428
  */
5324
5429
  const OCTOPUS_TENTACLE_COUNT = 8;
5430
+ /**
5431
+ * Cache keyed by the `createRandom` factory reference, which is stable for the lifetime of one
5432
+ * mounted `<Avatar/>` component (created inside `resolveAvatarRenderDefinition` and held in a
5433
+ * React `useMemo`). Using a `WeakMap` ensures the entry is collected when the component unmounts.
5434
+ *
5435
+ * @private helper of `octopus3d3AvatarVisual`
5436
+ */
5437
+ const stableStateCache = new WeakMap();
5438
+ /**
5439
+ * Returns the stable per-avatar state, computing it on first access and returning the cached
5440
+ * result on every subsequent call within the same `<Avatar/>` mount.
5441
+ *
5442
+ * @private helper of `octopus3d3AvatarVisual`
5443
+ */
5444
+ function getOctopus3d3StableState(createRandom) {
5445
+ const cached = stableStateCache.get(createRandom);
5446
+ if (cached !== undefined) {
5447
+ return cached;
5448
+ }
5449
+ const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
5450
+ const animationRandom = createRandom('octopus3d3-animation-profile');
5451
+ const eyeRandom = createRandom('octopus3d3-eye-profile');
5452
+ const leftEyePhaseOffset = eyeRandom() * 0.7;
5453
+ const rightEyePhaseOffset = eyeRandom() * 0.7;
5454
+ const state = {
5455
+ morphologyProfile,
5456
+ animationPhase: animationRandom() * Math.PI * 2,
5457
+ leftEyePhaseOffset,
5458
+ rightEyePhaseOffset,
5459
+ tentacleProfiles: createContinuousTentacleProfiles(createRandom, morphologyProfile),
5460
+ };
5461
+ stableStateCache.set(createRandom, state);
5462
+ return state;
5463
+ }
5325
5464
  /**
5326
5465
  * Octopus 3D 3 avatar visual.
5327
5466
  *
@@ -5334,11 +5473,7 @@ const octopus3d3AvatarVisual = {
5334
5473
  isAnimated: true,
5335
5474
  supportsPointerTracking: true,
5336
5475
  render({ context, size, palette, createRandom, timeMs, interaction }) {
5337
- const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
5338
- const animationRandom = createRandom('octopus3d3-animation-profile');
5339
- const eyeRandom = createRandom('octopus3d3-eye-profile');
5340
- const animationPhase = animationRandom() * Math.PI * 2;
5341
- const tentacleProfiles = createContinuousTentacleProfiles(createRandom, morphologyProfile);
5476
+ const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset, tentacleProfiles } = getOctopus3d3StableState(createRandom);
5342
5477
  const sceneCenterX = size * 0.5;
5343
5478
  const sceneCenterY = size * 0.535;
5344
5479
  const bob = Math.sin(timeMs / 960 + animationPhase) * size * 0.012;
@@ -5415,8 +5550,8 @@ const octopus3d3AvatarVisual = {
5415
5550
  size,
5416
5551
  palette,
5417
5552
  });
5418
- drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, -eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + eyeRandom() * 0.7, interaction, morphologyProfile.face.eyeStyle);
5419
- drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.85 + eyeRandom() * 0.7, interaction, morphologyProfile.face.eyeStyle);
5553
+ drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, -eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
5554
+ drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.85 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
5420
5555
  drawProjectedOrganicMouth(context, [
5421
5556
  sampleContinuousOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude - mouthHalfLongitude),
5422
5557
  sampleContinuousOctopusSurfacePoint(surfaceOptions, mouthCurveLatitude, mouthCenterLongitude),
@@ -5467,14 +5602,30 @@ function drawContinuousOctopusAtmosphere(context, size, palette, sceneCenterX, s
5467
5602
  /**
5468
5603
  * Draws the soft lower shadow that anchors the octopus in the avatar frame.
5469
5604
  *
5605
+ * Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
5606
+ * blurry ellipse without triggering a costly software rasterization pass on every frame.
5607
+ *
5470
5608
  * @private helper of `octopus3d3AvatarVisual`
5471
5609
  */
5472
5610
  function drawContinuousOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile) {
5611
+ const cx = size * 0.5 + interaction.gazeX * size * 0.045;
5612
+ const cy = size * 0.9 + Math.sin(timeMs / 980) * size * 0.007;
5613
+ const rx = size * (0.19 + morphologyProfile.tentacles.rootSpreadScale * 0.022 + interaction.intensity * 0.02);
5614
+ const ry = size * 0.06;
5615
+ // Scale the context so that drawing a circle produces the correct ellipse aspect ratio,
5616
+ // then fill with a radial gradient that approximates the blurry edge without context.filter.
5473
5617
  context.save();
5474
- context.fillStyle = `${palette.shadow}66`;
5475
- context.filter = `blur(${size * 0.025}px)`;
5618
+ context.translate(cx, cy);
5619
+ context.scale(1, ry / rx);
5620
+ const blurRadius = rx * 1.4;
5621
+ const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
5622
+ shadowGradient.addColorStop(0, `${palette.shadow}7a`);
5623
+ shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
5624
+ shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
5625
+ shadowGradient.addColorStop(1, `${palette.shadow}00`);
5626
+ context.fillStyle = shadowGradient;
5476
5627
  context.beginPath();
5477
- context.ellipse(size * 0.5 + interaction.gazeX * size * 0.045, size * 0.9 + Math.sin(timeMs / 980) * size * 0.007, size * (0.19 + morphologyProfile.tentacles.rootSpreadScale * 0.022 + interaction.intensity * 0.02), size * 0.06, 0, 0, Math.PI * 2);
5628
+ context.arc(0, 0, blurRadius, 0, Math.PI * 2);
5478
5629
  context.fill();
5479
5630
  context.restore();
5480
5631
  }
@@ -7073,7 +7224,7 @@ function valueToString(value) {
7073
7224
  * @public exported from `@promptbook/utils`
7074
7225
  */
7075
7226
  function computeHash(value) {
7076
- return SHA256(hexEncoder.parse(spaceTrim$1(valueToString(value)))).toString( /* hex */);
7227
+ return CryptoJS.SHA256(hexEncoder.parse(spaceTrim$1(valueToString(value)))).toString( /* hex */);
7077
7228
  }
7078
7229
  // TODO: [🥬][🥬] Use this ACRY
7079
7230
 
@@ -18467,7 +18618,7 @@ function getTimeoutToolRuntimeAdapterOrDisabledResult(action, runtimeContext) {
18467
18618
  * @private internal helper function
18468
18619
  */
18469
18620
  function $randomToken(randomness) {
18470
- return randomBytes(randomness).toString('hex');
18621
+ return CryptoJS.lib.WordArray.random(randomness).toString(CryptoJS.enc.Hex);
18471
18622
  }
18472
18623
  // TODO: [🤶] Maybe export through `@promptbook/utils` or `@promptbook/random` package
18473
18624
  // TODO: Maybe use nanoid instead https://github.com/ai/nanoid
@@ -20588,7 +20739,7 @@ function parseAgentSourcePrelude(agentSource) {
20588
20739
  * Regex pattern to match horizontal lines (markdown thematic breaks)
20589
20740
  * Matches 3 or more hyphens, underscores, or asterisks (with optional spaces between)
20590
20741
  */
20591
- const HORIZONTAL_LINE_PATTERN$1 = /^[\s]*[-_*][\s]*[-_*][\s]*[-_*][\s]*[-_*]*[\s]*$/;
20742
+ const HORIZONTAL_LINE_PATTERN$2 = /^[\s]*[-_*][\s]*[-_*][\s]*[-_*][\s]*[-_*]*[\s]*$/;
20592
20743
  /**
20593
20744
  * Parses agent source using the new commitment system with multiline support
20594
20745
  * This function replaces the hardcoded commitment parsing in the original parseAgentSource
@@ -20677,7 +20828,7 @@ function parseAgentSourceWithCommitments(agentSource) {
20677
20828
  }
20678
20829
  }
20679
20830
  // Check if this is a horizontal line (ends any current commitment)
20680
- const isHorizontalLine = HORIZONTAL_LINE_PATTERN$1.test(line);
20831
+ const isHorizontalLine = HORIZONTAL_LINE_PATTERN$2.test(line);
20681
20832
  if (isHorizontalLine) {
20682
20833
  // Save the current commitment if it exists
20683
20834
  if (currentCommitment) {
@@ -21622,6 +21773,56 @@ function countLines(text) {
21622
21773
  // TODO: [🥴] Implement counting in formats - like JSON, CSV, XML,...
21623
21774
  // TODO: [🧠][✌️] Make some Promptbook-native token system
21624
21775
 
21776
+ /**
21777
+ * Core Promptbook server configuration
21778
+ *
21779
+ * Used for "Adam" agent which is built in as default ancestor for new agents and other well known agents
21780
+ *
21781
+ * @public exported from `@promptbook/core`
21782
+ */
21783
+ const CORE_AGENTS_SERVER = {
21784
+ title: 'Promptbook Core',
21785
+ description: `Core Promptbook server used for Adam agent which is built in as default ancestor for new agents and other well known agents.`,
21786
+ owner: PROMPTBOOK_LEGAL_ENTITY,
21787
+ url: 'https://core.ptbk.io/',
21788
+ };
21789
+ // <- TODO: [🆎] Allow to override (set) well-known agent names via Metadata
21790
+ /**
21791
+ * Available agents servers for the Promptbook
21792
+ *
21793
+ * Tip: 💡 If you are running your own server, you can add it to this list by creating a pull request!
21794
+ *
21795
+ * @public exported from `@promptbook/core`
21796
+ */
21797
+ const PUBLIC_AGENTS_SERVERS = [
21798
+ CORE_AGENTS_SERVER,
21799
+ {
21800
+ title: 'Promptbook Gallery',
21801
+ description: `Gallery of ideas, AI professions,... like AI Agenta photobank.`,
21802
+ owner: PROMPTBOOK_LEGAL_ENTITY,
21803
+ url: 'https://gallery.ptbk.io/',
21804
+ },
21805
+ {
21806
+ title: 'Promptbook Testing server 6',
21807
+ description: `General-purpose testing server.`,
21808
+ owner: PROMPTBOOK_LEGAL_ENTITY,
21809
+ url: 'https://s6.ptbk.io/',
21810
+ },
21811
+ {
21812
+ title: 'Promptbook Testing server 7',
21813
+ description: `General-purpose testing server.`,
21814
+ owner: PROMPTBOOK_LEGAL_ENTITY,
21815
+ url: 'https://s7.ptbk.io/',
21816
+ },
21817
+ {
21818
+ title: 'Promptbook Testing server 8',
21819
+ description: `General-purpose testing server.`,
21820
+ owner: PROMPTBOOK_LEGAL_ENTITY,
21821
+ url: 'https://s8.ptbk.io/',
21822
+ },
21823
+ ];
21824
+ // Note: [💞] Ignore a discrepancy between file name and entity name
21825
+
21625
21826
  var css_248z$d = ".BookEditor-module_BookEditor__s-0PU{width:100%}.BookEditor-module_bookEditorContainer__wLMwM{box-sizing:border-box;height:100%;padding:10px 25px 0;position:relative;width:100%}.BookEditor-module_bookEditorContainer__wLMwM.BookEditor-module_isVerbose__VQ6iL{background-color:rgba(0,0,0,.05);outline:1px dotted rgba(0,0,0,.5)}.BookEditor-module_isVerbose__VQ6iL{outline:2px dotted #ff7526}.BookEditor-module_bookEditorWrapper__twppD{background-color:#fff;border:1px solid rgba(209,213,219,.8);border-radius:1rem;box-shadow:0 1px 2px 0 rgba(0,0,0,.05);overflow:hidden;padding-top:10px;transition:box-shadow .2s ease-in-out}.BookEditor-module_isVerbose__VQ6iL .BookEditor-module_bookEditorWrapper__twppD{overflow:visible}.BookEditor-module_bookEditorWrapper__twppD:hover{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.BookEditor-module_BookEditor__s-0PU[data-book-editor-theme=dark] .BookEditor-module_bookEditorWrapper__twppD{background:linear-gradient(180deg,rgba(15,23,42,.98),rgba(8,15,28,.98));border-color:rgba(51,65,85,.92);box-shadow:0 20px 45px rgba(2,6,23,.4)}.BookEditor-module_BookEditor__s-0PU[data-book-editor-theme=dark] .BookEditor-module_bookEditorWrapper__twppD:hover{box-shadow:0 24px 50px rgba(2,6,23,.48)}.BookEditor-module_bookEditorWrapper__twppD.BookEditor-module_isBorderRadiusDisabled__h1I3v{border-radius:0}.BookEditor-module_dropOverlay__xWWoX{align-items:center;background-color:rgba(0,0,0,.5);bottom:0;color:#fff;display:flex;font-size:1.5rem;justify-content:center;left:0;pointer-events:none;position:absolute;right:0;top:0;z-index:100}.BookEditor-module_bookEditorActionbar__KW6dc{position:absolute;right:55px;top:10px;z-index:100}.BookEditor-module_fullscreen__rktsl{border:none;border-radius:0;bottom:0;box-shadow:none;height:100%;left:0;padding-top:50px;position:fixed;right:0;top:0;width:100%;z-index:9999}.BookEditor-module_button__hS390{align-items:center;background-color:#fff;border:1px solid #d1d5db;border-radius:.375rem;box-shadow:0 1px 2px 0 rgba(0,0,0,.05);color:#374151;cursor:pointer;display:inline-flex;gap:.5rem;padding:.5rem 1rem;transition:all .2s ease-in-out}.BookEditor-module_button__hS390:hover{background-color:#f9fafb;border-color:#b7bcce;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.BookEditor-module_BookEditor__s-0PU[data-book-editor-theme=dark] .BookEditor-module_button__hS390{background-color:rgba(15,23,42,.92);border-color:rgba(71,85,105,.9);box-shadow:0 1px 2px 0 rgba(2,6,23,.35);color:#e2e8f0}.BookEditor-module_BookEditor__s-0PU[data-book-editor-theme=dark] .BookEditor-module_button__hS390:hover{background-color:rgba(30,41,59,.98);border-color:rgba(125,211,252,.5);box-shadow:0 10px 24px rgba(2,6,23,.35)}.BookEditor-module_savedNotification__OiX9L{align-items:center;animation:BookEditor-module_fadeOut__q8JnR 2s forwards;background-color:rgba(0,0,0,.7);border-radius:.5rem;color:#fff;display:flex;font-size:1.25rem;gap:.5rem;left:50%;padding:1rem 2rem;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);z-index:1000}.BookEditor-module_BookEditor__s-0PU[data-book-editor-theme=dark] .BookEditor-module_savedNotification__OiX9L{background-color:rgba(2,6,23,.86);border:1px solid rgba(51,65,85,.9);color:#e2e8f0}.BookEditor-module_uploadPanel__2JJtD{background:hsla(0,0%,100%,.98);border:1px solid rgba(209,213,219,.9);border-radius:12px;bottom:20px;box-shadow:0 12px 30px rgba(15,23,42,.15);display:flex;flex-direction:column;gap:10px;max-width:calc(100% - 40px);padding:12px;position:absolute;right:20px;width:420px;z-index:220}.BookEditor-module_BookEditor__s-0PU[data-book-editor-theme=dark] .BookEditor-module_uploadPanel__2JJtD{background:rgba(8,15,28,.96);border-color:rgba(51,65,85,.9);box-shadow:0 18px 40px rgba(2,6,23,.45)}.BookEditor-module_uploadPanelHeader__pdJd2{align-items:center;display:flex;gap:12px;justify-content:space-between}.BookEditor-module_uploadPanelTitle__TJIVF{color:#111827;font-size:.95rem;font-weight:600}.BookEditor-module_BookEditor__s-0PU[data-book-editor-theme=dark] .BookEditor-module_uploadPanelTitle__TJIVF{color:#f8fafc}.BookEditor-module_uploadPanelHeaderMeta__Xw0uI{color:#6b7280;font-size:.75rem}.BookEditor-module_BookEditor__s-0PU[data-book-editor-theme=dark] .BookEditor-module_uploadPanelHeaderMeta__Xw0uI,.BookEditor-module_BookEditor__s-0PU[data-book-editor-theme=dark] .BookEditor-module_uploadPanelSummary__rwSbG,.BookEditor-module_BookEditor__s-0PU[data-book-editor-theme=dark] .BookEditor-module_uploadRowMeta__1lz9h,.BookEditor-module_BookEditor__s-0PU[data-book-editor-theme=dark] .BookEditor-module_uploadRowStatus__jsUb-{color:#94a3b8}.BookEditor-module_uploadPanelSummary__rwSbG{color:#6b7280;display:grid;font-size:.75rem;gap:4px 12px;grid-template-columns:1fr 1fr}.BookEditor-module_uploadPanelProgressBar__a6pjf{background:#e5e7eb;border-radius:999px;height:6px;overflow:hidden}.BookEditor-module_uploadPanelProgressFill__l-TKR{background:linear-gradient(90deg,#2563eb,#10b981);height:100%;transition:width .2s ease}.BookEditor-module_BookEditor__s-0PU[data-book-editor-theme=dark] .BookEditor-module_uploadPanelProgressBar__a6pjf,.BookEditor-module_BookEditor__s-0PU[data-book-editor-theme=dark] .BookEditor-module_uploadRowProgressBar__NoBA7{background:#1e293b}.BookEditor-module_uploadPanelList__VxEd5{display:flex;flex-direction:column;gap:8px;max-height:220px;overflow-y:auto;padding-right:4px}.BookEditor-module_uploadRow__QiSFg{background:#fff;border:1px solid #e5e7eb;border-radius:10px;display:flex;flex-direction:column;gap:6px;padding:8px}.BookEditor-module_BookEditor__s-0PU[data-book-editor-theme=dark] .BookEditor-module_uploadRow__QiSFg{background:rgba(15,23,42,.92);border-color:#334155}.BookEditor-module_uploadRowHeader__po0j5{align-items:center;display:flex;gap:8px;justify-content:space-between}.BookEditor-module_uploadRowName__doQRO{color:#111827;font-size:.8rem;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.BookEditor-module_BookEditor__s-0PU[data-book-editor-theme=dark] .BookEditor-module_uploadRowName__doQRO{color:#f8fafc}.BookEditor-module_uploadRowStatus__jsUb-{color:#6b7280;font-size:.7rem}.BookEditor-module_uploadRowMeta__1lz9h{color:#6b7280;display:flex;font-size:.7rem;justify-content:space-between}.BookEditor-module_uploadRowProgressBar__NoBA7{background:#e5e7eb;border-radius:999px;height:4px;overflow:hidden}.BookEditor-module_uploadRowProgressFill__TrP7e{background:#3b82f6;height:100%;transition:width .2s ease}.BookEditor-module_uploadRowActions__5Y1Mq{display:flex;gap:6px}.BookEditor-module_uploadActionButton__CqJrr{background:#f9fafb;border:1px solid #d1d5db;border-radius:6px;color:#374151;cursor:pointer;font-size:.7rem;padding:2px 8px;transition:all .15s ease-in-out}.BookEditor-module_uploadActionButton__CqJrr:hover{background:#eef2f7;border-color:#cbd5f5}.BookEditor-module_BookEditor__s-0PU[data-book-editor-theme=dark] .BookEditor-module_uploadActionButton__CqJrr{background:#0f172a;border-color:#475569;color:#e2e8f0}.BookEditor-module_BookEditor__s-0PU[data-book-editor-theme=dark] .BookEditor-module_uploadActionButton__CqJrr:hover{background:#1e293b;border-color:#7dd3fc}.BookEditor-module_uploadRowError__eEHWw{color:#b91c1c;font-size:.7rem}.BookEditor-module_aboutPromptbookInformation__eiBL0{color:#111827;font-family:var(--font-poppins,system-ui,-apple-system,BlinkMacSystemFont,\"Segoe UI\",sans-serif);font-size:.95rem;line-height:1.6;max-width:680px}.BookEditor-module_aboutPromptbookInformation__eiBL0>:first-child{margin-top:0}.BookEditor-module_aboutPromptbookInformation__eiBL0>:last-child{margin-bottom:0}.BookEditor-module_aboutPromptbookInformation__eiBL0 h1,.BookEditor-module_aboutPromptbookInformation__eiBL0 h2{color:#0f172a;font-weight:650;line-height:1.25}.BookEditor-module_aboutPromptbookInformation__eiBL0 h1{font-size:1.5rem;margin:0 0 .75rem}.BookEditor-module_aboutPromptbookInformation__eiBL0 h2{font-size:1.15rem;margin:1.35rem 0 .55rem}.BookEditor-module_aboutPromptbookInformation__eiBL0 p{margin:0 0 .9rem}.BookEditor-module_aboutPromptbookInformation__eiBL0 ol,.BookEditor-module_aboutPromptbookInformation__eiBL0 ul{display:grid;gap:.35rem;margin:.55rem 0 1rem;padding-left:1.35rem}.BookEditor-module_aboutPromptbookInformation__eiBL0 a{color:#2563eb;text-decoration:underline;text-underline-offset:.16em}.BookEditor-module_aboutPromptbookInformation__eiBL0 code{background:rgba(15,23,42,.06);border:1px solid rgba(15,23,42,.12);border-radius:6px;color:#111827;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,monospace;font-size:.9em;padding:.12em .34em}@keyframes BookEditor-module_fadeOut__q8JnR{0%{opacity:0}10%{opacity:1}70%{opacity:1}to{opacity:0}}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkJvb2tFZGl0b3IubW9kdWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxxQ0FFSSxVQUNKLENBRUEsOENBS0kscUJBQXNCLENBSHRCLFdBQVksQ0FFWixtQkFBb0IsQ0FEcEIsaUJBQWtCLENBRmxCLFVBS0osQ0FFQSxpRkFFSSxnQ0FBcUMsQ0FDckMsaUNBRUosQ0FFQSxvQ0FDSSwwQkFDSixDQUVBLDRDQUtJLHFCQUF1QixDQUR2QixxQ0FBMEMsQ0FGMUMsa0JBQW1CLENBSW5CLHNDQUEyQyxDQUwzQyxlQUFnQixDQUVoQixnQkFBaUIsQ0FJakIscUNBQ0osQ0FDQSxnRkFFSSxnQkFFSixDQUVBLGtEQUNJLHVFQUNKLENBRUEsOEdBRUksdUVBQWtGLENBRGxGLCtCQUFvQyxDQUVwQyxzQ0FDSixDQUVBLG9IQUNJLHVDQUNKLENBVUEsNEZBQ0ksZUFDSixDQUVBLHNDQVNJLGtCQUFtQixDQUhuQiwrQkFBb0MsQ0FEcEMsUUFBUyxDQUVULFVBQVksQ0FDWixZQUFhLENBR2IsZ0JBQWlCLENBRGpCLHNCQUF1QixDQVB2QixNQUFPLENBVVAsbUJBQW9CLENBWnBCLGlCQUFrQixDQUdsQixPQUFRLENBRlIsS0FBTSxDQVVOLFdBRUosQ0FRQSw4Q0FDSSxpQkFBa0IsQ0FFbEIsVUFBVyxDQURYLFFBQVMsQ0FFVCxXQUNKLENBRUEscUNBV0ksV0FBWSxDQUZaLGVBQWdCLENBSmhCLFFBQVMsQ0FPVCxlQUFnQixDQUxoQixXQUFZLENBSlosTUFBTyxDQU9QLGdCQUFpQixDQVRqQixjQUFlLENBR2YsT0FBUSxDQUZSLEtBQU0sQ0FJTixVQUFXLENBRVgsWUFLSixDQUVBLGlDQU9JLGtCQUFtQixDQU5uQixxQkFBc0IsQ0FDdEIsd0JBQXlCLENBQ3pCLHFCQUF1QixDQU92QixzQ0FBMkMsQ0FEM0MsYUFBYyxDQUpkLGNBQWUsQ0FDZixtQkFBb0IsQ0FFcEIsU0FBVyxDQUpYLGtCQUFvQixDQU9wQiw4QkFDSixDQUVBLHVDQUNJLHdCQUF5QixDQUN6QixvQkFBcUIsQ0FDckIsaUVBQ0osQ0FFQSxtR0FDSSxtQ0FBd0MsQ0FDeEMsK0JBQW9DLENBRXBDLHVDQUE0QyxDQUQ1QyxhQUVKLENBRUEseUdBQ0ksbUNBQXdDLENBQ3hDLGlDQUFzQyxDQUN0Qyx1Q0FDSixDQUVBLDRDQWFJLGtCQUFtQixDQUVuQixzREFBOEIsQ0FWOUIsK0JBQW9DLENBR3BDLG1CQUFxQixDQUZyQixVQUFZLENBTVosWUFBYSxDQUhiLGlCQUFrQixDQUtsQixTQUFXLENBWFgsUUFBUyxDQUlULGlCQUFrQixDQUlsQixtQkFBb0IsQ0FWcEIsaUJBQWtCLENBQ2xCLE9BQVEsQ0FFUiw4QkFBZ0MsQ0FNaEMsWUFNSixDQUVBLDhHQUNJLGlDQUFzQyxDQUV0QyxrQ0FBdUMsQ0FEdkMsYUFFSixDQUVBLHNDQU1JLDhCQUFxQyxDQUNyQyxxQ0FBMEMsQ0FDMUMsa0JBQW1CLENBTG5CLFdBQVksQ0FNWix5Q0FBOEMsQ0FFOUMsWUFBYSxDQUNiLHFCQUFzQixDQUN0QixRQUFTLENBUlQsMkJBQTRCLENBSzVCLFlBQWEsQ0FUYixpQkFBa0IsQ0FDbEIsVUFBVyxDQUVYLFdBQVksQ0FVWixXQUNKLENBRUEsd0dBQ0ksNEJBQWlDLENBQ2pDLDhCQUFtQyxDQUNuQyx1Q0FDSixDQUVBLDRDQUVJLGtCQUFtQixDQURuQixZQUFhLENBR2IsUUFBUyxDQURULDZCQUVKLENBRUEsMkNBR0ksYUFBYyxDQURkLGdCQUFrQixDQURsQixlQUdKLENBRUEsNkdBQ0ksYUFDSixDQUVBLGdEQUVJLGFBQWMsQ0FEZCxnQkFFSixDQUVBLHViQUlJLGFBQ0osQ0FFQSw2Q0FLSSxhQUFjLENBSmQsWUFBYSxDQUdiLGdCQUFrQixDQURsQixZQUFhLENBRGIsNkJBSUosQ0FFQSxpREFFSSxrQkFBbUIsQ0FDbkIsbUJBQW9CLENBRnBCLFVBQVcsQ0FHWCxlQUNKLENBRUEsa0RBRUksaURBQW9ELENBRHBELFdBQVksQ0FFWix5QkFDSixDQUVBLG9PQUVJLGtCQUNKLENBRUEsMENBQ0ksWUFBYSxDQUNiLHFCQUFzQixDQUN0QixPQUFRLENBQ1IsZ0JBQWlCLENBQ2pCLGVBQWdCLENBQ2hCLGlCQUNKLENBRUEsb0NBT0ksZUFBZ0IsQ0FOaEIsd0JBQXlCLENBQ3pCLGtCQUFtQixDQUVuQixZQUFhLENBQ2IscUJBQXNCLENBQ3RCLE9BQVEsQ0FIUixXQUtKLENBRUEsc0dBRUksNkJBQWtDLENBRGxDLG9CQUVKLENBRUEsMENBRUksa0JBQW1CLENBRG5CLFlBQWEsQ0FHYixPQUFRLENBRFIsNkJBRUosQ0FFQSx3Q0FHSSxhQUFjLENBRmQsZUFBaUIsQ0FDakIsZUFBZ0IsQ0FFaEIsZUFBZ0IsQ0FDaEIsc0JBQXVCLENBQ3ZCLGtCQUNKLENBRUEsMEdBQ0ksYUFDSixDQUVBLDBDQUVJLGFBQWMsQ0FEZCxlQUVKLENBRUEsd0NBSUksYUFBYyxDQUhkLFlBQWEsQ0FFYixlQUFpQixDQURqQiw2QkFHSixDQUVBLCtDQUVJLGtCQUFtQixDQUNuQixtQkFBb0IsQ0FGcEIsVUFBVyxDQUdYLGVBQ0osQ0FFQSxnREFFSSxrQkFBbUIsQ0FEbkIsV0FBWSxDQUVaLHlCQUNKLENBRUEsMkNBQ0ksWUFBYSxDQUNiLE9BQ0osQ0FFQSw2Q0FFSSxrQkFBbUIsQ0FEbkIsd0JBQXlCLENBS3pCLGlCQUFrQixDQUhsQixhQUFjLENBSWQsY0FBZSxDQUhmLGVBQWlCLENBQ2pCLGVBQWdCLENBR2hCLCtCQUNKLENBRUEsbURBQ0ksa0JBQW1CLENBQ25CLG9CQUNKLENBRUEsK0dBRUksa0JBQW1CLENBRG5CLG9CQUFxQixDQUVyQixhQUNKLENBRUEscUhBQ0ksa0JBQW1CLENBQ25CLG9CQUNKLENBRUEseUNBRUksYUFBYyxDQURkLGVBRUosQ0FFQSxxREFFSSxhQUFjLENBQ2QsZ0dBQXNHLENBQ3RHLGdCQUFrQixDQUNsQixlQUFnQixDQUpoQixlQUtKLENBRUEsa0VBQ0ksWUFDSixDQUVBLGlFQUNJLGVBQ0osQ0FFQSxnSEFFSSxhQUFjLENBQ2QsZUFBZ0IsQ0FDaEIsZ0JBQ0osQ0FFQSx3REFFSSxnQkFBaUIsQ0FEakIsaUJBRUosQ0FFQSx3REFFSSxpQkFBa0IsQ0FEbEIsdUJBRUosQ0FFQSx1REFDSSxnQkFDSixDQUVBLGdIQUVJLFlBQWEsQ0FDYixVQUFZLENBQ1osb0JBQXNCLENBQ3RCLG9CQUNKLENBRUEsdURBQ0ksYUFBYyxDQUNkLHlCQUEwQixDQUMxQiwyQkFDSixDQUVBLDBEQUlJLDZCQUFrQyxDQUZsQyxtQ0FBd0MsQ0FDeEMsaUJBQWtCLENBRWxCLGFBQWMsQ0FDZCx1RkFBZ0csQ0FDaEcsY0FBZ0IsQ0FOaEIsbUJBT0osQ0FFQSw0Q0FDSSxHQUNJLFNBQ0osQ0FDQSxJQUNJLFNBQ0osQ0FDQSxJQUNJLFNBQ0osQ0FDQSxHQUNJLFNBQ0osQ0FDSiIsImZpbGUiOiJCb29rRWRpdG9yLm1vZHVsZS5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyIuQm9va0VkaXRvciB7XG4gICAgLyogaGVpZ2h0OiA0NTBweDsgKi9cbiAgICB3aWR0aDogMTAwJTtcbn1cblxuLmJvb2tFZGl0b3JDb250YWluZXIge1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgcGFkZGluZzogMTBweCAyNXB4IDA7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbn1cblxuLmJvb2tFZGl0b3JDb250YWluZXIuaXNWZXJib3NlIHtcbiAgICAvKiovXG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjA1KTtcbiAgICBvdXRsaW5lOiAxcHggZG90dGVkIHJnYmEoMCwgMCwgMCwgMC41KTtcbiAgICAvKiovXG59XG5cbi5pc1ZlcmJvc2Uge1xuICAgIG91dGxpbmU6IDJweCBkb3R0ZWQgcmdiKDI1NSAxMTcgMzgpO1xufVxuXG4uYm9va0VkaXRvcldyYXBwZXIge1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgYm9yZGVyLXJhZGl1czogMXJlbTtcbiAgICBwYWRkaW5nLXRvcDogMTBweDtcbiAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDIwOSwgMjEzLCAyMTksIDAuOCk7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XG4gICAgYm94LXNoYWRvdzogMCAxcHggMnB4IDAgcmdiYSgwLCAwLCAwLCAwLjA1KTtcbiAgICB0cmFuc2l0aW9uOiBib3gtc2hhZG93IDAuMnMgZWFzZS1pbi1vdXQ7XG59XG4uaXNWZXJib3NlIC5ib29rRWRpdG9yV3JhcHBlciB7XG4gICAgLyoqL1xuICAgIG92ZXJmbG93OiB2aXNpYmxlO1xuICAgIC8qKi9cbn1cblxuLmJvb2tFZGl0b3JXcmFwcGVyOmhvdmVyIHtcbiAgICBib3gtc2hhZG93OiAwIDRweCA2cHggLTFweCByZ2JhKDAsIDAsIDAsIDAuMSksIDAgMnB4IDRweCAtMXB4IHJnYmEoMCwgMCwgMCwgMC4wNik7XG59XG5cbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAuYm9va0VkaXRvcldyYXBwZXIge1xuICAgIGJvcmRlci1jb2xvcjogcmdiYSg1MSwgNjUsIDg1LCAwLjkyKTtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTgwZGVnLCByZ2JhKDE1LCAyMywgNDIsIDAuOTgpLCByZ2JhKDgsIDE1LCAyOCwgMC45OCkpO1xuICAgIGJveC1zaGFkb3c6IDAgMjBweCA0NXB4IHJnYmEoMiwgNiwgMjMsIDAuNCk7XG59XG5cbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAuYm9va0VkaXRvcldyYXBwZXI6aG92ZXIge1xuICAgIGJveC1zaGFkb3c6IDAgMjRweCA1MHB4IHJnYmEoMiwgNiwgMjMsIDAuNDgpO1xufVxuXG4uYm9va0VkaXRvcldyYXBwZXI6Zm9jdXMtd2l0aGluIHtcbiAgICAvKlxuICAgIG91dGxpbmU6IDJweCBzb2xpZCB0cmFuc3BhcmVudDtcbiAgICBvdXRsaW5lLW9mZnNldDogMnB4O1xuICAgIGJveC1zaGFkb3c6IDAgMCAwIDNweCByZ2JhKDk5LCAxMDIsIDI0MSwgMC40KTtcbiAgICAqL1xufVxuXG4uYm9va0VkaXRvcldyYXBwZXIuaXNCb3JkZXJSYWRpdXNEaXNhYmxlZCB7XG4gICAgYm9yZGVyLXJhZGl1czogMDtcbn1cblxuLmRyb3BPdmVybGF5IHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdG9wOiAwO1xuICAgIGxlZnQ6IDA7XG4gICAgcmlnaHQ6IDA7XG4gICAgYm90dG9tOiAwO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC41KTtcbiAgICBjb2xvcjogd2hpdGU7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIGZvbnQtc2l6ZTogMS41cmVtO1xuICAgIHotaW5kZXg6IDEwMDtcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cblxuLypcbi5ib29rRWRpdG9yQ29udGFpbmVyIDpnbG9iYWwoLnZpZXctbGluZSkge1xuICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjZWVlOyAvKiA8LSBOb3RlOiBgUFJPTVBUQk9PS19TWU5UQVhfQ09MT1JTLkxJTkVgICogL1xufVxuKi9cblxuLmJvb2tFZGl0b3JBY3Rpb25iYXIge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDEwcHg7XG4gICAgcmlnaHQ6IDU1cHg7XG4gICAgei1pbmRleDogMTAwO1xufVxuXG4uZnVsbHNjcmVlbiB7XG4gICAgcG9zaXRpb246IGZpeGVkO1xuICAgIHRvcDogMDtcbiAgICBsZWZ0OiAwO1xuICAgIHJpZ2h0OiAwO1xuICAgIGJvdHRvbTogMDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgei1pbmRleDogOTk5OTtcbiAgICBib3JkZXItcmFkaXVzOiAwO1xuICAgIHBhZGRpbmctdG9wOiA1MHB4O1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBib3gtc2hhZG93OiBub25lO1xufVxuXG4uYnV0dG9uIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xuICAgIGJvcmRlcjogMXB4IHNvbGlkICNkMWQ1ZGI7XG4gICAgYm9yZGVyLXJhZGl1czogMC4zNzVyZW07XG4gICAgcGFkZGluZzogMC41cmVtIDFyZW07XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgZ2FwOiAwLjVyZW07XG4gICAgY29sb3I6ICMzNzQxNTE7XG4gICAgYm94LXNoYWRvdzogMCAxcHggMnB4IDAgcmdiYSgwLCAwLCAwLCAwLjA1KTtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4ycyBlYXNlLWluLW91dDtcbn1cblxuLmJ1dHRvbjpob3ZlciB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2Y5ZmFmYjtcbiAgICBib3JkZXItY29sb3I6ICNiN2JjY2U7XG4gICAgYm94LXNoYWRvdzogMCAxcHggM3B4IDAgcmdiYSgwLCAwLCAwLCAwLjEpLCAwIDFweCAycHggMCByZ2JhKDAsIDAsIDAsIDAuMDYpO1xufVxuXG4uQm9va0VkaXRvcltkYXRhLWJvb2stZWRpdG9yLXRoZW1lPSdkYXJrJ10gLmJ1dHRvbiB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgxNSwgMjMsIDQyLCAwLjkyKTtcbiAgICBib3JkZXItY29sb3I6IHJnYmEoNzEsIDg1LCAxMDUsIDAuOSk7XG4gICAgY29sb3I6ICNlMmU4ZjA7XG4gICAgYm94LXNoYWRvdzogMCAxcHggMnB4IDAgcmdiYSgyLCA2LCAyMywgMC4zNSk7XG59XG5cbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAuYnV0dG9uOmhvdmVyIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDMwLCA0MSwgNTksIDAuOTgpO1xuICAgIGJvcmRlci1jb2xvcjogcmdiYSgxMjUsIDIxMSwgMjUyLCAwLjUpO1xuICAgIGJveC1zaGFkb3c6IDAgMTBweCAyNHB4IHJnYmEoMiwgNiwgMjMsIDAuMzUpO1xufVxuXG4uc2F2ZWROb3RpZmljYXRpb24ge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDUwJTtcbiAgICBsZWZ0OiA1MCU7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjcpO1xuICAgIGNvbG9yOiB3aGl0ZTtcbiAgICBwYWRkaW5nOiAxcmVtIDJyZW07XG4gICAgYm9yZGVyLXJhZGl1czogMC41cmVtO1xuICAgIGZvbnQtc2l6ZTogMS4yNXJlbTtcbiAgICB6LWluZGV4OiAxMDAwO1xuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBnYXA6IDAuNXJlbTtcbiAgICBhbmltYXRpb246IGZhZGVPdXQgMnMgZm9yd2FyZHM7XG59XG5cbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAuc2F2ZWROb3RpZmljYXRpb24ge1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMiwgNiwgMjMsIDAuODYpO1xuICAgIGNvbG9yOiAjZTJlOGYwO1xuICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoNTEsIDY1LCA4NSwgMC45KTtcbn1cblxuLnVwbG9hZFBhbmVsIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgcmlnaHQ6IDIwcHg7XG4gICAgYm90dG9tOiAyMHB4O1xuICAgIHdpZHRoOiA0MjBweDtcbiAgICBtYXgtd2lkdGg6IGNhbGMoMTAwJSAtIDQwcHgpO1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC45OCk7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyMDksIDIxMywgMjE5LCAwLjkpO1xuICAgIGJvcmRlci1yYWRpdXM6IDEycHg7XG4gICAgYm94LXNoYWRvdzogMCAxMnB4IDMwcHggcmdiYSgxNSwgMjMsIDQyLCAwLjE1KTtcbiAgICBwYWRkaW5nOiAxMnB4O1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICBnYXA6IDEwcHg7XG4gICAgei1pbmRleDogMjIwO1xufVxuXG4uQm9va0VkaXRvcltkYXRhLWJvb2stZWRpdG9yLXRoZW1lPSdkYXJrJ10gLnVwbG9hZFBhbmVsIHtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDgsIDE1LCAyOCwgMC45Nik7XG4gICAgYm9yZGVyLWNvbG9yOiByZ2JhKDUxLCA2NSwgODUsIDAuOSk7XG4gICAgYm94LXNoYWRvdzogMCAxOHB4IDQwcHggcmdiYSgyLCA2LCAyMywgMC40NSk7XG59XG5cbi51cGxvYWRQYW5lbEhlYWRlciB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICBnYXA6IDEycHg7XG59XG5cbi51cGxvYWRQYW5lbFRpdGxlIHtcbiAgICBmb250LXdlaWdodDogNjAwO1xuICAgIGZvbnQtc2l6ZTogMC45NXJlbTtcbiAgICBjb2xvcjogIzExMTgyNztcbn1cblxuLkJvb2tFZGl0b3JbZGF0YS1ib29rLWVkaXRvci10aGVtZT0nZGFyayddIC51cGxvYWRQYW5lbFRpdGxlIHtcbiAgICBjb2xvcjogI2Y4ZmFmYztcbn1cblxuLnVwbG9hZFBhbmVsSGVhZGVyTWV0YSB7XG4gICAgZm9udC1zaXplOiAwLjc1cmVtO1xuICAgIGNvbG9yOiAjNmI3MjgwO1xufVxuXG4uQm9va0VkaXRvcltkYXRhLWJvb2stZWRpdG9yLXRoZW1lPSdkYXJrJ10gLnVwbG9hZFBhbmVsSGVhZGVyTWV0YSxcbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAudXBsb2FkUGFuZWxTdW1tYXJ5LFxuLkJvb2tFZGl0b3JbZGF0YS1ib29rLWVkaXRvci10aGVtZT0nZGFyayddIC51cGxvYWRSb3dTdGF0dXMsXG4uQm9va0VkaXRvcltkYXRhLWJvb2stZWRpdG9yLXRoZW1lPSdkYXJrJ10gLnVwbG9hZFJvd01ldGEge1xuICAgIGNvbG9yOiAjOTRhM2I4O1xufVxuXG4udXBsb2FkUGFuZWxTdW1tYXJ5IHtcbiAgICBkaXNwbGF5OiBncmlkO1xuICAgIGdyaWQtdGVtcGxhdGUtY29sdW1uczogMWZyIDFmcjtcbiAgICBnYXA6IDRweCAxMnB4O1xuICAgIGZvbnQtc2l6ZTogMC43NXJlbTtcbiAgICBjb2xvcjogIzZiNzI4MDtcbn1cblxuLnVwbG9hZFBhbmVsUHJvZ3Jlc3NCYXIge1xuICAgIGhlaWdodDogNnB4O1xuICAgIGJhY2tncm91bmQ6ICNlNWU3ZWI7XG4gICAgYm9yZGVyLXJhZGl1czogOTk5cHg7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbn1cblxuLnVwbG9hZFBhbmVsUHJvZ3Jlc3NGaWxsIHtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDkwZGVnLCAjMjU2M2ViLCAjMTBiOTgxKTtcbiAgICB0cmFuc2l0aW9uOiB3aWR0aCAwLjJzIGVhc2U7XG59XG5cbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAudXBsb2FkUGFuZWxQcm9ncmVzc0Jhcixcbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAudXBsb2FkUm93UHJvZ3Jlc3NCYXIge1xuICAgIGJhY2tncm91bmQ6ICMxZTI5M2I7XG59XG5cbi51cGxvYWRQYW5lbExpc3Qge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICBnYXA6IDhweDtcbiAgICBtYXgtaGVpZ2h0OiAyMjBweDtcbiAgICBvdmVyZmxvdy15OiBhdXRvO1xuICAgIHBhZGRpbmctcmlnaHQ6IDRweDtcbn1cblxuLnVwbG9hZFJvdyB7XG4gICAgYm9yZGVyOiAxcHggc29saWQgI2U1ZTdlYjtcbiAgICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICAgIHBhZGRpbmc6IDhweDtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgZ2FwOiA2cHg7XG4gICAgYmFja2dyb3VuZDogI2ZmZjtcbn1cblxuLkJvb2tFZGl0b3JbZGF0YS1ib29rLWVkaXRvci10aGVtZT0nZGFyayddIC51cGxvYWRSb3cge1xuICAgIGJvcmRlci1jb2xvcjogIzMzNDE1NTtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDE1LCAyMywgNDIsIDAuOTIpO1xufVxuXG4udXBsb2FkUm93SGVhZGVyIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgIGdhcDogOHB4O1xufVxuXG4udXBsb2FkUm93TmFtZSB7XG4gICAgZm9udC1zaXplOiAwLjhyZW07XG4gICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICBjb2xvcjogIzExMTgyNztcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG59XG5cbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAudXBsb2FkUm93TmFtZSB7XG4gICAgY29sb3I6ICNmOGZhZmM7XG59XG5cbi51cGxvYWRSb3dTdGF0dXMge1xuICAgIGZvbnQtc2l6ZTogMC43cmVtO1xuICAgIGNvbG9yOiAjNmI3MjgwO1xufVxuXG4udXBsb2FkUm93TWV0YSB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gICAgZm9udC1zaXplOiAwLjdyZW07XG4gICAgY29sb3I6ICM2YjcyODA7XG59XG5cbi51cGxvYWRSb3dQcm9ncmVzc0JhciB7XG4gICAgaGVpZ2h0OiA0cHg7XG4gICAgYmFja2dyb3VuZDogI2U1ZTdlYjtcbiAgICBib3JkZXItcmFkaXVzOiA5OTlweDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xufVxuXG4udXBsb2FkUm93UHJvZ3Jlc3NGaWxsIHtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgYmFja2dyb3VuZDogIzNiODJmNjtcbiAgICB0cmFuc2l0aW9uOiB3aWR0aCAwLjJzIGVhc2U7XG59XG5cbi51cGxvYWRSb3dBY3Rpb25zIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGdhcDogNnB4O1xufVxuXG4udXBsb2FkQWN0aW9uQnV0dG9uIHtcbiAgICBib3JkZXI6IDFweCBzb2xpZCAjZDFkNWRiO1xuICAgIGJhY2tncm91bmQ6ICNmOWZhZmI7XG4gICAgY29sb3I6ICMzNzQxNTE7XG4gICAgZm9udC1zaXplOiAwLjdyZW07XG4gICAgcGFkZGluZzogMnB4IDhweDtcbiAgICBib3JkZXItcmFkaXVzOiA2cHg7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIHRyYW5zaXRpb246IGFsbCAwLjE1cyBlYXNlLWluLW91dDtcbn1cblxuLnVwbG9hZEFjdGlvbkJ1dHRvbjpob3ZlciB7XG4gICAgYmFja2dyb3VuZDogI2VlZjJmNztcbiAgICBib3JkZXItY29sb3I6ICNjYmQ1ZjU7XG59XG5cbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAudXBsb2FkQWN0aW9uQnV0dG9uIHtcbiAgICBib3JkZXItY29sb3I6ICM0NzU1Njk7XG4gICAgYmFja2dyb3VuZDogIzBmMTcyYTtcbiAgICBjb2xvcjogI2UyZThmMDtcbn1cblxuLkJvb2tFZGl0b3JbZGF0YS1ib29rLWVkaXRvci10aGVtZT0nZGFyayddIC51cGxvYWRBY3Rpb25CdXR0b246aG92ZXIge1xuICAgIGJhY2tncm91bmQ6ICMxZTI5M2I7XG4gICAgYm9yZGVyLWNvbG9yOiAjN2RkM2ZjO1xufVxuXG4udXBsb2FkUm93RXJyb3Ige1xuICAgIGZvbnQtc2l6ZTogMC43cmVtO1xuICAgIGNvbG9yOiAjYjkxYzFjO1xufVxuXG4uYWJvdXRQcm9tcHRib29rSW5mb3JtYXRpb24ge1xuICAgIG1heC13aWR0aDogNjgwcHg7XG4gICAgY29sb3I6ICMxMTE4Mjc7XG4gICAgZm9udC1mYW1pbHk6IHZhcigtLWZvbnQtcG9wcGlucywgc3lzdGVtLXVpLCAtYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsICdTZWdvZSBVSScsIHNhbnMtc2VyaWYpO1xuICAgIGZvbnQtc2l6ZTogMC45NXJlbTtcbiAgICBsaW5lLWhlaWdodDogMS42O1xufVxuXG4uYWJvdXRQcm9tcHRib29rSW5mb3JtYXRpb24gPiA6Zmlyc3QtY2hpbGQge1xuICAgIG1hcmdpbi10b3A6IDA7XG59XG5cbi5hYm91dFByb21wdGJvb2tJbmZvcm1hdGlvbiA+IDpsYXN0LWNoaWxkIHtcbiAgICBtYXJnaW4tYm90dG9tOiAwO1xufVxuXG4uYWJvdXRQcm9tcHRib29rSW5mb3JtYXRpb24gaDEsXG4uYWJvdXRQcm9tcHRib29rSW5mb3JtYXRpb24gaDIge1xuICAgIGNvbG9yOiAjMGYxNzJhO1xuICAgIGZvbnQtd2VpZ2h0OiA2NTA7XG4gICAgbGluZS1oZWlnaHQ6IDEuMjU7XG59XG5cbi5hYm91dFByb21wdGJvb2tJbmZvcm1hdGlvbiBoMSB7XG4gICAgbWFyZ2luOiAwIDAgMC43NXJlbTtcbiAgICBmb250LXNpemU6IDEuNXJlbTtcbn1cblxuLmFib3V0UHJvbXB0Ym9va0luZm9ybWF0aW9uIGgyIHtcbiAgICBtYXJnaW46IDEuMzVyZW0gMCAwLjU1cmVtO1xuICAgIGZvbnQtc2l6ZTogMS4xNXJlbTtcbn1cblxuLmFib3V0UHJvbXB0Ym9va0luZm9ybWF0aW9uIHAge1xuICAgIG1hcmdpbjogMCAwIDAuOXJlbTtcbn1cblxuLmFib3V0UHJvbXB0Ym9va0luZm9ybWF0aW9uIHVsLFxuLmFib3V0UHJvbXB0Ym9va0luZm9ybWF0aW9uIG9sIHtcbiAgICBkaXNwbGF5OiBncmlkO1xuICAgIGdhcDogMC4zNXJlbTtcbiAgICBtYXJnaW46IDAuNTVyZW0gMCAxcmVtO1xuICAgIHBhZGRpbmctbGVmdDogMS4zNXJlbTtcbn1cblxuLmFib3V0UHJvbXB0Ym9va0luZm9ybWF0aW9uIGEge1xuICAgIGNvbG9yOiAjMjU2M2ViO1xuICAgIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lO1xuICAgIHRleHQtdW5kZXJsaW5lLW9mZnNldDogMC4xNmVtO1xufVxuXG4uYWJvdXRQcm9tcHRib29rSW5mb3JtYXRpb24gY29kZSB7XG4gICAgcGFkZGluZzogMC4xMmVtIDAuMzRlbTtcbiAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDE1LCAyMywgNDIsIDAuMTIpO1xuICAgIGJvcmRlci1yYWRpdXM6IDZweDtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDE1LCAyMywgNDIsIDAuMDYpO1xuICAgIGNvbG9yOiAjMTExODI3O1xuICAgIGZvbnQtZmFtaWx5OiB1aS1tb25vc3BhY2UsIFNGTW9uby1SZWd1bGFyLCBNZW5sbywgTW9uYWNvLCBDb25zb2xhcywgJ0xpYmVyYXRpb24gTW9ubycsIG1vbm9zcGFjZTtcbiAgICBmb250LXNpemU6IDAuOWVtO1xufVxuXG5Aa2V5ZnJhbWVzIGZhZGVPdXQge1xuICAgIDAlIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICB9XG4gICAgMTAlIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG4gICAgNzAlIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG4gICAgMTAwJSB7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgfVxufVxuIl19 */";
21626
21827
  var styles$d = {"BookEditor":"BookEditor-module_BookEditor__s-0PU","bookEditorContainer":"BookEditor-module_bookEditorContainer__wLMwM","isVerbose":"BookEditor-module_isVerbose__VQ6iL","bookEditorWrapper":"BookEditor-module_bookEditorWrapper__twppD","isBorderRadiusDisabled":"BookEditor-module_isBorderRadiusDisabled__h1I3v","dropOverlay":"BookEditor-module_dropOverlay__xWWoX","bookEditorActionbar":"BookEditor-module_bookEditorActionbar__KW6dc","fullscreen":"BookEditor-module_fullscreen__rktsl","button":"BookEditor-module_button__hS390","savedNotification":"BookEditor-module_savedNotification__OiX9L","fadeOut":"BookEditor-module_fadeOut__q8JnR","uploadPanel":"BookEditor-module_uploadPanel__2JJtD","uploadPanelHeader":"BookEditor-module_uploadPanelHeader__pdJd2","uploadPanelTitle":"BookEditor-module_uploadPanelTitle__TJIVF","uploadPanelHeaderMeta":"BookEditor-module_uploadPanelHeaderMeta__Xw0uI","uploadPanelSummary":"BookEditor-module_uploadPanelSummary__rwSbG","uploadRowStatus":"BookEditor-module_uploadRowStatus__jsUb-","uploadRowMeta":"BookEditor-module_uploadRowMeta__1lz9h","uploadPanelProgressBar":"BookEditor-module_uploadPanelProgressBar__a6pjf","uploadPanelProgressFill":"BookEditor-module_uploadPanelProgressFill__l-TKR","uploadRowProgressBar":"BookEditor-module_uploadRowProgressBar__NoBA7","uploadPanelList":"BookEditor-module_uploadPanelList__VxEd5","uploadRow":"BookEditor-module_uploadRow__QiSFg","uploadRowHeader":"BookEditor-module_uploadRowHeader__po0j5","uploadRowName":"BookEditor-module_uploadRowName__doQRO","uploadRowProgressFill":"BookEditor-module_uploadRowProgressFill__TrP7e","uploadRowActions":"BookEditor-module_uploadRowActions__5Y1Mq","uploadActionButton":"BookEditor-module_uploadActionButton__CqJrr","uploadRowError":"BookEditor-module_uploadRowError__eEHWw","aboutPromptbookInformation":"BookEditor-module_aboutPromptbookInformation__eiBL0"};
21627
21828
  styleInject(css_248z$d);
@@ -21653,135 +21854,6 @@ function SaveIcon({ size = 20, color = 'currentColor', ...props }) {
21653
21854
  return (jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", ...props, children: [jsx("path", { d: "M4 17V7a3 3 0 0 1 3-3h10a3 3 0 0 1 3 3v7a3 3 0 0 1-3 3H7l-3 3z", fill: color, fillOpacity: "0.08", stroke: color }), jsx("path", { d: "M12 9v5", stroke: color }), jsx("path", { d: "M9.5 12.5L12 15l2.5-2.5", stroke: color })] }));
21654
21855
  }
21655
21856
 
21656
- /**
21657
- * Detects if the code is running in a browser environment in main thread (Not in a web worker)
21658
- *
21659
- * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
21660
- *
21661
- * @public exported from `@promptbook/utils`
21662
- */
21663
- function $isRunningInBrowser() {
21664
- try {
21665
- return typeof window !== 'undefined' && typeof window.document !== 'undefined';
21666
- }
21667
- catch (e) {
21668
- return false;
21669
- }
21670
- }
21671
- // TODO: [🎺]
21672
-
21673
- /**
21674
- * Converts Blob, File or MediaSource to url using URL.createObjectURL
21675
- *
21676
- * @public exported from `@promptbook/browser`
21677
- */
21678
- class ObjectUrl extends Registration {
21679
- constructor(teardownLogic, src) {
21680
- super(teardownLogic);
21681
- this.src = src;
21682
- }
21683
- /**
21684
- * Creates ObjectUrl from multiple input types
21685
- * Note: DO NOT forget to call destroy() when you are done with it
21686
- */
21687
- static from(source, mimeType) {
21688
- if (typeof source === 'string') {
21689
- return ObjectUrl.fromString(source, mimeType);
21690
- }
21691
- if ((source instanceof Blob || source instanceof File) && source.type !== mimeType) {
21692
- throw new Error(`Source type ${source.type} does not match given mimeType ${mimeType}`);
21693
- }
21694
- return ObjectUrl.fromBlob(source);
21695
- }
21696
- /**
21697
- * Creates ObjectUrl from string
21698
- * Note: DO NOT forget to call destroy() when you are done with it
21699
- */
21700
- static fromString(source, mimeType) {
21701
- return ObjectUrl.fromBlob(new Blob([source], { type: mimeType }));
21702
- }
21703
- /**
21704
- * Creates ObjectUrl
21705
- * DO NOT forget to call destroy() when you are done with it
21706
- */
21707
- static fromBlob(source) {
21708
- const src = URL.createObjectURL(source);
21709
- return new ObjectUrl(() => {
21710
- URL.revokeObjectURL(src);
21711
- }, src);
21712
- }
21713
- /**
21714
- * Creates ObjectUrl:
21715
- * 1) With functionality for Blobs, Files or MediaSources
21716
- * 2) Just a wrapper for string urls
21717
- *
21718
- * DO NOT forget to call destroy() when you are done with it
21719
- */
21720
- static fromBlobOrUrl(source) {
21721
- if (typeof source === 'string' || source instanceof URL /* <- TODO: Probably check isValidUrl */) {
21722
- return new ObjectUrl(() => {
21723
- // Note: Nothing to do here
21724
- }, source.toString());
21725
- }
21726
- else {
21727
- return ObjectUrl.fromBlob(source);
21728
- }
21729
- }
21730
- /**
21731
- * Gets object url as string
21732
- * @alias src
21733
- */
21734
- get href() {
21735
- return this.src;
21736
- }
21737
- /**
21738
- * Gets object url as URL object
21739
- */
21740
- get url() {
21741
- return new URL(this.src);
21742
- }
21743
- }
21744
- // Note: [🔵] Code for browser file helper [ObjectUrl](src/utils/files/ObjectUrl.ts) should never be published outside of `@promptbook/browser`
21745
-
21746
- /**
21747
- * Download a File in a browser
21748
- *
21749
- * Note: `$` is used to indicate that this function is not a pure function - its purpose is to cause a side effect (download a file)
21750
- *
21751
- * @public exported from `@promptbook/browser`
21752
- */
21753
- async function $induceFileDownload(fileOrBlobOrUrl) {
21754
- if (!$isRunningInBrowser()) {
21755
- throw new Error('Function `$induceFileDownload` is available ONLY in browser');
21756
- }
21757
- const objectUrl = ObjectUrl.fromBlobOrUrl(fileOrBlobOrUrl);
21758
- const link = window.document.createElement('a');
21759
- link.href = objectUrl.href;
21760
- link.download = fileOrBlobOrUrl.name || 'untitled' /* <- TODO: Add proper extension according to url */;
21761
- link.click();
21762
- await objectUrl.destroy();
21763
- }
21764
- // Note: [🔵] Code for browser file helper [$induceFileDownload](src/utils/files/$induceFileDownload.ts) should never be published outside of `@promptbook/browser`
21765
-
21766
- /**
21767
- * Download a Book in a browser
21768
- *
21769
- * Note: `$` is used to indicate that this function is not a pure function - its purpose is to cause a side effect (download a file)
21770
- *
21771
- * @public exported from `@promptbook/browser`
21772
- */
21773
- async function $induceBookDownload(book) {
21774
- if (!$isRunningInBrowser()) {
21775
- throw new Error('Function `$induceBookDownload` is available ONLY in browser');
21776
- }
21777
- const { agentName } = parseAgentSource(book);
21778
- const bookFile = new File([book], `${titleToName(agentName || 'AI Avatar')}.book`, {
21779
- type: 'application/json',
21780
- });
21781
- return /* not await */ $induceFileDownload(bookFile);
21782
- }
21783
- // Note: [🔵] Code for browser file helper [$induceBookDownload](src/utils/files/$induceBookDownload.ts) should never be published outside of `@promptbook/browser`
21784
-
21785
21857
  /**
21786
21858
  * Renders an information/about icon.
21787
21859
  *
@@ -21998,54 +22070,21 @@ function Modal({ children, onClose, className, }) {
21998
22070
  }
21999
22071
 
22000
22072
  /**
22001
- * Core Promptbook server configuration
22002
- *
22003
- * Used for "Adam" agent which is built in as default ancestor for new agents and other well known agents
22004
- *
22005
- * @public exported from `@promptbook/core`
22006
- */
22007
- const CORE_AGENTS_SERVER = {
22008
- title: 'Promptbook Core',
22009
- description: `Core Promptbook server used for Adam agent which is built in as default ancestor for new agents and other well known agents.`,
22010
- owner: PROMPTBOOK_LEGAL_ENTITY,
22011
- url: 'https://core.ptbk.io/',
22012
- };
22013
- // <- TODO: [🆎] Allow to override (set) well-known agent names via Metadata
22014
- /**
22015
- * Available agents servers for the Promptbook
22073
+ * Detects if the code is running in a browser environment in main thread (Not in a web worker)
22016
22074
  *
22017
- * Tip: 💡 If you are running your own server, you can add it to this list by creating a pull request!
22075
+ * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
22018
22076
  *
22019
- * @public exported from `@promptbook/core`
22077
+ * @public exported from `@promptbook/utils`
22020
22078
  */
22021
- const PUBLIC_AGENTS_SERVERS = [
22022
- CORE_AGENTS_SERVER,
22023
- {
22024
- title: 'Promptbook Gallery',
22025
- description: `Gallery of ideas, AI professions,... like AI Agenta photobank.`,
22026
- owner: PROMPTBOOK_LEGAL_ENTITY,
22027
- url: 'https://gallery.ptbk.io/',
22028
- },
22029
- {
22030
- title: 'Promptbook Testing server 6',
22031
- description: `General-purpose testing server.`,
22032
- owner: PROMPTBOOK_LEGAL_ENTITY,
22033
- url: 'https://s6.ptbk.io/',
22034
- },
22035
- {
22036
- title: 'Promptbook Testing server 7',
22037
- description: `General-purpose testing server.`,
22038
- owner: PROMPTBOOK_LEGAL_ENTITY,
22039
- url: 'https://s7.ptbk.io/',
22040
- },
22041
- {
22042
- title: 'Promptbook Testing server 8',
22043
- description: `General-purpose testing server.`,
22044
- owner: PROMPTBOOK_LEGAL_ENTITY,
22045
- url: 'https://s8.ptbk.io/',
22046
- },
22047
- ];
22048
- // Note: [💞] Ignore a discrepancy between file name and entity name
22079
+ function $isRunningInBrowser() {
22080
+ try {
22081
+ return typeof window !== 'undefined' && typeof window.document !== 'undefined';
22082
+ }
22083
+ catch (e) {
22084
+ return false;
22085
+ }
22086
+ }
22087
+ // TODO: [🎺]
22049
22088
 
22050
22089
  /**
22051
22090
  * Detects if the code is running in jest environment
@@ -22135,9 +22174,32 @@ function BookEditorAboutPromptbookInformation(props = {}) {
22135
22174
  ...$detectRuntimeEnvironment(),
22136
22175
  isCostPrevented: IS_COST_PREVENTED,
22137
22176
  };
22138
- return (jsxs("div", { className: styles$d.aboutPromptbookInformation, children: [jsx("h1", { children: NAME }), jsx("p", { children: CLAIM }), jsxs("ul", { children: [jsx("li", { children: jsxs("a", { href: "https://github.com/webgptorg/promptbook", target: "_blank", rel: "noopener noreferrer", children: ["Promptbook engine version ", jsx("code", { children: PROMPTBOOK_ENGINE_VERSION })] }) }), jsx("li", { children: jsxs("a", { href: "https://github.com/webgptorg/book", target: "_blank", rel: "noopener noreferrer", children: ["Book language version ", jsx("code", { children: BOOK_LANGUAGE_VERSION })] }) })] }), isServersInfoIncluded && (jsxs(Fragment, { children: [jsx("h2", { children: "Servers" }), jsx("ol", { children: PUBLIC_AGENTS_SERVERS.map(({ title, description, url }) => (jsxs("li", { children: [jsx("strong", { children: title }), " ", description, ' ', jsx("a", { href: url, target: "_blank", rel: "noopener noreferrer", children: url })] }, url))) })] })), isRuntimeEnvironmentInfoIncluded && (jsxs(Fragment, { children: [jsx("h2", { children: "Environment" }), jsx("ul", { children: Object.entries(runtimeEnvironmentInfo).map(([key, value]) => (jsxs("li", { children: [jsxs("strong", { children: [key, ":"] }), " ", valueToString(value)] }, key))) })] }))] }));
22177
+ return (jsxs("div", { className: styles$d.aboutPromptbookInformation, children: [jsx("h1", { children: NAME }), jsx("p", { children: CLAIM }), jsxs("ul", { children: [jsx("li", { children: jsxs("a", { href: "https://github.com/webgptorg/promptbook", target: "_blank", rel: "noopener noreferrer", children: ["Promptbook engine version ", jsx("code", { children: PROMPTBOOK_ENGINE_VERSION })] }) }), jsx("li", { children: jsxs("a", { href: "https://github.com/webgptorg/book", target: "_blank", rel: "noopener noreferrer", children: ["Book language version ", jsx("code", { children: BOOK_LANGUAGE_VERSION })] }) })] }), isServersInfoIncluded && (jsxs(Fragment, { children: [jsx("h2", { children: "Servers" }), jsx("ol", { children: PUBLIC_AGENTS_SERVERS.map(({ title, description, url }) => (jsxs("li", { children: [jsx("strong", { children: title }), " ", description, ' ', jsx("a", { href: url, target: "_blank", rel: "noopener noreferrer", children: url })] }, url))) })] })), isRuntimeEnvironmentInfoIncluded && (jsxs(Fragment, { children: [jsx("h2", { children: "Environment" }), jsx("ul", { children: Object.entries(runtimeEnvironmentInfo).map(([key, value]) => (jsxs("li", { children: [jsxs("strong", { children: [key, ":"] }), " ", String(value)] }, key))) })] }))] }));
22139
22178
  }
22140
22179
 
22180
+ function induceBookDownloadInBrowser(book) {
22181
+ const filename = `${normalizeBookDownloadName(extractBookTitle(book) || 'AI Avatar')}.book`;
22182
+ const objectUrl = URL.createObjectURL(new Blob([book], { type: 'application/json' }));
22183
+ const link = window.document.createElement('a');
22184
+ link.href = objectUrl;
22185
+ link.download = filename;
22186
+ link.click();
22187
+ URL.revokeObjectURL(objectUrl);
22188
+ }
22189
+ function extractBookTitle(book) {
22190
+ return (book
22191
+ .split(/\r?\n/)
22192
+ .map((line) => line.trim())
22193
+ .find(Boolean) || null);
22194
+ }
22195
+ function normalizeBookDownloadName(value) {
22196
+ return (value
22197
+ .normalize('NFD')
22198
+ .replace(/[\u0300-\u036f]/g, '')
22199
+ .replace(/[^\dA-Za-z]+/g, '-')
22200
+ .replace(/^-+|-+$/g, '')
22201
+ .toLowerCase() || 'ai-avatar');
22202
+ }
22141
22203
  /**
22142
22204
  * Handles book editor actionbar.
22143
22205
  *
@@ -22154,7 +22216,7 @@ function BookEditorActionbar(props) {
22154
22216
  }, [value]);
22155
22217
  const handleDownload = useCallback(() => {
22156
22218
  const book = validateBook(valueRef.current || DEFAULT_BOOK);
22157
- /* not await */ $induceBookDownload(book);
22219
+ induceBookDownloadInBrowser(book);
22158
22220
  }, []);
22159
22221
  const actions = useMemo(() => {
22160
22222
  const _actions = [...(hoistedMenuItems || [])];
@@ -22269,144 +22331,15 @@ function resolveBookEditorRenderTheme(hostTheme = BOOK_EDITOR_RENDER_THEME) {
22269
22331
  }
22270
22332
 
22271
22333
  /**
22272
- * Gets a commitment definition by its type
22334
+ * Browser-compatible stub for `createDeprecatedCommitmentDiagnostics`.
22273
22335
  *
22274
- * @param type The commitment type to look up
22275
- * @returns The commitment definition or null if not found
22276
- *
22277
- * @public exported from `@promptbook/core`
22278
- */
22279
- function getCommitmentDefinition(type) {
22280
- return COMMITMENT_REGISTRY.find((commitmentDefinition) => commitmentDefinition.type === type) || null;
22281
- }
22282
-
22283
- /**
22284
- * Warning message used for unfinished commitments.
22285
- */
22286
- const UNFINISHED_COMMITMENT_MESSAGE = 'This commitment is unfinished and not ready to use. Be careful when using it.';
22287
- /**
22288
- * Low-level warning message used for low-level commitments.
22289
- */
22290
- const LOW_LEVEL_COMMITMENT_MESSAGE = 'This commitment is low-level and not used by most of the users. Be careful when using it.';
22291
- /**
22292
- * Short badge text used for deprecated commitments.
22293
- */
22294
- const DEPRECATED_COMMITMENT_BADGE_LABEL = 'Deprecated';
22295
- /**
22296
- * Short badge text used for unfinished and low-level commitments.
22297
- */
22298
- const LOW_LEVEL_COMMITMENT_BADGE_LABEL = 'Low-level';
22299
- /**
22300
- * Longer label used for deprecated commitments.
22301
- */
22302
- const DEPRECATED_COMMITMENT_DETAIL_LABEL = 'Deprecated commitment';
22303
- /**
22304
- * Longer label used for unfinished and low-level commitments.
22305
- */
22306
- const LOW_LEVEL_COMMITMENT_DETAIL_LABEL = 'Low-level commitment';
22307
- /**
22308
- * Prefix used when formatting replacement guidance.
22309
- */
22310
- const PREFERRED_REPLACEMENT_LABEL = 'Preferred replacement';
22311
- /**
22312
- * Formats preferred replacement guidance for deprecated commitments.
22313
- *
22314
- * @param replacedBy - Preferred replacement commitment keywords.
22315
- * @returns Optional replacement guidance sentence with leading space.
22316
- *
22317
- * @private internal utility of commitment catalog notices
22318
- */
22319
- function formatCommitmentReplacementText(replacedBy) {
22320
- if (!replacedBy || replacedBy.length === 0) {
22321
- return '';
22322
- }
22323
- return ` ${PREFERRED_REPLACEMENT_LABEL}: ${replacedBy.map((type) => `\`${type}\``).join(', ')}.`;
22324
- }
22325
- /**
22326
- * Resolves the notice metadata for deprecated, unfinished, or low-level commitments.
22327
- *
22328
- * @param definition - Commitment definition to inspect.
22329
- * @returns Notice metadata when the commitment should be surfaced with caution.
22330
- *
22331
- * @private internal utility of commitment catalog notices
22332
- */
22333
- function getCommitmentNoticeMetadata(definition) {
22334
- if (definition.isUnfinished) {
22335
- return {
22336
- kind: 'unfinished',
22337
- badgeLabel: LOW_LEVEL_COMMITMENT_BADGE_LABEL,
22338
- detailLabel: LOW_LEVEL_COMMITMENT_DETAIL_LABEL,
22339
- message: UNFINISHED_COMMITMENT_MESSAGE,
22340
- };
22341
- }
22342
- if (definition.isLowLevel) {
22343
- return {
22344
- kind: 'lowLevel',
22345
- badgeLabel: LOW_LEVEL_COMMITMENT_BADGE_LABEL,
22346
- detailLabel: LOW_LEVEL_COMMITMENT_DETAIL_LABEL,
22347
- message: LOW_LEVEL_COMMITMENT_MESSAGE,
22348
- };
22349
- }
22350
- if (definition.deprecation) {
22351
- return {
22352
- kind: 'deprecated',
22353
- badgeLabel: DEPRECATED_COMMITMENT_BADGE_LABEL,
22354
- detailLabel: DEPRECATED_COMMITMENT_DETAIL_LABEL,
22355
- message: definition.deprecation.message,
22356
- };
22357
- }
22358
- return null;
22359
- }
22360
-
22361
- /**
22362
- * Creates Book editor diagnostics for deprecated, unfinished, and low-level commitment keywords.
22363
- *
22364
- * The notice metadata is UI-only. This helper surfaces it in Monaco so legacy,
22365
- * unfinished, and low-level commitments remain functional while still guiding
22366
- * authors toward preferred replacements or cautioning them about low-level
22367
- * usage.
22368
- *
22369
- * @param agentSource - Current editor content.
22370
- * @returns Warning markers for deprecated, unfinished, and low-level commitment keywords.
22336
+ * In the browser build the full Node.js implementation is not available,
22337
+ * so this stub always returns an empty array to keep the editor functional.
22371
22338
  *
22372
22339
  * @private internal utility of `BookEditorMonaco`
22373
22340
  */
22374
- function createDeprecatedCommitmentDiagnostics(agentSource) {
22375
- var _a;
22376
- if (!(agentSource === null || agentSource === void 0 ? void 0 : agentSource.trim())) {
22377
- return [];
22378
- }
22379
- const parsed = parseAgentSourceWithCommitments(agentSource);
22380
- const diagnostics = [];
22381
- for (const commitment of parsed.commitments) {
22382
- const definition = getCommitmentDefinition(commitment.type);
22383
- const notice = definition ? getCommitmentNoticeMetadata(definition) : null;
22384
- if (!definition || !notice) {
22385
- continue;
22386
- }
22387
- const typeMatch = definition.createTypeRegex().exec(commitment.originalLine);
22388
- if (!((_a = typeMatch === null || typeMatch === void 0 ? void 0 : typeMatch.groups) === null || _a === void 0 ? void 0 : _a.type)) {
22389
- continue;
22390
- }
22391
- const matchedType = typeMatch.groups.type;
22392
- const leadingCharactersCount = typeMatch[0].length - matchedType.length;
22393
- const startColumn = leadingCharactersCount + 1;
22394
- const endColumn = startColumn + matchedType.length;
22395
- // Keep the diagnostic sentence compact while reusing the shared notice copy.
22396
- const message = notice.kind === 'deprecated'
22397
- ? `\`${commitment.type}\` is deprecated. ${notice.message}`
22398
- : `\`${commitment.type}\` is ${notice.message.replace(/^This commitment is\s+/u, '')}`;
22399
- diagnostics.push({
22400
- startLineNumber: commitment.lineNumber,
22401
- startColumn,
22402
- endLineNumber: commitment.lineNumber,
22403
- endColumn,
22404
- message,
22405
- source: 'Promptbook',
22406
- severity: 'warning',
22407
- });
22408
- }
22409
- return diagnostics;
22341
+ function createDeprecatedCommitmentDiagnostics(_agentSource) {
22342
+ return [];
22410
22343
  }
22411
22344
 
22412
22345
  /**
@@ -22765,103 +22698,6 @@ function useBookEditorMonacoInteractions({ editor, handleFiles, }) {
22765
22698
  };
22766
22699
  }
22767
22700
 
22768
- /**
22769
- * Priority order for the important commitments shown first in catalogues and intellisense.
22770
- *
22771
- * Canonical singular names stay ahead of their plural aliases so the most important
22772
- * commitments remain easy to scan.
22773
- *
22774
- * @private internal constant of commitment catalog sorting
22775
- */
22776
- const IMPORTANT_COMMITMENT_TYPE_SORT_ORDER = new Map([
22777
- ['GOAL', 0],
22778
- ['RULE', 1],
22779
- ['KNOWLEDGE', 2],
22780
- ['TEAM', 3],
22781
- ['GOALS', 4],
22782
- ['RULES', 5],
22783
- ]);
22784
- /**
22785
- * Sort rank used when unfinished, low-level, and deprecated commitments should be grouped last.
22786
- *
22787
- * @private internal constant of commitment catalog sorting
22788
- */
22789
- const COMMITMENT_STATUS_SORT_ORDER = {
22790
- normal: 0,
22791
- deprecated: 1,
22792
- unfinished: 2,
22793
- lowLevel: 3,
22794
- };
22795
- /**
22796
- * Resolves the relative sort rank of one commitment status.
22797
- *
22798
- * @param definition - Commitment definition to rank.
22799
- * @param options - Sorting options.
22800
- * @returns Relative sort rank for the definition.
22801
- *
22802
- * @private internal helper of commitment catalog sorting
22803
- */
22804
- function resolveCommitmentStatusSortRank(definition, options) {
22805
- let statusSortRank = COMMITMENT_STATUS_SORT_ORDER.normal;
22806
- if (options.isDeprecatedLast && definition.deprecation) {
22807
- statusSortRank = Math.max(statusSortRank, COMMITMENT_STATUS_SORT_ORDER.deprecated);
22808
- }
22809
- if (options.isUnfinishedLast && definition.isUnfinished) {
22810
- statusSortRank = Math.max(statusSortRank, COMMITMENT_STATUS_SORT_ORDER.unfinished);
22811
- }
22812
- if (options.isLowLevelLast && definition.isLowLevel) {
22813
- statusSortRank = Math.max(statusSortRank, COMMITMENT_STATUS_SORT_ORDER.lowLevel);
22814
- }
22815
- return statusSortRank;
22816
- }
22817
- /**
22818
- * Sorts commitment definitions so the important ones stay at the top.
22819
- *
22820
- * @param commitmentDefinitions - Definitions to sort.
22821
- * @param options - Sorting options.
22822
- * @returns Sorted commitment definitions.
22823
- *
22824
- * @private internal helper of commitment catalog sorting
22825
- */
22826
- function sortCommitmentDefinitions(commitmentDefinitions, options = {}) {
22827
- return [...commitmentDefinitions]
22828
- .map((definition, index) => ({
22829
- definition,
22830
- index,
22831
- }))
22832
- .sort((left, right) => {
22833
- var _a, _b;
22834
- if (left.definition.isImportant !== right.definition.isImportant) {
22835
- return left.definition.isImportant ? -1 : 1;
22836
- }
22837
- if (left.definition.isImportant && right.definition.isImportant) {
22838
- const leftPriority = (_a = IMPORTANT_COMMITMENT_TYPE_SORT_ORDER.get(left.definition.type)) !== null && _a !== void 0 ? _a : Number.MAX_SAFE_INTEGER;
22839
- const rightPriority = (_b = IMPORTANT_COMMITMENT_TYPE_SORT_ORDER.get(right.definition.type)) !== null && _b !== void 0 ? _b : Number.MAX_SAFE_INTEGER;
22840
- if (leftPriority !== rightPriority) {
22841
- return leftPriority - rightPriority;
22842
- }
22843
- }
22844
- const leftStatusSortRank = resolveCommitmentStatusSortRank(left.definition, options);
22845
- const rightStatusSortRank = resolveCommitmentStatusSortRank(right.definition, options);
22846
- if (leftStatusSortRank !== rightStatusSortRank) {
22847
- return leftStatusSortRank - rightStatusSortRank;
22848
- }
22849
- return left.index - right.index;
22850
- })
22851
- .map(({ definition }) => definition);
22852
- }
22853
-
22854
- /**
22855
- * Gets all available commitment definitions
22856
- *
22857
- * @returns Array of all commitment definitions
22858
- *
22859
- * @public exported from `@promptbook/core`
22860
- */
22861
- function getAllCommitmentDefinitions() {
22862
- return $deepFreeze(sortCommitmentDefinitions(COMMITMENT_REGISTRY, { isUnfinishedLast: true, isLowLevelLast: true }));
22863
- }
22864
-
22865
22701
  /**
22866
22702
  * Regex source for absolute URL references inside TEAM/FROM/IMPORT commitments.
22867
22703
  *
@@ -22885,12 +22721,38 @@ const AGENT_REFERENCE_BRACED_PATTERN = '\\{[^{}\\r\\n]+\\}';
22885
22721
  *
22886
22722
  * @private function of BookEditorMonaco
22887
22723
  */
22888
- const AGENT_REFERENCE_COMMITMENT_TYPES = new Set([
22724
+ const AGENT_REFERENCE_COMMITMENT_TYPES = ['FROM', 'IMPORT', 'IMPORTS', 'TEAM'];
22725
+ /**
22726
+ * Commitment types known to the browser editor tokenizer.
22727
+ *
22728
+ * @private function of BookEditorMonaco
22729
+ */
22730
+ const BOOK_EDITOR_COMMITMENT_TYPES = [
22731
+ 'PERSONA',
22732
+ 'KNOWLEDGE',
22733
+ 'TASK',
22734
+ 'PROMPT',
22735
+ 'EXPECT',
22736
+ 'FORMAT',
22737
+ 'MODEL',
22738
+ 'SAMPLE',
22889
22739
  'FROM',
22890
22740
  'IMPORT',
22891
22741
  'IMPORTS',
22892
22742
  'TEAM',
22893
- ]);
22743
+ 'TODO',
22744
+ 'NOTE',
22745
+ 'NOTES',
22746
+ 'NONCE',
22747
+ ];
22748
+ /**
22749
+ * Regex pattern to match horizontal lines.
22750
+ *
22751
+ * @private function of BookEditorMonaco
22752
+ */
22753
+ const HORIZONTAL_LINE_PATTERN$1 = /^[\s]*[-_*][\s]*[-_*][\s]*[-_*][\s]*[-_*]*[\s]*$/;
22754
+ const BOOK_EDITOR_COMMITMENT_LINE_REGEX = createCommitmentLineRegex(BOOK_EDITOR_COMMITMENT_TYPES);
22755
+ const AGENT_REFERENCE_COMMITMENT_LINE_REGEX = createCommitmentLineRegex(AGENT_REFERENCE_COMMITMENT_TYPES);
22894
22756
  /**
22895
22757
  * Agent reference helpers for `BookEditorMonaco`.
22896
22758
  *
@@ -23045,26 +22907,60 @@ function collectLineStartOffsets(content, sourceLines) {
23045
22907
  * @private function of BookEditorMonaco
23046
22908
  */
23047
22909
  function collectAgentReferenceCommitmentLineRanges(content, sourceLines) {
23048
- var _a, _b;
23049
- const parsed = parseAgentSourceWithCommitments(content);
23050
22910
  const ranges = [];
23051
- for (let index = 0; index < parsed.commitments.length; index++) {
23052
- const commitment = parsed.commitments[index];
23053
- if (!commitment || !AGENT_REFERENCE_COMMITMENT_TYPES.has(commitment.type)) {
22911
+ let activeRangeStartLineNumber = null;
22912
+ let isInsideCodeBlock = false;
22913
+ const startLineIndex = findBookBodyStartLineIndex(sourceLines);
22914
+ for (let lineIndex = startLineIndex; lineIndex < sourceLines.length; lineIndex++) {
22915
+ const line = sourceLines[lineIndex] || '';
22916
+ const trimmedLine = line.trim();
22917
+ if (trimmedLine.startsWith('```')) {
22918
+ isInsideCodeBlock = !isInsideCodeBlock;
22919
+ continue;
22920
+ }
22921
+ if (isInsideCodeBlock) {
22922
+ continue;
22923
+ }
22924
+ if (HORIZONTAL_LINE_PATTERN$1.test(line)) {
22925
+ if (activeRangeStartLineNumber !== null) {
22926
+ ranges.push({
22927
+ startLineNumber: activeRangeStartLineNumber,
22928
+ endLineNumber: lineIndex,
22929
+ });
22930
+ activeRangeStartLineNumber = null;
22931
+ }
23054
22932
  continue;
23055
22933
  }
23056
- const nextCommitmentStartLine = (_b = (_a = parsed.commitments[index + 1]) === null || _a === void 0 ? void 0 : _a.lineNumber) !== null && _b !== void 0 ? _b : sourceLines.length + 1;
23057
- const endLineNumber = Math.min(nextCommitmentStartLine - 1, sourceLines.length);
23058
- if (commitment.lineNumber > endLineNumber) {
22934
+ if (!BOOK_EDITOR_COMMITMENT_LINE_REGEX.test(trimmedLine)) {
23059
22935
  continue;
23060
22936
  }
22937
+ if (activeRangeStartLineNumber !== null) {
22938
+ ranges.push({
22939
+ startLineNumber: activeRangeStartLineNumber,
22940
+ endLineNumber: lineIndex,
22941
+ });
22942
+ }
22943
+ activeRangeStartLineNumber = AGENT_REFERENCE_COMMITMENT_LINE_REGEX.test(trimmedLine) ? lineIndex + 1 : null;
22944
+ }
22945
+ if (activeRangeStartLineNumber !== null) {
23061
22946
  ranges.push({
23062
- startLineNumber: commitment.lineNumber,
23063
- endLineNumber,
22947
+ startLineNumber: activeRangeStartLineNumber,
22948
+ endLineNumber: sourceLines.length,
23064
22949
  });
23065
22950
  }
23066
22951
  return ranges;
23067
22952
  }
22953
+ function createCommitmentLineRegex(commitmentTypes) {
22954
+ const commitmentPattern = [...commitmentTypes]
22955
+ .sort((a, b) => b.length - a.length)
22956
+ .map((type) => type.replace(/\s+/, '\\s+'))
22957
+ .join('|');
22958
+ return new RegExp(`^\\s*(${commitmentPattern})(?=\\s|$)`, 'i');
22959
+ }
22960
+ function findBookBodyStartLineIndex(sourceLines) {
22961
+ const titleLineIndex = sourceLines.findIndex((line) => line.trim().length > 0);
22962
+ return titleLineIndex === -1 ? 0 : titleLineIndex + 1;
22963
+ }
23068
22964
  /**
23069
22965
  * Agent reference helpers for `BookEditorMonaco`.
23070
22966
  *
@@ -23292,19 +23188,26 @@ function ensureBookEditorMonacoLanguage(monaco, theme = BOOK_EDITOR_RENDER_THEME
23292
23188
  monacoWithLanguageState[BOOK_EDITOR_LANGUAGE_INITIALIZED_FLAG] = true;
23293
23189
  monacoWithLanguageState[BOOK_EDITOR_THEME_MODE_FLAG] = renderedTheme;
23294
23190
  monaco.languages.register({ id: BookEditorMonacoConstants.BOOK_LANGUAGE_ID });
23295
- const commitmentDefinitions = getAllCommitmentDefinitions();
23296
- const commitmentTypes = [...new Set(commitmentDefinitions.map(({ type }) => type))];
23297
- const commitmentDefinitionByType = new Map(commitmentDefinitions.map((definition) => [definition.type, definition]));
23298
- const completionCommitmentTypes = [...commitmentTypes].sort((leftType, rightType) => {
23299
- const leftDefinition = commitmentDefinitionByType.get(leftType);
23300
- const rightDefinition = commitmentDefinitionByType.get(rightType);
23301
- const leftRank = (leftDefinition === null || leftDefinition === void 0 ? void 0 : leftDefinition.isUnfinished) ? 1 : 0;
23302
- const rightRank = (rightDefinition === null || rightDefinition === void 0 ? void 0 : rightDefinition.isUnfinished) ? 1 : 0;
23303
- if (leftRank !== rightRank) {
23304
- return leftRank - rightRank;
23305
- }
23306
- return commitmentTypes.indexOf(leftType) - commitmentTypes.indexOf(rightType);
23307
- });
23191
+ const commitmentTypes = [
23192
+ 'GOAL',
23193
+ 'RULE',
23194
+ 'PERSONA',
23195
+ 'KNOWLEDGE',
23196
+ 'TASK',
23197
+ 'PROMPT',
23198
+ 'EXPECT',
23199
+ 'FORMAT',
23200
+ 'MODEL',
23201
+ 'SAMPLE',
23202
+ 'FROM',
23203
+ 'IMPORT',
23204
+ 'IMPORTS',
23205
+ 'TEAM',
23206
+ ...TODO_COMMITMENT_TYPES,
23207
+ ...NOTE_COMMITMENT_TYPES,
23208
+ 'REMOVE',
23209
+ ];
23210
+ const completionCommitmentTypes = [...commitmentTypes];
23308
23211
  const noteLikeCommitmentTypeSet = new Set([...TODO_COMMITMENT_TYPES, ...NOTE_COMMITMENT_TYPES]);
23309
23212
  const noteLikeCommitmentStates = createNoteLikeCommitmentStates(commitmentTypes);
23310
23213
  const executableCommitmentTypes = commitmentTypes.filter((type) => !noteLikeCommitmentTypeSet.has(type.toUpperCase()));
@@ -23361,27 +23264,17 @@ function ensureBookEditorMonacoLanguage(monaco, theme = BOOK_EDITOR_RENDER_THEME
23361
23264
  startColumn: word.startColumn,
23362
23265
  endColumn: word.endColumn,
23363
23266
  };
23364
- const suggestions = completionCommitmentTypes.map((type, index) => {
23365
- var _a;
23366
- const definition = commitmentDefinitionByType.get(type);
23367
- const notice = definition ? getCommitmentNoticeMetadata(definition) : null;
23368
- const completionDocumentation = notice
23369
- ? `${notice.detailLabel}. ${notice.message}${notice.kind === 'deprecated'
23370
- ? formatCommitmentReplacementText((_a = definition === null || definition === void 0 ? void 0 : definition.deprecation) === null || _a === void 0 ? void 0 : _a.replacedBy)
23371
- : ''}`
23372
- : (definition === null || definition === void 0 ? void 0 : definition.description) || 'Commitment';
23373
- return {
23374
- label: type,
23375
- kind: monaco.languages.CompletionItemKind.Keyword,
23376
- insertText: type,
23377
- range,
23378
- sortText: index.toString().padStart(4, '0'),
23379
- detail: (notice === null || notice === void 0 ? void 0 : notice.detailLabel) || 'Commitment',
23380
- documentation: {
23381
- value: completionDocumentation,
23382
- },
23383
- };
23384
- });
23267
+ const suggestions = completionCommitmentTypes.map((type, index) => ({
23268
+ label: type,
23269
+ kind: monaco.languages.CompletionItemKind.Keyword,
23270
+ insertText: type,
23271
+ range,
23272
+ sortText: index.toString().padStart(4, '0'),
23273
+ detail: 'Commitment',
23274
+ documentation: {
23275
+ value: 'Book commitment',
23276
+ },
23277
+ }));
23385
23278
  return { suggestions };
23386
23279
  },
23387
23280
  });
@@ -24667,7 +24560,7 @@ function BookEditorMonaco(props) {
24667
24560
  editor,
24668
24561
  handleFiles,
24669
24562
  });
24670
- const combinedDiagnostics = [...(diagnostics || []), ...createDeprecatedCommitmentDiagnostics(value)];
24563
+ const combinedDiagnostics = [...(diagnostics || []), ...createDeprecatedCommitmentDiagnostics()];
24671
24564
  const isActionBarVisible = isBookEditorMonacoActionbarVisible({
24672
24565
  hoistedMenuItems,
24673
24566
  isUploadButtonShown,
@@ -24761,6 +24654,36 @@ function BookEditor(props) {
24761
24654
  return isFullscreen && typeof document !== 'undefined' ? createPortal(editorContent, document.body) : editorContent;
24762
24655
  }
24763
24656
 
24657
+ var BookEditor$1 = /*#__PURE__*/Object.freeze({
24658
+ __proto__: null,
24659
+ DEFAULT_BOOK_EDITOR_HEIGHT: DEFAULT_BOOK_EDITOR_HEIGHT,
24660
+ BookEditor: BookEditor
24661
+ });
24662
+
24663
+ /**
24664
+ * Renders a book editor
24665
+ *
24666
+ * @public exported from `@promptbook/components`
24667
+ */
24668
+ function BookEditorForClient(props) {
24669
+ const [BookEditorComponent, setBookEditorComponent] = useState(null);
24670
+ useEffect(() => {
24671
+ let isCancelled = false;
24672
+ void Promise.resolve().then(function () { return BookEditor$1; }).then(({ BookEditor }) => {
24673
+ if (!isCancelled) {
24674
+ setBookEditorComponent(() => BookEditor);
24675
+ }
24676
+ });
24677
+ return () => {
24678
+ isCancelled = true;
24679
+ };
24680
+ }, []);
24681
+ if (!BookEditorComponent) {
24682
+ return jsx("div", { style: { minHeight: 260 } });
24683
+ }
24684
+ return jsx(BookEditorComponent, { ...props });
24685
+ }
24686
+
24764
24687
  /**
24765
24688
  * Restricts an Updatable to a (2) BehaviorSubject variant
24766
24689
  *
@@ -26515,7 +26438,7 @@ function normalizeMarkdownSublists(markdown) {
26515
26438
  function createChatMarkdownConverter(options) {
26516
26439
  var _a;
26517
26440
  const citationReferenceClassName = (_a = options === null || options === void 0 ? void 0 : options.citationReferenceClassName) !== null && _a !== void 0 ? _a : DEFAULT_CITATION_REFERENCE_CLASS_NAME;
26518
- return new Converter({
26441
+ return new showdown.Converter({
26519
26442
  flavor: 'github',
26520
26443
  tables: true,
26521
26444
  strikethrough: true,
@@ -30969,6 +30892,22 @@ function ChatInputArea(props) {
30969
30892
  }
30970
30893
 
30971
30894
  // Note: [💞] Ignore a discrepancy between file name and entity name
30895
+ /**
30896
+ * Target frames per second for the shared avatar animation loop.
30897
+ *
30898
+ * Animated octopus visuals change slowly enough that 24 fps is indistinguishable
30899
+ * from 60 fps in practice, while cutting rendering work by ~60% when multiple
30900
+ * avatars are on screen simultaneously.
30901
+ *
30902
+ * @private utility of the avatar rendering system
30903
+ */
30904
+ const AVATAR_TARGET_FPS = 24;
30905
+ /**
30906
+ * Minimum elapsed time in milliseconds required between avatar render passes.
30907
+ *
30908
+ * @private utility of the avatar rendering system
30909
+ */
30910
+ const AVATAR_TARGET_FRAME_INTERVAL_MS = 1000 / AVATAR_TARGET_FPS;
30972
30911
  /**
30973
30912
  * Next registration id used by the shared avatar animation scheduler.
30974
30913
  *
@@ -30987,6 +30926,14 @@ const avatarAnimationListeners = new Map();
30987
30926
  * @private utility of the avatar rendering system
30988
30927
  */
30989
30928
  let avatarAnimationFrameId = null;
30929
+ /**
30930
+ * Timestamp of the most recently rendered avatar frame.
30931
+ *
30932
+ * Used to throttle callbacks to `AVATAR_TARGET_FRAME_INTERVAL_MS`.
30933
+ *
30934
+ * @private utility of the avatar rendering system
30935
+ */
30936
+ let lastAvatarFrameTime = 0;
30990
30937
  /**
30991
30938
  * Registers one avatar animation callback in the shared animation loop.
30992
30939
  *
@@ -31021,8 +30968,11 @@ function ensureAvatarAnimationLoop() {
31021
30968
  }
31022
30969
  const runFrame = (now) => {
31023
30970
  avatarAnimationFrameId = null;
31024
- for (const avatarAnimationListener of [...avatarAnimationListeners.values()]) {
31025
- avatarAnimationListener(now);
30971
+ if (now - lastAvatarFrameTime >= AVATAR_TARGET_FRAME_INTERVAL_MS) {
30972
+ lastAvatarFrameTime = now;
30973
+ for (const avatarAnimationListener of [...avatarAnimationListeners.values()]) {
30974
+ avatarAnimationListener(now);
30975
+ }
31026
30976
  }
31027
30977
  ensureAvatarAnimationLoop();
31028
30978
  };
@@ -42689,6 +42639,103 @@ function deduplicatePreparationToolCalls(toolCalls) {
42689
42639
  return toolCalls;
42690
42640
  }
42691
42641
 
42642
+ /**
42643
+ * Priority order for the important commitments shown first in catalogues and intellisense.
42644
+ *
42645
+ * Canonical singular names stay ahead of their plural aliases so the most important
42646
+ * commitments remain easy to scan.
42647
+ *
42648
+ * @private internal constant of commitment catalog sorting
42649
+ */
42650
+ const IMPORTANT_COMMITMENT_TYPE_SORT_ORDER = new Map([
42651
+ ['GOAL', 0],
42652
+ ['RULE', 1],
42653
+ ['KNOWLEDGE', 2],
42654
+ ['TEAM', 3],
42655
+ ['GOALS', 4],
42656
+ ['RULES', 5],
42657
+ ]);
42658
+ /**
42659
+ * Sort rank used when unfinished, low-level, and deprecated commitments should be grouped last.
42660
+ *
42661
+ * @private internal constant of commitment catalog sorting
42662
+ */
42663
+ const COMMITMENT_STATUS_SORT_ORDER = {
42664
+ normal: 0,
42665
+ deprecated: 1,
42666
+ unfinished: 2,
42667
+ lowLevel: 3,
42668
+ };
42669
+ /**
42670
+ * Resolves the relative sort rank of one commitment status.
42671
+ *
42672
+ * @param definition - Commitment definition to rank.
42673
+ * @param options - Sorting options.
42674
+ * @returns Relative sort rank for the definition.
42675
+ *
42676
+ * @private internal helper of commitment catalog sorting
42677
+ */
42678
+ function resolveCommitmentStatusSortRank(definition, options) {
42679
+ let statusSortRank = COMMITMENT_STATUS_SORT_ORDER.normal;
42680
+ if (options.isDeprecatedLast && definition.deprecation) {
42681
+ statusSortRank = Math.max(statusSortRank, COMMITMENT_STATUS_SORT_ORDER.deprecated);
42682
+ }
42683
+ if (options.isUnfinishedLast && definition.isUnfinished) {
42684
+ statusSortRank = Math.max(statusSortRank, COMMITMENT_STATUS_SORT_ORDER.unfinished);
42685
+ }
42686
+ if (options.isLowLevelLast && definition.isLowLevel) {
42687
+ statusSortRank = Math.max(statusSortRank, COMMITMENT_STATUS_SORT_ORDER.lowLevel);
42688
+ }
42689
+ return statusSortRank;
42690
+ }
42691
+ /**
42692
+ * Sorts commitment definitions so the important ones stay at the top.
42693
+ *
42694
+ * @param commitmentDefinitions - Definitions to sort.
42695
+ * @param options - Sorting options.
42696
+ * @returns Sorted commitment definitions.
42697
+ *
42698
+ * @private internal helper of commitment catalog sorting
42699
+ */
42700
+ function sortCommitmentDefinitions(commitmentDefinitions, options = {}) {
42701
+ return [...commitmentDefinitions]
42702
+ .map((definition, index) => ({
42703
+ definition,
42704
+ index,
42705
+ }))
42706
+ .sort((left, right) => {
42707
+ var _a, _b;
42708
+ if (left.definition.isImportant !== right.definition.isImportant) {
42709
+ return left.definition.isImportant ? -1 : 1;
42710
+ }
42711
+ if (left.definition.isImportant && right.definition.isImportant) {
42712
+ const leftPriority = (_a = IMPORTANT_COMMITMENT_TYPE_SORT_ORDER.get(left.definition.type)) !== null && _a !== void 0 ? _a : Number.MAX_SAFE_INTEGER;
42713
+ const rightPriority = (_b = IMPORTANT_COMMITMENT_TYPE_SORT_ORDER.get(right.definition.type)) !== null && _b !== void 0 ? _b : Number.MAX_SAFE_INTEGER;
42714
+ if (leftPriority !== rightPriority) {
42715
+ return leftPriority - rightPriority;
42716
+ }
42717
+ }
42718
+ const leftStatusSortRank = resolveCommitmentStatusSortRank(left.definition, options);
42719
+ const rightStatusSortRank = resolveCommitmentStatusSortRank(right.definition, options);
42720
+ if (leftStatusSortRank !== rightStatusSortRank) {
42721
+ return leftStatusSortRank - rightStatusSortRank;
42722
+ }
42723
+ return left.index - right.index;
42724
+ })
42725
+ .map(({ definition }) => definition);
42726
+ }
42727
+
42728
+ /**
42729
+ * Gets all available commitment definitions
42730
+ *
42731
+ * @returns Array of all commitment definitions
42732
+ *
42733
+ * @public exported from `@promptbook/core`
42734
+ */
42735
+ function getAllCommitmentDefinitions() {
42736
+ return $deepFreeze(sortCommitmentDefinitions(COMMITMENT_REGISTRY, { isUnfinishedLast: true, isLowLevelLast: true }));
42737
+ }
42738
+
42692
42739
  /**
42693
42740
  * Gets all tool titles provided by all commitments
42694
42741
  *
@@ -45363,7 +45410,7 @@ function $registeredScrapersMessage(availableScrapers) {
45363
45410
  * @public exported from `@promptbook/editable`
45364
45411
  */
45365
45412
  function knowledgeSourceContentToName(knowledgeSourceContent) {
45366
- const hash = SHA256(hexEncoder.parse(JSON.stringify(knowledgeSourceContent)))
45413
+ const hash = CryptoJS.SHA256(hexEncoder.parse(JSON.stringify(knowledgeSourceContent)))
45367
45414
  // <- TODO: [🥬] Encapsulate sha256 to some private utility function
45368
45415
  .toString( /* hex */)
45369
45416
  .substring(0, 20);
@@ -46211,7 +46258,7 @@ function csvParse(value /* <- TODO: string_csv */, settings, schema /* <- TODO:
46211
46258
  console.warn('CSV string contains carriage return characters, but in the CSV settings the `newline` setting does not include them. Autohealing the CSV string.');
46212
46259
  value = value.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
46213
46260
  }
46214
- const csv = parse(value, settings);
46261
+ const csv = papaparse.parse(value, settings);
46215
46262
  return csv;
46216
46263
  }
46217
46264
 
@@ -46296,10 +46343,10 @@ const CsvFormatParser = {
46296
46343
  i > index ? { ...row, [outputParameterName]: PENDING_VALUE_PLACEHOLDER } : row,
46297
46344
  );
46298
46345
  */
46299
- await onProgress(unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS }));
46346
+ await onProgress(papaparse.unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS }));
46300
46347
  }
46301
46348
  }
46302
- return unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
46349
+ return papaparse.unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
46303
46350
  },
46304
46351
  },
46305
46352
  {
@@ -46327,7 +46374,7 @@ const CsvFormatParser = {
46327
46374
  return /* not await */ mapCallback({ [key]: value }, index, array.length);
46328
46375
  }));
46329
46376
  }));
46330
- return unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
46377
+ return papaparse.unparse(mappedData, { ...settings, ...MANDATORY_CSV_SETTINGS });
46331
46378
  },
46332
46379
  },
46333
46380
  ],
@@ -48344,6 +48391,18 @@ function createBasicAgentModelRequirements(agentName) {
48344
48391
  }
48345
48392
  // TODO: [🐤] Deduplicate `AgentModelRequirements` and `ModelRequirements` model requirements
48346
48393
 
48394
+ /**
48395
+ * Gets a commitment definition by its type
48396
+ *
48397
+ * @param type The commitment type to look up
48398
+ * @returns The commitment definition or null if not found
48399
+ *
48400
+ * @public exported from `@promptbook/core`
48401
+ */
48402
+ function getCommitmentDefinition(type) {
48403
+ return COMMITMENT_REGISTRY.find((commitmentDefinition) => commitmentDefinition.type === type) || null;
48404
+ }
48405
+
48347
48406
  /**
48348
48407
  * Commitment types whose content may contain compact agent references that must be resolved before applying the commitment.
48349
48408
  *
@@ -54837,7 +54896,7 @@ function emitAgentLlmExecutionToolsAssistantPreparationProgress(options) {
54837
54896
  * Computes one stable hash from a JSON-serializable value.
54838
54897
  */
54839
54898
  function computeJsonHash$1(value) {
54840
- return SHA256(JSON.stringify(value)).toString();
54899
+ return CryptoJS.SHA256(JSON.stringify(value)).toString();
54841
54900
  }
54842
54901
  /**
54843
54902
  * Handles OpenAI AgentKit-backed executions for `AgentLlmExecutionTools`.
@@ -54995,7 +55054,7 @@ AgentLlmExecutionToolsAgentKitRunner.vectorStoreCache = new Map();
54995
55054
  * Computes one stable hash from a JSON-serializable value.
54996
55055
  */
54997
55056
  function computeJsonHash(value) {
54998
- return SHA256(JSON.stringify(value)).toString();
55057
+ return CryptoJS.SHA256(JSON.stringify(value)).toString();
54999
55058
  }
55000
55059
  /**
55001
55060
  * Removes assistant-managed requirements before the prompt is executed via OpenAI Assistants.
@@ -55851,7 +55910,7 @@ class AgentLlmExecutionTools {
55851
55910
  * Returns a virtual model name representing the agent behavior.
55852
55911
  */
55853
55912
  get modelName() {
55854
- const hash = SHA256(hexEncoder.parse(this.options.agentSource)).toString( /* hex */);
55913
+ const hash = CryptoJS.SHA256(hexEncoder.parse(this.options.agentSource)).toString( /* hex */);
55855
55914
  const agentId = hash.substring(0, 10);
55856
55915
  return (normalizeToKebabCase(this.title) + '-' + agentId);
55857
55916
  }
@@ -59260,5 +59319,5 @@ function AboutPromptbookInformation(props) {
59260
59319
  return (jsx(Fragment, { children: jsx(MarkdownContent, { content: aboutPromptbookInformation(props) }) }));
59261
59320
  }
59262
59321
 
59263
- export { AboutPromptbookInformation, AgentChat, ArrowIcon, AvatarChip, AvatarChipFromSource, AvatarProfile, AvatarProfileFromSource, BLOCKY_FLOW, BOOK_LANGUAGE_VERSION, BookEditor, BrandedQrCode, CHAT_SAVE_FORMATS, Chat, ChatEffectsSystem, ChatSoundAndVibrationPanel, ChatSoundToggle, ChatVibrationToggle, ConfettiEffect, DEFAULT_BOOK_EDITOR_HEIGHT, FAST_FLOW, GenericQrCode, HeartsEffect, LlmChat, MOCKED_CHAT_DELAY_CONFIGS, MarkdownContent, MicIcon, MockedChat, NORMAL_FLOW, PROMPTBOOK_ENGINE_VERSION, PauseIcon, PlayIcon, PromptbookAgentIntegration, PromptbookQrCode, RANDOM_FLOW, ResetIcon, SLOW_FLOW, SendIcon, StopIcon, TemplateIcon, defaultEffectConfigs, getChatSaveFormatDefinitions, htmlSaveFormatDefinition, injectCssModuleIntoShadowRoot, jsonSaveFormatDefinition, mdSaveFormatDefinition, parseMessageButtons, pdfSaveFormatDefinition, reactSaveFormatDefinition, txtSaveFormatDefinition, useChatAutoScroll, useSendMessageToLlmChat };
59322
+ export { AboutPromptbookInformation, AgentChat, ArrowIcon, AvatarChip, AvatarChipFromSource, AvatarProfile, AvatarProfileFromSource, BLOCKY_FLOW, BOOK_LANGUAGE_VERSION, BookEditor, BookEditorForClient, BrandedQrCode, CHAT_SAVE_FORMATS, Chat, ChatEffectsSystem, ChatSoundAndVibrationPanel, ChatSoundToggle, ChatVibrationToggle, ConfettiEffect, DEFAULT_BOOK_EDITOR_HEIGHT, FAST_FLOW, GenericQrCode, HeartsEffect, LlmChat, MOCKED_CHAT_DELAY_CONFIGS, MarkdownContent, MicIcon, MockedChat, NORMAL_FLOW, PROMPTBOOK_ENGINE_VERSION, PauseIcon, PlayIcon, PromptbookAgentIntegration, PromptbookQrCode, RANDOM_FLOW, ResetIcon, SLOW_FLOW, SendIcon, StopIcon, TemplateIcon, defaultEffectConfigs, getChatSaveFormatDefinitions, htmlSaveFormatDefinition, injectCssModuleIntoShadowRoot, jsonSaveFormatDefinition, mdSaveFormatDefinition, parseMessageButtons, pdfSaveFormatDefinition, reactSaveFormatDefinition, txtSaveFormatDefinition, useChatAutoScroll, useSendMessageToLlmChat };
59264
59323
  //# sourceMappingURL=index.es.js.map