@promptbook/wizard 0.112.0-73 → 0.112.0-80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -9
- package/esm/index.es.js +823 -374
- package/esm/index.es.js.map +1 -1
- package/esm/src/avatars/types/AvatarVisualDefinition.d.ts +1 -1
- package/esm/src/avatars/visuals/octopus3d2AvatarVisual.d.ts +7 -0
- package/esm/src/avatars/visuals/octopus3dAvatarVisualShared.d.ts +37 -0
- package/esm/src/book-components/Chat/save/_common/chatExportRendering.d.ts +47 -0
- package/esm/src/book-components/Chat/save/html/htmlSaveFormatDefinition.d.ts +12 -0
- package/esm/src/book-components/Chat/save/index.d.ts +2 -2
- package/esm/src/book-components/Chat/save/markdown/mdSaveFormatDefinition.d.ts +5 -3
- package/esm/src/book-components/Chat/save/pdf/buildChatPdf.d.ts +3 -3
- package/esm/src/book-components/Chat/save/pdf/pdfSaveFormatDefinition.d.ts +1 -1
- package/esm/src/cli/cli-commands/agent/agentProjectPaths.d.ts +8 -8
- package/esm/src/cli/cli-commands/agent/initializeAgentRunnerCommand.d.ts +1 -1
- package/esm/src/cli/cli-commands/agents-server/buildAgentsServer.d.ts +56 -0
- package/esm/src/cli/cli-commands/agents-server/buildAgentsServer.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.d.ts +7 -0
- package/esm/src/cli/cli-commands/agents-server/ensureAgentsServerGitignoreFile.d.ts +7 -0
- package/esm/src/cli/cli-commands/agents-server/init.d.ts +9 -0
- package/esm/src/cli/cli-commands/agents-server/init.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/agents-server/initializeAgentsServerProjectConfiguration.d.ts +17 -0
- package/esm/src/cli/cli-commands/agents-server/printAgentsServerInitializationSummary.d.ts +7 -0
- package/esm/src/cli/cli-commands/agents-server/run.d.ts +14 -0
- package/esm/src/cli/cli-commands/agents-server/run.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/agents-server/startAgentsServer.d.ts +23 -0
- package/esm/src/cli/cli-commands/agents-server.d.ts +8 -0
- package/esm/src/cli/cli-commands/common/projectInitialization.d.ts +65 -0
- package/esm/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +44 -0
- package/esm/src/cli/common/$deprecateCliCommand.d.ts +8 -0
- package/esm/src/cli/common/$deprecateCliCommand.test.d.ts +1 -0
- package/esm/src/utils/color/Color.d.ts +4 -44
- package/esm/src/utils/color/ColorValue.d.ts +55 -0
- package/esm/src/utils/color/isHexColorString.d.ts +10 -0
- package/esm/src/utils/color/parseColorString.d.ts +11 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +2 -2
- package/umd/index.umd.js +823 -374
- package/umd/index.umd.js.map +1 -1
- package/umd/src/avatars/types/AvatarVisualDefinition.d.ts +1 -1
- package/umd/src/avatars/visuals/octopus3d2AvatarVisual.d.ts +7 -0
- package/umd/src/avatars/visuals/octopus3dAvatarVisualShared.d.ts +37 -0
- package/umd/src/book-components/Chat/save/_common/chatExportRendering.d.ts +47 -0
- package/umd/src/book-components/Chat/save/html/htmlSaveFormatDefinition.d.ts +12 -0
- package/umd/src/book-components/Chat/save/index.d.ts +2 -2
- package/umd/src/book-components/Chat/save/markdown/mdSaveFormatDefinition.d.ts +5 -3
- package/umd/src/book-components/Chat/save/pdf/buildChatPdf.d.ts +3 -3
- package/umd/src/book-components/Chat/save/pdf/pdfSaveFormatDefinition.d.ts +1 -1
- package/umd/src/cli/cli-commands/agent/agentProjectPaths.d.ts +8 -8
- package/umd/src/cli/cli-commands/agent/initializeAgentRunnerCommand.d.ts +1 -1
- package/umd/src/cli/cli-commands/agents-server/buildAgentsServer.d.ts +56 -0
- package/umd/src/cli/cli-commands/agents-server/buildAgentsServer.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/agents-server/ensureAgentsServerEnvFile.d.ts +7 -0
- package/umd/src/cli/cli-commands/agents-server/ensureAgentsServerGitignoreFile.d.ts +7 -0
- package/umd/src/cli/cli-commands/agents-server/init.d.ts +9 -0
- package/umd/src/cli/cli-commands/agents-server/init.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/agents-server/initializeAgentsServerProjectConfiguration.d.ts +17 -0
- package/umd/src/cli/cli-commands/agents-server/printAgentsServerInitializationSummary.d.ts +7 -0
- package/umd/src/cli/cli-commands/agents-server/run.d.ts +14 -0
- package/umd/src/cli/cli-commands/agents-server/run.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/agents-server/startAgentsServer.d.ts +23 -0
- package/umd/src/cli/cli-commands/agents-server.d.ts +8 -0
- package/umd/src/cli/cli-commands/common/projectInitialization.d.ts +65 -0
- package/umd/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +44 -0
- package/umd/src/cli/common/$deprecateCliCommand.d.ts +8 -0
- package/umd/src/cli/common/$deprecateCliCommand.test.d.ts +1 -0
- package/umd/src/utils/color/Color.d.ts +4 -44
- package/umd/src/utils/color/ColorValue.d.ts +55 -0
- package/umd/src/utils/color/isHexColorString.d.ts +10 -0
- package/umd/src/utils/color/parseColorString.d.ts +11 -0
- package/umd/src/version.d.ts +1 -1
- package/esm/src/cli/cli-commands/coder/appendBlock.d.ts +0 -6
- package/esm/src/cli/cli-commands/coder/readTextFileIfExists.d.ts +0 -6
- package/umd/src/cli/cli-commands/coder/appendBlock.d.ts +0 -6
- package/umd/src/cli/cli-commands/coder/readTextFileIfExists.d.ts +0 -6
package/esm/index.es.js
CHANGED
|
@@ -38,7 +38,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
38
38
|
* @generated
|
|
39
39
|
* @see https://github.com/webgptorg/promptbook
|
|
40
40
|
*/
|
|
41
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
41
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-80';
|
|
42
42
|
/**
|
|
43
43
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
44
44
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -302,6 +302,111 @@ function checkChannelValue(channelName, value) {
|
|
|
302
302
|
}
|
|
303
303
|
}
|
|
304
304
|
|
|
305
|
+
/**
|
|
306
|
+
* Shared immutable channel storage and serialization helpers for `Color`.
|
|
307
|
+
*
|
|
308
|
+
* @private base class of Color
|
|
309
|
+
*/
|
|
310
|
+
class ColorValue {
|
|
311
|
+
constructor(red, green, blue, alpha = 255) {
|
|
312
|
+
this.red = red;
|
|
313
|
+
this.green = green;
|
|
314
|
+
this.blue = blue;
|
|
315
|
+
this.alpha = alpha;
|
|
316
|
+
checkChannelValue('Red', red);
|
|
317
|
+
checkChannelValue('Green', green);
|
|
318
|
+
checkChannelValue('Blue', blue);
|
|
319
|
+
checkChannelValue('Alpha', alpha);
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Shortcut for `red` property
|
|
323
|
+
* Number from 0 to 255
|
|
324
|
+
* @alias red
|
|
325
|
+
*/
|
|
326
|
+
get r() {
|
|
327
|
+
return this.red;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Shortcut for `green` property
|
|
331
|
+
* Number from 0 to 255
|
|
332
|
+
* @alias green
|
|
333
|
+
*/
|
|
334
|
+
get g() {
|
|
335
|
+
return this.green;
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Shortcut for `blue` property
|
|
339
|
+
* Number from 0 to 255
|
|
340
|
+
* @alias blue
|
|
341
|
+
*/
|
|
342
|
+
get b() {
|
|
343
|
+
return this.blue;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Shortcut for `alpha` property
|
|
347
|
+
* Number from 0 (transparent) to 255 (opaque)
|
|
348
|
+
* @alias alpha
|
|
349
|
+
*/
|
|
350
|
+
get a() {
|
|
351
|
+
return this.alpha;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Shortcut for `alpha` property
|
|
355
|
+
* Number from 0 (transparent) to 255 (opaque)
|
|
356
|
+
* @alias alpha
|
|
357
|
+
*/
|
|
358
|
+
get opacity() {
|
|
359
|
+
return this.alpha;
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Shortcut for 1-`alpha` property
|
|
363
|
+
*/
|
|
364
|
+
get transparency() {
|
|
365
|
+
return 255 - this.alpha;
|
|
366
|
+
}
|
|
367
|
+
clone() {
|
|
368
|
+
return take(this.createColor(this.red, this.green, this.blue, this.alpha));
|
|
369
|
+
}
|
|
370
|
+
toString() {
|
|
371
|
+
return this.toHex();
|
|
372
|
+
}
|
|
373
|
+
toHex() {
|
|
374
|
+
if (this.alpha === 255) {
|
|
375
|
+
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
376
|
+
.toString(16)
|
|
377
|
+
.padStart(2, '0')}`;
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
381
|
+
.toString(16)
|
|
382
|
+
.padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
toRgb() {
|
|
386
|
+
if (this.alpha === 255) {
|
|
387
|
+
return `rgb(${this.red}, ${this.green}, ${this.blue})`;
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
toHsl() {
|
|
394
|
+
throw new Error(`Getting HSL is not implemented`);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Checks if the given value is a valid hex color string
|
|
400
|
+
*
|
|
401
|
+
* @param value - value to check
|
|
402
|
+
* @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
|
|
403
|
+
*
|
|
404
|
+
* @private function of Color
|
|
405
|
+
*/
|
|
406
|
+
function isHexColorString(value) {
|
|
407
|
+
return (typeof value === 'string' && /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value));
|
|
408
|
+
}
|
|
409
|
+
|
|
305
410
|
/**
|
|
306
411
|
* Constant for short hex lengths.
|
|
307
412
|
*/
|
|
@@ -513,16 +618,53 @@ function parseAlphaValue(value) {
|
|
|
513
618
|
|
|
514
619
|
/**
|
|
515
620
|
* Pattern matching hsl regex.
|
|
621
|
+
*
|
|
622
|
+
* @private function of Color
|
|
516
623
|
*/
|
|
517
624
|
const HSL_REGEX_PATTERN = /^hsl\(\s*([0-9.]+)\s*,\s*([0-9.]+)%\s*,\s*([0-9.]+)%\s*\)$/;
|
|
518
625
|
/**
|
|
519
626
|
* Pattern matching RGB regex.
|
|
627
|
+
*
|
|
628
|
+
* @private function of Color
|
|
520
629
|
*/
|
|
521
630
|
const RGB_REGEX_PATTERN = /^rgb\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/;
|
|
522
631
|
/**
|
|
523
632
|
* Pattern matching rgba regex.
|
|
633
|
+
*
|
|
634
|
+
* @private function of Color
|
|
524
635
|
*/
|
|
525
636
|
const RGBA_REGEX_PATTERN = /^rgba\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/;
|
|
637
|
+
/**
|
|
638
|
+
* Parses a supported color string into RGBA channels.
|
|
639
|
+
*
|
|
640
|
+
* @param color as a string for example `#009edd`, `rgb(0,158,221)`, `rgb(0%,62%,86.7%)`, `hsl(197.1,100%,43.3%)`, `red`, `darkgrey`,...
|
|
641
|
+
* @returns RGBA channel values.
|
|
642
|
+
*
|
|
643
|
+
* @private function of Color
|
|
644
|
+
*/
|
|
645
|
+
function parseColorString(color) {
|
|
646
|
+
const trimmed = color.trim();
|
|
647
|
+
const cssColor = CSS_COLORS[trimmed];
|
|
648
|
+
if (cssColor) {
|
|
649
|
+
return parseColorString(cssColor);
|
|
650
|
+
}
|
|
651
|
+
else if (isHexColorString(trimmed)) {
|
|
652
|
+
return parseHexColor(trimmed);
|
|
653
|
+
}
|
|
654
|
+
if (HSL_REGEX_PATTERN.test(trimmed)) {
|
|
655
|
+
return parseHslColor(trimmed);
|
|
656
|
+
}
|
|
657
|
+
else if (RGB_REGEX_PATTERN.test(trimmed)) {
|
|
658
|
+
return parseRgbColor(trimmed);
|
|
659
|
+
}
|
|
660
|
+
else if (RGBA_REGEX_PATTERN.test(trimmed)) {
|
|
661
|
+
return parseRgbaColor(trimmed);
|
|
662
|
+
}
|
|
663
|
+
else {
|
|
664
|
+
throw new Error(`Can not create a new Color instance from string "${trimmed}".`);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
526
668
|
/**
|
|
527
669
|
* Color object represents an RGB color with alpha channel
|
|
528
670
|
*
|
|
@@ -530,7 +672,7 @@ const RGBA_REGEX_PATTERN = /^rgba\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.
|
|
|
530
672
|
*
|
|
531
673
|
* @public exported from `@promptbook/color`
|
|
532
674
|
*/
|
|
533
|
-
class Color {
|
|
675
|
+
class Color extends ColorValue {
|
|
534
676
|
/**
|
|
535
677
|
* Creates a new Color instance from miscellaneous formats
|
|
536
678
|
* - It can receive Color instance and just return the same instance
|
|
@@ -603,25 +745,7 @@ class Color {
|
|
|
603
745
|
* @returns Color object
|
|
604
746
|
*/
|
|
605
747
|
static fromString(color) {
|
|
606
|
-
|
|
607
|
-
if (CSS_COLORS[trimmed]) {
|
|
608
|
-
return Color.fromString(CSS_COLORS[trimmed]);
|
|
609
|
-
}
|
|
610
|
-
else if (Color.isHexColorString(trimmed)) {
|
|
611
|
-
return Color.fromHex(trimmed);
|
|
612
|
-
}
|
|
613
|
-
if (HSL_REGEX_PATTERN.test(trimmed)) {
|
|
614
|
-
return Color.fromHsl(trimmed);
|
|
615
|
-
}
|
|
616
|
-
else if (RGB_REGEX_PATTERN.test(trimmed)) {
|
|
617
|
-
return Color.fromRgbString(trimmed);
|
|
618
|
-
}
|
|
619
|
-
else if (RGBA_REGEX_PATTERN.test(trimmed)) {
|
|
620
|
-
return Color.fromRgbaString(trimmed);
|
|
621
|
-
}
|
|
622
|
-
else {
|
|
623
|
-
throw new Error(`Can not create a new Color instance from string "${trimmed}".`);
|
|
624
|
-
}
|
|
748
|
+
return Color.fromColorChannels(parseColorString(color));
|
|
625
749
|
}
|
|
626
750
|
/**
|
|
627
751
|
* Gets common color
|
|
@@ -651,8 +775,7 @@ class Color {
|
|
|
651
775
|
* @returns Color object
|
|
652
776
|
*/
|
|
653
777
|
static fromHex(hex) {
|
|
654
|
-
|
|
655
|
-
return take(new Color(red, green, blue, alpha));
|
|
778
|
+
return Color.fromColorChannels(parseHexColor(hex));
|
|
656
779
|
}
|
|
657
780
|
/**
|
|
658
781
|
* Creates a new Color instance from color in hsl format
|
|
@@ -661,8 +784,7 @@ class Color {
|
|
|
661
784
|
* @returns Color object
|
|
662
785
|
*/
|
|
663
786
|
static fromHsl(hsl) {
|
|
664
|
-
|
|
665
|
-
return take(new Color(red, green, blue, alpha));
|
|
787
|
+
return Color.fromColorChannels(parseHslColor(hsl));
|
|
666
788
|
}
|
|
667
789
|
/**
|
|
668
790
|
* Creates a new Color instance from color in rgb format
|
|
@@ -671,8 +793,7 @@ class Color {
|
|
|
671
793
|
* @returns Color object
|
|
672
794
|
*/
|
|
673
795
|
static fromRgbString(rgb) {
|
|
674
|
-
|
|
675
|
-
return take(new Color(red, green, blue, alpha));
|
|
796
|
+
return Color.fromColorChannels(parseRgbColor(rgb));
|
|
676
797
|
}
|
|
677
798
|
/**
|
|
678
799
|
* Creates a new Color instance from color in rbga format
|
|
@@ -681,8 +802,7 @@ class Color {
|
|
|
681
802
|
* @returns Color object
|
|
682
803
|
*/
|
|
683
804
|
static fromRgbaString(rgba) {
|
|
684
|
-
|
|
685
|
-
return take(new Color(red, green, blue, alpha));
|
|
805
|
+
return Color.fromColorChannels(parseRgbaColor(rgba));
|
|
686
806
|
}
|
|
687
807
|
/**
|
|
688
808
|
* Creates a new Color for color channels values
|
|
@@ -694,7 +814,7 @@ class Color {
|
|
|
694
814
|
* @returns Color object
|
|
695
815
|
*/
|
|
696
816
|
static fromValues(red, green, blue, alpha = 255) {
|
|
697
|
-
return
|
|
817
|
+
return Color.fromColorChannels({ red, green, blue, alpha });
|
|
698
818
|
}
|
|
699
819
|
/**
|
|
700
820
|
* Checks if the given value is a valid Color object.
|
|
@@ -727,8 +847,7 @@ class Color {
|
|
|
727
847
|
* @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
|
|
728
848
|
*/
|
|
729
849
|
static isHexColorString(value) {
|
|
730
|
-
return (
|
|
731
|
-
/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(value));
|
|
850
|
+
return isHexColorString(value);
|
|
732
851
|
}
|
|
733
852
|
/**
|
|
734
853
|
* Creates new Color object
|
|
@@ -741,89 +860,13 @@ class Color {
|
|
|
741
860
|
* @param alpha number from 0 (transparent) to 255 (opaque)
|
|
742
861
|
*/
|
|
743
862
|
constructor(red, green, blue, alpha = 255) {
|
|
744
|
-
|
|
745
|
-
this.green = green;
|
|
746
|
-
this.blue = blue;
|
|
747
|
-
this.alpha = alpha;
|
|
748
|
-
checkChannelValue('Red', red);
|
|
749
|
-
checkChannelValue('Green', green);
|
|
750
|
-
checkChannelValue('Blue', blue);
|
|
751
|
-
checkChannelValue('Alpha', alpha);
|
|
752
|
-
}
|
|
753
|
-
/**
|
|
754
|
-
* Shortcut for `red` property
|
|
755
|
-
* Number from 0 to 255
|
|
756
|
-
* @alias red
|
|
757
|
-
*/
|
|
758
|
-
get r() {
|
|
759
|
-
return this.red;
|
|
760
|
-
}
|
|
761
|
-
/**
|
|
762
|
-
* Shortcut for `green` property
|
|
763
|
-
* Number from 0 to 255
|
|
764
|
-
* @alias green
|
|
765
|
-
*/
|
|
766
|
-
get g() {
|
|
767
|
-
return this.green;
|
|
768
|
-
}
|
|
769
|
-
/**
|
|
770
|
-
* Shortcut for `blue` property
|
|
771
|
-
* Number from 0 to 255
|
|
772
|
-
* @alias blue
|
|
773
|
-
*/
|
|
774
|
-
get b() {
|
|
775
|
-
return this.blue;
|
|
776
|
-
}
|
|
777
|
-
/**
|
|
778
|
-
* Shortcut for `alpha` property
|
|
779
|
-
* Number from 0 (transparent) to 255 (opaque)
|
|
780
|
-
* @alias alpha
|
|
781
|
-
*/
|
|
782
|
-
get a() {
|
|
783
|
-
return this.alpha;
|
|
784
|
-
}
|
|
785
|
-
/**
|
|
786
|
-
* Shortcut for `alpha` property
|
|
787
|
-
* Number from 0 (transparent) to 255 (opaque)
|
|
788
|
-
* @alias alpha
|
|
789
|
-
*/
|
|
790
|
-
get opacity() {
|
|
791
|
-
return this.alpha;
|
|
792
|
-
}
|
|
793
|
-
/**
|
|
794
|
-
* Shortcut for 1-`alpha` property
|
|
795
|
-
*/
|
|
796
|
-
get transparency() {
|
|
797
|
-
return 255 - this.alpha;
|
|
798
|
-
}
|
|
799
|
-
clone() {
|
|
800
|
-
return take(new Color(this.red, this.green, this.blue, this.alpha));
|
|
801
|
-
}
|
|
802
|
-
toString() {
|
|
803
|
-
return this.toHex();
|
|
804
|
-
}
|
|
805
|
-
toHex() {
|
|
806
|
-
if (this.alpha === 255) {
|
|
807
|
-
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
808
|
-
.toString(16)
|
|
809
|
-
.padStart(2, '0')}`;
|
|
810
|
-
}
|
|
811
|
-
else {
|
|
812
|
-
return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
|
|
813
|
-
.toString(16)
|
|
814
|
-
.padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
|
|
815
|
-
}
|
|
863
|
+
super(red, green, blue, alpha);
|
|
816
864
|
}
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
return `rgb(${this.red}, ${this.green}, ${this.blue})`;
|
|
820
|
-
}
|
|
821
|
-
else {
|
|
822
|
-
return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
|
|
823
|
-
}
|
|
865
|
+
createColor(red, green, blue, alpha) {
|
|
866
|
+
return new Color(red, green, blue, alpha);
|
|
824
867
|
}
|
|
825
|
-
|
|
826
|
-
|
|
868
|
+
static fromColorChannels({ red, green, blue, alpha }) {
|
|
869
|
+
return take(new Color(red, green, blue, alpha));
|
|
827
870
|
}
|
|
828
871
|
}
|
|
829
872
|
|
|
@@ -1499,120 +1542,183 @@ function assertsError(whatWasThrown) {
|
|
|
1499
1542
|
* @public exported from `@promptbook/utils`
|
|
1500
1543
|
*/
|
|
1501
1544
|
function checkSerializableAsJson(options) {
|
|
1502
|
-
|
|
1545
|
+
checkSerializableValue(options);
|
|
1546
|
+
}
|
|
1547
|
+
// TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
1548
|
+
// TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
1549
|
+
// Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
1550
|
+
/**
|
|
1551
|
+
* Checks one value and dispatches to the appropriate specialized validator.
|
|
1552
|
+
*
|
|
1553
|
+
* @private function of `checkSerializableAsJson`
|
|
1554
|
+
*/
|
|
1555
|
+
function checkSerializableValue(options) {
|
|
1556
|
+
const { value } = options;
|
|
1557
|
+
if (isSerializablePrimitive(value)) {
|
|
1558
|
+
return;
|
|
1559
|
+
}
|
|
1503
1560
|
if (value === undefined) {
|
|
1504
|
-
throw new UnexpectedError(`${name} is undefined`);
|
|
1561
|
+
throw new UnexpectedError(`${options.name} is undefined`);
|
|
1505
1562
|
}
|
|
1506
|
-
|
|
1507
|
-
|
|
1563
|
+
if (typeof value === 'symbol') {
|
|
1564
|
+
throw new UnexpectedError(`${options.name} is symbol`);
|
|
1508
1565
|
}
|
|
1509
|
-
|
|
1510
|
-
|
|
1566
|
+
if (typeof value === 'function') {
|
|
1567
|
+
throw new UnexpectedError(`${options.name} is function`);
|
|
1511
1568
|
}
|
|
1512
|
-
|
|
1569
|
+
if (Array.isArray(value)) {
|
|
1570
|
+
checkSerializableArray(options, value);
|
|
1513
1571
|
return;
|
|
1514
1572
|
}
|
|
1515
|
-
|
|
1573
|
+
if (value !== null && typeof value === 'object') {
|
|
1574
|
+
checkSerializableObject(options, value);
|
|
1516
1575
|
return;
|
|
1517
1576
|
}
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1577
|
+
throwUnknownTypeError(options);
|
|
1578
|
+
}
|
|
1579
|
+
/**
|
|
1580
|
+
* Checks the primitive values that are directly JSON serializable.
|
|
1581
|
+
*
|
|
1582
|
+
* @private function of `checkSerializableAsJson`
|
|
1583
|
+
*/
|
|
1584
|
+
function isSerializablePrimitive(value) {
|
|
1585
|
+
return (value === null ||
|
|
1586
|
+
typeof value === 'boolean' ||
|
|
1587
|
+
(typeof value === 'number' && !isNaN(value)) ||
|
|
1588
|
+
typeof value === 'string');
|
|
1589
|
+
}
|
|
1590
|
+
/**
|
|
1591
|
+
* Recursively checks JSON array items.
|
|
1592
|
+
*
|
|
1593
|
+
* @private function of `checkSerializableAsJson`
|
|
1594
|
+
*/
|
|
1595
|
+
function checkSerializableArray(context, arrayValue) {
|
|
1596
|
+
for (let index = 0; index < arrayValue.length; index++) {
|
|
1597
|
+
checkSerializableAsJson({
|
|
1598
|
+
...context,
|
|
1599
|
+
name: `${context.name}[${index}]`,
|
|
1600
|
+
value: arrayValue[index],
|
|
1601
|
+
});
|
|
1528
1602
|
}
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1603
|
+
}
|
|
1604
|
+
/**
|
|
1605
|
+
* Checks object-like values and dispatches special unsupported built-ins.
|
|
1606
|
+
*
|
|
1607
|
+
* @private function of `checkSerializableAsJson`
|
|
1608
|
+
*/
|
|
1609
|
+
function checkSerializableObject(context, objectValue) {
|
|
1610
|
+
checkUnsupportedObjectType(context, objectValue);
|
|
1611
|
+
checkSerializableObjectEntries(context, objectValue);
|
|
1612
|
+
assertJsonStringificationSucceeds(context, objectValue);
|
|
1613
|
+
}
|
|
1614
|
+
/**
|
|
1615
|
+
* Rejects built-in objects that must be converted before JSON serialization.
|
|
1616
|
+
*
|
|
1617
|
+
* @private function of `checkSerializableAsJson`
|
|
1618
|
+
*/
|
|
1619
|
+
function checkUnsupportedObjectType(context, objectValue) {
|
|
1620
|
+
if (objectValue instanceof Date) {
|
|
1621
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1622
|
+
\`${context.name}\` is Date
|
|
1533
1623
|
|
|
1534
|
-
|
|
1624
|
+
Use \`string_date_iso8601\` instead
|
|
1535
1625
|
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1626
|
+
Additional message for \`${context.name}\`:
|
|
1627
|
+
${block(context.message || '(nothing)')}
|
|
1628
|
+
`));
|
|
1629
|
+
}
|
|
1630
|
+
if (objectValue instanceof Map) {
|
|
1631
|
+
throw new UnexpectedError(`${context.name} is Map`);
|
|
1632
|
+
}
|
|
1633
|
+
if (objectValue instanceof Set) {
|
|
1634
|
+
throw new UnexpectedError(`${context.name} is Set`);
|
|
1635
|
+
}
|
|
1636
|
+
if (objectValue instanceof RegExp) {
|
|
1637
|
+
throw new UnexpectedError(`${context.name} is RegExp`);
|
|
1638
|
+
}
|
|
1639
|
+
if (objectValue instanceof Error) {
|
|
1640
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1641
|
+
\`${context.name}\` is unserialized Error
|
|
1552
1642
|
|
|
1553
|
-
|
|
1643
|
+
Use function \`serializeError\`
|
|
1554
1644
|
|
|
1555
|
-
|
|
1556
|
-
|
|
1645
|
+
Additional message for \`${context.name}\`:
|
|
1646
|
+
${block(context.message || '(nothing)')}
|
|
1557
1647
|
|
|
1558
|
-
|
|
1648
|
+
`));
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
/**
|
|
1652
|
+
* Recursively checks object properties while preserving omitted `undefined` keys.
|
|
1653
|
+
*
|
|
1654
|
+
* @private function of `checkSerializableAsJson`
|
|
1655
|
+
*/
|
|
1656
|
+
function checkSerializableObjectEntries(context, objectValue) {
|
|
1657
|
+
for (const [subName, subValue] of Object.entries(objectValue)) {
|
|
1658
|
+
if (subValue === undefined) {
|
|
1659
|
+
// Note: undefined in object is serializable - it is just omitted
|
|
1660
|
+
continue;
|
|
1559
1661
|
}
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1662
|
+
checkSerializableAsJson({
|
|
1663
|
+
...context,
|
|
1664
|
+
name: `${context.name}.${subName}`,
|
|
1665
|
+
value: subValue,
|
|
1666
|
+
});
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
/**
|
|
1670
|
+
* Uses `JSON.stringify` as the final guard for cases like circular references.
|
|
1671
|
+
*
|
|
1672
|
+
* @private function of `checkSerializableAsJson`
|
|
1673
|
+
*/
|
|
1674
|
+
function assertJsonStringificationSucceeds(context, objectValue) {
|
|
1675
|
+
try {
|
|
1676
|
+
JSON.stringify(objectValue); // <- TODO: [0]
|
|
1677
|
+
}
|
|
1678
|
+
catch (error) {
|
|
1679
|
+
assertsError(error);
|
|
1680
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1681
|
+
\`${context.name}\` is not serializable
|
|
1575
1682
|
|
|
1576
|
-
|
|
1683
|
+
${block(error.stack || error.message)}
|
|
1577
1684
|
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1685
|
+
Additional message for \`${context.name}\`:
|
|
1686
|
+
${block(context.message || '(nothing)')}
|
|
1687
|
+
`));
|
|
1688
|
+
}
|
|
1689
|
+
/*
|
|
1690
|
+
TODO: [0] Is there some more elegant way to check circular references?
|
|
1691
|
+
const seen = new Set();
|
|
1692
|
+
const stack = [{ value }];
|
|
1693
|
+
while (stack.length > 0) {
|
|
1694
|
+
const { value } = stack.pop()!;
|
|
1695
|
+
if (typeof value === 'object' && value !== null) {
|
|
1696
|
+
if (seen.has(value)) {
|
|
1697
|
+
throw new UnexpectedError(`${name} has circular reference`);
|
|
1581
1698
|
}
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
const { value } = stack.pop()!;
|
|
1588
|
-
if (typeof value === 'object' && value !== null) {
|
|
1589
|
-
if (seen.has(value)) {
|
|
1590
|
-
throw new UnexpectedError(`${name} has circular reference`);
|
|
1591
|
-
}
|
|
1592
|
-
seen.add(value);
|
|
1593
|
-
if (Array.isArray(value)) {
|
|
1594
|
-
stack.push(...value.map((value) => ({ value })));
|
|
1595
|
-
} else {
|
|
1596
|
-
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
1597
|
-
}
|
|
1598
|
-
}
|
|
1699
|
+
seen.add(value);
|
|
1700
|
+
if (Array.isArray(value)) {
|
|
1701
|
+
stack.push(...value.map((value) => ({ value })));
|
|
1702
|
+
} else {
|
|
1703
|
+
stack.push(...Object.values(value).map((value) => ({ value })));
|
|
1599
1704
|
}
|
|
1600
|
-
*/
|
|
1601
|
-
return;
|
|
1602
1705
|
}
|
|
1603
1706
|
}
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1707
|
+
*/
|
|
1708
|
+
}
|
|
1709
|
+
/**
|
|
1710
|
+
* Throws the fallback error for unsupported value types like `bigint` and `NaN`.
|
|
1711
|
+
*
|
|
1712
|
+
* @private function of `checkSerializableAsJson`
|
|
1713
|
+
*/
|
|
1714
|
+
function throwUnknownTypeError(context) {
|
|
1715
|
+
throw new UnexpectedError(spaceTrim$1((block) => `
|
|
1716
|
+
\`${context.name}\` is unknown type
|
|
1607
1717
|
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
}
|
|
1718
|
+
Additional message for \`${context.name}\`:
|
|
1719
|
+
${block(context.message || '(nothing)')}
|
|
1720
|
+
`));
|
|
1612
1721
|
}
|
|
1613
|
-
// TODO: Can be return type more type-safe? like `asserts options.value is JsonValue`
|
|
1614
|
-
// TODO: [🧠][main] !!3 In-memory cache of same values to prevent multiple checks
|
|
1615
|
-
// Note: [🐠] This is how `checkSerializableAsJson` + `isSerializableAsJson` together can just retun true/false or rich error message
|
|
1616
1722
|
|
|
1617
1723
|
/**
|
|
1618
1724
|
* Creates a deep clone of the given object
|
|
@@ -5973,7 +6079,10 @@ class OpenAiCompatibleModelCatalog {
|
|
|
5973
6079
|
Cannot find model in ${this.options.getTitle()} models with name "${defaultModelName}" which should be used as default.
|
|
5974
6080
|
|
|
5975
6081
|
Available models:
|
|
5976
|
-
${block(this.options
|
|
6082
|
+
${block(this.options
|
|
6083
|
+
.getHardcodedModels()
|
|
6084
|
+
.map(({ modelName }) => `- "${modelName}"`)
|
|
6085
|
+
.join('\n'))}
|
|
5977
6086
|
|
|
5978
6087
|
Model "${defaultModelName}" is probably not available anymore, not installed, inaccessible or misconfigured.
|
|
5979
6088
|
|
|
@@ -6327,7 +6436,8 @@ class OpenAiCompatibleNonChatPromptCaller {
|
|
|
6327
6436
|
};
|
|
6328
6437
|
let rawPromptContent = templateParameters(content, { ...parameters, modelName });
|
|
6329
6438
|
if ('attachments' in prompt && Array.isArray(prompt.attachments) && prompt.attachments.length > 0) {
|
|
6330
|
-
rawPromptContent +=
|
|
6439
|
+
rawPromptContent +=
|
|
6440
|
+
'\n\n' + prompt.attachments.map((attachment) => `Image attachment: ${attachment.url}`).join('\n');
|
|
6331
6441
|
}
|
|
6332
6442
|
const rawRequest = {
|
|
6333
6443
|
...modelSettings,
|
|
@@ -6432,7 +6542,9 @@ class OpenAiCompatibleRequestManager {
|
|
|
6432
6542
|
* Schedules one request through the shared limiter and retry policy.
|
|
6433
6543
|
*/
|
|
6434
6544
|
async executeRateLimitedRequest(requestFn) {
|
|
6435
|
-
return this.limiter
|
|
6545
|
+
return this.limiter
|
|
6546
|
+
.schedule(() => this.makeRequestWithNetworkRetry(requestFn))
|
|
6547
|
+
.catch((error) => {
|
|
6436
6548
|
assertsError(error);
|
|
6437
6549
|
if (this.options.isVerbose) {
|
|
6438
6550
|
console.info(colors.bgRed('error'), error);
|
|
@@ -9172,7 +9284,9 @@ class OpenAiVectorStoreFileBatchPoller {
|
|
|
9172
9284
|
pollingState.lastProgressAtMs = nowMs;
|
|
9173
9285
|
pollingState.lastProgressKey = progressKey;
|
|
9174
9286
|
}
|
|
9175
|
-
if (this.options.isVerbose &&
|
|
9287
|
+
if (this.options.isVerbose &&
|
|
9288
|
+
(statusCountsKey !== pollingState.lastCountsKey ||
|
|
9289
|
+
nowMs - pollingState.lastLogAtMs >= progressLogIntervalMs)) {
|
|
9176
9290
|
console.info('[🤰]', 'Vector store file batch status', {
|
|
9177
9291
|
vectorStoreId,
|
|
9178
9292
|
batchId,
|
|
@@ -11245,7 +11359,7 @@ function createJokerCommands(task) {
|
|
|
11245
11359
|
*/
|
|
11246
11360
|
function createPostprocessingCommands(task) {
|
|
11247
11361
|
var _a;
|
|
11248
|
-
return ((_a = task.postprocessingFunctionNames) === null || _a === void 0 ? void 0 : _a.map((postprocessingFunctionName) => `POSTPROCESSING \`${postprocessingFunctionName}\``)) || [];
|
|
11362
|
+
return (((_a = task.postprocessingFunctionNames) === null || _a === void 0 ? void 0 : _a.map((postprocessingFunctionName) => `POSTPROCESSING \`${postprocessingFunctionName}\``)) || []);
|
|
11249
11363
|
}
|
|
11250
11364
|
/**
|
|
11251
11365
|
* Collects expectation commands.
|
|
@@ -11775,8 +11889,7 @@ function hasTaskJokers(task) {
|
|
|
11775
11889
|
* @private internal utility of `validatePipeline`
|
|
11776
11890
|
*/
|
|
11777
11891
|
function validateTaskSupportsJokers(task, pipelineIdentification) {
|
|
11778
|
-
if (task.format ||
|
|
11779
|
-
task.expectations /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
|
|
11892
|
+
if (task.format || task.expectations /* <- TODO: Require at least 1 -> min <- expectation to use jokers */) {
|
|
11780
11893
|
return;
|
|
11781
11894
|
}
|
|
11782
11895
|
throw new PipelineLogicError(spaceTrim$1((block) => `
|
|
@@ -14971,9 +15084,7 @@ function createFailuresSummary($failedResults) {
|
|
|
14971
15084
|
${block(quoteMultilineText(((_b = failure.error) === null || _b === void 0 ? void 0 : _b.message) || ''))}
|
|
14972
15085
|
|
|
14973
15086
|
Result:
|
|
14974
|
-
${block(failure.result === null
|
|
14975
|
-
? 'null'
|
|
14976
|
-
: quoteMultilineText(spaceTrim$1(failure.result)))}
|
|
15087
|
+
${block(failure.result === null ? 'null' : quoteMultilineText(spaceTrim$1(failure.result)))}
|
|
14977
15088
|
`;
|
|
14978
15089
|
}))
|
|
14979
15090
|
.join('\n\n---\n\n');
|
|
@@ -22459,7 +22570,7 @@ function fillTextureRect(texture, x, y, width, height, color) {
|
|
|
22459
22570
|
*
|
|
22460
22571
|
* @private helper of `minecraft2AvatarVisual`
|
|
22461
22572
|
*/
|
|
22462
|
-
const LIGHT_DIRECTION$
|
|
22573
|
+
const LIGHT_DIRECTION$2 = normalizeVector3({
|
|
22463
22574
|
x: 0.4,
|
|
22464
22575
|
y: -0.65,
|
|
22465
22576
|
z: 0.92,
|
|
@@ -22671,7 +22782,7 @@ function resolveVisibleCuboidFaces(cuboid, size, sceneCenterX, sceneCenterY) {
|
|
|
22671
22782
|
corners: projectedCorners,
|
|
22672
22783
|
texture: faceDefinition.texture,
|
|
22673
22784
|
averageDepth: transformedCorners.reduce((depthSum, corner) => depthSum + corner.z, 0) / transformedCorners.length,
|
|
22674
|
-
lightIntensity: clampNumber$1(dotProduct3D(faceNormal, LIGHT_DIRECTION$
|
|
22785
|
+
lightIntensity: clampNumber$1(dotProduct3D(faceNormal, LIGHT_DIRECTION$2), -1, 1),
|
|
22675
22786
|
outlineColor: cuboid.outlineColor,
|
|
22676
22787
|
};
|
|
22677
22788
|
});
|
|
@@ -23731,13 +23842,138 @@ function drawSeededEye(context, centerX, centerY, radiusX, radiusY, rotation, pa
|
|
|
23731
23842
|
context.restore();
|
|
23732
23843
|
}
|
|
23733
23844
|
|
|
23845
|
+
/* eslint-disable no-magic-numbers */
|
|
23846
|
+
/**
|
|
23847
|
+
* Draws one projected eye on a rotated octopus surface.
|
|
23848
|
+
*
|
|
23849
|
+
* @private helper of the 3D octopus avatar visuals
|
|
23850
|
+
*/
|
|
23851
|
+
function drawProjectedOrganicEye(context, localCenter, radiusX, radiusY, center, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, phase, interaction, eyeStyle) {
|
|
23852
|
+
const centerScenePoint = transformScenePoint(localCenter, center, rotationX, rotationY);
|
|
23853
|
+
if (centerScenePoint.z <= center.z) {
|
|
23854
|
+
return;
|
|
23855
|
+
}
|
|
23856
|
+
const horizontalScenePoint = transformScenePoint({ x: localCenter.x + radiusX, y: localCenter.y, z: localCenter.z }, center, rotationX, rotationY);
|
|
23857
|
+
const verticalScenePoint = transformScenePoint({ x: localCenter.x, y: localCenter.y + radiusY, z: localCenter.z }, center, rotationX, rotationY);
|
|
23858
|
+
const projectedCenterPoint = projectScenePoint(centerScenePoint, size, sceneCenterX, sceneCenterY);
|
|
23859
|
+
const projectedHorizontalPoint = projectScenePoint(horizontalScenePoint, size, sceneCenterX, sceneCenterY);
|
|
23860
|
+
const projectedVerticalPoint = projectScenePoint(verticalScenePoint, size, sceneCenterX, sceneCenterY);
|
|
23861
|
+
const projectedRadiusX = Math.hypot(projectedHorizontalPoint.x - projectedCenterPoint.x, projectedHorizontalPoint.y - projectedCenterPoint.y);
|
|
23862
|
+
const projectedRadiusY = Math.hypot(projectedVerticalPoint.x - projectedCenterPoint.x, projectedVerticalPoint.y - projectedCenterPoint.y);
|
|
23863
|
+
if (projectedRadiusX < size * 0.008 || projectedRadiusY < size * 0.008) {
|
|
23864
|
+
return;
|
|
23865
|
+
}
|
|
23866
|
+
const { pupilOffsetX, pupilOffsetY } = resolveOrganicEyeMotion({
|
|
23867
|
+
radiusX: projectedRadiusX,
|
|
23868
|
+
radiusY: projectedRadiusY,
|
|
23869
|
+
timeMs,
|
|
23870
|
+
phase,
|
|
23871
|
+
interaction,
|
|
23872
|
+
});
|
|
23873
|
+
const rotation = Math.atan2(projectedHorizontalPoint.y - projectedCenterPoint.y, projectedHorizontalPoint.x - projectedCenterPoint.x);
|
|
23874
|
+
context.save();
|
|
23875
|
+
context.translate(projectedCenterPoint.x, projectedCenterPoint.y);
|
|
23876
|
+
context.rotate(rotation);
|
|
23877
|
+
context.beginPath();
|
|
23878
|
+
context.ellipse(0, 0, projectedRadiusX, projectedRadiusY, 0, 0, Math.PI * 2);
|
|
23879
|
+
context.fillStyle = '#f8fbff';
|
|
23880
|
+
context.fill();
|
|
23881
|
+
context.clip();
|
|
23882
|
+
const irisGradient = context.createRadialGradient(-projectedRadiusX * 0.2, -projectedRadiusY * 0.26, projectedRadiusX * 0.05, 0, 0, projectedRadiusX * 0.92);
|
|
23883
|
+
irisGradient.addColorStop(0, palette.highlight);
|
|
23884
|
+
irisGradient.addColorStop(0.56, palette.secondary);
|
|
23885
|
+
irisGradient.addColorStop(1, palette.shadow);
|
|
23886
|
+
context.beginPath();
|
|
23887
|
+
context.ellipse(pupilOffsetX, pupilOffsetY, projectedRadiusX * 0.62 * eyeStyle.irisScale, projectedRadiusY * 0.72 * eyeStyle.irisScale, 0, 0, Math.PI * 2);
|
|
23888
|
+
context.fillStyle = irisGradient;
|
|
23889
|
+
context.fill();
|
|
23890
|
+
context.beginPath();
|
|
23891
|
+
context.ellipse(pupilOffsetX, pupilOffsetY, projectedRadiusX * 0.15 * eyeStyle.pupilWidthScale, projectedRadiusY * 0.48 * eyeStyle.pupilHeightScale, 0, 0, Math.PI * 2);
|
|
23892
|
+
context.fillStyle = palette.ink;
|
|
23893
|
+
context.fill();
|
|
23894
|
+
context.beginPath();
|
|
23895
|
+
context.ellipse(pupilOffsetX - projectedRadiusX * 0.22, pupilOffsetY - projectedRadiusY * 0.24, projectedRadiusX * 0.12, projectedRadiusY * 0.14, 0, 0, Math.PI * 2);
|
|
23896
|
+
context.fillStyle = '#ffffff';
|
|
23897
|
+
context.fill();
|
|
23898
|
+
context.restore();
|
|
23899
|
+
context.save();
|
|
23900
|
+
context.translate(projectedCenterPoint.x, projectedCenterPoint.y);
|
|
23901
|
+
context.rotate(rotation);
|
|
23902
|
+
context.beginPath();
|
|
23903
|
+
context.ellipse(0, 0, projectedRadiusX, projectedRadiusY, 0, 0, Math.PI * 2);
|
|
23904
|
+
context.strokeStyle = `${palette.shadow}cc`;
|
|
23905
|
+
context.lineWidth = projectedRadiusX * 0.16;
|
|
23906
|
+
context.stroke();
|
|
23907
|
+
context.beginPath();
|
|
23908
|
+
context.moveTo(-projectedRadiusX * 0.88, -projectedRadiusY * eyeStyle.upperLidInsetRatio);
|
|
23909
|
+
context.quadraticCurveTo(0, -projectedRadiusY * (eyeStyle.upperLidArchRatio - interaction.gazeY * 0.16 + interaction.intensity * 0.08), projectedRadiusX * 0.88, -projectedRadiusY * eyeStyle.upperLidInsetRatio);
|
|
23910
|
+
context.strokeStyle = `${palette.shadow}73`;
|
|
23911
|
+
context.lineWidth = projectedRadiusX * 0.14;
|
|
23912
|
+
context.lineCap = 'round';
|
|
23913
|
+
context.stroke();
|
|
23914
|
+
if (eyeStyle.lowerLidOpacity > 0) {
|
|
23915
|
+
context.beginPath();
|
|
23916
|
+
context.moveTo(-projectedRadiusX * 0.74, projectedRadiusY * 0.2);
|
|
23917
|
+
context.quadraticCurveTo(0, projectedRadiusY * 0.38, projectedRadiusX * 0.74, projectedRadiusY * 0.2);
|
|
23918
|
+
context.strokeStyle = `${palette.highlight}${formatAlphaHex(eyeStyle.lowerLidOpacity)}`;
|
|
23919
|
+
context.lineWidth = projectedRadiusX * 0.08;
|
|
23920
|
+
context.lineCap = 'round';
|
|
23921
|
+
context.stroke();
|
|
23922
|
+
}
|
|
23923
|
+
context.restore();
|
|
23924
|
+
}
|
|
23925
|
+
/**
|
|
23926
|
+
* Draws a subtle projected mouth arc across the front of a rotated octopus surface.
|
|
23927
|
+
*
|
|
23928
|
+
* @private helper of the 3D octopus avatar visuals
|
|
23929
|
+
*/
|
|
23930
|
+
function drawProjectedOrganicMouth(context, localPoints, center, rotationX, rotationY, sceneCenterX, sceneCenterY, palette, size) {
|
|
23931
|
+
const scenePoints = localPoints.map((localPoint) => transformScenePoint(localPoint, center, rotationX, rotationY));
|
|
23932
|
+
if (scenePoints.some((scenePoint) => scenePoint.z <= center.z)) {
|
|
23933
|
+
return;
|
|
23934
|
+
}
|
|
23935
|
+
const projectedPoints = scenePoints.map((scenePoint) => projectScenePoint(scenePoint, size, sceneCenterX, sceneCenterY));
|
|
23936
|
+
context.beginPath();
|
|
23937
|
+
context.moveTo(projectedPoints[0].x, projectedPoints[0].y);
|
|
23938
|
+
context.quadraticCurveTo(projectedPoints[1].x, projectedPoints[1].y, projectedPoints[2].x, projectedPoints[2].y);
|
|
23939
|
+
context.strokeStyle = `${palette.ink}b8`;
|
|
23940
|
+
context.lineWidth = Math.max(1.1, size * 0.009);
|
|
23941
|
+
context.lineCap = 'round';
|
|
23942
|
+
context.stroke();
|
|
23943
|
+
}
|
|
23944
|
+
/**
|
|
23945
|
+
* Draws one filled projected quad.
|
|
23946
|
+
*
|
|
23947
|
+
* @private helper of the 3D octopus avatar visuals
|
|
23948
|
+
*/
|
|
23949
|
+
function drawProjectedQuad(context, corners, fillStyle) {
|
|
23950
|
+
context.beginPath();
|
|
23951
|
+
context.moveTo(corners[0].x, corners[0].y);
|
|
23952
|
+
context.lineTo(corners[1].x, corners[1].y);
|
|
23953
|
+
context.lineTo(corners[2].x, corners[2].y);
|
|
23954
|
+
context.lineTo(corners[3].x, corners[3].y);
|
|
23955
|
+
context.closePath();
|
|
23956
|
+
context.fillStyle = fillStyle;
|
|
23957
|
+
context.fill();
|
|
23958
|
+
}
|
|
23959
|
+
/**
|
|
23960
|
+
* Converts an opacity ratio into a two-digit hexadecimal alpha suffix.
|
|
23961
|
+
*
|
|
23962
|
+
* @private helper of the 3D octopus avatar visuals
|
|
23963
|
+
*/
|
|
23964
|
+
function formatAlphaHex(opacity) {
|
|
23965
|
+
return Math.round(clampNumber$1(opacity, 0, 1) * 255)
|
|
23966
|
+
.toString(16)
|
|
23967
|
+
.padStart(2, '0');
|
|
23968
|
+
}
|
|
23969
|
+
|
|
23734
23970
|
/* eslint-disable no-magic-numbers */
|
|
23735
23971
|
/**
|
|
23736
23972
|
* Light direction used by the organic 3D octopus shading.
|
|
23737
23973
|
*
|
|
23738
23974
|
* @private helper of `octopus3dAvatarVisual`
|
|
23739
23975
|
*/
|
|
23740
|
-
const LIGHT_DIRECTION = normalizeVector3({
|
|
23976
|
+
const LIGHT_DIRECTION$1 = normalizeVector3({
|
|
23741
23977
|
x: 0.48,
|
|
23742
23978
|
y: -0.62,
|
|
23743
23979
|
z: 0.94,
|
|
@@ -23850,17 +24086,17 @@ const octopus3dAvatarVisual = {
|
|
|
23850
24086
|
for (const tentacleStroke of tentacleStrokes.filter((candidateTentacleStroke) => candidateTentacleStroke.isFrontFacing)) {
|
|
23851
24087
|
drawTentacleStroke(context, tentacleStroke, palette);
|
|
23852
24088
|
}
|
|
23853
|
-
|
|
24089
|
+
drawProjectedOrganicEye(context, {
|
|
23854
24090
|
x: -faceEyeSpacing,
|
|
23855
24091
|
y: faceEyeYOffset,
|
|
23856
24092
|
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -faceEyeSpacing, faceEyeYOffset),
|
|
23857
24093
|
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + eyeRandom() * 0.6, interaction, morphologyProfile.face.eyeStyle);
|
|
23858
|
-
|
|
24094
|
+
drawProjectedOrganicEye(context, {
|
|
23859
24095
|
x: faceEyeSpacing,
|
|
23860
24096
|
y: faceEyeYOffset,
|
|
23861
24097
|
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, faceEyeSpacing, faceEyeYOffset),
|
|
23862
24098
|
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + eyeRandom() * 0.6, interaction, morphologyProfile.face.eyeStyle);
|
|
23863
|
-
|
|
24099
|
+
drawProjectedOrganicMouth(context, [
|
|
23864
24100
|
{
|
|
23865
24101
|
x: -mouthHalfWidth,
|
|
23866
24102
|
y: mouthY,
|
|
@@ -23947,7 +24183,7 @@ function resolveVisibleEllipsoidPatches(options) {
|
|
|
23947
24183
|
corners: projectedCorners,
|
|
23948
24184
|
averageDepth: transformedCorners.reduce((depthSum, transformedCorner) => depthSum + transformedCorner.z, 0) /
|
|
23949
24185
|
transformedCorners.length,
|
|
23950
|
-
lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION), -1, 1),
|
|
24186
|
+
lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION$1), -1, 1),
|
|
23951
24187
|
fillStyle: resolveSurfacePatchFillStyle(palette, verticalProgress + verticalColorBias),
|
|
23952
24188
|
outlineColor,
|
|
23953
24189
|
});
|
|
@@ -24129,128 +24365,260 @@ function resolveEllipsoidSurfaceDepth(radiusX, radiusY, radiusZ, x, y) {
|
|
|
24129
24365
|
const remainingDepthRatio = Math.max(0, 1 - normalizedX * normalizedX - normalizedY * normalizedY);
|
|
24130
24366
|
return Math.sqrt(remainingDepthRatio) * radiusZ;
|
|
24131
24367
|
}
|
|
24368
|
+
|
|
24369
|
+
/* eslint-disable no-magic-numbers */
|
|
24132
24370
|
/**
|
|
24133
|
-
*
|
|
24371
|
+
* Light direction used by the single-mesh octopus shading.
|
|
24134
24372
|
*
|
|
24135
|
-
* @private helper of `
|
|
24373
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
24136
24374
|
*/
|
|
24137
|
-
|
|
24138
|
-
|
|
24139
|
-
|
|
24140
|
-
|
|
24141
|
-
|
|
24142
|
-
|
|
24143
|
-
|
|
24144
|
-
|
|
24145
|
-
|
|
24146
|
-
|
|
24147
|
-
|
|
24148
|
-
|
|
24149
|
-
|
|
24150
|
-
|
|
24151
|
-
|
|
24152
|
-
|
|
24153
|
-
|
|
24154
|
-
|
|
24155
|
-
|
|
24156
|
-
|
|
24157
|
-
|
|
24158
|
-
|
|
24159
|
-
|
|
24375
|
+
const LIGHT_DIRECTION = normalizeVector3({
|
|
24376
|
+
x: 0.38,
|
|
24377
|
+
y: -0.6,
|
|
24378
|
+
z: 0.98,
|
|
24379
|
+
});
|
|
24380
|
+
/**
|
|
24381
|
+
* Octopus 3D 2 avatar visual.
|
|
24382
|
+
*
|
|
24383
|
+
* @private built-in avatar visual
|
|
24384
|
+
*/
|
|
24385
|
+
const octopus3d2AvatarVisual = {
|
|
24386
|
+
id: 'octopus3d2',
|
|
24387
|
+
title: 'Octopus 3D 2',
|
|
24388
|
+
description: 'Continuous blobby 3D octopus portrait with one soft mesh, turning silhouette, and cursor-aware eyes.',
|
|
24389
|
+
isAnimated: true,
|
|
24390
|
+
supportsPointerTracking: true,
|
|
24391
|
+
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
24392
|
+
const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
|
|
24393
|
+
const animationRandom = createRandom('octopus3d2-animation-profile');
|
|
24394
|
+
const eyeRandom = createRandom('octopus3d2-eye-profile');
|
|
24395
|
+
const animationPhase = animationRandom() * Math.PI * 2;
|
|
24396
|
+
const sceneCenterX = size * 0.5;
|
|
24397
|
+
const sceneCenterY = size * 0.575;
|
|
24398
|
+
const bob = Math.sin(timeMs / 940 + animationPhase) * size * 0.013;
|
|
24399
|
+
const meshCenter = {
|
|
24400
|
+
x: interaction.bodyOffsetX * size * 0.044 + size * morphologyProfile.body.centerXJitterRatio * 0.5,
|
|
24401
|
+
y: -size * 0.03 + interaction.bodyOffsetY * size * 0.026 + bob,
|
|
24402
|
+
z: interaction.intensity * size * 0.018,
|
|
24403
|
+
};
|
|
24404
|
+
const rotationY = -0.14 +
|
|
24405
|
+
Math.sin(timeMs / 2600 + animationPhase) * 0.04 +
|
|
24406
|
+
interaction.bodyOffsetX * 0.2 +
|
|
24407
|
+
interaction.gazeX * 0.78;
|
|
24408
|
+
const rotationX = -0.06 +
|
|
24409
|
+
Math.cos(timeMs / 3000 + animationPhase * 0.7) * 0.02 -
|
|
24410
|
+
interaction.bodyOffsetY * 0.08 -
|
|
24411
|
+
interaction.gazeY * 0.34;
|
|
24412
|
+
const surfaceOptions = {
|
|
24413
|
+
radiusX: size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.horizontalStretch * 1.02,
|
|
24414
|
+
radiusY: size * morphologyProfile.body.bodyRadiusRatio * morphologyProfile.body.verticalStretch * 1.22,
|
|
24415
|
+
radiusZ: size *
|
|
24416
|
+
morphologyProfile.body.bodyRadiusRatio *
|
|
24417
|
+
(0.98 + (morphologyProfile.body.horizontalStretch - 1) * 0.2),
|
|
24418
|
+
morphologyProfile,
|
|
24419
|
+
timeMs,
|
|
24420
|
+
animationPhase,
|
|
24421
|
+
};
|
|
24422
|
+
const surfacePatches = resolveVisibleBlobbyOctopusPatches({
|
|
24423
|
+
...surfaceOptions,
|
|
24424
|
+
center: meshCenter,
|
|
24425
|
+
rotationX,
|
|
24426
|
+
rotationY,
|
|
24427
|
+
sceneCenterX,
|
|
24428
|
+
sceneCenterY,
|
|
24429
|
+
size,
|
|
24430
|
+
palette,
|
|
24431
|
+
});
|
|
24432
|
+
const eyeLatitude = clampNumber$1(morphologyProfile.face.eyeCenterYOffsetRatio * 4.4, -0.16, 0.11);
|
|
24433
|
+
const eyeLongitude = clampNumber$1(morphologyProfile.face.eyeSpacingRatio * 3.25, 0.2, 0.34);
|
|
24434
|
+
const mouthLatitude = clampNumber$1(eyeLatitude + 0.19 + morphologyProfile.face.mouthYOffsetRatio * 1.08, 0.08, 0.34);
|
|
24435
|
+
const mouthCenterLongitude = clampNumber$1(morphologyProfile.face.mouthCenterOffsetRatio * 5.8, -0.08, 0.08);
|
|
24436
|
+
const mouthHalfLongitude = clampNumber$1(eyeLongitude * 0.82, 0.16, 0.29);
|
|
24437
|
+
const mouthCurveLatitude = clampNumber$1(mouthLatitude + morphologyProfile.face.mouthCurveDepthRatio * 0.85, mouthLatitude + 0.03, 0.42);
|
|
24438
|
+
drawAvatarFrame(context, size, palette);
|
|
24439
|
+
drawBlobbyOctopusAtmosphere(context, size, palette, sceneCenterX, sceneCenterY, interaction, timeMs);
|
|
24440
|
+
drawBlobbyOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile);
|
|
24441
|
+
for (const surfacePatch of surfacePatches.sort((firstSurfacePatch, secondSurfacePatch) => firstSurfacePatch.averageDepth - secondSurfacePatch.averageDepth)) {
|
|
24442
|
+
drawBlobbySurfacePatch(context, surfacePatch);
|
|
24443
|
+
}
|
|
24444
|
+
const leftEyeLocalCenter = sampleBlobbyOctopusSurfacePoint(surfaceOptions, eyeLatitude, -eyeLongitude);
|
|
24445
|
+
const rightEyeLocalCenter = sampleBlobbyOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude);
|
|
24446
|
+
const eyeRadiusX = size * morphologyProfile.face.eyeRadiusXRatio * 0.78;
|
|
24447
|
+
const eyeRadiusY = eyeRadiusX * morphologyProfile.face.eyeHeightRatio * 0.92;
|
|
24448
|
+
drawProjectedOrganicEye(context, leftEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + eyeRandom() * 0.7, interaction, morphologyProfile.face.eyeStyle);
|
|
24449
|
+
drawProjectedOrganicEye(context, rightEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.9 + eyeRandom() * 0.7, interaction, morphologyProfile.face.eyeStyle);
|
|
24450
|
+
drawProjectedOrganicMouth(context, [
|
|
24451
|
+
sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude - mouthHalfLongitude),
|
|
24452
|
+
sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthCurveLatitude, mouthCenterLongitude),
|
|
24453
|
+
sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude + mouthHalfLongitude),
|
|
24454
|
+
], meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, palette, size);
|
|
24455
|
+
},
|
|
24456
|
+
};
|
|
24457
|
+
/**
|
|
24458
|
+
* Draws the deep-water glow behind the continuous octopus mesh.
|
|
24459
|
+
*
|
|
24460
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
24461
|
+
*/
|
|
24462
|
+
function drawBlobbyOctopusAtmosphere(context, size, palette, sceneCenterX, sceneCenterY, interaction, timeMs) {
|
|
24463
|
+
const glowGradient = context.createRadialGradient(sceneCenterX + interaction.gazeX * size * 0.11, sceneCenterY - size * 0.17 + interaction.gazeY * size * 0.05, size * 0.05, sceneCenterX, sceneCenterY - size * 0.03, size * 0.66);
|
|
24464
|
+
glowGradient.addColorStop(0, `${palette.highlight}5e`);
|
|
24465
|
+
glowGradient.addColorStop(0.38, `${palette.accent}26`);
|
|
24466
|
+
glowGradient.addColorStop(1, `${palette.highlight}00`);
|
|
24467
|
+
context.fillStyle = glowGradient;
|
|
24468
|
+
context.fillRect(0, 0, size, size);
|
|
24469
|
+
const lowerGradient = context.createRadialGradient(sceneCenterX + Math.sin(timeMs / 1650) * size * 0.045, sceneCenterY + size * 0.28, size * 0.06, sceneCenterX, sceneCenterY + size * 0.28, size * 0.52);
|
|
24470
|
+
lowerGradient.addColorStop(0, `${palette.secondary}22`);
|
|
24471
|
+
lowerGradient.addColorStop(1, `${palette.secondary}00`);
|
|
24472
|
+
context.fillStyle = lowerGradient;
|
|
24473
|
+
context.fillRect(0, 0, size, size);
|
|
24474
|
+
}
|
|
24475
|
+
/**
|
|
24476
|
+
* Draws the soft floor shadow that anchors the single mesh in the frame.
|
|
24477
|
+
*
|
|
24478
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
24479
|
+
*/
|
|
24480
|
+
function drawBlobbyOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile) {
|
|
24160
24481
|
context.save();
|
|
24161
|
-
context.
|
|
24162
|
-
context.
|
|
24163
|
-
context.beginPath();
|
|
24164
|
-
context.ellipse(0, 0, projectedRadiusX, projectedRadiusY, 0, 0, Math.PI * 2);
|
|
24165
|
-
context.fillStyle = '#f8fbff';
|
|
24166
|
-
context.fill();
|
|
24167
|
-
context.clip();
|
|
24168
|
-
const irisGradient = context.createRadialGradient(-projectedRadiusX * 0.2, -projectedRadiusY * 0.26, projectedRadiusX * 0.05, 0, 0, projectedRadiusX * 0.92);
|
|
24169
|
-
irisGradient.addColorStop(0, palette.highlight);
|
|
24170
|
-
irisGradient.addColorStop(0.56, palette.secondary);
|
|
24171
|
-
irisGradient.addColorStop(1, palette.shadow);
|
|
24172
|
-
context.beginPath();
|
|
24173
|
-
context.ellipse(pupilOffsetX, pupilOffsetY, projectedRadiusX * 0.62 * eyeStyle.irisScale, projectedRadiusY * 0.72 * eyeStyle.irisScale, 0, 0, Math.PI * 2);
|
|
24174
|
-
context.fillStyle = irisGradient;
|
|
24175
|
-
context.fill();
|
|
24482
|
+
context.fillStyle = `${palette.shadow}66`;
|
|
24483
|
+
context.filter = `blur(${size * 0.024}px)`;
|
|
24176
24484
|
context.beginPath();
|
|
24177
|
-
context.ellipse(
|
|
24178
|
-
context.fillStyle = palette.ink;
|
|
24485
|
+
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);
|
|
24179
24486
|
context.fill();
|
|
24180
|
-
context.beginPath();
|
|
24181
|
-
context.ellipse(pupilOffsetX - projectedRadiusX * 0.22, pupilOffsetY - projectedRadiusY * 0.24, projectedRadiusX * 0.12, projectedRadiusY * 0.14, 0, 0, Math.PI * 2);
|
|
24182
|
-
context.fillStyle = '#ffffff';
|
|
24183
|
-
context.fill();
|
|
24184
|
-
context.restore();
|
|
24185
|
-
context.save();
|
|
24186
|
-
context.translate(projectedCenterPoint.x, projectedCenterPoint.y);
|
|
24187
|
-
context.rotate(rotation);
|
|
24188
|
-
context.beginPath();
|
|
24189
|
-
context.ellipse(0, 0, projectedRadiusX, projectedRadiusY, 0, 0, Math.PI * 2);
|
|
24190
|
-
context.strokeStyle = `${palette.shadow}cc`;
|
|
24191
|
-
context.lineWidth = projectedRadiusX * 0.16;
|
|
24192
|
-
context.stroke();
|
|
24193
|
-
context.beginPath();
|
|
24194
|
-
context.moveTo(-projectedRadiusX * 0.88, -projectedRadiusY * eyeStyle.upperLidInsetRatio);
|
|
24195
|
-
context.quadraticCurveTo(0, -projectedRadiusY * (eyeStyle.upperLidArchRatio - interaction.gazeY * 0.16 + interaction.intensity * 0.08), projectedRadiusX * 0.88, -projectedRadiusY * eyeStyle.upperLidInsetRatio);
|
|
24196
|
-
context.strokeStyle = `${palette.shadow}73`;
|
|
24197
|
-
context.lineWidth = projectedRadiusX * 0.14;
|
|
24198
|
-
context.lineCap = 'round';
|
|
24199
|
-
context.stroke();
|
|
24200
|
-
if (eyeStyle.lowerLidOpacity > 0) {
|
|
24201
|
-
context.beginPath();
|
|
24202
|
-
context.moveTo(-projectedRadiusX * 0.74, projectedRadiusY * 0.2);
|
|
24203
|
-
context.quadraticCurveTo(0, projectedRadiusY * 0.38, projectedRadiusX * 0.74, projectedRadiusY * 0.2);
|
|
24204
|
-
context.strokeStyle = `${palette.highlight}${formatAlphaHex(eyeStyle.lowerLidOpacity)}`;
|
|
24205
|
-
context.lineWidth = projectedRadiusX * 0.08;
|
|
24206
|
-
context.lineCap = 'round';
|
|
24207
|
-
context.stroke();
|
|
24208
|
-
}
|
|
24209
24487
|
context.restore();
|
|
24210
24488
|
}
|
|
24211
24489
|
/**
|
|
24212
|
-
*
|
|
24490
|
+
* Resolves all visible projected patches for the single blobby octopus mesh.
|
|
24213
24491
|
*
|
|
24214
|
-
* @private helper of `
|
|
24492
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
24215
24493
|
*/
|
|
24216
|
-
function
|
|
24217
|
-
const
|
|
24218
|
-
|
|
24219
|
-
|
|
24494
|
+
function resolveVisibleBlobbyOctopusPatches(options) {
|
|
24495
|
+
const { center, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, morphologyProfile, animationPhase, timeMs, } = options;
|
|
24496
|
+
const latitudePatchCount = 12;
|
|
24497
|
+
const longitudePatchCount = 24;
|
|
24498
|
+
const surfacePatches = [];
|
|
24499
|
+
for (let latitudeIndex = 0; latitudeIndex < latitudePatchCount; latitudeIndex++) {
|
|
24500
|
+
const startLatitude = -Math.PI / 2 + (latitudeIndex / latitudePatchCount) * Math.PI;
|
|
24501
|
+
const endLatitude = -Math.PI / 2 + ((latitudeIndex + 1) / latitudePatchCount) * Math.PI;
|
|
24502
|
+
const centerLatitude = (startLatitude + endLatitude) / 2;
|
|
24503
|
+
const verticalProgress = (Math.sin(centerLatitude) + 1) / 2;
|
|
24504
|
+
for (let longitudeIndex = 0; longitudeIndex < longitudePatchCount; longitudeIndex++) {
|
|
24505
|
+
const startLongitude = -Math.PI + (longitudeIndex / longitudePatchCount) * Math.PI * 2;
|
|
24506
|
+
const endLongitude = -Math.PI + ((longitudeIndex + 1) / longitudePatchCount) * Math.PI * 2;
|
|
24507
|
+
const centerLongitude = (startLongitude + endLongitude) / 2;
|
|
24508
|
+
const localCorners = [
|
|
24509
|
+
sampleBlobbyOctopusSurfacePoint(options, startLatitude, startLongitude),
|
|
24510
|
+
sampleBlobbyOctopusSurfacePoint(options, startLatitude, endLongitude),
|
|
24511
|
+
sampleBlobbyOctopusSurfacePoint(options, endLatitude, endLongitude),
|
|
24512
|
+
sampleBlobbyOctopusSurfacePoint(options, endLatitude, startLongitude),
|
|
24513
|
+
];
|
|
24514
|
+
const transformedCorners = localCorners.map((localCorner) => transformScenePoint(localCorner, center, rotationX, rotationY));
|
|
24515
|
+
const surfaceNormal = normalizeVector3(crossProduct3D(subtractPoint3D(transformedCorners[1], transformedCorners[0]), subtractPoint3D(transformedCorners[2], transformedCorners[0])));
|
|
24516
|
+
if (surfaceNormal.z <= 0.01) {
|
|
24517
|
+
continue;
|
|
24518
|
+
}
|
|
24519
|
+
const projectedCorners = transformedCorners.map((transformedCorner) => projectScenePoint(transformedCorner, size, sceneCenterX, sceneCenterY));
|
|
24520
|
+
surfacePatches.push({
|
|
24521
|
+
corners: projectedCorners,
|
|
24522
|
+
averageDepth: transformedCorners.reduce((depthSum, transformedCorner) => depthSum + transformedCorner.z, 0) /
|
|
24523
|
+
transformedCorners.length,
|
|
24524
|
+
lightIntensity: clampNumber$1(dotProduct3D(surfaceNormal, LIGHT_DIRECTION), -1, 1),
|
|
24525
|
+
fillStyle: resolveBlobbySurfacePatchFillStyle(palette, verticalProgress, Math.max(0, Math.cos(centerLongitude)), resolveLowerLobeWave(centerLongitude, morphologyProfile, animationPhase, timeMs)),
|
|
24526
|
+
outlineColor: verticalProgress < 0.58 ? `${palette.highlight}73` : `${palette.shadow}8a`,
|
|
24527
|
+
});
|
|
24528
|
+
}
|
|
24220
24529
|
}
|
|
24221
|
-
|
|
24222
|
-
context.beginPath();
|
|
24223
|
-
context.moveTo(projectedPoints[0].x, projectedPoints[0].y);
|
|
24224
|
-
context.quadraticCurveTo(projectedPoints[1].x, projectedPoints[1].y, projectedPoints[2].x, projectedPoints[2].y);
|
|
24225
|
-
context.strokeStyle = `${palette.ink}b8`;
|
|
24226
|
-
context.lineWidth = Math.max(1.1, size * 0.009);
|
|
24227
|
-
context.lineCap = 'round';
|
|
24228
|
-
context.stroke();
|
|
24530
|
+
return surfacePatches;
|
|
24229
24531
|
}
|
|
24230
24532
|
/**
|
|
24231
|
-
*
|
|
24533
|
+
* Samples one point on the continuous Octopus 3D 2 surface.
|
|
24534
|
+
*
|
|
24535
|
+
* The lower hemisphere widens and falls into soft lobe waves so the octopus stays one connected mesh
|
|
24536
|
+
* instead of switching to separately rendered tentacles.
|
|
24537
|
+
*
|
|
24538
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
24539
|
+
*/
|
|
24540
|
+
function sampleBlobbyOctopusSurfacePoint(options, latitude, longitude) {
|
|
24541
|
+
const { radiusX, radiusY, radiusZ, morphologyProfile, timeMs, animationPhase } = options;
|
|
24542
|
+
const cosineLatitude = Math.max(0, Math.cos(latitude));
|
|
24543
|
+
const verticalProgress = (Math.sin(latitude) + 1) / 2;
|
|
24544
|
+
const upperBlend = Math.pow(1 - verticalProgress, 1.2);
|
|
24545
|
+
const lowerBlend = Math.pow(verticalProgress, 1.42);
|
|
24546
|
+
const lowerLobeWave = resolveLowerLobeWave(longitude, morphologyProfile, animationPhase, timeMs);
|
|
24547
|
+
const skirtEnvelope = Math.pow(cosineLatitude, 0.5) * lowerBlend;
|
|
24548
|
+
const horizontalScale = 1.02 +
|
|
24549
|
+
skirtEnvelope * (0.34 + (morphologyProfile.tentacles.rootSpreadScale - 1) * 0.22 + lowerLobeWave * 0.22) -
|
|
24550
|
+
upperBlend * 0.08;
|
|
24551
|
+
const depthScale = 1.04 +
|
|
24552
|
+
upperBlend * 0.16 +
|
|
24553
|
+
Math.max(0, Math.cos(longitude)) * 0.1 +
|
|
24554
|
+
skirtEnvelope * (0.08 + lowerLobeWave * 0.06) -
|
|
24555
|
+
Math.max(0, -Math.cos(longitude)) * 0.04;
|
|
24556
|
+
const lowerDrop = skirtEnvelope *
|
|
24557
|
+
radiusY *
|
|
24558
|
+
(0.28 + lowerLobeWave * 0.14 + (morphologyProfile.tentacles.flowLengthScale - 1) * 0.12);
|
|
24559
|
+
const swayX = Math.sin(timeMs / 1250 + longitude * 1.8 + animationPhase) * skirtEnvelope * radiusX * 0.05;
|
|
24560
|
+
const swayZ = Math.cos(timeMs / 1480 + longitude * 1.2 - animationPhase * 0.7) * skirtEnvelope * radiusZ * 0.03;
|
|
24561
|
+
return {
|
|
24562
|
+
x: Math.sin(longitude) * cosineLatitude * radiusX * horizontalScale + swayX,
|
|
24563
|
+
y: Math.sin(latitude) * radiusY * (1 + upperBlend * 0.14) -
|
|
24564
|
+
upperBlend * radiusY * 0.1 +
|
|
24565
|
+
lowerDrop +
|
|
24566
|
+
Math.sin(timeMs / 1780 + animationPhase + latitude * 1.4) * skirtEnvelope * radiusY * 0.02,
|
|
24567
|
+
z: Math.cos(longitude) * cosineLatitude * radiusZ * depthScale + swayZ,
|
|
24568
|
+
};
|
|
24569
|
+
}
|
|
24570
|
+
/**
|
|
24571
|
+
* Resolves the soft lower-lobe wave that makes the silhouette read more like a real octopus.
|
|
24232
24572
|
*
|
|
24233
|
-
* @private helper of `
|
|
24573
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
24234
24574
|
*/
|
|
24235
|
-
function
|
|
24236
|
-
|
|
24237
|
-
|
|
24238
|
-
context.lineTo(corners[1].x, corners[1].y);
|
|
24239
|
-
context.lineTo(corners[2].x, corners[2].y);
|
|
24240
|
-
context.lineTo(corners[3].x, corners[3].y);
|
|
24241
|
-
context.closePath();
|
|
24242
|
-
context.fillStyle = fillStyle;
|
|
24243
|
-
context.fill();
|
|
24575
|
+
function resolveLowerLobeWave(longitude, morphologyProfile, animationPhase, timeMs) {
|
|
24576
|
+
const lobeCount = Math.max(4, Math.round((morphologyProfile.body.lobeCount + morphologyProfile.tentacles.count) / 2));
|
|
24577
|
+
return (Math.cos(longitude * lobeCount + animationPhase + timeMs / 1040) + 1) / 2;
|
|
24244
24578
|
}
|
|
24245
24579
|
/**
|
|
24246
|
-
*
|
|
24580
|
+
* Resolves one base fill tone for a surface patch on the single octopus mesh.
|
|
24247
24581
|
*
|
|
24248
|
-
* @private helper of `
|
|
24582
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
24249
24583
|
*/
|
|
24250
|
-
function
|
|
24251
|
-
|
|
24252
|
-
|
|
24253
|
-
.
|
|
24584
|
+
function resolveBlobbySurfacePatchFillStyle(palette, verticalProgress, forwardness, lowerLobeWave) {
|
|
24585
|
+
const tonalProgress = clampNumber$1(verticalProgress + lowerLobeWave * 0.12 - forwardness * 0.07, 0, 1);
|
|
24586
|
+
if (tonalProgress < 0.16) {
|
|
24587
|
+
return palette.highlight;
|
|
24588
|
+
}
|
|
24589
|
+
if (tonalProgress < 0.34) {
|
|
24590
|
+
return palette.secondary;
|
|
24591
|
+
}
|
|
24592
|
+
if (tonalProgress < 0.72) {
|
|
24593
|
+
return forwardness > 0.58 ? palette.secondary : palette.primary;
|
|
24594
|
+
}
|
|
24595
|
+
return `${palette.shadow}f2`;
|
|
24596
|
+
}
|
|
24597
|
+
/**
|
|
24598
|
+
* Draws one projected patch with soft octopus shading.
|
|
24599
|
+
*
|
|
24600
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
24601
|
+
*/
|
|
24602
|
+
function drawBlobbySurfacePatch(context, surfacePatch) {
|
|
24603
|
+
drawProjectedQuad(context, surfacePatch.corners, surfacePatch.fillStyle);
|
|
24604
|
+
if (surfacePatch.lightIntensity > 0) {
|
|
24605
|
+
drawProjectedQuad(context, surfacePatch.corners, `rgba(255, 255, 255, ${0.16 * surfacePatch.lightIntensity})`);
|
|
24606
|
+
}
|
|
24607
|
+
else if (surfacePatch.lightIntensity < 0) {
|
|
24608
|
+
drawProjectedQuad(context, surfacePatch.corners, `rgba(0, 0, 0, ${0.24 * Math.abs(surfacePatch.lightIntensity)})`);
|
|
24609
|
+
}
|
|
24610
|
+
context.save();
|
|
24611
|
+
context.beginPath();
|
|
24612
|
+
context.moveTo(surfacePatch.corners[0].x, surfacePatch.corners[0].y);
|
|
24613
|
+
for (let cornerIndex = 1; cornerIndex < surfacePatch.corners.length; cornerIndex++) {
|
|
24614
|
+
context.lineTo(surfacePatch.corners[cornerIndex].x, surfacePatch.corners[cornerIndex].y);
|
|
24615
|
+
}
|
|
24616
|
+
context.closePath();
|
|
24617
|
+
context.strokeStyle = surfacePatch.outlineColor;
|
|
24618
|
+
context.lineWidth = Math.max(1, getProjectedQuadPerimeter(surfacePatch.corners) * 0.0042);
|
|
24619
|
+
context.lineJoin = 'round';
|
|
24620
|
+
context.stroke();
|
|
24621
|
+
context.restore();
|
|
24254
24622
|
}
|
|
24255
24623
|
|
|
24256
24624
|
/* eslint-disable no-magic-numbers */
|
|
@@ -25022,6 +25390,7 @@ const AVATAR_VISUALS = [
|
|
|
25022
25390
|
octopus2AvatarVisual,
|
|
25023
25391
|
octopus3AvatarVisual,
|
|
25024
25392
|
octopus3dAvatarVisual,
|
|
25393
|
+
octopus3d2AvatarVisual,
|
|
25025
25394
|
asciiOctopusAvatarVisual,
|
|
25026
25395
|
minecraftAvatarVisual,
|
|
25027
25396
|
minecraft2AvatarVisual,
|
|
@@ -30434,11 +30803,11 @@ function buildCandidateEncodings(options) {
|
|
|
30434
30803
|
});
|
|
30435
30804
|
}
|
|
30436
30805
|
/**
|
|
30437
|
-
*
|
|
30806
|
+
* Prepares one attachment for best-effort text decoding.
|
|
30438
30807
|
*
|
|
30439
|
-
* @private
|
|
30808
|
+
* @private function of decodeAttachmentAsText
|
|
30440
30809
|
*/
|
|
30441
|
-
function
|
|
30810
|
+
function createDecodeAttachmentPreparation(input, options) {
|
|
30442
30811
|
var _a;
|
|
30443
30812
|
const maxBytes = Math.max(1, Math.floor((_a = options.maxBytes) !== null && _a !== void 0 ? _a : DEFAULT_ATTACHMENT_TEXT_DECODE_BYTES));
|
|
30444
30813
|
const forceText = options.forceText === true;
|
|
@@ -30452,54 +30821,102 @@ function decodeAttachmentAsText(input, options = {}) {
|
|
|
30452
30821
|
const inspection = inspectBytes(truncatedBytes);
|
|
30453
30822
|
const trustedTextMime = isTrustedTextMimeType(mimeType);
|
|
30454
30823
|
const trustedBinaryMime = isTrustedBinaryMimeType(mimeType);
|
|
30824
|
+
const shouldTreatAsBinary = (trustedBinaryMime || inspection.looksBinary) && !trustedTextMime;
|
|
30455
30825
|
if (isTruncated) {
|
|
30456
30826
|
warnings.push(`Decoded only the first ${maxBytes} bytes of \`${input.filename}\` because the attachment exceeded the text preview limit.`);
|
|
30457
30827
|
}
|
|
30458
|
-
|
|
30459
|
-
|
|
30460
|
-
|
|
30461
|
-
|
|
30462
|
-
|
|
30463
|
-
|
|
30464
|
-
|
|
30465
|
-
|
|
30466
|
-
|
|
30467
|
-
|
|
30468
|
-
|
|
30828
|
+
return {
|
|
30829
|
+
warnings,
|
|
30830
|
+
charset,
|
|
30831
|
+
bom,
|
|
30832
|
+
inspection,
|
|
30833
|
+
truncatedBytes,
|
|
30834
|
+
isTruncated,
|
|
30835
|
+
forceText,
|
|
30836
|
+
shouldTreatAsBinary,
|
|
30837
|
+
};
|
|
30838
|
+
}
|
|
30839
|
+
/**
|
|
30840
|
+
* Returns an early result when the attachment should stay classified as binary.
|
|
30841
|
+
*
|
|
30842
|
+
* @private function of decodeAttachmentAsText
|
|
30843
|
+
*/
|
|
30844
|
+
function createBinaryDecodeResult(preparation) {
|
|
30845
|
+
if (!preparation.shouldTreatAsBinary) {
|
|
30846
|
+
return null;
|
|
30469
30847
|
}
|
|
30470
|
-
if (
|
|
30471
|
-
warnings.push('File content looks binary, but text decoding was forced with `forceText`.');
|
|
30848
|
+
if (preparation.forceText) {
|
|
30849
|
+
preparation.warnings.push('File content looks binary, but text decoding was forced with `forceText`.');
|
|
30850
|
+
return null;
|
|
30472
30851
|
}
|
|
30473
|
-
|
|
30474
|
-
|
|
30852
|
+
preparation.warnings.push('File content looks binary, so text decoding was skipped.');
|
|
30853
|
+
return {
|
|
30854
|
+
text: '',
|
|
30855
|
+
encodingUsed: 'binary',
|
|
30856
|
+
confidence: 1,
|
|
30857
|
+
warnings: preparation.warnings,
|
|
30858
|
+
wasBinary: true,
|
|
30859
|
+
isTruncated: preparation.isTruncated,
|
|
30860
|
+
};
|
|
30861
|
+
}
|
|
30862
|
+
/**
|
|
30863
|
+
* Warns when the declared charset cannot be used by the runtime decoder.
|
|
30864
|
+
*
|
|
30865
|
+
* @private function of decodeAttachmentAsText
|
|
30866
|
+
*/
|
|
30867
|
+
function addUnsupportedCharsetWarning(preparation) {
|
|
30868
|
+
if (preparation.charset && !isSupportedEncoding(preparation.charset)) {
|
|
30869
|
+
preparation.warnings.push(`Ignored unsupported declared charset \`${preparation.charset}\` and used best-effort detection instead.`);
|
|
30475
30870
|
}
|
|
30476
|
-
|
|
30477
|
-
|
|
30478
|
-
|
|
30479
|
-
|
|
30480
|
-
|
|
30481
|
-
|
|
30482
|
-
|
|
30483
|
-
|
|
30871
|
+
}
|
|
30872
|
+
/**
|
|
30873
|
+
* Returns the byte slice that should actually be decoded as text.
|
|
30874
|
+
*
|
|
30875
|
+
* @private function of decodeAttachmentAsText
|
|
30876
|
+
*/
|
|
30877
|
+
function getBytesToDecode(preparation) {
|
|
30878
|
+
return preparation.bom ? preparation.truncatedBytes.subarray(preparation.bom.offset) : preparation.truncatedBytes;
|
|
30879
|
+
}
|
|
30880
|
+
/**
|
|
30881
|
+
* Decodes all candidate encodings and sorts the successful results by score.
|
|
30882
|
+
*
|
|
30883
|
+
* @private function of decodeAttachmentAsText
|
|
30884
|
+
*/
|
|
30885
|
+
function decodeAttachmentCandidates(preparation) {
|
|
30886
|
+
return buildCandidateEncodings({
|
|
30887
|
+
charset: preparation.charset && isSupportedEncoding(preparation.charset) ? preparation.charset : null,
|
|
30888
|
+
bom: preparation.bom,
|
|
30889
|
+
inspection: preparation.inspection,
|
|
30890
|
+
})
|
|
30484
30891
|
.map(({ encoding, source }) => {
|
|
30485
|
-
const decoded = decodeWithEncoding(
|
|
30892
|
+
const decoded = decodeWithEncoding(getBytesToDecode(preparation), encoding);
|
|
30486
30893
|
return decoded ? { ...decoded, source } : null;
|
|
30487
30894
|
})
|
|
30488
30895
|
.filter((candidate) => candidate !== null)
|
|
30489
30896
|
.sort((left, right) => left.score - right.score);
|
|
30490
|
-
|
|
30491
|
-
|
|
30492
|
-
|
|
30493
|
-
|
|
30494
|
-
|
|
30495
|
-
|
|
30496
|
-
|
|
30497
|
-
|
|
30498
|
-
|
|
30499
|
-
|
|
30500
|
-
|
|
30501
|
-
|
|
30502
|
-
|
|
30897
|
+
}
|
|
30898
|
+
/**
|
|
30899
|
+
* Returns the fallback result used when no text decoder could be applied.
|
|
30900
|
+
*
|
|
30901
|
+
* @private function of decodeAttachmentAsText
|
|
30902
|
+
*/
|
|
30903
|
+
function createNoDecoderAvailableResult(preparation) {
|
|
30904
|
+
preparation.warnings.push('No supported text decoder was available.');
|
|
30905
|
+
return {
|
|
30906
|
+
text: '',
|
|
30907
|
+
encodingUsed: 'binary',
|
|
30908
|
+
confidence: 0,
|
|
30909
|
+
warnings: preparation.warnings,
|
|
30910
|
+
wasBinary: true,
|
|
30911
|
+
isTruncated: preparation.isTruncated,
|
|
30912
|
+
};
|
|
30913
|
+
}
|
|
30914
|
+
/**
|
|
30915
|
+
* Estimates confidence for the winning decoded text candidate.
|
|
30916
|
+
*
|
|
30917
|
+
* @private function of decodeAttachmentAsText
|
|
30918
|
+
*/
|
|
30919
|
+
function computeDecodeConfidence(bestCandidate, secondBestCandidate, preparation) {
|
|
30503
30920
|
const baseConfidence = bestCandidate.source === 'bom'
|
|
30504
30921
|
? 1
|
|
30505
30922
|
: bestCandidate.source === 'charset'
|
|
@@ -30512,27 +30929,62 @@ function decodeAttachmentAsText(input, options = {}) {
|
|
|
30512
30929
|
? 0.82
|
|
30513
30930
|
: 0.62;
|
|
30514
30931
|
const scoreMargin = secondBestCandidate ? Math.max(0, secondBestCandidate.score - bestCandidate.score) : 0.2;
|
|
30515
|
-
|
|
30932
|
+
return Math.max(0.2, Math.min(preparation.shouldTreatAsBinary && preparation.forceText ? 0.45 : 1, baseConfidence + Math.min(0.18, scoreMargin / 2)));
|
|
30933
|
+
}
|
|
30934
|
+
/**
|
|
30935
|
+
* Appends user-facing warnings derived from the chosen decoded text candidate.
|
|
30936
|
+
*
|
|
30937
|
+
* @private function of decodeAttachmentAsText
|
|
30938
|
+
*/
|
|
30939
|
+
function addDecodeWarnings(bestCandidate, confidence, preparation) {
|
|
30516
30940
|
if (bestCandidate.source === 'heuristic' && bestCandidate.encoding !== 'utf-8') {
|
|
30517
|
-
warnings.push(`Encoding was guessed as \`${bestCandidate.encoding}\`.`);
|
|
30941
|
+
preparation.warnings.push(`Encoding was guessed as \`${bestCandidate.encoding}\`.`);
|
|
30518
30942
|
}
|
|
30519
30943
|
if (bestCandidate.source === 'heuristic' &&
|
|
30520
30944
|
bestCandidate.encoding === 'utf-8' &&
|
|
30521
30945
|
bestCandidate.replacementCount > 0) {
|
|
30522
|
-
warnings.push('UTF-8 decoding produced replacement characters, so the extracted text may contain errors.');
|
|
30946
|
+
preparation.warnings.push('UTF-8 decoding produced replacement characters, so the extracted text may contain errors.');
|
|
30523
30947
|
}
|
|
30524
30948
|
if (confidence < 0.6) {
|
|
30525
|
-
warnings.push('Decoding confidence is low, so the extracted text may contain errors.');
|
|
30949
|
+
preparation.warnings.push('Decoding confidence is low, so the extracted text may contain errors.');
|
|
30526
30950
|
}
|
|
30951
|
+
}
|
|
30952
|
+
/**
|
|
30953
|
+
* Creates the final decoded-text result from the chosen candidate and accumulated metadata.
|
|
30954
|
+
*
|
|
30955
|
+
* @private function of decodeAttachmentAsText
|
|
30956
|
+
*/
|
|
30957
|
+
function createDecodedTextResult(bestCandidate, confidence, preparation) {
|
|
30527
30958
|
return {
|
|
30528
|
-
text: isTruncated ? appendTruncatedMarker(bestCandidate.text) : bestCandidate.text,
|
|
30959
|
+
text: preparation.isTruncated ? appendTruncatedMarker(bestCandidate.text) : bestCandidate.text,
|
|
30529
30960
|
encodingUsed: bestCandidate.encoding,
|
|
30530
30961
|
confidence,
|
|
30531
|
-
warnings,
|
|
30962
|
+
warnings: preparation.warnings,
|
|
30532
30963
|
wasBinary: false,
|
|
30533
|
-
isTruncated,
|
|
30964
|
+
isTruncated: preparation.isTruncated,
|
|
30534
30965
|
};
|
|
30535
30966
|
}
|
|
30967
|
+
/**
|
|
30968
|
+
* Best-effort decoder for uploaded or remote file bytes whose extension or encoding may be unknown.
|
|
30969
|
+
*
|
|
30970
|
+
* @private internal utility for shared text decoding
|
|
30971
|
+
*/
|
|
30972
|
+
function decodeAttachmentAsText(input, options = {}) {
|
|
30973
|
+
const preparation = createDecodeAttachmentPreparation(input, options);
|
|
30974
|
+
const binaryResult = createBinaryDecodeResult(preparation);
|
|
30975
|
+
if (binaryResult) {
|
|
30976
|
+
return binaryResult;
|
|
30977
|
+
}
|
|
30978
|
+
addUnsupportedCharsetWarning(preparation);
|
|
30979
|
+
const decodedCandidates = decodeAttachmentCandidates(preparation);
|
|
30980
|
+
const bestCandidate = decodedCandidates[0];
|
|
30981
|
+
if (!bestCandidate) {
|
|
30982
|
+
return createNoDecoderAvailableResult(preparation);
|
|
30983
|
+
}
|
|
30984
|
+
const confidence = computeDecodeConfidence(bestCandidate, decodedCandidates[1], preparation);
|
|
30985
|
+
addDecodeWarnings(bestCandidate, confidence, preparation);
|
|
30986
|
+
return createDecodedTextResult(bestCandidate, confidence, preparation);
|
|
30987
|
+
}
|
|
30536
30988
|
|
|
30537
30989
|
/**
|
|
30538
30990
|
* Base GitHub API URL.
|
|
@@ -39240,10 +39692,7 @@ function createAvailableProviderMessage(llmToolStatus, index, env) {
|
|
|
39240
39692
|
* @private internal function of `$registeredLlmToolsMessage`
|
|
39241
39693
|
*/
|
|
39242
39694
|
function createProviderStatusMessages(llmToolStatus, env) {
|
|
39243
|
-
return [
|
|
39244
|
-
createInstallationStatusMessage(llmToolStatus),
|
|
39245
|
-
createConfigurationStatusMessage(llmToolStatus, env),
|
|
39246
|
-
];
|
|
39695
|
+
return [createInstallationStatusMessage(llmToolStatus), createConfigurationStatusMessage(llmToolStatus, env)];
|
|
39247
39696
|
}
|
|
39248
39697
|
/**
|
|
39249
39698
|
* Creates the installation-status sentence for one provider.
|