@promptbook/components 0.112.0-48 → 0.112.0-50

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 (45) hide show
  1. package/esm/index.es.js +798 -195
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/src/avatars/avatarAnimationScheduler.d.ts +16 -0
  4. package/esm/src/avatars/avatarPointerTracking.d.ts +16 -0
  5. package/esm/src/avatars/avatarVisibilityTracking.d.ts +17 -0
  6. package/esm/src/avatars/renderAvatarVisual.d.ts +29 -1
  7. package/esm/src/avatars/visuals/octopus3AvatarVisual.d.ts +72 -0
  8. package/esm/src/avatars/visuals/octopus3AvatarVisual.test.d.ts +1 -0
  9. package/esm/src/avatars/visuals/octopusAvatarVisualShared.d.ts +16 -0
  10. package/esm/src/book-components/BookEditor/BookEditor.d.ts +9 -0
  11. package/esm/src/book-components/BookEditor/useBookEditorMonacoLanguage.d.ts +10 -2
  12. package/esm/src/book-components/BookEditor/useBookEditorMonacoStyles.d.ts +2 -1
  13. package/esm/src/book-components/Chat/Chat/ChatMessageRichContent.d.ts +4 -0
  14. package/esm/src/book-components/Chat/Chat/ChatProps.d.ts +12 -3
  15. package/esm/src/book-components/Chat/Chat/ChatToolCallModal.d.ts +1 -0
  16. package/esm/src/book-components/Chat/Chat/ChatToolCallModalContent.d.ts +2 -1
  17. package/esm/src/book-components/Chat/Chat/renderAdvancedToolCallDetails.d.ts +4 -0
  18. package/esm/src/book-components/Chat/CodeBlock/CodeBlock.d.ts +2 -1
  19. package/esm/src/speech-recognition/OpenAiSpeechRecognition.d.ts +24 -2
  20. package/esm/src/speech-recognition/OpenAiSpeechRecognition.test.d.ts +1 -0
  21. package/esm/src/types/SpeechRecognition.d.ts +4 -0
  22. package/esm/src/version.d.ts +1 -1
  23. package/package.json +1 -1
  24. package/umd/index.umd.js +798 -195
  25. package/umd/index.umd.js.map +1 -1
  26. package/umd/src/avatars/avatarAnimationScheduler.d.ts +16 -0
  27. package/umd/src/avatars/avatarPointerTracking.d.ts +16 -0
  28. package/umd/src/avatars/avatarVisibilityTracking.d.ts +17 -0
  29. package/umd/src/avatars/renderAvatarVisual.d.ts +29 -1
  30. package/umd/src/avatars/visuals/octopus3AvatarVisual.d.ts +72 -0
  31. package/umd/src/avatars/visuals/octopus3AvatarVisual.test.d.ts +1 -0
  32. package/umd/src/avatars/visuals/octopusAvatarVisualShared.d.ts +16 -0
  33. package/umd/src/book-components/BookEditor/BookEditor.d.ts +9 -0
  34. package/umd/src/book-components/BookEditor/useBookEditorMonacoLanguage.d.ts +10 -2
  35. package/umd/src/book-components/BookEditor/useBookEditorMonacoStyles.d.ts +2 -1
  36. package/umd/src/book-components/Chat/Chat/ChatMessageRichContent.d.ts +4 -0
  37. package/umd/src/book-components/Chat/Chat/ChatProps.d.ts +12 -3
  38. package/umd/src/book-components/Chat/Chat/ChatToolCallModal.d.ts +1 -0
  39. package/umd/src/book-components/Chat/Chat/ChatToolCallModalContent.d.ts +2 -1
  40. package/umd/src/book-components/Chat/Chat/renderAdvancedToolCallDetails.d.ts +4 -0
  41. package/umd/src/book-components/Chat/CodeBlock/CodeBlock.d.ts +2 -1
  42. package/umd/src/speech-recognition/OpenAiSpeechRecognition.d.ts +24 -2
  43. package/umd/src/speech-recognition/OpenAiSpeechRecognition.test.d.ts +1 -0
  44. package/umd/src/types/SpeechRecognition.d.ts +4 -0
  45. package/umd/src/version.d.ts +1 -1
package/umd/index.umd.js CHANGED
@@ -30,7 +30,7 @@
30
30
  * @generated
31
31
  * @see https://github.com/webgptorg/promptbook
32
32
  */
33
- const PROMPTBOOK_ENGINE_VERSION = '0.112.0-48';
33
+ const PROMPTBOOK_ENGINE_VERSION = '0.112.0-50';
34
34
  /**
35
35
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
36
36
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -1509,10 +1509,22 @@
1509
1509
  */
1510
1510
  function prepareAvatarCanvas(canvas, context, size, devicePixelRatio) {
1511
1511
  const normalizedDevicePixelRatio = Math.max(1, Math.round(devicePixelRatio * 100) / 100);
1512
- canvas.width = Math.round(size * normalizedDevicePixelRatio);
1513
- canvas.height = Math.round(size * normalizedDevicePixelRatio);
1514
- canvas.style.width = `${size}px`;
1515
- canvas.style.height = `${size}px`;
1512
+ const nextCanvasWidth = Math.round(size * normalizedDevicePixelRatio);
1513
+ const nextCanvasHeight = Math.round(size * normalizedDevicePixelRatio);
1514
+ const nextCanvasStyleWidth = `${size}px`;
1515
+ const nextCanvasStyleHeight = `${size}px`;
1516
+ if (canvas.width !== nextCanvasWidth) {
1517
+ canvas.width = nextCanvasWidth;
1518
+ }
1519
+ if (canvas.height !== nextCanvasHeight) {
1520
+ canvas.height = nextCanvasHeight;
1521
+ }
1522
+ if (canvas.style.width !== nextCanvasStyleWidth) {
1523
+ canvas.style.width = nextCanvasStyleWidth;
1524
+ }
1525
+ if (canvas.style.height !== nextCanvasStyleHeight) {
1526
+ canvas.style.height = nextCanvasStyleHeight;
1527
+ }
1516
1528
  context.setTransform(normalizedDevicePixelRatio, 0, 0, normalizedDevicePixelRatio, 0, 0);
1517
1529
  context.clearRect(0, 0, size, size);
1518
1530
  }
@@ -18706,8 +18718,8 @@
18706
18718
  // <- [🐱‍🚀] Buttons into genesis book
18707
18719
  // <- TODO: [🐱‍🚀] generateBookBoilerplate and deprecate `DEFAULT_BOOK`
18708
18720
 
18709
- 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_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_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_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_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_uploadPanelHeaderMeta__Xw0uI{color:#6b7280;font-size:.75rem}.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_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_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_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_uploadRowError__eEHWw{color:#b91c1c;font-size:.7rem}@keyframes BookEditor-module_fadeOut__q8JnR{0%{opacity:0}10%{opacity:1}70%{opacity:1}to{opacity:0}}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkJvb2tFZGl0b3IubW9kdWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxxQ0FFSSxVQUNKLENBRUEsOENBS0kscUJBQXNCLENBSHRCLFdBQVksQ0FFWixtQkFBb0IsQ0FEcEIsaUJBQWtCLENBRmxCLFVBS0osQ0FFQSxpRkFFSSxnQ0FBcUMsQ0FDckMsaUNBRUosQ0FFQSxvQ0FDSSwwQkFDSixDQUVBLDRDQUtJLHFCQUF1QixDQUR2QixxQ0FBMEMsQ0FGMUMsa0JBQW1CLENBSW5CLHNDQUEyQyxDQUwzQyxlQUFnQixDQUVoQixnQkFBaUIsQ0FJakIscUNBQ0osQ0FDQSxnRkFFSSxnQkFFSixDQUVBLGtEQUNJLHVFQUNKLENBVUEsNEZBQ0ksZUFDSixDQUVBLHNDQVNJLGtCQUFtQixDQUhuQiwrQkFBb0MsQ0FEcEMsUUFBUyxDQUVULFVBQVksQ0FDWixZQUFhLENBR2IsZ0JBQWlCLENBRGpCLHNCQUF1QixDQVB2QixNQUFPLENBVVAsbUJBQW9CLENBWnBCLGlCQUFrQixDQUdsQixPQUFRLENBRlIsS0FBTSxDQVVOLFdBRUosQ0FRQSw4Q0FDSSxpQkFBa0IsQ0FFbEIsVUFBVyxDQURYLFFBQVMsQ0FFVCxXQUNKLENBRUEscUNBV0ksV0FBWSxDQUZaLGVBQWdCLENBSmhCLFFBQVMsQ0FPVCxlQUFnQixDQUxoQixXQUFZLENBSlosTUFBTyxDQU9QLGdCQUFpQixDQVRqQixjQUFlLENBR2YsT0FBUSxDQUZSLEtBQU0sQ0FJTixVQUFXLENBRVgsWUFLSixDQUVBLGlDQU9JLGtCQUFtQixDQU5uQixxQkFBc0IsQ0FDdEIsd0JBQXlCLENBQ3pCLHFCQUF1QixDQU92QixzQ0FBMkMsQ0FEM0MsYUFBYyxDQUpkLGNBQWUsQ0FDZixtQkFBb0IsQ0FFcEIsU0FBVyxDQUpYLGtCQUFvQixDQU9wQiw4QkFDSixDQUVBLHVDQUNJLHdCQUF5QixDQUN6QixvQkFBcUIsQ0FDckIsaUVBQ0osQ0FFQSw0Q0FhSSxrQkFBbUIsQ0FFbkIsc0RBQThCLENBVjlCLCtCQUFvQyxDQUdwQyxtQkFBcUIsQ0FGckIsVUFBWSxDQU1aLFlBQWEsQ0FIYixpQkFBa0IsQ0FLbEIsU0FBVyxDQVhYLFFBQVMsQ0FJVCxpQkFBa0IsQ0FJbEIsbUJBQW9CLENBVnBCLGlCQUFrQixDQUNsQixPQUFRLENBRVIsOEJBQWdDLENBTWhDLFlBTUosQ0FFQSxzQ0FNSSw4QkFBcUMsQ0FDckMscUNBQTBDLENBQzFDLGtCQUFtQixDQUxuQixXQUFZLENBTVoseUNBQThDLENBRTlDLFlBQWEsQ0FDYixxQkFBc0IsQ0FDdEIsUUFBUyxDQVJULDJCQUE0QixDQUs1QixZQUFhLENBVGIsaUJBQWtCLENBQ2xCLFVBQVcsQ0FFWCxXQUFZLENBVVosV0FDSixDQUVBLDRDQUVJLGtCQUFtQixDQURuQixZQUFhLENBR2IsUUFBUyxDQURULDZCQUVKLENBRUEsMkNBR0ksYUFBYyxDQURkLGdCQUFrQixDQURsQixlQUdKLENBRUEsZ0RBRUksYUFBYyxDQURkLGdCQUVKLENBRUEsNkNBS0ksYUFBYyxDQUpkLFlBQWEsQ0FHYixnQkFBa0IsQ0FEbEIsWUFBYSxDQURiLDZCQUlKLENBRUEsaURBRUksa0JBQW1CLENBQ25CLG1CQUFvQixDQUZwQixVQUFXLENBR1gsZUFDSixDQUVBLGtEQUVJLGlEQUFvRCxDQURwRCxXQUFZLENBRVoseUJBQ0osQ0FFQSwwQ0FDSSxZQUFhLENBQ2IscUJBQXNCLENBQ3RCLE9BQVEsQ0FDUixnQkFBaUIsQ0FDakIsZUFBZ0IsQ0FDaEIsaUJBQ0osQ0FFQSxvQ0FPSSxlQUFnQixDQU5oQix3QkFBeUIsQ0FDekIsa0JBQW1CLENBRW5CLFlBQWEsQ0FDYixxQkFBc0IsQ0FDdEIsT0FBUSxDQUhSLFdBS0osQ0FFQSwwQ0FFSSxrQkFBbUIsQ0FEbkIsWUFBYSxDQUdiLE9BQVEsQ0FEUiw2QkFFSixDQUVBLHdDQUdJLGFBQWMsQ0FGZCxlQUFpQixDQUNqQixlQUFnQixDQUVoQixlQUFnQixDQUNoQixzQkFBdUIsQ0FDdkIsa0JBQ0osQ0FFQSwwQ0FFSSxhQUFjLENBRGQsZUFFSixDQUVBLHdDQUlJLGFBQWMsQ0FIZCxZQUFhLENBRWIsZUFBaUIsQ0FEakIsNkJBR0osQ0FFQSwrQ0FFSSxrQkFBbUIsQ0FDbkIsbUJBQW9CLENBRnBCLFVBQVcsQ0FHWCxlQUNKLENBRUEsZ0RBRUksa0JBQW1CLENBRG5CLFdBQVksQ0FFWix5QkFDSixDQUVBLDJDQUNJLFlBQWEsQ0FDYixPQUNKLENBRUEsNkNBRUksa0JBQW1CLENBRG5CLHdCQUF5QixDQUt6QixpQkFBa0IsQ0FIbEIsYUFBYyxDQUlkLGNBQWUsQ0FIZixlQUFpQixDQUNqQixlQUFnQixDQUdoQiwrQkFDSixDQUVBLG1EQUNJLGtCQUFtQixDQUNuQixvQkFDSixDQUVBLHlDQUVJLGFBQWMsQ0FEZCxlQUVKLENBRUEsNENBQ0ksR0FDSSxTQUNKLENBQ0EsSUFDSSxTQUNKLENBQ0EsSUFDSSxTQUNKLENBQ0EsR0FDSSxTQUNKLENBQ0oiLCJmaWxlIjoiQm9va0VkaXRvci5tb2R1bGUuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLkJvb2tFZGl0b3Ige1xuICAgIC8qIGhlaWdodDogNDUwcHg7ICovXG4gICAgd2lkdGg6IDEwMCU7XG59XG5cbi5ib29rRWRpdG9yQ29udGFpbmVyIHtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIHBhZGRpbmc6IDEwcHggMjVweCAwO1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG59XG5cbi5ib29rRWRpdG9yQ29udGFpbmVyLmlzVmVyYm9zZSB7XG4gICAgLyoqL1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC4wNSk7XG4gICAgb3V0bGluZTogMXB4IGRvdHRlZCByZ2JhKDAsIDAsIDAsIDAuNSk7XG4gICAgLyoqL1xufVxuXG4uaXNWZXJib3NlIHtcbiAgICBvdXRsaW5lOiAycHggZG90dGVkIHJnYigyNTUgMTE3IDM4KTtcbn1cblxuLmJvb2tFZGl0b3JXcmFwcGVyIHtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIGJvcmRlci1yYWRpdXM6IDFyZW07XG4gICAgcGFkZGluZy10b3A6IDEwcHg7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyMDksIDIxMywgMjE5LCAwLjgpO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHdoaXRlO1xuICAgIGJveC1zaGFkb3c6IDAgMXB4IDJweCAwIHJnYmEoMCwgMCwgMCwgMC4wNSk7XG4gICAgdHJhbnNpdGlvbjogYm94LXNoYWRvdyAwLjJzIGVhc2UtaW4tb3V0O1xufVxuLmlzVmVyYm9zZSAuYm9va0VkaXRvcldyYXBwZXIge1xuICAgIC8qKi9cbiAgICBvdmVyZmxvdzogdmlzaWJsZTtcbiAgICAvKiovXG59XG5cbi5ib29rRWRpdG9yV3JhcHBlcjpob3ZlciB7XG4gICAgYm94LXNoYWRvdzogMCA0cHggNnB4IC0xcHggcmdiYSgwLCAwLCAwLCAwLjEpLCAwIDJweCA0cHggLTFweCByZ2JhKDAsIDAsIDAsIDAuMDYpO1xufVxuXG4uYm9va0VkaXRvcldyYXBwZXI6Zm9jdXMtd2l0aGluIHtcbiAgICAvKlxuICAgIG91dGxpbmU6IDJweCBzb2xpZCB0cmFuc3BhcmVudDtcbiAgICBvdXRsaW5lLW9mZnNldDogMnB4O1xuICAgIGJveC1zaGFkb3c6IDAgMCAwIDNweCByZ2JhKDk5LCAxMDIsIDI0MSwgMC40KTtcbiAgICAqL1xufVxuXG4uYm9va0VkaXRvcldyYXBwZXIuaXNCb3JkZXJSYWRpdXNEaXNhYmxlZCB7XG4gICAgYm9yZGVyLXJhZGl1czogMDtcbn1cblxuLmRyb3BPdmVybGF5IHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdG9wOiAwO1xuICAgIGxlZnQ6IDA7XG4gICAgcmlnaHQ6IDA7XG4gICAgYm90dG9tOiAwO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC41KTtcbiAgICBjb2xvcjogd2hpdGU7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIGZvbnQtc2l6ZTogMS41cmVtO1xuICAgIHotaW5kZXg6IDEwMDtcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cblxuLypcbi5ib29rRWRpdG9yQ29udGFpbmVyIDpnbG9iYWwoLnZpZXctbGluZSkge1xuICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjZWVlOyAvKiA8LSBOb3RlOiBgUFJPTVBUQk9PS19TWU5UQVhfQ09MT1JTLkxJTkVgICogL1xufVxuKi9cblxuLmJvb2tFZGl0b3JBY3Rpb25iYXIge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDEwcHg7XG4gICAgcmlnaHQ6IDU1cHg7XG4gICAgei1pbmRleDogMTAwO1xufVxuXG4uZnVsbHNjcmVlbiB7XG4gICAgcG9zaXRpb246IGZpeGVkO1xuICAgIHRvcDogMDtcbiAgICBsZWZ0OiAwO1xuICAgIHJpZ2h0OiAwO1xuICAgIGJvdHRvbTogMDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgei1pbmRleDogOTk5OTtcbiAgICBib3JkZXItcmFkaXVzOiAwO1xuICAgIHBhZGRpbmctdG9wOiA1MHB4O1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBib3gtc2hhZG93OiBub25lO1xufVxuXG4uYnV0dG9uIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xuICAgIGJvcmRlcjogMXB4IHNvbGlkICNkMWQ1ZGI7XG4gICAgYm9yZGVyLXJhZGl1czogMC4zNzVyZW07XG4gICAgcGFkZGluZzogMC41cmVtIDFyZW07XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgZ2FwOiAwLjVyZW07XG4gICAgY29sb3I6ICMzNzQxNTE7XG4gICAgYm94LXNoYWRvdzogMCAxcHggMnB4IDAgcmdiYSgwLCAwLCAwLCAwLjA1KTtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4ycyBlYXNlLWluLW91dDtcbn1cblxuLmJ1dHRvbjpob3ZlciB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2Y5ZmFmYjtcbiAgICBib3JkZXItY29sb3I6ICNiN2JjY2U7XG4gICAgYm94LXNoYWRvdzogMCAxcHggM3B4IDAgcmdiYSgwLCAwLCAwLCAwLjEpLCAwIDFweCAycHggMCByZ2JhKDAsIDAsIDAsIDAuMDYpO1xufVxuXG4uc2F2ZWROb3RpZmljYXRpb24ge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDUwJTtcbiAgICBsZWZ0OiA1MCU7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjcpO1xuICAgIGNvbG9yOiB3aGl0ZTtcbiAgICBwYWRkaW5nOiAxcmVtIDJyZW07XG4gICAgYm9yZGVyLXJhZGl1czogMC41cmVtO1xuICAgIGZvbnQtc2l6ZTogMS4yNXJlbTtcbiAgICB6LWluZGV4OiAxMDAwO1xuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBnYXA6IDAuNXJlbTtcbiAgICBhbmltYXRpb246IGZhZGVPdXQgMnMgZm9yd2FyZHM7XG59XG5cbi51cGxvYWRQYW5lbCB7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHJpZ2h0OiAyMHB4O1xuICAgIGJvdHRvbTogMjBweDtcbiAgICB3aWR0aDogNDIwcHg7XG4gICAgbWF4LXdpZHRoOiBjYWxjKDEwMCUgLSA0MHB4KTtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuOTgpO1xuICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMjA5LCAyMTMsIDIxOSwgMC45KTtcbiAgICBib3JkZXItcmFkaXVzOiAxMnB4O1xuICAgIGJveC1zaGFkb3c6IDAgMTJweCAzMHB4IHJnYmEoMTUsIDIzLCA0MiwgMC4xNSk7XG4gICAgcGFkZGluZzogMTJweDtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgZ2FwOiAxMHB4O1xuICAgIHotaW5kZXg6IDIyMDtcbn1cblxuLnVwbG9hZFBhbmVsSGVhZGVyIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgIGdhcDogMTJweDtcbn1cblxuLnVwbG9hZFBhbmVsVGl0bGUge1xuICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgZm9udC1zaXplOiAwLjk1cmVtO1xuICAgIGNvbG9yOiAjMTExODI3O1xufVxuXG4udXBsb2FkUGFuZWxIZWFkZXJNZXRhIHtcbiAgICBmb250LXNpemU6IDAuNzVyZW07XG4gICAgY29sb3I6ICM2YjcyODA7XG59XG5cbi51cGxvYWRQYW5lbFN1bW1hcnkge1xuICAgIGRpc3BsYXk6IGdyaWQ7XG4gICAgZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zOiAxZnIgMWZyO1xuICAgIGdhcDogNHB4IDEycHg7XG4gICAgZm9udC1zaXplOiAwLjc1cmVtO1xuICAgIGNvbG9yOiAjNmI3MjgwO1xufVxuXG4udXBsb2FkUGFuZWxQcm9ncmVzc0JhciB7XG4gICAgaGVpZ2h0OiA2cHg7XG4gICAgYmFja2dyb3VuZDogI2U1ZTdlYjtcbiAgICBib3JkZXItcmFkaXVzOiA5OTlweDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xufVxuXG4udXBsb2FkUGFuZWxQcm9ncmVzc0ZpbGwge1xuICAgIGhlaWdodDogMTAwJTtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoOTBkZWcsICMyNTYzZWIsICMxMGI5ODEpO1xuICAgIHRyYW5zaXRpb246IHdpZHRoIDAuMnMgZWFzZTtcbn1cblxuLnVwbG9hZFBhbmVsTGlzdCB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgIGdhcDogOHB4O1xuICAgIG1heC1oZWlnaHQ6IDIyMHB4O1xuICAgIG92ZXJmbG93LXk6IGF1dG87XG4gICAgcGFkZGluZy1yaWdodDogNHB4O1xufVxuXG4udXBsb2FkUm93IHtcbiAgICBib3JkZXI6IDFweCBzb2xpZCAjZTVlN2ViO1xuICAgIGJvcmRlci1yYWRpdXM6IDEwcHg7XG4gICAgcGFkZGluZzogOHB4O1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICBnYXA6IDZweDtcbiAgICBiYWNrZ3JvdW5kOiAjZmZmO1xufVxuXG4udXBsb2FkUm93SGVhZGVyIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgIGdhcDogOHB4O1xufVxuXG4udXBsb2FkUm93TmFtZSB7XG4gICAgZm9udC1zaXplOiAwLjhyZW07XG4gICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICBjb2xvcjogIzExMTgyNztcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG59XG5cbi51cGxvYWRSb3dTdGF0dXMge1xuICAgIGZvbnQtc2l6ZTogMC43cmVtO1xuICAgIGNvbG9yOiAjNmI3MjgwO1xufVxuXG4udXBsb2FkUm93TWV0YSB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gICAgZm9udC1zaXplOiAwLjdyZW07XG4gICAgY29sb3I6ICM2YjcyODA7XG59XG5cbi51cGxvYWRSb3dQcm9ncmVzc0JhciB7XG4gICAgaGVpZ2h0OiA0cHg7XG4gICAgYmFja2dyb3VuZDogI2U1ZTdlYjtcbiAgICBib3JkZXItcmFkaXVzOiA5OTlweDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xufVxuXG4udXBsb2FkUm93UHJvZ3Jlc3NGaWxsIHtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgYmFja2dyb3VuZDogIzNiODJmNjtcbiAgICB0cmFuc2l0aW9uOiB3aWR0aCAwLjJzIGVhc2U7XG59XG5cbi51cGxvYWRSb3dBY3Rpb25zIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGdhcDogNnB4O1xufVxuXG4udXBsb2FkQWN0aW9uQnV0dG9uIHtcbiAgICBib3JkZXI6IDFweCBzb2xpZCAjZDFkNWRiO1xuICAgIGJhY2tncm91bmQ6ICNmOWZhZmI7XG4gICAgY29sb3I6ICMzNzQxNTE7XG4gICAgZm9udC1zaXplOiAwLjdyZW07XG4gICAgcGFkZGluZzogMnB4IDhweDtcbiAgICBib3JkZXItcmFkaXVzOiA2cHg7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIHRyYW5zaXRpb246IGFsbCAwLjE1cyBlYXNlLWluLW91dDtcbn1cblxuLnVwbG9hZEFjdGlvbkJ1dHRvbjpob3ZlciB7XG4gICAgYmFja2dyb3VuZDogI2VlZjJmNztcbiAgICBib3JkZXItY29sb3I6ICNjYmQ1ZjU7XG59XG5cbi51cGxvYWRSb3dFcnJvciB7XG4gICAgZm9udC1zaXplOiAwLjdyZW07XG4gICAgY29sb3I6ICNiOTFjMWM7XG59XG5cbkBrZXlmcmFtZXMgZmFkZU91dCB7XG4gICAgMCUge1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgIH1cbiAgICAxMCUge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbiAgICA3MCUge1xuICAgICAgICBvcGFjaXR5OiAxO1xuICAgIH1cbiAgICAxMDAlIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICB9XG59XG4iXX0= */";
18710
- 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","uploadPanelProgressBar":"BookEditor-module_uploadPanelProgressBar__a6pjf","uploadPanelProgressFill":"BookEditor-module_uploadPanelProgressFill__l-TKR","uploadPanelList":"BookEditor-module_uploadPanelList__VxEd5","uploadRow":"BookEditor-module_uploadRow__QiSFg","uploadRowHeader":"BookEditor-module_uploadRowHeader__po0j5","uploadRowName":"BookEditor-module_uploadRowName__doQRO","uploadRowStatus":"BookEditor-module_uploadRowStatus__jsUb-","uploadRowMeta":"BookEditor-module_uploadRowMeta__1lz9h","uploadRowProgressBar":"BookEditor-module_uploadRowProgressBar__NoBA7","uploadRowProgressFill":"BookEditor-module_uploadRowProgressFill__TrP7e","uploadRowActions":"BookEditor-module_uploadRowActions__5Y1Mq","uploadActionButton":"BookEditor-module_uploadActionButton__CqJrr","uploadRowError":"BookEditor-module_uploadRowError__eEHWw"};
18721
+ 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}@keyframes BookEditor-module_fadeOut__q8JnR{0%{opacity:0}10%{opacity:1}70%{opacity:1}to{opacity:0}}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkJvb2tFZGl0b3IubW9kdWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxxQ0FFSSxVQUNKLENBRUEsOENBS0kscUJBQXNCLENBSHRCLFdBQVksQ0FFWixtQkFBb0IsQ0FEcEIsaUJBQWtCLENBRmxCLFVBS0osQ0FFQSxpRkFFSSxnQ0FBcUMsQ0FDckMsaUNBRUosQ0FFQSxvQ0FDSSwwQkFDSixDQUVBLDRDQUtJLHFCQUF1QixDQUR2QixxQ0FBMEMsQ0FGMUMsa0JBQW1CLENBSW5CLHNDQUEyQyxDQUwzQyxlQUFnQixDQUVoQixnQkFBaUIsQ0FJakIscUNBQ0osQ0FDQSxnRkFFSSxnQkFFSixDQUVBLGtEQUNJLHVFQUNKLENBRUEsOEdBRUksdUVBQWtGLENBRGxGLCtCQUFvQyxDQUVwQyxzQ0FDSixDQUVBLG9IQUNJLHVDQUNKLENBVUEsNEZBQ0ksZUFDSixDQUVBLHNDQVNJLGtCQUFtQixDQUhuQiwrQkFBb0MsQ0FEcEMsUUFBUyxDQUVULFVBQVksQ0FDWixZQUFhLENBR2IsZ0JBQWlCLENBRGpCLHNCQUF1QixDQVB2QixNQUFPLENBVVAsbUJBQW9CLENBWnBCLGlCQUFrQixDQUdsQixPQUFRLENBRlIsS0FBTSxDQVVOLFdBRUosQ0FRQSw4Q0FDSSxpQkFBa0IsQ0FFbEIsVUFBVyxDQURYLFFBQVMsQ0FFVCxXQUNKLENBRUEscUNBV0ksV0FBWSxDQUZaLGVBQWdCLENBSmhCLFFBQVMsQ0FPVCxlQUFnQixDQUxoQixXQUFZLENBSlosTUFBTyxDQU9QLGdCQUFpQixDQVRqQixjQUFlLENBR2YsT0FBUSxDQUZSLEtBQU0sQ0FJTixVQUFXLENBRVgsWUFLSixDQUVBLGlDQU9JLGtCQUFtQixDQU5uQixxQkFBc0IsQ0FDdEIsd0JBQXlCLENBQ3pCLHFCQUF1QixDQU92QixzQ0FBMkMsQ0FEM0MsYUFBYyxDQUpkLGNBQWUsQ0FDZixtQkFBb0IsQ0FFcEIsU0FBVyxDQUpYLGtCQUFvQixDQU9wQiw4QkFDSixDQUVBLHVDQUNJLHdCQUF5QixDQUN6QixvQkFBcUIsQ0FDckIsaUVBQ0osQ0FFQSxtR0FDSSxtQ0FBd0MsQ0FDeEMsK0JBQW9DLENBRXBDLHVDQUE0QyxDQUQ1QyxhQUVKLENBRUEseUdBQ0ksbUNBQXdDLENBQ3hDLGlDQUFzQyxDQUN0Qyx1Q0FDSixDQUVBLDRDQWFJLGtCQUFtQixDQUVuQixzREFBOEIsQ0FWOUIsK0JBQW9DLENBR3BDLG1CQUFxQixDQUZyQixVQUFZLENBTVosWUFBYSxDQUhiLGlCQUFrQixDQUtsQixTQUFXLENBWFgsUUFBUyxDQUlULGlCQUFrQixDQUlsQixtQkFBb0IsQ0FWcEIsaUJBQWtCLENBQ2xCLE9BQVEsQ0FFUiw4QkFBZ0MsQ0FNaEMsWUFNSixDQUVBLDhHQUNJLGlDQUFzQyxDQUV0QyxrQ0FBdUMsQ0FEdkMsYUFFSixDQUVBLHNDQU1JLDhCQUFxQyxDQUNyQyxxQ0FBMEMsQ0FDMUMsa0JBQW1CLENBTG5CLFdBQVksQ0FNWix5Q0FBOEMsQ0FFOUMsWUFBYSxDQUNiLHFCQUFzQixDQUN0QixRQUFTLENBUlQsMkJBQTRCLENBSzVCLFlBQWEsQ0FUYixpQkFBa0IsQ0FDbEIsVUFBVyxDQUVYLFdBQVksQ0FVWixXQUNKLENBRUEsd0dBQ0ksNEJBQWlDLENBQ2pDLDhCQUFtQyxDQUNuQyx1Q0FDSixDQUVBLDRDQUVJLGtCQUFtQixDQURuQixZQUFhLENBR2IsUUFBUyxDQURULDZCQUVKLENBRUEsMkNBR0ksYUFBYyxDQURkLGdCQUFrQixDQURsQixlQUdKLENBRUEsNkdBQ0ksYUFDSixDQUVBLGdEQUVJLGFBQWMsQ0FEZCxnQkFFSixDQUVBLHViQUlJLGFBQ0osQ0FFQSw2Q0FLSSxhQUFjLENBSmQsWUFBYSxDQUdiLGdCQUFrQixDQURsQixZQUFhLENBRGIsNkJBSUosQ0FFQSxpREFFSSxrQkFBbUIsQ0FDbkIsbUJBQW9CLENBRnBCLFVBQVcsQ0FHWCxlQUNKLENBRUEsa0RBRUksaURBQW9ELENBRHBELFdBQVksQ0FFWix5QkFDSixDQUVBLG9PQUVJLGtCQUNKLENBRUEsMENBQ0ksWUFBYSxDQUNiLHFCQUFzQixDQUN0QixPQUFRLENBQ1IsZ0JBQWlCLENBQ2pCLGVBQWdCLENBQ2hCLGlCQUNKLENBRUEsb0NBT0ksZUFBZ0IsQ0FOaEIsd0JBQXlCLENBQ3pCLGtCQUFtQixDQUVuQixZQUFhLENBQ2IscUJBQXNCLENBQ3RCLE9BQVEsQ0FIUixXQUtKLENBRUEsc0dBRUksNkJBQWtDLENBRGxDLG9CQUVKLENBRUEsMENBRUksa0JBQW1CLENBRG5CLFlBQWEsQ0FHYixPQUFRLENBRFIsNkJBRUosQ0FFQSx3Q0FHSSxhQUFjLENBRmQsZUFBaUIsQ0FDakIsZUFBZ0IsQ0FFaEIsZUFBZ0IsQ0FDaEIsc0JBQXVCLENBQ3ZCLGtCQUNKLENBRUEsMEdBQ0ksYUFDSixDQUVBLDBDQUVJLGFBQWMsQ0FEZCxlQUVKLENBRUEsd0NBSUksYUFBYyxDQUhkLFlBQWEsQ0FFYixlQUFpQixDQURqQiw2QkFHSixDQUVBLCtDQUVJLGtCQUFtQixDQUNuQixtQkFBb0IsQ0FGcEIsVUFBVyxDQUdYLGVBQ0osQ0FFQSxnREFFSSxrQkFBbUIsQ0FEbkIsV0FBWSxDQUVaLHlCQUNKLENBRUEsMkNBQ0ksWUFBYSxDQUNiLE9BQ0osQ0FFQSw2Q0FFSSxrQkFBbUIsQ0FEbkIsd0JBQXlCLENBS3pCLGlCQUFrQixDQUhsQixhQUFjLENBSWQsY0FBZSxDQUhmLGVBQWlCLENBQ2pCLGVBQWdCLENBR2hCLCtCQUNKLENBRUEsbURBQ0ksa0JBQW1CLENBQ25CLG9CQUNKLENBRUEsK0dBRUksa0JBQW1CLENBRG5CLG9CQUFxQixDQUVyQixhQUNKLENBRUEscUhBQ0ksa0JBQW1CLENBQ25CLG9CQUNKLENBRUEseUNBRUksYUFBYyxDQURkLGVBRUosQ0FFQSw0Q0FDSSxHQUNJLFNBQ0osQ0FDQSxJQUNJLFNBQ0osQ0FDQSxJQUNJLFNBQ0osQ0FDQSxHQUNJLFNBQ0osQ0FDSiIsImZpbGUiOiJCb29rRWRpdG9yLm1vZHVsZS5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyIuQm9va0VkaXRvciB7XG4gICAgLyogaGVpZ2h0OiA0NTBweDsgKi9cbiAgICB3aWR0aDogMTAwJTtcbn1cblxuLmJvb2tFZGl0b3JDb250YWluZXIge1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgcGFkZGluZzogMTBweCAyNXB4IDA7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbn1cblxuLmJvb2tFZGl0b3JDb250YWluZXIuaXNWZXJib3NlIHtcbiAgICAvKiovXG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjA1KTtcbiAgICBvdXRsaW5lOiAxcHggZG90dGVkIHJnYmEoMCwgMCwgMCwgMC41KTtcbiAgICAvKiovXG59XG5cbi5pc1ZlcmJvc2Uge1xuICAgIG91dGxpbmU6IDJweCBkb3R0ZWQgcmdiKDI1NSAxMTcgMzgpO1xufVxuXG4uYm9va0VkaXRvcldyYXBwZXIge1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgYm9yZGVyLXJhZGl1czogMXJlbTtcbiAgICBwYWRkaW5nLXRvcDogMTBweDtcbiAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDIwOSwgMjEzLCAyMTksIDAuOCk7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XG4gICAgYm94LXNoYWRvdzogMCAxcHggMnB4IDAgcmdiYSgwLCAwLCAwLCAwLjA1KTtcbiAgICB0cmFuc2l0aW9uOiBib3gtc2hhZG93IDAuMnMgZWFzZS1pbi1vdXQ7XG59XG4uaXNWZXJib3NlIC5ib29rRWRpdG9yV3JhcHBlciB7XG4gICAgLyoqL1xuICAgIG92ZXJmbG93OiB2aXNpYmxlO1xuICAgIC8qKi9cbn1cblxuLmJvb2tFZGl0b3JXcmFwcGVyOmhvdmVyIHtcbiAgICBib3gtc2hhZG93OiAwIDRweCA2cHggLTFweCByZ2JhKDAsIDAsIDAsIDAuMSksIDAgMnB4IDRweCAtMXB4IHJnYmEoMCwgMCwgMCwgMC4wNik7XG59XG5cbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAuYm9va0VkaXRvcldyYXBwZXIge1xuICAgIGJvcmRlci1jb2xvcjogcmdiYSg1MSwgNjUsIDg1LCAwLjkyKTtcbiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQoMTgwZGVnLCByZ2JhKDE1LCAyMywgNDIsIDAuOTgpLCByZ2JhKDgsIDE1LCAyOCwgMC45OCkpO1xuICAgIGJveC1zaGFkb3c6IDAgMjBweCA0NXB4IHJnYmEoMiwgNiwgMjMsIDAuNCk7XG59XG5cbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAuYm9va0VkaXRvcldyYXBwZXI6aG92ZXIge1xuICAgIGJveC1zaGFkb3c6IDAgMjRweCA1MHB4IHJnYmEoMiwgNiwgMjMsIDAuNDgpO1xufVxuXG4uYm9va0VkaXRvcldyYXBwZXI6Zm9jdXMtd2l0aGluIHtcbiAgICAvKlxuICAgIG91dGxpbmU6IDJweCBzb2xpZCB0cmFuc3BhcmVudDtcbiAgICBvdXRsaW5lLW9mZnNldDogMnB4O1xuICAgIGJveC1zaGFkb3c6IDAgMCAwIDNweCByZ2JhKDk5LCAxMDIsIDI0MSwgMC40KTtcbiAgICAqL1xufVxuXG4uYm9va0VkaXRvcldyYXBwZXIuaXNCb3JkZXJSYWRpdXNEaXNhYmxlZCB7XG4gICAgYm9yZGVyLXJhZGl1czogMDtcbn1cblxuLmRyb3BPdmVybGF5IHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdG9wOiAwO1xuICAgIGxlZnQ6IDA7XG4gICAgcmlnaHQ6IDA7XG4gICAgYm90dG9tOiAwO1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMCwgMCwgMCwgMC41KTtcbiAgICBjb2xvcjogd2hpdGU7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgIGZvbnQtc2l6ZTogMS41cmVtO1xuICAgIHotaW5kZXg6IDEwMDtcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cblxuLypcbi5ib29rRWRpdG9yQ29udGFpbmVyIDpnbG9iYWwoLnZpZXctbGluZSkge1xuICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjZWVlOyAvKiA8LSBOb3RlOiBgUFJPTVBUQk9PS19TWU5UQVhfQ09MT1JTLkxJTkVgICogL1xufVxuKi9cblxuLmJvb2tFZGl0b3JBY3Rpb25iYXIge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDEwcHg7XG4gICAgcmlnaHQ6IDU1cHg7XG4gICAgei1pbmRleDogMTAwO1xufVxuXG4uZnVsbHNjcmVlbiB7XG4gICAgcG9zaXRpb246IGZpeGVkO1xuICAgIHRvcDogMDtcbiAgICBsZWZ0OiAwO1xuICAgIHJpZ2h0OiAwO1xuICAgIGJvdHRvbTogMDtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgei1pbmRleDogOTk5OTtcbiAgICBib3JkZXItcmFkaXVzOiAwO1xuICAgIHBhZGRpbmctdG9wOiA1MHB4O1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBib3gtc2hhZG93OiBub25lO1xufVxuXG4uYnV0dG9uIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xuICAgIGJvcmRlcjogMXB4IHNvbGlkICNkMWQ1ZGI7XG4gICAgYm9yZGVyLXJhZGl1czogMC4zNzVyZW07XG4gICAgcGFkZGluZzogMC41cmVtIDFyZW07XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgZ2FwOiAwLjVyZW07XG4gICAgY29sb3I6ICMzNzQxNTE7XG4gICAgYm94LXNoYWRvdzogMCAxcHggMnB4IDAgcmdiYSgwLCAwLCAwLCAwLjA1KTtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4ycyBlYXNlLWluLW91dDtcbn1cblxuLmJ1dHRvbjpob3ZlciB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogI2Y5ZmFmYjtcbiAgICBib3JkZXItY29sb3I6ICNiN2JjY2U7XG4gICAgYm94LXNoYWRvdzogMCAxcHggM3B4IDAgcmdiYSgwLCAwLCAwLCAwLjEpLCAwIDFweCAycHggMCByZ2JhKDAsIDAsIDAsIDAuMDYpO1xufVxuXG4uQm9va0VkaXRvcltkYXRhLWJvb2stZWRpdG9yLXRoZW1lPSdkYXJrJ10gLmJ1dHRvbiB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgxNSwgMjMsIDQyLCAwLjkyKTtcbiAgICBib3JkZXItY29sb3I6IHJnYmEoNzEsIDg1LCAxMDUsIDAuOSk7XG4gICAgY29sb3I6ICNlMmU4ZjA7XG4gICAgYm94LXNoYWRvdzogMCAxcHggMnB4IDAgcmdiYSgyLCA2LCAyMywgMC4zNSk7XG59XG5cbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAuYnV0dG9uOmhvdmVyIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDMwLCA0MSwgNTksIDAuOTgpO1xuICAgIGJvcmRlci1jb2xvcjogcmdiYSgxMjUsIDIxMSwgMjUyLCAwLjUpO1xuICAgIGJveC1zaGFkb3c6IDAgMTBweCAyNHB4IHJnYmEoMiwgNiwgMjMsIDAuMzUpO1xufVxuXG4uc2F2ZWROb3RpZmljYXRpb24ge1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDUwJTtcbiAgICBsZWZ0OiA1MCU7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgwLCAwLCAwLCAwLjcpO1xuICAgIGNvbG9yOiB3aGl0ZTtcbiAgICBwYWRkaW5nOiAxcmVtIDJyZW07XG4gICAgYm9yZGVyLXJhZGl1czogMC41cmVtO1xuICAgIGZvbnQtc2l6ZTogMS4yNXJlbTtcbiAgICB6LWluZGV4OiAxMDAwO1xuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBnYXA6IDAuNXJlbTtcbiAgICBhbmltYXRpb246IGZhZGVPdXQgMnMgZm9yd2FyZHM7XG59XG5cbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAuc2F2ZWROb3RpZmljYXRpb24ge1xuICAgIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMiwgNiwgMjMsIDAuODYpO1xuICAgIGNvbG9yOiAjZTJlOGYwO1xuICAgIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoNTEsIDY1LCA4NSwgMC45KTtcbn1cblxuLnVwbG9hZFBhbmVsIHtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgcmlnaHQ6IDIwcHg7XG4gICAgYm90dG9tOiAyMHB4O1xuICAgIHdpZHRoOiA0MjBweDtcbiAgICBtYXgtd2lkdGg6IGNhbGMoMTAwJSAtIDQwcHgpO1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC45OCk7XG4gICAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyMDksIDIxMywgMjE5LCAwLjkpO1xuICAgIGJvcmRlci1yYWRpdXM6IDEycHg7XG4gICAgYm94LXNoYWRvdzogMCAxMnB4IDMwcHggcmdiYSgxNSwgMjMsIDQyLCAwLjE1KTtcbiAgICBwYWRkaW5nOiAxMnB4O1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICBnYXA6IDEwcHg7XG4gICAgei1pbmRleDogMjIwO1xufVxuXG4uQm9va0VkaXRvcltkYXRhLWJvb2stZWRpdG9yLXRoZW1lPSdkYXJrJ10gLnVwbG9hZFBhbmVsIHtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDgsIDE1LCAyOCwgMC45Nik7XG4gICAgYm9yZGVyLWNvbG9yOiByZ2JhKDUxLCA2NSwgODUsIDAuOSk7XG4gICAgYm94LXNoYWRvdzogMCAxOHB4IDQwcHggcmdiYSgyLCA2LCAyMywgMC40NSk7XG59XG5cbi51cGxvYWRQYW5lbEhlYWRlciB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICBnYXA6IDEycHg7XG59XG5cbi51cGxvYWRQYW5lbFRpdGxlIHtcbiAgICBmb250LXdlaWdodDogNjAwO1xuICAgIGZvbnQtc2l6ZTogMC45NXJlbTtcbiAgICBjb2xvcjogIzExMTgyNztcbn1cblxuLkJvb2tFZGl0b3JbZGF0YS1ib29rLWVkaXRvci10aGVtZT0nZGFyayddIC51cGxvYWRQYW5lbFRpdGxlIHtcbiAgICBjb2xvcjogI2Y4ZmFmYztcbn1cblxuLnVwbG9hZFBhbmVsSGVhZGVyTWV0YSB7XG4gICAgZm9udC1zaXplOiAwLjc1cmVtO1xuICAgIGNvbG9yOiAjNmI3MjgwO1xufVxuXG4uQm9va0VkaXRvcltkYXRhLWJvb2stZWRpdG9yLXRoZW1lPSdkYXJrJ10gLnVwbG9hZFBhbmVsSGVhZGVyTWV0YSxcbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAudXBsb2FkUGFuZWxTdW1tYXJ5LFxuLkJvb2tFZGl0b3JbZGF0YS1ib29rLWVkaXRvci10aGVtZT0nZGFyayddIC51cGxvYWRSb3dTdGF0dXMsXG4uQm9va0VkaXRvcltkYXRhLWJvb2stZWRpdG9yLXRoZW1lPSdkYXJrJ10gLnVwbG9hZFJvd01ldGEge1xuICAgIGNvbG9yOiAjOTRhM2I4O1xufVxuXG4udXBsb2FkUGFuZWxTdW1tYXJ5IHtcbiAgICBkaXNwbGF5OiBncmlkO1xuICAgIGdyaWQtdGVtcGxhdGUtY29sdW1uczogMWZyIDFmcjtcbiAgICBnYXA6IDRweCAxMnB4O1xuICAgIGZvbnQtc2l6ZTogMC43NXJlbTtcbiAgICBjb2xvcjogIzZiNzI4MDtcbn1cblxuLnVwbG9hZFBhbmVsUHJvZ3Jlc3NCYXIge1xuICAgIGhlaWdodDogNnB4O1xuICAgIGJhY2tncm91bmQ6ICNlNWU3ZWI7XG4gICAgYm9yZGVyLXJhZGl1czogOTk5cHg7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbn1cblxuLnVwbG9hZFBhbmVsUHJvZ3Jlc3NGaWxsIHtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgYmFja2dyb3VuZDogbGluZWFyLWdyYWRpZW50KDkwZGVnLCAjMjU2M2ViLCAjMTBiOTgxKTtcbiAgICB0cmFuc2l0aW9uOiB3aWR0aCAwLjJzIGVhc2U7XG59XG5cbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAudXBsb2FkUGFuZWxQcm9ncmVzc0Jhcixcbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAudXBsb2FkUm93UHJvZ3Jlc3NCYXIge1xuICAgIGJhY2tncm91bmQ6ICMxZTI5M2I7XG59XG5cbi51cGxvYWRQYW5lbExpc3Qge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICBnYXA6IDhweDtcbiAgICBtYXgtaGVpZ2h0OiAyMjBweDtcbiAgICBvdmVyZmxvdy15OiBhdXRvO1xuICAgIHBhZGRpbmctcmlnaHQ6IDRweDtcbn1cblxuLnVwbG9hZFJvdyB7XG4gICAgYm9yZGVyOiAxcHggc29saWQgI2U1ZTdlYjtcbiAgICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICAgIHBhZGRpbmc6IDhweDtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgZ2FwOiA2cHg7XG4gICAgYmFja2dyb3VuZDogI2ZmZjtcbn1cblxuLkJvb2tFZGl0b3JbZGF0YS1ib29rLWVkaXRvci10aGVtZT0nZGFyayddIC51cGxvYWRSb3cge1xuICAgIGJvcmRlci1jb2xvcjogIzMzNDE1NTtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDE1LCAyMywgNDIsIDAuOTIpO1xufVxuXG4udXBsb2FkUm93SGVhZGVyIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgIGdhcDogOHB4O1xufVxuXG4udXBsb2FkUm93TmFtZSB7XG4gICAgZm9udC1zaXplOiAwLjhyZW07XG4gICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICBjb2xvcjogIzExMTgyNztcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG59XG5cbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAudXBsb2FkUm93TmFtZSB7XG4gICAgY29sb3I6ICNmOGZhZmM7XG59XG5cbi51cGxvYWRSb3dTdGF0dXMge1xuICAgIGZvbnQtc2l6ZTogMC43cmVtO1xuICAgIGNvbG9yOiAjNmI3MjgwO1xufVxuXG4udXBsb2FkUm93TWV0YSB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gICAgZm9udC1zaXplOiAwLjdyZW07XG4gICAgY29sb3I6ICM2YjcyODA7XG59XG5cbi51cGxvYWRSb3dQcm9ncmVzc0JhciB7XG4gICAgaGVpZ2h0OiA0cHg7XG4gICAgYmFja2dyb3VuZDogI2U1ZTdlYjtcbiAgICBib3JkZXItcmFkaXVzOiA5OTlweDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xufVxuXG4udXBsb2FkUm93UHJvZ3Jlc3NGaWxsIHtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgYmFja2dyb3VuZDogIzNiODJmNjtcbiAgICB0cmFuc2l0aW9uOiB3aWR0aCAwLjJzIGVhc2U7XG59XG5cbi51cGxvYWRSb3dBY3Rpb25zIHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGdhcDogNnB4O1xufVxuXG4udXBsb2FkQWN0aW9uQnV0dG9uIHtcbiAgICBib3JkZXI6IDFweCBzb2xpZCAjZDFkNWRiO1xuICAgIGJhY2tncm91bmQ6ICNmOWZhZmI7XG4gICAgY29sb3I6ICMzNzQxNTE7XG4gICAgZm9udC1zaXplOiAwLjdyZW07XG4gICAgcGFkZGluZzogMnB4IDhweDtcbiAgICBib3JkZXItcmFkaXVzOiA2cHg7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIHRyYW5zaXRpb246IGFsbCAwLjE1cyBlYXNlLWluLW91dDtcbn1cblxuLnVwbG9hZEFjdGlvbkJ1dHRvbjpob3ZlciB7XG4gICAgYmFja2dyb3VuZDogI2VlZjJmNztcbiAgICBib3JkZXItY29sb3I6ICNjYmQ1ZjU7XG59XG5cbi5Cb29rRWRpdG9yW2RhdGEtYm9vay1lZGl0b3ItdGhlbWU9J2RhcmsnXSAudXBsb2FkQWN0aW9uQnV0dG9uIHtcbiAgICBib3JkZXItY29sb3I6ICM0NzU1Njk7XG4gICAgYmFja2dyb3VuZDogIzBmMTcyYTtcbiAgICBjb2xvcjogI2UyZThmMDtcbn1cblxuLkJvb2tFZGl0b3JbZGF0YS1ib29rLWVkaXRvci10aGVtZT0nZGFyayddIC51cGxvYWRBY3Rpb25CdXR0b246aG92ZXIge1xuICAgIGJhY2tncm91bmQ6ICMxZTI5M2I7XG4gICAgYm9yZGVyLWNvbG9yOiAjN2RkM2ZjO1xufVxuXG4udXBsb2FkUm93RXJyb3Ige1xuICAgIGZvbnQtc2l6ZTogMC43cmVtO1xuICAgIGNvbG9yOiAjYjkxYzFjO1xufVxuXG5Aa2V5ZnJhbWVzIGZhZGVPdXQge1xuICAgIDAlIHtcbiAgICAgICAgb3BhY2l0eTogMDtcbiAgICB9XG4gICAgMTAlIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG4gICAgNzAlIHtcbiAgICAgICAgb3BhY2l0eTogMTtcbiAgICB9XG4gICAgMTAwJSB7XG4gICAgICAgIG9wYWNpdHk6IDA7XG4gICAgfVxufVxuIl19 */";
18722
+ 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"};
18711
18723
  styleInject(css_248z$d);
18712
18724
 
18713
18725
  /**
@@ -18918,7 +18930,7 @@
18918
18930
  return CODE_BLOCK_LANGUAGE_ALIASES[normalizedLanguage] || 'plaintext';
18919
18931
  }
18920
18932
 
18921
- var css_248z$c = ".CodeBlock-module_CodeBlock__6K33Z{border:1px solid #444;border-radius:5px;margin:10px 0;max-width:100%;overflow:hidden;width:100%}.CodeBlock-module_CodeBlockHeader__tfOwl{align-items:center;background-color:#2d2d2d;border-bottom:1px solid #444;color:#ccc;display:flex;font-size:.8em;justify-content:space-between;padding:5px 10px}.CodeBlock-module_CodeBlockButtons__rz1VO{display:flex;gap:8px}.CodeBlock-module_CopyButton__M07tp,.CodeBlock-module_CreateAgentButton__kUEnp,.CodeBlock-module_DownloadButton__ZTrzQ{align-items:center;background:transparent;border:none;color:#aaa;cursor:pointer;display:flex;font-size:inherit;gap:5px;padding:0;transition:color .2s}.CodeBlock-module_CopyButton__M07tp:hover,.CodeBlock-module_CreateAgentButton__kUEnp:hover,.CodeBlock-module_DownloadButton__ZTrzQ:hover{color:#fff}.CodeBlock-module_CodeBlock__6K33Z .monaco-editor,.CodeBlock-module_CodeBlock__6K33Z .monaco-editor .overflow-guard{max-width:100%}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkNvZGVCbG9jay5tb2R1bGUuY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLG1DQUlJLHFCQUFzQixDQUZ0QixpQkFBa0IsQ0FEbEIsYUFBYyxDQUtkLGNBQWUsQ0FIZixlQUFnQixDQUVoQixVQUVKLENBRUEseUNBUUksa0JBQW1CLENBUG5CLHdCQUF5QixDQUl6Qiw0QkFBNkIsQ0FIN0IsVUFBVyxDQUlYLFlBQWEsQ0FGYixjQUFnQixDQUdoQiw2QkFBOEIsQ0FKOUIsZ0JBTUosQ0FFQSwwQ0FDSSxZQUFhLENBQ2IsT0FDSixDQUVBLHVIQVVJLGtCQUFtQixDQVBuQixzQkFBdUIsQ0FDdkIsV0FBWSxDQUNaLFVBQVcsQ0FDWCxjQUFlLENBR2YsWUFBYSxDQUZiLGlCQUFrQixDQUlsQixPQUFRLENBSFIsU0FBVSxDQUlWLG9CQUNKLENBRUEseUlBR0ksVUFDSixDQUVBLG9IQUVJLGNBQ0oiLCJmaWxlIjoiQ29kZUJsb2NrLm1vZHVsZS5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyIuQ29kZUJsb2NrIHtcbiAgICBtYXJnaW46IDEwcHggMDtcbiAgICBib3JkZXItcmFkaXVzOiA1cHg7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICBib3JkZXI6IDFweCBzb2xpZCAjNDQ0OyAvKiBEYXJrIG1vZGUgYm9yZGVyICovXG4gICAgd2lkdGg6IDEwMCU7XG4gICAgbWF4LXdpZHRoOiAxMDAlO1xufVxuXG4uQ29kZUJsb2NrSGVhZGVyIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjMmQyZDJkO1xuICAgIGNvbG9yOiAjY2NjO1xuICAgIHBhZGRpbmc6IDVweCAxMHB4O1xuICAgIGZvbnQtc2l6ZTogMC44ZW07XG4gICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICM0NDQ7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbn1cblxuLkNvZGVCbG9ja0J1dHRvbnMge1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZ2FwOiA4cHg7XG59XG5cbi5Db3B5QnV0dG9uLFxuLkRvd25sb2FkQnV0dG9uLFxuLkNyZWF0ZUFnZW50QnV0dG9uIHtcbiAgICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgICBib3JkZXI6IG5vbmU7XG4gICAgY29sb3I6ICNhYWE7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGZvbnQtc2l6ZTogaW5oZXJpdDtcbiAgICBwYWRkaW5nOiAwO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICBnYXA6IDVweDtcbiAgICB0cmFuc2l0aW9uOiBjb2xvciAwLjJzO1xufVxuXG4uQ29weUJ1dHRvbjpob3Zlcixcbi5Eb3dubG9hZEJ1dHRvbjpob3Zlcixcbi5DcmVhdGVBZ2VudEJ1dHRvbjpob3ZlciB7XG4gICAgY29sb3I6ICNmZmY7XG59XG5cbi5Db2RlQmxvY2sgOmdsb2JhbCgubW9uYWNvLWVkaXRvciksXG4uQ29kZUJsb2NrIDpnbG9iYWwoLm1vbmFjby1lZGl0b3IgLm92ZXJmbG93LWd1YXJkKSB7XG4gICAgbWF4LXdpZHRoOiAxMDAlO1xufVxuIl19 */";
18933
+ var css_248z$c = ".CodeBlock-module_CodeBlock__6K33Z{background:#fff;border:1px solid #d0d7e2;border-radius:5px;margin:10px 0;max-width:100%;overflow:hidden;width:100%}.CodeBlock-module_CodeBlockHeader__tfOwl{align-items:center;background-color:#f8fafc;border-bottom:1px solid #d0d7e2;color:#475569;display:flex;font-size:.8em;justify-content:space-between;padding:5px 10px}.CodeBlock-module_CodeBlockButtons__rz1VO{display:flex;gap:8px}.CodeBlock-module_CopyButton__M07tp,.CodeBlock-module_CreateAgentButton__kUEnp,.CodeBlock-module_DownloadButton__ZTrzQ{align-items:center;background:transparent;border:none;color:#64748b;cursor:pointer;display:flex;font-size:inherit;gap:5px;padding:0;transition:color .2s}.CodeBlock-module_CopyButton__M07tp:hover,.CodeBlock-module_CreateAgentButton__kUEnp:hover,.CodeBlock-module_DownloadButton__ZTrzQ:hover{color:#0f172a}.CodeBlock-module_CodeBlock__6K33Z[data-code-theme=dark]{background:#0f172a;border-color:#334155}.CodeBlock-module_CodeBlock__6K33Z[data-code-theme=dark] .CodeBlock-module_CodeBlockHeader__tfOwl{background-color:#111827;border-bottom-color:#334155;color:#cbd5e1}.CodeBlock-module_CodeBlock__6K33Z[data-code-theme=dark] .CodeBlock-module_CopyButton__M07tp,.CodeBlock-module_CodeBlock__6K33Z[data-code-theme=dark] .CodeBlock-module_CreateAgentButton__kUEnp,.CodeBlock-module_CodeBlock__6K33Z[data-code-theme=dark] .CodeBlock-module_DownloadButton__ZTrzQ{color:#94a3b8}.CodeBlock-module_CodeBlock__6K33Z[data-code-theme=dark] .CodeBlock-module_CopyButton__M07tp:hover,.CodeBlock-module_CodeBlock__6K33Z[data-code-theme=dark] .CodeBlock-module_CreateAgentButton__kUEnp:hover,.CodeBlock-module_CodeBlock__6K33Z[data-code-theme=dark] .CodeBlock-module_DownloadButton__ZTrzQ:hover{color:#f8fafc}.CodeBlock-module_CodeBlock__6K33Z .monaco-editor,.CodeBlock-module_CodeBlock__6K33Z .monaco-editor .overflow-guard{max-width:100%}\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkNvZGVCbG9jay5tb2R1bGUuY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLG1DQUtJLGVBQW1CLENBRG5CLHdCQUF5QixDQUZ6QixpQkFBa0IsQ0FEbEIsYUFBYyxDQU1kLGNBQWUsQ0FKZixlQUFnQixDQUdoQixVQUVKLENBRUEseUNBUUksa0JBQW1CLENBUG5CLHdCQUF5QixDQUl6QiwrQkFBZ0MsQ0FIaEMsYUFBYyxDQUlkLFlBQWEsQ0FGYixjQUFnQixDQUdoQiw2QkFBOEIsQ0FKOUIsZ0JBTUosQ0FFQSwwQ0FDSSxZQUFhLENBQ2IsT0FDSixDQUVBLHVIQVVJLGtCQUFtQixDQVBuQixzQkFBdUIsQ0FDdkIsV0FBWSxDQUNaLGFBQWMsQ0FDZCxjQUFlLENBR2YsWUFBYSxDQUZiLGlCQUFrQixDQUlsQixPQUFRLENBSFIsU0FBVSxDQUlWLG9CQUNKLENBRUEseUlBR0ksYUFDSixDQUVBLHlEQUVJLGtCQUFtQixDQURuQixvQkFFSixDQUVBLGtHQUNJLHdCQUF5QixDQUV6QiwyQkFBNEIsQ0FENUIsYUFFSixDQUVBLGtTQUdJLGFBQ0osQ0FFQSxvVEFHSSxhQUNKLENBRUEsb0hBRUksY0FDSiIsImZpbGUiOiJDb2RlQmxvY2subW9kdWxlLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIi5Db2RlQmxvY2sge1xuICAgIG1hcmdpbjogMTBweCAwO1xuICAgIGJvcmRlci1yYWRpdXM6IDVweDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIGJvcmRlcjogMXB4IHNvbGlkICNkMGQ3ZTI7XG4gICAgYmFja2dyb3VuZDogI2ZmZmZmZjtcbiAgICB3aWR0aDogMTAwJTtcbiAgICBtYXgtd2lkdGg6IDEwMCU7XG59XG5cbi5Db2RlQmxvY2tIZWFkZXIge1xuICAgIGJhY2tncm91bmQtY29sb3I6ICNmOGZhZmM7XG4gICAgY29sb3I6ICM0NzU1Njk7XG4gICAgcGFkZGluZzogNXB4IDEwcHg7XG4gICAgZm9udC1zaXplOiAwLjhlbTtcbiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgI2QwZDdlMjtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xufVxuXG4uQ29kZUJsb2NrQnV0dG9ucyB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBnYXA6IDhweDtcbn1cblxuLkNvcHlCdXR0b24sXG4uRG93bmxvYWRCdXR0b24sXG4uQ3JlYXRlQWdlbnRCdXR0b24ge1xuICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBjb2xvcjogIzY0NzQ4YjtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgZm9udC1zaXplOiBpbmhlcml0O1xuICAgIHBhZGRpbmc6IDA7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgIGdhcDogNXB4O1xuICAgIHRyYW5zaXRpb246IGNvbG9yIDAuMnM7XG59XG5cbi5Db3B5QnV0dG9uOmhvdmVyLFxuLkRvd25sb2FkQnV0dG9uOmhvdmVyLFxuLkNyZWF0ZUFnZW50QnV0dG9uOmhvdmVyIHtcbiAgICBjb2xvcjogIzBmMTcyYTtcbn1cblxuLkNvZGVCbG9ja1tkYXRhLWNvZGUtdGhlbWU9J2RhcmsnXSB7XG4gICAgYm9yZGVyLWNvbG9yOiAjMzM0MTU1O1xuICAgIGJhY2tncm91bmQ6ICMwZjE3MmE7XG59XG5cbi5Db2RlQmxvY2tbZGF0YS1jb2RlLXRoZW1lPSdkYXJrJ10gLkNvZGVCbG9ja0hlYWRlciB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogIzExMTgyNztcbiAgICBjb2xvcjogI2NiZDVlMTtcbiAgICBib3JkZXItYm90dG9tLWNvbG9yOiAjMzM0MTU1O1xufVxuXG4uQ29kZUJsb2NrW2RhdGEtY29kZS10aGVtZT0nZGFyayddIC5Db3B5QnV0dG9uLFxuLkNvZGVCbG9ja1tkYXRhLWNvZGUtdGhlbWU9J2RhcmsnXSAuRG93bmxvYWRCdXR0b24sXG4uQ29kZUJsb2NrW2RhdGEtY29kZS10aGVtZT0nZGFyayddIC5DcmVhdGVBZ2VudEJ1dHRvbiB7XG4gICAgY29sb3I6ICM5NGEzYjg7XG59XG5cbi5Db2RlQmxvY2tbZGF0YS1jb2RlLXRoZW1lPSdkYXJrJ10gLkNvcHlCdXR0b246aG92ZXIsXG4uQ29kZUJsb2NrW2RhdGEtY29kZS10aGVtZT0nZGFyayddIC5Eb3dubG9hZEJ1dHRvbjpob3Zlcixcbi5Db2RlQmxvY2tbZGF0YS1jb2RlLXRoZW1lPSdkYXJrJ10gLkNyZWF0ZUFnZW50QnV0dG9uOmhvdmVyIHtcbiAgICBjb2xvcjogI2Y4ZmFmYztcbn1cblxuLkNvZGVCbG9jayA6Z2xvYmFsKC5tb25hY28tZWRpdG9yKSxcbi5Db2RlQmxvY2sgOmdsb2JhbCgubW9uYWNvLWVkaXRvciAub3ZlcmZsb3ctZ3VhcmQpIHtcbiAgICBtYXgtd2lkdGg6IDEwMCU7XG59XG4iXX0= */";
18922
18934
  var styles$c = {"CodeBlock":"CodeBlock-module_CodeBlock__6K33Z","CodeBlockHeader":"CodeBlock-module_CodeBlockHeader__tfOwl","CodeBlockButtons":"CodeBlock-module_CodeBlockButtons__rz1VO","CopyButton":"CodeBlock-module_CopyButton__M07tp","DownloadButton":"CodeBlock-module_DownloadButton__ZTrzQ","CreateAgentButton":"CodeBlock-module_CreateAgentButton__kUEnp"};
18923
18935
  styleInject(css_248z$c);
18924
18936
 
@@ -18964,7 +18976,7 @@
18964
18976
  *
18965
18977
  * @private Internal utility of `<ChatMessage />` component
18966
18978
  */
18967
- function CodeBlock({ code, language, className, onCreateAgent }) {
18979
+ function CodeBlock({ code, language, className, onCreateAgent, theme = 'LIGHT' }) {
18968
18980
  const reactId = react.useId();
18969
18981
  const normalizedLanguage = resolveCodeBlockLanguage(language);
18970
18982
  const isBookLanguage = normalizedLanguage === 'book';
@@ -18997,9 +19009,9 @@
18997
19009
  };
18998
19010
  const header = language ? (jsxRuntime.jsxs("div", { className: styles$c.CodeBlockHeader, children: [jsxRuntime.jsx("span", { children: language }), jsxRuntime.jsxs("div", { className: styles$c.CodeBlockButtons, children: [jsxRuntime.jsx("button", { onClick: handleCopy, className: styles$c.CopyButton, title: "Copy to clipboard", children: copied ? 'Copied!' : 'Copy' }), jsxRuntime.jsx("button", { onClick: handleDownload, className: styles$c.DownloadButton, title: "Download code", children: "Download" }), isBookLanguage && onCreateAgent && (jsxRuntime.jsx("button", { onClick: () => onCreateAgent(code), className: styles$c.CreateAgentButton, title: "Create agent from this book", children: "Create Agent" }))] })] })) : null;
18999
19011
  if (isBookLanguage) {
19000
- return (jsxRuntime.jsxs("div", { className: classNames(styles$c.CodeBlock, className), children: [header, jsxRuntime.jsx(BookEditor, { value: code, isReadonly: true, height: lines * 25 /* <- [🧠] A bit more than 19px to accommodate BookEditor lines */ })] }));
19012
+ return (jsxRuntime.jsxs("div", { className: classNames(styles$c.CodeBlock, className), "data-code-theme": theme.toLowerCase(), children: [header, jsxRuntime.jsx(BookEditor, { value: code, isReadonly: true, height: lines * 25 /* <- [🧠] A bit more than 19px to accommodate BookEditor lines */, theme: theme })] }));
19001
19013
  }
19002
- return (jsxRuntime.jsxs("div", { className: classNames(styles$c.CodeBlock, className), children: [header, jsxRuntime.jsx(MonacoEditorWithShadowDom, { height: `${height}px`, language: normalizedLanguage, path: modelPath, value: code, theme: "vs-dark", options: {
19014
+ return (jsxRuntime.jsxs("div", { className: classNames(styles$c.CodeBlock, className), "data-code-theme": theme.toLowerCase(), children: [header, jsxRuntime.jsx(MonacoEditorWithShadowDom, { height: `${height}px`, language: normalizedLanguage, path: modelPath, value: code, theme: theme === 'DARK' ? 'vs-dark' : 'vs-light', options: {
19003
19015
  readOnly: true,
19004
19016
  minimap: { enabled: false },
19005
19017
  automaticLayout: true,
@@ -20496,12 +20508,91 @@
20496
20508
  * @private function of BookEditorMonaco
20497
20509
  */
20498
20510
  const BOOK_EDITOR_LANGUAGE_INITIALIZED_FLAG = 'promptbookBookEditorLanguageInitialized';
20511
+ /**
20512
+ * Internal Monaco flag used to avoid re-defining the Book theme when the requested mode stays unchanged.
20513
+ *
20514
+ * @private function of BookEditorMonaco
20515
+ */
20516
+ const BOOK_EDITOR_THEME_MODE_FLAG = 'promptbookBookEditorThemeMode';
20499
20517
  /**
20500
20518
  * Matches fenced code-block delimiters, including optional leading indentation.
20501
20519
  *
20502
20520
  * @private function of BookEditorMonaco
20503
20521
  */
20504
20522
  const CODE_BLOCK_FENCE_REGEX = /^\s*```.*$/;
20523
+ /**
20524
+ * Shared token rules reused by both light and dark Book Monaco themes.
20525
+ *
20526
+ * @private function of BookEditorMonaco
20527
+ */
20528
+ const BOOK_EDITOR_THEME_RULES = [
20529
+ {
20530
+ token: 'title',
20531
+ foreground: PROMPTBOOK_SYNTAX_COLORS.TITLE.toHex(),
20532
+ fontStyle: 'bold underline',
20533
+ },
20534
+ {
20535
+ token: 'commitment',
20536
+ foreground: PROMPTBOOK_SYNTAX_COLORS.COMMITMENT.toHex(),
20537
+ fontStyle: 'bold',
20538
+ },
20539
+ {
20540
+ token: 'note-commitment',
20541
+ foreground: PROMPTBOOK_SYNTAX_COLORS.NOTE_COMMITMENT.toHex(),
20542
+ },
20543
+ {
20544
+ token: 'todo-commitment',
20545
+ foreground: PROMPTBOOK_SYNTAX_COLORS.TODO_COMMITMENT_TEXT.toHex(),
20546
+ background: PROMPTBOOK_SYNTAX_COLORS.TODO_COMMITMENT_BACKGROUND.toHex(),
20547
+ fontStyle: 'bold',
20548
+ },
20549
+ {
20550
+ token: 'parameter',
20551
+ foreground: PROMPTBOOK_SYNTAX_COLORS.PARAMETER.toHex(),
20552
+ fontStyle: 'italic',
20553
+ },
20554
+ {
20555
+ token: 'agent-reference',
20556
+ foreground: PROMPTBOOK_SYNTAX_COLORS.COMMITMENT.toHex(),
20557
+ fontStyle: 'underline',
20558
+ },
20559
+ {
20560
+ token: 'code-block',
20561
+ foreground: PROMPTBOOK_SYNTAX_COLORS.CODE_BLOCK.toHex(),
20562
+ },
20563
+ ];
20564
+ /**
20565
+ * Re-defines the shared Book Monaco theme according to the requested light/dark mode.
20566
+ *
20567
+ * @private function of BookEditorMonaco
20568
+ */
20569
+ function applyBookEditorMonacoTheme(monaco, theme) {
20570
+ const colors = theme === 'DARK'
20571
+ ? {
20572
+ 'editor.background': '#09111f',
20573
+ 'editor.foreground': '#e2e8f0',
20574
+ 'editorLineNumber.foreground': '#64748b',
20575
+ 'editorLineNumber.activeForeground': '#cbd5e1',
20576
+ 'editorCursor.foreground': '#7dd3fc',
20577
+ 'editor.selectionBackground': '#1d4ed866',
20578
+ 'editor.inactiveSelectionBackground': '#1e3a8a44',
20579
+ 'editor.scrollbarSlider.background': '#334155',
20580
+ 'editor.scrollbarSlider.hoverBackground': '#475569',
20581
+ 'editor.scrollbarSlider.activeBackground': '#64748b',
20582
+ }
20583
+ : {
20584
+ 'editor.scrollbarSlider.background': '#E0E0E0',
20585
+ 'editor.scrollbarSlider.hoverBackground': '#D0D0D0',
20586
+ 'editor.scrollbarSlider.activeBackground': '#C0C0C0',
20587
+ };
20588
+ monaco.editor.defineTheme(BookEditorMonacoConstants.BOOK_THEME_ID, {
20589
+ base: theme === 'DARK' ? 'vs-dark' : 'vs',
20590
+ inherit: true,
20591
+ rules: [...BOOK_EDITOR_THEME_RULES],
20592
+ colors,
20593
+ });
20594
+ monaco.editor.setTheme(BookEditorMonacoConstants.BOOK_THEME_ID);
20595
+ }
20505
20596
  /**
20506
20597
  * Builds a regex that matches one commitment keyword at line start.
20507
20598
  *
@@ -20579,13 +20670,19 @@
20579
20670
  *
20580
20671
  * @private function of BookEditorMonaco
20581
20672
  */
20582
- function ensureBookEditorMonacoLanguage(monaco) {
20673
+ function ensureBookEditorMonacoLanguage(monaco, theme = 'LIGHT') {
20583
20674
  const monacoWithLanguageState = monaco;
20584
20675
  if (monacoWithLanguageState[BOOK_EDITOR_LANGUAGE_INITIALIZED_FLAG]) {
20676
+ if (monacoWithLanguageState[BOOK_EDITOR_THEME_MODE_FLAG] !== theme) {
20677
+ applyBookEditorMonacoTheme(monaco, theme);
20678
+ monacoWithLanguageState[BOOK_EDITOR_THEME_MODE_FLAG] = theme;
20679
+ return;
20680
+ }
20585
20681
  monaco.editor.setTheme(BookEditorMonacoConstants.BOOK_THEME_ID);
20586
20682
  return;
20587
20683
  }
20588
20684
  monacoWithLanguageState[BOOK_EDITOR_LANGUAGE_INITIALIZED_FLAG] = true;
20685
+ monacoWithLanguageState[BOOK_EDITOR_THEME_MODE_FLAG] = theme;
20589
20686
  monaco.languages.register({ id: BookEditorMonacoConstants.BOOK_LANGUAGE_ID });
20590
20687
  const commitmentDefinitions = getAllCommitmentDefinitions();
20591
20688
  const commitmentTypes = [...new Set(commitmentDefinitions.map(({ type }) => type))];
@@ -20680,52 +20777,7 @@
20680
20777
  return { links };
20681
20778
  },
20682
20779
  });
20683
- monaco.editor.defineTheme(BookEditorMonacoConstants.BOOK_THEME_ID, {
20684
- base: 'vs',
20685
- inherit: true,
20686
- rules: [
20687
- {
20688
- token: 'title',
20689
- foreground: PROMPTBOOK_SYNTAX_COLORS.TITLE.toHex(),
20690
- fontStyle: 'bold underline',
20691
- },
20692
- {
20693
- token: 'commitment',
20694
- foreground: PROMPTBOOK_SYNTAX_COLORS.COMMITMENT.toHex(),
20695
- fontStyle: 'bold',
20696
- },
20697
- {
20698
- token: 'note-commitment',
20699
- foreground: PROMPTBOOK_SYNTAX_COLORS.NOTE_COMMITMENT.toHex(),
20700
- },
20701
- {
20702
- token: 'todo-commitment',
20703
- foreground: PROMPTBOOK_SYNTAX_COLORS.TODO_COMMITMENT_TEXT.toHex(),
20704
- background: PROMPTBOOK_SYNTAX_COLORS.TODO_COMMITMENT_BACKGROUND.toHex(),
20705
- fontStyle: 'bold',
20706
- },
20707
- {
20708
- token: 'parameter',
20709
- foreground: PROMPTBOOK_SYNTAX_COLORS.PARAMETER.toHex(),
20710
- fontStyle: 'italic',
20711
- },
20712
- {
20713
- token: 'agent-reference',
20714
- foreground: PROMPTBOOK_SYNTAX_COLORS.COMMITMENT.toHex(),
20715
- fontStyle: 'underline',
20716
- },
20717
- {
20718
- token: 'code-block',
20719
- foreground: PROMPTBOOK_SYNTAX_COLORS.CODE_BLOCK.toHex(),
20720
- },
20721
- ],
20722
- colors: {
20723
- 'editor.scrollbarSlider.background': '#E0E0E0',
20724
- 'editor.scrollbarSlider.hoverBackground': '#D0D0D0',
20725
- 'editor.scrollbarSlider.activeBackground': '#C0C0C0',
20726
- },
20727
- });
20728
- monaco.editor.setTheme(BookEditorMonacoConstants.BOOK_THEME_ID);
20780
+ applyBookEditorMonacoTheme(monaco, theme);
20729
20781
  }
20730
20782
  /**
20731
20783
  * Ensures the mounted Monaco editor model uses Book language and Book theme.
@@ -20738,8 +20790,8 @@
20738
20790
  * @private function of BookEditorMonaco
20739
20791
  */
20740
20792
  function ensureBookEditorMonacoLanguageForEditor(props) {
20741
- const { monaco, monacoEditor } = props;
20742
- ensureBookEditorMonacoLanguage(monaco);
20793
+ const { monaco, monacoEditor, theme = 'LIGHT' } = props;
20794
+ ensureBookEditorMonacoLanguage(monaco, theme);
20743
20795
  const model = monacoEditor.getModel();
20744
20796
  if (!model) {
20745
20797
  return;
@@ -20754,13 +20806,13 @@
20754
20806
  *
20755
20807
  * @private function of BookEditorMonaco
20756
20808
  */
20757
- function useBookEditorMonacoLanguage({ monaco }) {
20809
+ function useBookEditorMonacoLanguage({ monaco, theme }) {
20758
20810
  react.useEffect(() => {
20759
20811
  if (!monaco) {
20760
20812
  return;
20761
20813
  }
20762
- ensureBookEditorMonacoLanguage(monaco);
20763
- }, [monaco]);
20814
+ ensureBookEditorMonacoLanguage(monaco, theme);
20815
+ }, [monaco, theme]);
20764
20816
  }
20765
20817
 
20766
20818
  /**
@@ -20774,9 +20826,13 @@
20774
20826
  *
20775
20827
  * @private function of BookEditorMonaco
20776
20828
  */
20777
- function useBookEditorMonacoStyles({ instanceClass, scaledLineHeight, scaledContentPaddingLeft, scaledVerticalLineLeft, zoomLevel, }) {
20829
+ function useBookEditorMonacoStyles({ instanceClass, scaledLineHeight, scaledContentPaddingLeft, scaledVerticalLineLeft, zoomLevel, theme, }) {
20778
20830
  react.useEffect(() => {
20779
20831
  const styleId = `notebook-margin-line-style-${instanceClass}`;
20832
+ const lineColor = theme === 'DARK' ? '#1f2937' : PROMPTBOOK_SYNTAX_COLORS.LINE.toHex();
20833
+ const separatorColor = theme === 'DARK' ? '#334155' : PROMPTBOOK_SYNTAX_COLORS.SEPARATOR.toHex();
20834
+ const codeBlockBackground = theme === 'DARK' ? '#0f172a99' : '#f5f5f566';
20835
+ const codeBlockBorderColor = theme === 'DARK' ? '#38bdf8aa' : PROMPTBOOK_SYNTAX_COLORS.CODE_BLOCK.toHex();
20780
20836
  let style = document.getElementById(styleId);
20781
20837
  if (!style) {
20782
20838
  style = document.createElement('style');
@@ -20789,7 +20845,7 @@
20789
20845
  /* <- [🚚] */
20790
20846
 
20791
20847
  .${instanceClass} .monaco-editor .view-lines {
20792
- background-image: linear-gradient(to bottom, transparent ${scaledLineHeight - 1}px, ${PROMPTBOOK_SYNTAX_COLORS.LINE.toHex()} ${scaledLineHeight - 1}px);
20848
+ background-image: linear-gradient(to bottom, transparent ${scaledLineHeight - 1}px, ${lineColor} ${scaledLineHeight - 1}px);
20793
20849
  background-size: calc(100% + ${scaledContentPaddingLeft}px) ${scaledLineHeight}px;
20794
20850
  background-position-x: -${scaledContentPaddingLeft}px;
20795
20851
  background-position-y: ${scaledLineHeight * BACKGROUND_POSITION_Y_MULTIPLIER}px;
@@ -20801,7 +20857,7 @@
20801
20857
  top: 0;
20802
20858
  bottom: 0;
20803
20859
  width: 1px;
20804
- background-color: ${PROMPTBOOK_SYNTAX_COLORS.LINE.toHex()};
20860
+ background-color: ${lineColor};
20805
20861
  z-index: 10;
20806
20862
  }
20807
20863
 
@@ -20809,8 +20865,8 @@
20809
20865
  background: linear-gradient(
20810
20866
  to bottom,
20811
20867
  transparent ${scaledLineHeight * 0.9 - 2}px,
20812
- ${PROMPTBOOK_SYNTAX_COLORS.SEPARATOR.toHex()} ${scaledLineHeight * 0.9 - 2}px,
20813
- ${PROMPTBOOK_SYNTAX_COLORS.SEPARATOR.toHex()} ${scaledLineHeight * 0.9 + 1}px,
20868
+ ${separatorColor} ${scaledLineHeight * 0.9 - 2}px,
20869
+ ${separatorColor} ${scaledLineHeight * 0.9 + 1}px,
20814
20870
  transparent ${scaledLineHeight * 0.9 + 1}px
20815
20871
  );
20816
20872
  }
@@ -20820,22 +20876,22 @@
20820
20876
  }
20821
20877
 
20822
20878
  .${instanceClass} .monaco-editor .code-block-box {
20823
- background-color: #f5f5f566;
20824
- border-left: 1px solid ${PROMPTBOOK_SYNTAX_COLORS.CODE_BLOCK.toHex()};
20825
- border-right: 1px solid ${PROMPTBOOK_SYNTAX_COLORS.CODE_BLOCK.toHex()};
20879
+ background-color: ${codeBlockBackground};
20880
+ border-left: 1px solid ${codeBlockBorderColor};
20881
+ border-right: 1px solid ${codeBlockBorderColor};
20826
20882
  padding-left: ${Math.round(8 * zoomLevel)}px;
20827
20883
  padding-right: ${Math.round(8 * zoomLevel)}px;
20828
20884
  }
20829
20885
 
20830
20886
  .${instanceClass} .monaco-editor .code-block-top {
20831
- border-top: 1px solid ${PROMPTBOOK_SYNTAX_COLORS.CODE_BLOCK.toHex()};
20887
+ border-top: 1px solid ${codeBlockBorderColor};
20832
20888
  border-top-left-radius: ${Math.round(10 * zoomLevel)}px;
20833
20889
  border-top-right-radius: ${Math.round(10 * zoomLevel)}px;
20834
20890
  overflow: hidden;
20835
20891
  }
20836
20892
 
20837
20893
  .${instanceClass} .monaco-editor .code-block-bottom {
20838
- border-bottom: 1px solid ${PROMPTBOOK_SYNTAX_COLORS.CODE_BLOCK.toHex()};
20894
+ border-bottom: 1px solid ${codeBlockBorderColor};
20839
20895
  border-bottom-left-radius: ${Math.round(10 * zoomLevel)}px;
20840
20896
  border-bottom-right-radius: ${Math.round(10 * zoomLevel)}px;
20841
20897
  overflow: hidden;
@@ -20846,7 +20902,7 @@
20846
20902
  style === null || style === void 0 ? void 0 : style.remove();
20847
20903
  }
20848
20904
  };
20849
- }, [instanceClass, scaledLineHeight, scaledContentPaddingLeft, scaledVerticalLineLeft, zoomLevel]);
20905
+ }, [instanceClass, scaledLineHeight, scaledContentPaddingLeft, scaledVerticalLineLeft, theme, zoomLevel]);
20850
20906
  }
20851
20907
 
20852
20908
  /**
@@ -21759,7 +21815,7 @@
21759
21815
  * @private Internal component used by `BookEditor`
21760
21816
  */
21761
21817
  function BookEditorMonaco(props) {
21762
- const { value, onChange, diagnostics, isReadonly, translations, onFileUpload, isUploadButtonShown, isCameraButtonShown, isDownloadButtonShown, isAboutButtonShown = true, isFullscreenButtonShown = true, onFullscreenClick, isFullscreen, zoom = 1, monacoModelPath, hoistedMenuItems, } = props;
21818
+ const { value, onChange, diagnostics, isReadonly, theme = 'LIGHT', translations, onFileUpload, isUploadButtonShown, isCameraButtonShown, isDownloadButtonShown, isAboutButtonShown = true, isFullscreenButtonShown = true, onFullscreenClick, isFullscreen, zoom = 1, monacoModelPath, hoistedMenuItems, } = props;
21763
21819
  const zoomLevel = zoom;
21764
21820
  const scaledLineHeight = Math.round(BookEditorMonacoConstants.LINE_HEIGHT * zoomLevel);
21765
21821
  const scaledContentPaddingLeft = Math.max(8, Math.round(BookEditorMonacoConstants.CONTENT_PADDING_LEFT * zoomLevel));
@@ -21784,7 +21840,7 @@
21784
21840
  onFileUpload,
21785
21841
  });
21786
21842
  const combinedDiagnostics = [...(diagnostics || []), ...createDeprecatedCommitmentDiagnostics(value)];
21787
- useBookEditorMonacoLanguage({ monaco });
21843
+ useBookEditorMonacoLanguage({ monaco, theme });
21788
21844
  useBookEditorMonacoDiagnostics({ monaco, editor, diagnostics: combinedDiagnostics });
21789
21845
  useBookEditorMonacoDecorations({ editor, monaco });
21790
21846
  useBookEditorMonacoStyles({
@@ -21793,6 +21849,7 @@
21793
21849
  scaledLineHeight,
21794
21850
  scaledVerticalLineLeft,
21795
21851
  zoomLevel,
21852
+ theme,
21796
21853
  });
21797
21854
  /**
21798
21855
  * Re-applies Book language + theme to the currently mounted Monaco model.
@@ -21801,9 +21858,9 @@
21801
21858
  if (!editor || !monaco) {
21802
21859
  return;
21803
21860
  }
21804
- ensureBookEditorMonacoLanguageForEditor({ monaco, monacoEditor: editor });
21861
+ ensureBookEditorMonacoLanguageForEditor({ monaco, monacoEditor: editor, theme });
21805
21862
  logBookEditorMonacoDebug(`Re-applied Book Monaco language/theme (${reason}).`);
21806
- }, [editor, monaco]);
21863
+ }, [editor, monaco, theme]);
21807
21864
  react.useEffect(() => {
21808
21865
  setIsTouchDevice(typeof window !== 'undefined' && window.matchMedia('(pointer: coarse)').matches);
21809
21866
  }, []);
@@ -21910,16 +21967,16 @@
21910
21967
  * Ensures Book language/tokenizer is ready before Monaco creates the editor model.
21911
21968
  */
21912
21969
  const handleBeforeMonacoMount = react.useCallback((beforeMountMonaco) => {
21913
- ensureBookEditorMonacoLanguage(beforeMountMonaco);
21914
- }, []);
21970
+ ensureBookEditorMonacoLanguage(beforeMountMonaco, theme);
21971
+ }, [theme]);
21915
21972
  /**
21916
21973
  * Re-applies Book language/theme once Monaco editor is mounted.
21917
21974
  */
21918
21975
  const handleMonacoMount = react.useCallback((mountedEditor, mountedMonaco) => {
21919
21976
  setEditor(mountedEditor);
21920
- ensureBookEditorMonacoLanguageForEditor({ monaco: mountedMonaco, monacoEditor: mountedEditor });
21977
+ ensureBookEditorMonacoLanguageForEditor({ monaco: mountedMonaco, monacoEditor: mountedEditor, theme });
21921
21978
  logBookEditorMonacoDebug('Mounted Monaco editor and re-applied Book language/theme.');
21922
- }, []);
21979
+ }, [theme]);
21923
21980
  const handleDragOver = react.useCallback((event) => {
21924
21981
  event.preventDefault();
21925
21982
  setIsDragOver(true);
@@ -22025,7 +22082,7 @@
22025
22082
  * @public exported from `@promptbook/components`
22026
22083
  */
22027
22084
  function BookEditor(props) {
22028
- const { agentSource, className, style, zoom = 1, value, onChange, diagnostics, onFileUpload, isVerbose = DEFAULT_IS_VERBOSE, isBorderRadiusDisabled = false, isReadonly = false, translations, isUploadButtonShown = true, isCameraButtonShown, isDownloadButtonShown = true, isAboutButtonShown = true, isFullscreenButtonShown = true, sync, monacoModelPath, hoistedMenuItems, } = props;
22085
+ const { agentSource, className, style, theme = 'LIGHT', zoom = 1, value, onChange, diagnostics, onFileUpload, isVerbose = DEFAULT_IS_VERBOSE, isBorderRadiusDisabled = false, isReadonly = false, translations, isUploadButtonShown = true, isCameraButtonShown, isDownloadButtonShown = true, isAboutButtonShown = true, isFullscreenButtonShown = true, sync, monacoModelPath, hoistedMenuItems, } = props;
22029
22086
  const [isFullscreen, setIsFullscreen] = react.useState(false);
22030
22087
  /**
22031
22088
  * Toggles fullscreen mode for the editor.
@@ -22033,7 +22090,7 @@
22033
22090
  const handleFullscreenToggle = () => {
22034
22091
  setIsFullscreen(!isFullscreen);
22035
22092
  };
22036
- const editorContent = (jsxRuntime.jsx("div", { "data-book-component": "BookEditor", className: classNames(styles$d.BookEditor, isVerbose && styles$d.isVerbose, styles$d.bookEditorWrapper, isBorderRadiusDisabled && styles$d.isBorderRadiusDisabled, isFullscreen && styles$d.fullscreen, className), style: isFullscreen
22093
+ const editorContent = (jsxRuntime.jsx("div", { "data-book-component": "BookEditor", "data-book-editor-theme": theme.toLowerCase(), className: classNames(styles$d.BookEditor, isVerbose && styles$d.isVerbose, styles$d.bookEditorWrapper, isBorderRadiusDisabled && styles$d.isBorderRadiusDisabled, isFullscreen && styles$d.fullscreen, className), style: isFullscreen
22037
22094
  ? style
22038
22095
  : {
22039
22096
  ...(style || {}),
@@ -22044,7 +22101,7 @@
22044
22101
  ? `${props.height}px`
22045
22102
  : props.height || `${DEFAULT_BOOK_EDITOR_HEIGHT}px`,
22046
22103
  }),
22047
- }, children: jsxRuntime.jsx(BookEditorMonaco, { value: agentSource || value, onChange: onChange, diagnostics: diagnostics, onFileUpload: onFileUpload, isVerbose: isVerbose, isBorderRadiusDisabled: isBorderRadiusDisabled, isReadonly: isReadonly, translations: translations, isUploadButtonShown: isUploadButtonShown, isCameraButtonShown: isCameraButtonShown, isDownloadButtonShown: isDownloadButtonShown, isAboutButtonShown: isAboutButtonShown, isFullscreenButtonShown: isFullscreenButtonShown, onFullscreenClick: handleFullscreenToggle, isFullscreen: isFullscreen, sync: sync, zoom: zoom, monacoModelPath: monacoModelPath, hoistedMenuItems: hoistedMenuItems }) }));
22104
+ }, children: jsxRuntime.jsx(BookEditorMonaco, { value: agentSource || value, onChange: onChange, diagnostics: diagnostics, onFileUpload: onFileUpload, isVerbose: isVerbose, isBorderRadiusDisabled: isBorderRadiusDisabled, isReadonly: isReadonly, translations: translations, isUploadButtonShown: isUploadButtonShown, isCameraButtonShown: isCameraButtonShown, isDownloadButtonShown: isDownloadButtonShown, isAboutButtonShown: isAboutButtonShown, isFullscreenButtonShown: isFullscreenButtonShown, onFullscreenClick: handleFullscreenToggle, isFullscreen: isFullscreen, sync: sync, zoom: zoom, monacoModelPath: monacoModelPath, hoistedMenuItems: hoistedMenuItems, theme: theme }) }));
22048
22105
  return isFullscreen && typeof document !== 'undefined' ? reactDom.createPortal(editorContent, document.body) : editorContent;
22049
22106
  }
22050
22107
 
@@ -26069,6 +26126,138 @@
26069
26126
  return currentValue + (targetValue - currentValue) * blend;
26070
26127
  }
26071
26128
 
26129
+ // Note: [💞] Ignore a discrepancy between file name and entity name
26130
+ /**
26131
+ * Next registration id used by the shared avatar animation scheduler.
26132
+ *
26133
+ * @private utility of the avatar rendering system
26134
+ */
26135
+ let nextAvatarAnimationListenerId = 1;
26136
+ /**
26137
+ * Active avatar animation callbacks keyed by their registration id.
26138
+ *
26139
+ * @private utility of the avatar rendering system
26140
+ */
26141
+ const avatarAnimationListeners = new Map();
26142
+ /**
26143
+ * Active shared animation-frame handle.
26144
+ *
26145
+ * @private utility of the avatar rendering system
26146
+ */
26147
+ let avatarAnimationFrameId = null;
26148
+ /**
26149
+ * Registers one avatar animation callback in the shared animation loop.
26150
+ *
26151
+ * @param avatarAnimationListener Frame callback invoked on every animation frame.
26152
+ * @returns Cleanup function that unregisters the callback.
26153
+ *
26154
+ * @private utility of the avatar rendering system
26155
+ */
26156
+ function retainAvatarAnimationListener(avatarAnimationListener) {
26157
+ if (typeof window === 'undefined') {
26158
+ return () => undefined;
26159
+ }
26160
+ const listenerId = nextAvatarAnimationListenerId++;
26161
+ avatarAnimationListeners.set(listenerId, avatarAnimationListener);
26162
+ ensureAvatarAnimationLoop();
26163
+ return () => {
26164
+ avatarAnimationListeners.delete(listenerId);
26165
+ if (avatarAnimationListeners.size === 0 && avatarAnimationFrameId !== null) {
26166
+ window.cancelAnimationFrame(avatarAnimationFrameId);
26167
+ avatarAnimationFrameId = null;
26168
+ }
26169
+ };
26170
+ }
26171
+ /**
26172
+ * Ensures the shared animation loop is running while at least one avatar listener is active.
26173
+ *
26174
+ * @private utility of the avatar rendering system
26175
+ */
26176
+ function ensureAvatarAnimationLoop() {
26177
+ if (avatarAnimationFrameId !== null || avatarAnimationListeners.size === 0 || typeof window === 'undefined') {
26178
+ return;
26179
+ }
26180
+ const runFrame = (now) => {
26181
+ avatarAnimationFrameId = null;
26182
+ for (const avatarAnimationListener of [...avatarAnimationListeners.values()]) {
26183
+ avatarAnimationListener(now);
26184
+ }
26185
+ ensureAvatarAnimationLoop();
26186
+ };
26187
+ avatarAnimationFrameId = window.requestAnimationFrame(runFrame);
26188
+ }
26189
+
26190
+ // Note: [💞] Ignore a discrepancy between file name and entity name
26191
+ /**
26192
+ * Shared `IntersectionObserver` callbacks grouped by observed element.
26193
+ *
26194
+ * @private utility of the avatar rendering system
26195
+ */
26196
+ const avatarVisibilityListeners = new Map();
26197
+ /**
26198
+ * Lazily created shared `IntersectionObserver` used by avatar canvases.
26199
+ *
26200
+ * @private utility of the avatar rendering system
26201
+ */
26202
+ let avatarVisibilityObserver = null;
26203
+ /**
26204
+ * Observes one avatar element and notifies the caller when it enters or leaves the viewport.
26205
+ *
26206
+ * @param element Observed avatar element.
26207
+ * @param avatarVisibilityListener Listener notified with the current visibility state.
26208
+ * @returns Cleanup function that stops observing the element.
26209
+ *
26210
+ * @private utility of the avatar rendering system
26211
+ */
26212
+ function observeAvatarVisibility(element, avatarVisibilityListener) {
26213
+ if (typeof window === 'undefined' || typeof IntersectionObserver === 'undefined') {
26214
+ avatarVisibilityListener(true);
26215
+ return () => undefined;
26216
+ }
26217
+ const observer = getAvatarVisibilityObserver();
26218
+ const elementListeners = avatarVisibilityListeners.get(element) || new Set();
26219
+ elementListeners.add(avatarVisibilityListener);
26220
+ avatarVisibilityListeners.set(element, elementListeners);
26221
+ observer.observe(element);
26222
+ return () => {
26223
+ const currentElementListeners = avatarVisibilityListeners.get(element);
26224
+ if (!currentElementListeners) {
26225
+ return;
26226
+ }
26227
+ currentElementListeners.delete(avatarVisibilityListener);
26228
+ if (currentElementListeners.size > 0) {
26229
+ return;
26230
+ }
26231
+ avatarVisibilityListeners.delete(element);
26232
+ observer.unobserve(element);
26233
+ };
26234
+ }
26235
+ /**
26236
+ * Creates the shared `IntersectionObserver` used by all avatar canvases.
26237
+ *
26238
+ * @returns Shared observer instance.
26239
+ *
26240
+ * @private utility of the avatar rendering system
26241
+ */
26242
+ function getAvatarVisibilityObserver() {
26243
+ if (avatarVisibilityObserver) {
26244
+ return avatarVisibilityObserver;
26245
+ }
26246
+ avatarVisibilityObserver = new IntersectionObserver((entries) => {
26247
+ for (const entry of entries) {
26248
+ const elementListeners = avatarVisibilityListeners.get(entry.target);
26249
+ if (!elementListeners) {
26250
+ continue;
26251
+ }
26252
+ const isVisible = entry.isIntersecting && entry.intersectionRatio > 0;
26253
+ for (const avatarVisibilityListener of elementListeners) {
26254
+ avatarVisibilityListener(isVisible);
26255
+ }
26256
+ }
26257
+ });
26258
+ return avatarVisibilityObserver;
26259
+ }
26260
+
26072
26261
  // Note: [💞] Ignore a discrepancy between file name and entity name
26073
26262
  /**
26074
26263
  * Active avatar instances currently consuming the shared pointer tracker.
@@ -26082,6 +26271,18 @@
26082
26271
  * @private utility of the avatar rendering system
26083
26272
  */
26084
26273
  let currentAvatarPointerSnapshot = null;
26274
+ /**
26275
+ * Monotonic version incremented whenever the shared pointer snapshot changes.
26276
+ *
26277
+ * @private utility of the avatar rendering system
26278
+ */
26279
+ let currentAvatarPointerSnapshotVersion = 0;
26280
+ /**
26281
+ * Monotonic version incremented whenever scrolling or resizing may invalidate cached avatar bounds.
26282
+ *
26283
+ * @private utility of the avatar rendering system
26284
+ */
26285
+ let currentAvatarViewportLayoutVersion = 0;
26085
26286
  /**
26086
26287
  * Cleanup function for the lazily attached global listeners.
26087
26288
  *
@@ -26119,6 +26320,26 @@
26119
26320
  function getAvatarPointerSnapshot() {
26120
26321
  return currentAvatarPointerSnapshot;
26121
26322
  }
26323
+ /**
26324
+ * Returns the current pointer snapshot version.
26325
+ *
26326
+ * @returns Monotonic pointer snapshot version.
26327
+ *
26328
+ * @private utility of the avatar rendering system
26329
+ */
26330
+ function getAvatarPointerSnapshotVersion() {
26331
+ return currentAvatarPointerSnapshotVersion;
26332
+ }
26333
+ /**
26334
+ * Returns the current viewport-layout version used to invalidate cached avatar bounds.
26335
+ *
26336
+ * @returns Monotonic viewport-layout version.
26337
+ *
26338
+ * @private utility of the avatar rendering system
26339
+ */
26340
+ function getAvatarViewportLayoutVersion() {
26341
+ return currentAvatarViewportLayoutVersion;
26342
+ }
26122
26343
  /**
26123
26344
  * Attaches the global pointer/touch listeners used by all live avatar canvases.
26124
26345
  *
@@ -26131,7 +26352,11 @@
26131
26352
  return () => undefined;
26132
26353
  }
26133
26354
  const clearPointerSnapshot = () => {
26355
+ if (currentAvatarPointerSnapshot === null) {
26356
+ return;
26357
+ }
26134
26358
  currentAvatarPointerSnapshot = null;
26359
+ currentAvatarPointerSnapshotVersion++;
26135
26360
  };
26136
26361
  const updatePointerSnapshot = (clientX, clientY, pointerType) => {
26137
26362
  currentAvatarPointerSnapshot = {
@@ -26140,6 +26365,10 @@
26140
26365
  isPointerActive: true,
26141
26366
  pointerType,
26142
26367
  };
26368
+ currentAvatarPointerSnapshotVersion++;
26369
+ };
26370
+ const invalidateViewportLayout = () => {
26371
+ currentAvatarViewportLayoutVersion++;
26143
26372
  };
26144
26373
  const handlePointerMove = (event) => {
26145
26374
  updatePointerSnapshot(event.clientX, event.clientY, normalizeAvatarPointerType(event.pointerType));
@@ -26175,6 +26404,8 @@
26175
26404
  window.addEventListener('touchmove', handleTouchEvent, { passive: true });
26176
26405
  window.addEventListener('touchend', clearPointerSnapshot, { passive: true });
26177
26406
  window.addEventListener('touchcancel', clearPointerSnapshot, { passive: true });
26407
+ window.addEventListener('scroll', invalidateViewportLayout, { passive: true, capture: true });
26408
+ window.addEventListener('resize', invalidateViewportLayout, { passive: true });
26178
26409
  return () => {
26179
26410
  window.removeEventListener('pointermove', handlePointerMove);
26180
26411
  window.removeEventListener('pointerdown', handlePointerDown);
@@ -26186,6 +26417,8 @@
26186
26417
  window.removeEventListener('touchmove', handleTouchEvent);
26187
26418
  window.removeEventListener('touchend', clearPointerSnapshot);
26188
26419
  window.removeEventListener('touchcancel', clearPointerSnapshot);
26420
+ window.removeEventListener('scroll', invalidateViewportLayout, true);
26421
+ window.removeEventListener('resize', invalidateViewportLayout);
26189
26422
  };
26190
26423
  }
26191
26424
  /**
@@ -26279,37 +26512,49 @@
26279
26512
  * @private shared geometry helper of `octopus3AvatarVisual` and `asciiOctopusAvatarVisual`
26280
26513
  */
26281
26514
  function createOrganicOctopusTentacleShapes(options) {
26282
- const { size, centerX, centerY, bodyRadius, horizontalStretch, tentacleCount, shapePhase, createRandom, timeMs, saltPrefix, bodyPoints } = options;
26515
+ var _a, _b, _c, _d, _e, _f, _g, _h;
26516
+ const { size, centerX, centerY, bodyRadius, horizontalStretch, tentacleCount, shapePhase, createRandom, timeMs, saltPrefix, bodyPoints, variation, } = options;
26283
26517
  const baseY = centerY + bodyRadius * 0.74;
26284
26518
  const lowerBodyAnchorPoints = bodyPoints ? resolveTentacleBodyAnchorPoints(bodyPoints, centerY + bodyRadius * 0.04) : null;
26519
+ const flowLengthScale = (_a = variation === null || variation === void 0 ? void 0 : variation.flowLengthScale) !== null && _a !== void 0 ? _a : 1;
26520
+ const lateralReachScale = (_b = variation === null || variation === void 0 ? void 0 : variation.lateralReachScale) !== null && _b !== void 0 ? _b : 1;
26521
+ const tipReachScale = (_c = variation === null || variation === void 0 ? void 0 : variation.tipReachScale) !== null && _c !== void 0 ? _c : 1;
26522
+ const baseWidthScale = (_d = variation === null || variation === void 0 ? void 0 : variation.baseWidthScale) !== null && _d !== void 0 ? _d : 1;
26523
+ const tipWidthScale = (_e = variation === null || variation === void 0 ? void 0 : variation.tipWidthScale) !== null && _e !== void 0 ? _e : 1;
26524
+ const rootSpreadScale = (_f = variation === null || variation === void 0 ? void 0 : variation.rootSpreadScale) !== null && _f !== void 0 ? _f : 1;
26525
+ const startYOffsetScale = (_g = variation === null || variation === void 0 ? void 0 : variation.startYOffsetScale) !== null && _g !== void 0 ? _g : 1;
26526
+ const swayScale = (_h = variation === null || variation === void 0 ? void 0 : variation.swayScale) !== null && _h !== void 0 ? _h : 1;
26285
26527
  return Array.from({ length: tentacleCount }, (_, tentacleIndex) => {
26286
26528
  const tentacleRandom = createRandom(`${saltPrefix}-tentacle-${tentacleIndex}`);
26287
26529
  const spreadProgress = tentacleCount === 1 ? 0.5 : tentacleIndex / (tentacleCount - 1);
26288
26530
  const centeredProgress = spreadProgress - 0.5;
26531
+ const spreadCenteredProgress = centeredProgress * rootSpreadScale;
26532
+ const spreadAnchorProgress = Math.min(1, Math.max(0, 0.5 + spreadCenteredProgress));
26289
26533
  const temporalSway = Math.sin(timeMs / (720 + tentacleIndex * 34) + shapePhase + tentacleRandom() * Math.PI * 2) *
26290
26534
  size *
26291
- (0.014 + tentacleRandom() * 0.015);
26292
- const flowLength = size * (0.24 + tentacleRandom() * 0.18);
26293
- const curlDirection = centeredProgress === 0 ? (tentacleRandom() < 0.5 ? -1 : 1) : Math.sign(centeredProgress);
26294
- const lateralReach = centeredProgress * size * (0.1 + tentacleRandom() * 0.1) + temporalSway;
26295
- const tipReach = curlDirection * size * (0.025 + tentacleRandom() * 0.07);
26296
- const startYOffset = Math.abs(centeredProgress) * size * 0.012 + tentacleRandom() * size * 0.01;
26535
+ (0.014 + tentacleRandom() * 0.015) *
26536
+ swayScale;
26537
+ const flowLength = size * (0.24 + tentacleRandom() * 0.18) * flowLengthScale;
26538
+ const curlDirection = spreadCenteredProgress === 0 ? (tentacleRandom() < 0.5 ? -1 : 1) : Math.sign(spreadCenteredProgress);
26539
+ const lateralReach = spreadCenteredProgress * size * (0.1 + tentacleRandom() * 0.1) * lateralReachScale + temporalSway;
26540
+ const tipReach = curlDirection * size * (0.025 + tentacleRandom() * 0.07) * tipReachScale;
26541
+ const startYOffset = (Math.abs(spreadCenteredProgress) * size * 0.012 + tentacleRandom() * size * 0.01) * startYOffsetScale;
26297
26542
  const startPoint = lowerBodyAnchorPoints && lowerBodyAnchorPoints.length >= 2
26298
26543
  ? createInsetTentacleStartPoint({
26299
26544
  bodyPoints: lowerBodyAnchorPoints,
26300
- anchorProgress: spreadProgress,
26545
+ anchorProgress: spreadAnchorProgress,
26301
26546
  centerX,
26302
26547
  centerY,
26303
26548
  bodyRadius,
26304
- centeredProgress,
26549
+ centeredProgress: spreadCenteredProgress,
26305
26550
  startYOffset,
26306
26551
  })
26307
26552
  : {
26308
- x: centerX + centeredProgress * bodyRadius * horizontalStretch * 1.52,
26553
+ x: centerX + spreadCenteredProgress * bodyRadius * horizontalStretch * 1.52,
26309
26554
  y: baseY + startYOffset,
26310
26555
  };
26311
26556
  const controlPointOne = {
26312
- x: startPoint.x + centeredProgress * size * 0.045 + temporalSway * 0.4,
26557
+ x: startPoint.x + spreadCenteredProgress * size * 0.045 * lateralReachScale + temporalSway * 0.4,
26313
26558
  y: startPoint.y + flowLength * (0.21 + tentacleRandom() * 0.08),
26314
26559
  };
26315
26560
  const controlPointTwo = {
@@ -26322,8 +26567,8 @@
26322
26567
  flowLength * (0.9 + tentacleRandom() * 0.12) +
26323
26568
  Math.cos(timeMs / (840 + tentacleIndex * 41) + shapePhase) * size * (0.008 + tentacleRandom() * 0.01),
26324
26569
  };
26325
- const baseWidth = size * (0.038 + tentacleRandom() * 0.02) * (1 - Math.abs(centeredProgress) * 0.18);
26326
- const tipWidth = baseWidth * (0.18 + tentacleRandom() * 0.2);
26570
+ const baseWidth = size * (0.038 + tentacleRandom() * 0.02) * (1 - Math.abs(spreadCenteredProgress) * 0.18) * baseWidthScale;
26571
+ const tipWidth = baseWidth * Math.min(0.52, (0.18 + tentacleRandom() * 0.2) * tipWidthScale);
26327
26572
  return {
26328
26573
  startPoint,
26329
26574
  controlPointOne,
@@ -27979,6 +28224,244 @@
27979
28224
  }
27980
28225
 
27981
28226
  /* eslint-disable no-magic-numbers */
28227
+ /**
28228
+ * Builds one deterministic morphology profile for `Octopus3`.
28229
+ *
28230
+ * @param createRandom Seeded random factory scoped to the current avatar.
28231
+ * @returns Stable morphology profile.
28232
+ *
28233
+ * @private helper of `octopus3AvatarVisual`
28234
+ */
28235
+ function createOctopus3MorphologyProfile(createRandom) {
28236
+ const bodyRandom = createRandom('octopus3-body-profile');
28237
+ const faceRandom = createRandom('octopus3-face-profile');
28238
+ const detailRandom = createRandom('octopus3-detail-profile');
28239
+ const bodyFamilyRoll = bodyRandom();
28240
+ let bodyFamily;
28241
+ let body;
28242
+ let tentacles;
28243
+ if (bodyFamilyRoll < 0.34) {
28244
+ bodyFamily = 'lantern';
28245
+ body = {
28246
+ centerXJitterRatio: resolveSeededRange(bodyRandom, -0.018, 0.018),
28247
+ centerYRatio: resolveSeededRange(bodyRandom, 0.39, 0.435),
28248
+ bodyRadiusRatio: resolveSeededRange(bodyRandom, 0.19, 0.23),
28249
+ horizontalStretch: resolveSeededRange(bodyRandom, 0.94, 1.08),
28250
+ verticalStretch: resolveSeededRange(bodyRandom, 1.02, 1.18),
28251
+ mantleLiftRatio: resolveSeededRange(bodyRandom, 0.115, 0.148),
28252
+ lowerDropRatio: resolveSeededRange(bodyRandom, 0.042, 0.066),
28253
+ tentacleDepthRatio: resolveSeededRange(bodyRandom, 0.018, 0.03),
28254
+ wobbleAmplitudeRatio: resolveSeededRange(bodyRandom, 0.009, 0.017),
28255
+ lobeCount: resolveSeededIntegerRange(bodyRandom, 4, 6),
28256
+ pointCount: resolveSeededIntegerRange(bodyRandom, 38, 42),
28257
+ shadowWidthRatio: resolveSeededRange(bodyRandom, 0.18, 0.23),
28258
+ shadowHeightRatio: resolveSeededRange(bodyRandom, 0.055, 0.075),
28259
+ crownHighlightWidthRatio: resolveSeededRange(bodyRandom, 0.14, 0.18),
28260
+ crownHighlightHeightRatio: resolveSeededRange(bodyRandom, 0.045, 0.062),
28261
+ crownHighlightYOffsetRatio: resolveSeededRange(bodyRandom, -0.165, -0.135),
28262
+ };
28263
+ tentacles = {
28264
+ count: resolveSeededIntegerRange(bodyRandom, 7, 10),
28265
+ flowLengthScale: resolveSeededRange(bodyRandom, 1.08, 1.34),
28266
+ lateralReachScale: resolveSeededRange(bodyRandom, 0.72, 0.94),
28267
+ tipReachScale: resolveSeededRange(bodyRandom, 0.82, 1.06),
28268
+ baseWidthScale: resolveSeededRange(bodyRandom, 0.82, 0.98),
28269
+ tipWidthScale: resolveSeededRange(bodyRandom, 0.9, 1.08),
28270
+ rootSpreadScale: resolveSeededRange(bodyRandom, 0.76, 0.94),
28271
+ startYOffsetScale: resolveSeededRange(bodyRandom, 0.82, 1),
28272
+ swayScale: resolveSeededRange(bodyRandom, 0.82, 1.02),
28273
+ };
28274
+ }
28275
+ else if (bodyFamilyRoll < 0.68) {
28276
+ bodyFamily = 'drifter';
28277
+ body = {
28278
+ centerXJitterRatio: resolveSeededRange(bodyRandom, -0.025, 0.025),
28279
+ centerYRatio: resolveSeededRange(bodyRandom, 0.425, 0.46),
28280
+ bodyRadiusRatio: resolveSeededRange(bodyRandom, 0.175, 0.215),
28281
+ horizontalStretch: resolveSeededRange(bodyRandom, 1.22, 1.42),
28282
+ verticalStretch: resolveSeededRange(bodyRandom, 0.82, 0.92),
28283
+ mantleLiftRatio: resolveSeededRange(bodyRandom, 0.092, 0.115),
28284
+ lowerDropRatio: resolveSeededRange(bodyRandom, 0.02, 0.036),
28285
+ tentacleDepthRatio: resolveSeededRange(bodyRandom, 0.032, 0.052),
28286
+ wobbleAmplitudeRatio: resolveSeededRange(bodyRandom, 0.013, 0.022),
28287
+ lobeCount: resolveSeededIntegerRange(bodyRandom, 7, 9),
28288
+ pointCount: resolveSeededIntegerRange(bodyRandom, 40, 46),
28289
+ shadowWidthRatio: resolveSeededRange(bodyRandom, 0.24, 0.28),
28290
+ shadowHeightRatio: resolveSeededRange(bodyRandom, 0.06, 0.082),
28291
+ crownHighlightWidthRatio: resolveSeededRange(bodyRandom, 0.17, 0.22),
28292
+ crownHighlightHeightRatio: resolveSeededRange(bodyRandom, 0.038, 0.055),
28293
+ crownHighlightYOffsetRatio: resolveSeededRange(bodyRandom, -0.14, -0.11),
28294
+ };
28295
+ tentacles = {
28296
+ count: resolveSeededIntegerRange(bodyRandom, 10, 13),
28297
+ flowLengthScale: resolveSeededRange(bodyRandom, 0.88, 1.08),
28298
+ lateralReachScale: resolveSeededRange(bodyRandom, 1.18, 1.42),
28299
+ tipReachScale: resolveSeededRange(bodyRandom, 1.12, 1.42),
28300
+ baseWidthScale: resolveSeededRange(bodyRandom, 0.9, 1.06),
28301
+ tipWidthScale: resolveSeededRange(bodyRandom, 0.88, 1.08),
28302
+ rootSpreadScale: resolveSeededRange(bodyRandom, 1.12, 1.32),
28303
+ startYOffsetScale: resolveSeededRange(bodyRandom, 0.92, 1.14),
28304
+ swayScale: resolveSeededRange(bodyRandom, 1.04, 1.22),
28305
+ };
28306
+ }
28307
+ else {
28308
+ bodyFamily = 'rounded';
28309
+ body = {
28310
+ centerXJitterRatio: resolveSeededRange(bodyRandom, -0.02, 0.02),
28311
+ centerYRatio: resolveSeededRange(bodyRandom, 0.398, 0.442),
28312
+ bodyRadiusRatio: resolveSeededRange(bodyRandom, 0.208, 0.248),
28313
+ horizontalStretch: resolveSeededRange(bodyRandom, 1.06, 1.22),
28314
+ verticalStretch: resolveSeededRange(bodyRandom, 0.9, 1.01),
28315
+ mantleLiftRatio: resolveSeededRange(bodyRandom, 0.1, 0.128),
28316
+ lowerDropRatio: resolveSeededRange(bodyRandom, 0.032, 0.052),
28317
+ tentacleDepthRatio: resolveSeededRange(bodyRandom, 0.038, 0.06),
28318
+ wobbleAmplitudeRatio: resolveSeededRange(bodyRandom, 0.014, 0.024),
28319
+ lobeCount: resolveSeededIntegerRange(bodyRandom, 5, 8),
28320
+ pointCount: resolveSeededIntegerRange(bodyRandom, 39, 44),
28321
+ shadowWidthRatio: resolveSeededRange(bodyRandom, 0.2, 0.25),
28322
+ shadowHeightRatio: resolveSeededRange(bodyRandom, 0.055, 0.08),
28323
+ crownHighlightWidthRatio: resolveSeededRange(bodyRandom, 0.16, 0.2),
28324
+ crownHighlightHeightRatio: resolveSeededRange(bodyRandom, 0.05, 0.07),
28325
+ crownHighlightYOffsetRatio: resolveSeededRange(bodyRandom, -0.155, -0.122),
28326
+ };
28327
+ tentacles = {
28328
+ count: resolveSeededIntegerRange(bodyRandom, 8, 12),
28329
+ flowLengthScale: resolveSeededRange(bodyRandom, 0.94, 1.16),
28330
+ lateralReachScale: resolveSeededRange(bodyRandom, 0.9, 1.14),
28331
+ tipReachScale: resolveSeededRange(bodyRandom, 0.96, 1.22),
28332
+ baseWidthScale: resolveSeededRange(bodyRandom, 1.02, 1.2),
28333
+ tipWidthScale: resolveSeededRange(bodyRandom, 1.02, 1.22),
28334
+ rootSpreadScale: resolveSeededRange(bodyRandom, 0.94, 1.08),
28335
+ startYOffsetScale: resolveSeededRange(bodyRandom, 0.9, 1.08),
28336
+ swayScale: resolveSeededRange(bodyRandom, 0.9, 1.1),
28337
+ };
28338
+ }
28339
+ const faceFamilyRoll = faceRandom();
28340
+ let faceFamily;
28341
+ let face;
28342
+ if (faceFamilyRoll < 0.34) {
28343
+ faceFamily = 'watchful';
28344
+ face = {
28345
+ eyeSpacingRatio: resolveSeededRange(faceRandom, 0.118, 0.152),
28346
+ eyeCenterYOffsetRatio: resolveSeededRange(faceRandom, -0.026, -0.002),
28347
+ eyeRadiusXRatio: resolveSeededRange(faceRandom, 0.05, 0.062),
28348
+ eyeHeightRatio: resolveSeededRange(faceRandom, 1.18, 1.38),
28349
+ eyeRotationRange: resolveSeededRange(faceRandom, 0.16, 0.28),
28350
+ eyeTiltBias: resolveSeededRange(faceRandom, 0.02, 0.06),
28351
+ mouthWidthRatio: resolveSeededRange(faceRandom, 0.058, 0.074),
28352
+ mouthYOffsetRatio: resolveSeededRange(faceRandom, 0.086, 0.104),
28353
+ mouthCurveDepthRatio: resolveSeededRange(faceRandom, 0.126, 0.15),
28354
+ mouthCenterOffsetRatio: resolveSeededRange(faceRandom, -0.006, 0.006),
28355
+ mouthCornerTiltRatio: resolveSeededRange(faceRandom, -0.002, 0.002),
28356
+ eyeStyle: {
28357
+ irisScale: resolveSeededRange(faceRandom, 1, 1.1),
28358
+ pupilWidthScale: resolveSeededRange(faceRandom, 0.86, 1.02),
28359
+ pupilHeightScale: resolveSeededRange(faceRandom, 0.94, 1.08),
28360
+ upperLidArchRatio: resolveSeededRange(faceRandom, 0.96, 1.12),
28361
+ upperLidInsetRatio: resolveSeededRange(faceRandom, 0.08, 0.14),
28362
+ lowerLidOpacity: resolveSeededRange(faceRandom, 0.12, 0.22),
28363
+ },
28364
+ };
28365
+ }
28366
+ else if (faceFamilyRoll < 0.68) {
28367
+ faceFamily = 'sleepy';
28368
+ face = {
28369
+ eyeSpacingRatio: resolveSeededRange(faceRandom, 0.092, 0.124),
28370
+ eyeCenterYOffsetRatio: resolveSeededRange(faceRandom, -0.002, 0.024),
28371
+ eyeRadiusXRatio: resolveSeededRange(faceRandom, 0.058, 0.074),
28372
+ eyeHeightRatio: resolveSeededRange(faceRandom, 0.96, 1.14),
28373
+ eyeRotationRange: resolveSeededRange(faceRandom, 0.1, 0.22),
28374
+ eyeTiltBias: resolveSeededRange(faceRandom, 0.01, 0.05),
28375
+ mouthWidthRatio: resolveSeededRange(faceRandom, 0.066, 0.086),
28376
+ mouthYOffsetRatio: resolveSeededRange(faceRandom, 0.094, 0.118),
28377
+ mouthCurveDepthRatio: resolveSeededRange(faceRandom, 0.118, 0.145),
28378
+ mouthCenterOffsetRatio: resolveSeededRange(faceRandom, -0.004, 0.004),
28379
+ mouthCornerTiltRatio: resolveSeededRange(faceRandom, -0.004, 0.004),
28380
+ eyeStyle: {
28381
+ irisScale: resolveSeededRange(faceRandom, 0.9, 1),
28382
+ pupilWidthScale: resolveSeededRange(faceRandom, 1, 1.18),
28383
+ pupilHeightScale: resolveSeededRange(faceRandom, 0.78, 0.92),
28384
+ upperLidArchRatio: resolveSeededRange(faceRandom, 0.7, 0.88),
28385
+ upperLidInsetRatio: resolveSeededRange(faceRandom, -0.02, 0.06),
28386
+ lowerLidOpacity: resolveSeededRange(faceRandom, 0.22, 0.34),
28387
+ },
28388
+ };
28389
+ }
28390
+ else {
28391
+ faceFamily = 'mischief';
28392
+ face = {
28393
+ eyeSpacingRatio: resolveSeededRange(faceRandom, 0.086, 0.114),
28394
+ eyeCenterYOffsetRatio: resolveSeededRange(faceRandom, -0.018, 0.01),
28395
+ eyeRadiusXRatio: resolveSeededRange(faceRandom, 0.046, 0.06),
28396
+ eyeHeightRatio: resolveSeededRange(faceRandom, 1.08, 1.28),
28397
+ eyeRotationRange: resolveSeededRange(faceRandom, 0.28, 0.44),
28398
+ eyeTiltBias: resolveSeededRange(faceRandom, 0.12, 0.22),
28399
+ mouthWidthRatio: resolveSeededRange(faceRandom, 0.052, 0.074),
28400
+ mouthYOffsetRatio: resolveSeededRange(faceRandom, 0.082, 0.1),
28401
+ mouthCurveDepthRatio: resolveSeededRange(faceRandom, 0.116, 0.15),
28402
+ mouthCenterOffsetRatio: resolveSeededRange(faceRandom, -0.018, 0.018),
28403
+ mouthCornerTiltRatio: resolveSeededRange(faceRandom, -0.01, 0.01),
28404
+ eyeStyle: {
28405
+ irisScale: resolveSeededRange(faceRandom, 1.04, 1.12),
28406
+ pupilWidthScale: resolveSeededRange(faceRandom, 0.72, 0.9),
28407
+ pupilHeightScale: resolveSeededRange(faceRandom, 0.96, 1.14),
28408
+ upperLidArchRatio: resolveSeededRange(faceRandom, 0.88, 1.02),
28409
+ upperLidInsetRatio: resolveSeededRange(faceRandom, 0.04, 0.12),
28410
+ lowerLidOpacity: resolveSeededRange(faceRandom, 0.08, 0.18),
28411
+ },
28412
+ };
28413
+ }
28414
+ return {
28415
+ bodyFamily,
28416
+ faceFamily,
28417
+ body,
28418
+ tentacles,
28419
+ face,
28420
+ details: {
28421
+ mantleCurrentCount: resolveSeededIntegerRange(detailRandom, 4, 8),
28422
+ mantleNodeCount: resolveSeededIntegerRange(detailRandom, 3, 7),
28423
+ },
28424
+ };
28425
+ }
28426
+ /**
28427
+ * Resolves one seeded floating-point number inside the provided range.
28428
+ *
28429
+ * @param random Seeded random generator.
28430
+ * @param minimumValue Inclusive lower bound.
28431
+ * @param maximumValue Inclusive upper bound.
28432
+ * @returns Seeded number within the range.
28433
+ *
28434
+ * @private helper of `octopus3AvatarVisual`
28435
+ */
28436
+ function resolveSeededRange(random, minimumValue, maximumValue) {
28437
+ return minimumValue + random() * (maximumValue - minimumValue);
28438
+ }
28439
+ /**
28440
+ * Resolves one seeded integer inside the provided inclusive range.
28441
+ *
28442
+ * @param random Seeded random generator.
28443
+ * @param minimumValue Inclusive lower bound.
28444
+ * @param maximumValue Inclusive upper bound.
28445
+ * @returns Seeded integer within the range.
28446
+ *
28447
+ * @private helper of `octopus3AvatarVisual`
28448
+ */
28449
+ function resolveSeededIntegerRange(random, minimumValue, maximumValue) {
28450
+ return minimumValue + Math.floor(random() * (maximumValue - minimumValue + 1));
28451
+ }
28452
+ /**
28453
+ * Converts an opacity ratio into a two-digit hexadecimal alpha suffix.
28454
+ *
28455
+ * @param opacity Opacity ratio in the range `[0, 1]`.
28456
+ * @returns Two-digit hexadecimal alpha string.
28457
+ *
28458
+ * @private helper of `octopus3AvatarVisual`
28459
+ */
28460
+ function formatAlphaHex(opacity) {
28461
+ return Math.round(Math.min(1, Math.max(0, opacity)) * 255)
28462
+ .toString(16)
28463
+ .padStart(2, '0');
28464
+ }
27982
28465
  /**
27983
28466
  * Octopus3 avatar visual.
27984
28467
  *
@@ -27991,22 +28474,24 @@
27991
28474
  isAnimated: true,
27992
28475
  supportsPointerTracking: true,
27993
28476
  render({ context, size, palette, createRandom, timeMs, interaction }) {
27994
- const staticRandom = createRandom('octopus3-static');
27995
- const centerX = size * (0.5 + (staticRandom() - 0.5) * 0.02) + interaction.bodyOffsetX * size * 0.05;
27996
- const centerY = size * (0.41 + staticRandom() * 0.05) + interaction.bodyOffsetY * size * 0.035;
27997
- const bodyRadius = size * (0.2 + staticRandom() * 0.045);
27998
- const horizontalStretch = 1.08 + staticRandom() * 0.22;
27999
- const verticalStretch = 0.9 + staticRandom() * 0.12;
28000
- const mantleLift = size * (0.105 + staticRandom() * 0.03);
28001
- const lowerDrop = size * (0.028 + staticRandom() * 0.022);
28002
- const tentacleDepth = size * (0.022 + staticRandom() * 0.018);
28003
- const wobbleAmplitude = size * (0.01 + staticRandom() * 0.01);
28004
- const lobeCount = 5 + Math.floor(staticRandom() * 3);
28005
- const shapePhase = staticRandom() * Math.PI * 2;
28006
- const tentacleCount = 8 + Math.floor(staticRandom() * 5);
28007
- const eyeSpacing = size * (0.11 + staticRandom() * 0.04);
28008
- const eyeRadiusX = size * (0.056 + staticRandom() * 0.014);
28009
- const eyeRadiusY = eyeRadiusX * (1.18 + staticRandom() * 0.18);
28477
+ const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
28478
+ const animationRandom = createRandom('octopus3-animation-profile');
28479
+ const eyeRandom = createRandom('octopus3-eye-profile');
28480
+ const centerX = size * (0.5 + morphologyProfile.body.centerXJitterRatio) + interaction.bodyOffsetX * size * 0.05;
28481
+ const centerY = size * morphologyProfile.body.centerYRatio + interaction.bodyOffsetY * size * 0.035;
28482
+ const bodyRadius = size * morphologyProfile.body.bodyRadiusRatio;
28483
+ const horizontalStretch = morphologyProfile.body.horizontalStretch;
28484
+ const verticalStretch = morphologyProfile.body.verticalStretch;
28485
+ const mantleLift = size * morphologyProfile.body.mantleLiftRatio;
28486
+ const lowerDrop = size * morphologyProfile.body.lowerDropRatio;
28487
+ const tentacleDepth = size * morphologyProfile.body.tentacleDepthRatio;
28488
+ const wobbleAmplitude = size * morphologyProfile.body.wobbleAmplitudeRatio;
28489
+ const lobeCount = morphologyProfile.body.lobeCount;
28490
+ const shapePhase = animationRandom() * Math.PI * 2;
28491
+ const eyeSpacing = size * morphologyProfile.face.eyeSpacingRatio;
28492
+ const eyeCenterY = centerY + size * morphologyProfile.face.eyeCenterYOffsetRatio;
28493
+ const eyeRadiusX = size * morphologyProfile.face.eyeRadiusXRatio;
28494
+ const eyeRadiusY = eyeRadiusX * morphologyProfile.face.eyeHeightRatio;
28010
28495
  const bodyPoints = createOrganicOctopusBodyPoints({
28011
28496
  centerX,
28012
28497
  centerY,
@@ -28020,7 +28505,7 @@
28020
28505
  lobeCount,
28021
28506
  shapePhase,
28022
28507
  timeMs,
28023
- pointCount: 40,
28508
+ pointCount: morphologyProfile.body.pointCount,
28024
28509
  });
28025
28510
  const tentacleShapes = createOrganicOctopusTentacleShapes({
28026
28511
  size,
@@ -28028,17 +28513,27 @@
28028
28513
  centerY,
28029
28514
  bodyRadius,
28030
28515
  horizontalStretch,
28031
- tentacleCount,
28516
+ tentacleCount: morphologyProfile.tentacles.count,
28032
28517
  shapePhase,
28033
28518
  createRandom,
28034
28519
  timeMs,
28035
28520
  saltPrefix: 'octopus3',
28036
28521
  bodyPoints,
28522
+ variation: {
28523
+ flowLengthScale: morphologyProfile.tentacles.flowLengthScale,
28524
+ lateralReachScale: morphologyProfile.tentacles.lateralReachScale,
28525
+ tipReachScale: morphologyProfile.tentacles.tipReachScale,
28526
+ baseWidthScale: morphologyProfile.tentacles.baseWidthScale,
28527
+ tipWidthScale: morphologyProfile.tentacles.tipWidthScale,
28528
+ rootSpreadScale: morphologyProfile.tentacles.rootSpreadScale,
28529
+ startYOffsetScale: morphologyProfile.tentacles.startYOffsetScale,
28530
+ swayScale: morphologyProfile.tentacles.swayScale,
28531
+ },
28037
28532
  });
28038
28533
  drawAvatarFrame(context, size, palette);
28039
- drawOctopus3Atmosphere(context, size, palette, centerX, centerY, timeMs, shapePhase);
28534
+ drawOctopus3Atmosphere(context, size, palette, centerX, centerY, timeMs, shapePhase, morphologyProfile);
28040
28535
  context.beginPath();
28041
- context.ellipse(centerX, centerY + size * 0.25, size * 0.24, size * 0.08, 0, 0, Math.PI * 2);
28536
+ context.ellipse(centerX, centerY + size * 0.25, size * morphologyProfile.body.shadowWidthRatio, size * morphologyProfile.body.shadowHeightRatio, 0, 0, Math.PI * 2);
28042
28537
  context.fillStyle = `${palette.shadow}33`;
28043
28538
  context.fill();
28044
28539
  for (const tentacleShape of tentacleShapes) {
@@ -28066,8 +28561,8 @@
28066
28561
  innerGlowGradient.addColorStop(1, `${palette.shadow}00`);
28067
28562
  context.fillStyle = innerGlowGradient;
28068
28563
  context.fillRect(centerX - size * 0.36, centerY - size * 0.34, size * 0.72, size * 0.72);
28069
- drawMantleCurrents(context, centerX, centerY, size, palette, timeMs, shapePhase);
28070
- drawMantleNodes(context, centerX, centerY, size, palette, createRandom);
28564
+ drawMantleCurrents(context, centerX, centerY, size, palette, timeMs, shapePhase, morphologyProfile);
28565
+ drawMantleNodes(context, centerX, centerY, size, palette, createRandom, morphologyProfile);
28071
28566
  context.restore();
28072
28567
  context.save();
28073
28568
  traceSmoothClosedPath(context, bodyPoints);
@@ -28076,14 +28571,19 @@
28076
28571
  context.stroke();
28077
28572
  context.restore();
28078
28573
  context.beginPath();
28079
- context.ellipse(centerX, centerY - size * 0.14, size * 0.18, size * 0.062, 0, Math.PI, Math.PI * 2);
28574
+ context.ellipse(centerX, centerY + size * morphologyProfile.body.crownHighlightYOffsetRatio, size * morphologyProfile.body.crownHighlightWidthRatio, size * morphologyProfile.body.crownHighlightHeightRatio, 0, Math.PI, Math.PI * 2);
28080
28575
  context.fillStyle = `${palette.highlight}3d`;
28081
28576
  context.fill();
28082
- drawSeededEye(context, centerX - eyeSpacing, centerY - size * 0.01, eyeRadiusX, eyeRadiusY, (staticRandom() - 0.5) * 0.28, palette, timeMs, shapePhase, interaction);
28083
- drawSeededEye(context, centerX + eyeSpacing, centerY - size * 0.01, eyeRadiusX, eyeRadiusY, (staticRandom() - 0.5) * 0.28, palette, timeMs, shapePhase + Math.PI / 4, interaction);
28577
+ drawSeededEye(context, centerX - eyeSpacing, eyeCenterY, eyeRadiusX, eyeRadiusY, -morphologyProfile.face.eyeTiltBias + (eyeRandom() - 0.5) * morphologyProfile.face.eyeRotationRange, palette, timeMs, shapePhase, interaction, morphologyProfile.face.eyeStyle);
28578
+ drawSeededEye(context, centerX + eyeSpacing, eyeCenterY, eyeRadiusX, eyeRadiusY, morphologyProfile.face.eyeTiltBias + (eyeRandom() - 0.5) * morphologyProfile.face.eyeRotationRange, palette, timeMs, shapePhase + Math.PI / 4, interaction, morphologyProfile.face.eyeStyle);
28579
+ const mouthHalfWidth = size * morphologyProfile.face.mouthWidthRatio;
28580
+ const mouthY = centerY + size * morphologyProfile.face.mouthYOffsetRatio;
28581
+ const mouthCornerTilt = size * morphologyProfile.face.mouthCornerTiltRatio;
28084
28582
  context.beginPath();
28085
- context.moveTo(centerX - size * 0.07, centerY + size * 0.09);
28086
- context.quadraticCurveTo(centerX, centerY + size * (0.14 + Math.sin(timeMs / 620 + shapePhase) * 0.016) + interaction.gazeY * size * 0.012, centerX + size * 0.07, centerY + size * 0.09);
28583
+ context.moveTo(centerX - mouthHalfWidth, mouthY - mouthCornerTilt);
28584
+ context.quadraticCurveTo(centerX + size * morphologyProfile.face.mouthCenterOffsetRatio, centerY +
28585
+ size * (morphologyProfile.face.mouthCurveDepthRatio + Math.sin(timeMs / 620 + shapePhase) * 0.016) +
28586
+ interaction.gazeY * size * 0.012, centerX + mouthHalfWidth, mouthY + mouthCornerTilt);
28087
28587
  context.strokeStyle = `${palette.ink}b3`;
28088
28588
  context.lineWidth = size * 0.012;
28089
28589
  context.lineCap = 'round';
@@ -28100,17 +28600,18 @@
28100
28600
  * @param centerY Body center Y coordinate.
28101
28601
  * @param timeMs Current animation time in milliseconds.
28102
28602
  * @param shapePhase Seed-based phase offset.
28603
+ * @param morphologyProfile Seeded morphology profile.
28103
28604
  *
28104
28605
  * @private helper of `octopus3AvatarVisual`
28105
28606
  */
28106
- function drawOctopus3Atmosphere(context, size, palette, centerX, centerY, timeMs, shapePhase) {
28107
- const haloGradient = context.createRadialGradient(centerX, centerY - size * 0.08, size * 0.06, centerX, centerY, size * 0.62);
28607
+ function drawOctopus3Atmosphere(context, size, palette, centerX, centerY, timeMs, shapePhase, morphologyProfile) {
28608
+ const haloGradient = context.createRadialGradient(centerX, centerY - size * (0.07 + (morphologyProfile.body.verticalStretch - 0.9) * 0.05), size * 0.06, centerX, centerY, size * (0.56 + morphologyProfile.body.bodyRadiusRatio * 0.45));
28108
28609
  haloGradient.addColorStop(0, `${palette.highlight}5c`);
28109
28610
  haloGradient.addColorStop(0.35, `${palette.accent}26`);
28110
28611
  haloGradient.addColorStop(1, `${palette.highlight}00`);
28111
28612
  context.fillStyle = haloGradient;
28112
28613
  context.fillRect(0, 0, size, size);
28113
- const lowerGlowGradient = context.createRadialGradient(centerX + Math.sin(timeMs / 1600 + shapePhase) * size * 0.04, centerY + size * 0.2, size * 0.04, centerX, centerY + size * 0.2, size * 0.48);
28614
+ const lowerGlowGradient = context.createRadialGradient(centerX + Math.sin(timeMs / 1600 + shapePhase) * size * 0.04, centerY + size * (0.18 + morphologyProfile.tentacles.flowLengthScale * 0.025), size * 0.04, centerX, centerY + size * (0.18 + morphologyProfile.tentacles.flowLengthScale * 0.025), size * (0.42 + morphologyProfile.tentacles.lateralReachScale * 0.06));
28114
28615
  lowerGlowGradient.addColorStop(0, `${palette.secondary}1f`);
28115
28616
  lowerGlowGradient.addColorStop(1, `${palette.secondary}00`);
28116
28617
  context.fillStyle = lowerGlowGradient;
@@ -28219,18 +28720,22 @@
28219
28720
  * @param palette Derived avatar palette.
28220
28721
  * @param timeMs Current animation time in milliseconds.
28221
28722
  * @param shapePhase Seed-based phase offset.
28723
+ * @param morphologyProfile Seeded morphology profile.
28222
28724
  *
28223
28725
  * @private helper of `octopus3AvatarVisual`
28224
28726
  */
28225
- function drawMantleCurrents(context, centerX, centerY, size, palette, timeMs, shapePhase) {
28226
- for (let currentIndex = 0; currentIndex < 6; currentIndex++) {
28227
- const horizontalOffset = (currentIndex - 2.5) * size * 0.06;
28727
+ function drawMantleCurrents(context, centerX, centerY, size, palette, timeMs, shapePhase, morphologyProfile) {
28728
+ const centeredCurrentIndex = (morphologyProfile.details.mantleCurrentCount - 1) / 2;
28729
+ for (let currentIndex = 0; currentIndex < morphologyProfile.details.mantleCurrentCount; currentIndex++) {
28730
+ const horizontalOffset = (currentIndex - centeredCurrentIndex) *
28731
+ size *
28732
+ (0.05 + (morphologyProfile.body.horizontalStretch - 0.9) * 0.025);
28228
28733
  const sway = Math.sin(timeMs / 680 + currentIndex * 0.78 + shapePhase) * size * 0.024;
28229
28734
  context.beginPath();
28230
- context.moveTo(centerX + horizontalOffset * 0.3, centerY - size * 0.13);
28231
- context.bezierCurveTo(centerX + horizontalOffset - sway * 0.25, centerY - size * 0.04, centerX + horizontalOffset + sway, centerY + size * 0.06, centerX + horizontalOffset * 0.7 + sway * 0.46, centerY + size * 0.2);
28735
+ context.moveTo(centerX + horizontalOffset * 0.3, centerY - size * (0.11 + morphologyProfile.body.verticalStretch * 0.02));
28736
+ context.bezierCurveTo(centerX + horizontalOffset - sway * 0.25, centerY - size * 0.04, centerX + horizontalOffset + sway, centerY + size * 0.06, centerX + horizontalOffset * 0.7 + sway * 0.46, centerY + size * (0.16 + morphologyProfile.body.verticalStretch * 0.035));
28232
28737
  context.strokeStyle = currentIndex % 2 === 0 ? `${palette.highlight}30` : `${palette.accent}26`;
28233
- context.lineWidth = size * (0.008 + currentIndex * 0.0007);
28738
+ context.lineWidth = size * (0.0075 + currentIndex * 0.00065 + morphologyProfile.tentacles.baseWidthScale * 0.0005);
28234
28739
  context.lineCap = 'round';
28235
28740
  context.stroke();
28236
28741
  }
@@ -28244,14 +28749,17 @@
28244
28749
  * @param size Canvas size in CSS pixels.
28245
28750
  * @param palette Derived avatar palette.
28246
28751
  * @param createRandom Seeded random factory scoped to the avatar.
28752
+ * @param morphologyProfile Seeded morphology profile.
28247
28753
  *
28248
28754
  * @private helper of `octopus3AvatarVisual`
28249
28755
  */
28250
- function drawMantleNodes(context, centerX, centerY, size, palette, createRandom) {
28251
- for (let nodeIndex = 0; nodeIndex < 5; nodeIndex++) {
28756
+ function drawMantleNodes(context, centerX, centerY, size, palette, createRandom, morphologyProfile) {
28757
+ for (let nodeIndex = 0; nodeIndex < morphologyProfile.details.mantleNodeCount; nodeIndex++) {
28252
28758
  const nodeRandom = createRandom(`octopus3-node-${nodeIndex}`);
28253
- const nodeX = centerX + (nodeRandom() - 0.5) * size * 0.28;
28254
- const nodeY = centerY - size * 0.03 + (nodeRandom() - 0.5) * size * 0.2;
28759
+ const nodeX = centerX + (nodeRandom() - 0.5) * size * (0.2 + (morphologyProfile.body.horizontalStretch - 0.9) * 0.16);
28760
+ const nodeY = centerY -
28761
+ size * 0.03 +
28762
+ (nodeRandom() - 0.5) * size * (0.16 + (morphologyProfile.body.verticalStretch - 0.82) * 0.1);
28255
28763
  const nodeRadius = size * (0.016 + nodeRandom() * 0.016);
28256
28764
  context.beginPath();
28257
28765
  context.arc(nodeX, nodeY, nodeRadius, 0, Math.PI * 2);
@@ -28272,10 +28780,11 @@
28272
28780
  * @param timeMs Current animation time in milliseconds.
28273
28781
  * @param phase Seed-based animation phase.
28274
28782
  * @param interaction Smoothed avatar interaction state.
28783
+ * @param eyeStyle Seeded eye-style traits.
28275
28784
  *
28276
28785
  * @private helper of `octopus3AvatarVisual`
28277
28786
  */
28278
- function drawSeededEye(context, centerX, centerY, radiusX, radiusY, rotation, palette, timeMs, phase, interaction) {
28787
+ function drawSeededEye(context, centerX, centerY, radiusX, radiusY, rotation, palette, timeMs, phase, interaction, eyeStyle) {
28279
28788
  const { pupilOffsetX, pupilOffsetY } = resolveOrganicEyeMotion({
28280
28789
  radiusX,
28281
28790
  radiusY,
@@ -28296,11 +28805,11 @@
28296
28805
  irisGradient.addColorStop(0.58, palette.secondary);
28297
28806
  irisGradient.addColorStop(1, palette.shadow);
28298
28807
  context.beginPath();
28299
- context.ellipse(pupilOffsetX, pupilOffsetY, radiusX * 0.66, radiusY * 0.74, 0, 0, Math.PI * 2);
28808
+ context.ellipse(pupilOffsetX, pupilOffsetY, radiusX * 0.66 * eyeStyle.irisScale, radiusY * 0.74 * eyeStyle.irisScale, 0, 0, Math.PI * 2);
28300
28809
  context.fillStyle = irisGradient;
28301
28810
  context.fill();
28302
28811
  context.beginPath();
28303
- context.ellipse(pupilOffsetX, pupilOffsetY, radiusX * 0.14, radiusY * 0.5, 0, 0, Math.PI * 2);
28812
+ context.ellipse(pupilOffsetX, pupilOffsetY, radiusX * 0.14 * eyeStyle.pupilWidthScale, radiusY * 0.5 * eyeStyle.pupilHeightScale, 0, 0, Math.PI * 2);
28304
28813
  context.fillStyle = palette.ink;
28305
28814
  context.fill();
28306
28815
  context.beginPath();
@@ -28317,12 +28826,21 @@
28317
28826
  context.lineWidth = radiusX * 0.18;
28318
28827
  context.stroke();
28319
28828
  context.beginPath();
28320
- context.moveTo(-radiusX * 0.88, -radiusY * 0.08);
28321
- context.quadraticCurveTo(0, -radiusY * (0.9 - interaction.gazeY * 0.16 + interaction.intensity * 0.08), radiusX * 0.88, -radiusY * 0.08);
28829
+ context.moveTo(-radiusX * 0.88, -radiusY * eyeStyle.upperLidInsetRatio);
28830
+ context.quadraticCurveTo(0, -radiusY * (eyeStyle.upperLidArchRatio - interaction.gazeY * 0.16 + interaction.intensity * 0.08), radiusX * 0.88, -radiusY * eyeStyle.upperLidInsetRatio);
28322
28831
  context.strokeStyle = `${palette.shadow}73`;
28323
28832
  context.lineWidth = radiusX * 0.16;
28324
28833
  context.lineCap = 'round';
28325
28834
  context.stroke();
28835
+ if (eyeStyle.lowerLidOpacity > 0) {
28836
+ context.beginPath();
28837
+ context.moveTo(-radiusX * 0.74, radiusY * 0.2);
28838
+ context.quadraticCurveTo(0, radiusY * 0.38, radiusX * 0.74, radiusY * 0.2);
28839
+ context.strokeStyle = `${palette.highlight}${formatAlphaHex(eyeStyle.lowerLidOpacity)}`;
28840
+ context.lineWidth = radiusX * 0.08;
28841
+ context.lineCap = 'round';
28842
+ context.stroke();
28843
+ }
28326
28844
  context.restore();
28327
28845
  }
28328
28846
 
@@ -28456,32 +28974,55 @@
28456
28974
  return avatarVisual;
28457
28975
  }
28458
28976
 
28977
+ /**
28978
+ * Resolves the stable avatar render inputs reused across multiple frames.
28979
+ *
28980
+ * @param options Avatar identity and visual selection.
28981
+ * @returns Stable render data ready to be used by `renderAvatarVisual`.
28982
+ *
28983
+ * @private shared helper for canvas avatar rendering
28984
+ */
28985
+ function resolveAvatarRenderDefinition(options) {
28986
+ const avatarDefinition = normalizeAvatarDefinition(options.avatarDefinition);
28987
+ const surface = options.surface || 'framed';
28988
+ return {
28989
+ avatarDefinition,
28990
+ avatarVisual: getAvatarVisualById(options.visualId),
28991
+ surface,
28992
+ palette: createAvatarPalette(avatarDefinition, surface),
28993
+ createRandom: createAvatarRandomFactory(avatarDefinition),
28994
+ };
28995
+ }
28459
28996
  /**
28460
28997
  * Renders one deterministic avatar frame into the provided canvas.
28461
28998
  *
28462
28999
  * @param options Rendering options.
29000
+ * @param resolvedAvatarRenderDefinition Optional stable render data reused between frames.
28463
29001
  *
28464
29002
  * @private shared helper for canvas avatar rendering
28465
29003
  */
28466
- function renderAvatarVisual(options) {
28467
- const normalizedAvatarDefinition = normalizeAvatarDefinition(options.avatarDefinition);
28468
- const avatarVisual = getAvatarVisualById(options.visualId);
28469
- const surface = options.surface || 'framed';
29004
+ function renderAvatarVisual(options, resolvedAvatarRenderDefinition) {
29005
+ const resolvedRenderDefinition = resolvedAvatarRenderDefinition ||
29006
+ resolveAvatarRenderDefinition({
29007
+ avatarDefinition: options.avatarDefinition,
29008
+ visualId: options.visualId,
29009
+ surface: options.surface,
29010
+ });
28470
29011
  const context = options.canvas.getContext('2d');
28471
29012
  if (!context) {
28472
29013
  throw new Error('2D canvas rendering context is unavailable.');
28473
29014
  }
28474
29015
  prepareAvatarCanvas(options.canvas, context, options.size, options.devicePixelRatio || 1);
28475
- avatarVisual.render({
29016
+ resolvedRenderDefinition.avatarVisual.render({
28476
29017
  canvas: options.canvas,
28477
29018
  context,
28478
29019
  size: options.size,
28479
29020
  devicePixelRatio: options.devicePixelRatio || 1,
28480
29021
  timeMs: options.timeMs,
28481
- avatarDefinition: normalizedAvatarDefinition,
28482
- palette: createAvatarPalette(normalizedAvatarDefinition, surface),
28483
- createRandom: createAvatarRandomFactory(normalizedAvatarDefinition),
28484
- surface,
29022
+ avatarDefinition: resolvedRenderDefinition.avatarDefinition,
29023
+ palette: resolvedRenderDefinition.palette,
29024
+ createRandom: resolvedRenderDefinition.createRandom,
29025
+ surface: resolvedRenderDefinition.surface,
28485
29026
  interaction: options.interaction || createIdleAvatarInteractionState(),
28486
29027
  });
28487
29028
  }
@@ -28492,6 +29033,14 @@
28492
29033
  * @private helper of `<Avatar/>`
28493
29034
  */
28494
29035
  const AVATAR_CANVAS_RADIUS_RATIO = 0.18;
29036
+ /**
29037
+ * Maximum time between layout-bound refreshes while pointer tracking is active.
29038
+ *
29039
+ * This keeps pointer-aware visuals aligned with chat/layout shifts without forcing a layout read every frame.
29040
+ *
29041
+ * @private helper of `<Avatar/>`
29042
+ */
29043
+ const ACTIVE_POINTER_BOUNDS_REFRESH_MS = 120;
28495
29044
  /**
28496
29045
  * Canvas-based deterministic avatar component.
28497
29046
  *
@@ -28502,21 +29051,58 @@
28502
29051
  const canvasRef = react.useRef(null);
28503
29052
  const animationStartRef = react.useRef(null);
28504
29053
  const interactionRuntimeStateRef = react.useRef(createAvatarInteractionRuntimeState());
29054
+ const avatarBoundsRef = react.useRef(null);
29055
+ const lastResolvedPointerVersionRef = react.useRef(-1);
29056
+ const lastResolvedViewportLayoutVersionRef = react.useRef(-1);
29057
+ const lastAvatarBoundsRefreshAtRef = react.useRef(0);
28505
29058
  const avatarColorsKey = avatarDefinition.colors.join('|');
28506
- const normalizedAvatarDefinition = react.useMemo(() => normalizeAvatarDefinition(avatarDefinition), [avatarDefinition.agentHash, avatarDefinition.agentName, avatarColorsKey]);
28507
- const avatarDefinitionKey = react.useMemo(() => createAvatarDefinitionKey(normalizedAvatarDefinition), [normalizedAvatarDefinition.agentHash, normalizedAvatarDefinition.agentName, normalizedAvatarDefinition.colors.join('|')]);
28508
- const avatarVisual = react.useMemo(() => getAvatarVisualById(visualId), [visualId]);
29059
+ const resolvedAvatarRenderDefinition = react.useMemo(() => resolveAvatarRenderDefinition({
29060
+ avatarDefinition,
29061
+ visualId,
29062
+ surface,
29063
+ }), [avatarDefinition.agentHash, avatarDefinition.agentName, avatarColorsKey, surface, visualId]);
29064
+ const avatarDefinitionKey = react.useMemo(() => createAvatarDefinitionKey(resolvedAvatarRenderDefinition.avatarDefinition), [
29065
+ resolvedAvatarRenderDefinition.avatarDefinition.agentHash,
29066
+ resolvedAvatarRenderDefinition.avatarDefinition.agentName,
29067
+ resolvedAvatarRenderDefinition.avatarDefinition.colors.join('|'),
29068
+ ]);
29069
+ const [isVisible, setIsVisible] = react.useState(true);
29070
+ react.useEffect(() => {
29071
+ const canvas = canvasRef.current;
29072
+ if (!canvas) {
29073
+ throw new Error('Avatar canvas is not mounted.');
29074
+ }
29075
+ return observeAvatarVisibility(canvas, setIsVisible);
29076
+ }, []);
28509
29077
  react.useEffect(() => {
28510
29078
  interactionRuntimeStateRef.current = createAvatarInteractionRuntimeState();
28511
- }, [avatarDefinitionKey, visualId]);
29079
+ avatarBoundsRef.current = null;
29080
+ lastResolvedPointerVersionRef.current = -1;
29081
+ lastResolvedViewportLayoutVersionRef.current = -1;
29082
+ lastAvatarBoundsRefreshAtRef.current = 0;
29083
+ }, [avatarDefinitionKey, isVisible, visualId]);
29084
+ react.useEffect(() => {
29085
+ const canvas = canvasRef.current;
29086
+ if (!canvas || typeof ResizeObserver === 'undefined') {
29087
+ return;
29088
+ }
29089
+ const resizeObserver = new ResizeObserver(() => {
29090
+ avatarBoundsRef.current = null;
29091
+ });
29092
+ resizeObserver.observe(canvas);
29093
+ return () => {
29094
+ resizeObserver.disconnect();
29095
+ };
29096
+ }, []);
28512
29097
  react.useEffect(() => {
28513
29098
  const canvas = canvasRef.current;
28514
29099
  if (!canvas) {
28515
29100
  throw new Error('Avatar canvas is not mounted.');
28516
29101
  }
29102
+ const avatarVisual = resolvedAvatarRenderDefinition.avatarVisual;
28517
29103
  const isDynamicAvatar = avatarVisual.isAnimated || avatarVisual.supportsPointerTracking === true;
28518
- const releasePointerTracking = avatarVisual.supportsPointerTracking ? retainAvatarPointerTracking() : null;
28519
- let animationFrameId = null;
29104
+ const shouldTrackPointer = avatarVisual.supportsPointerTracking === true && isVisible;
29105
+ const releasePointerTracking = shouldTrackPointer ? retainAvatarPointerTracking() : null;
28520
29106
  if (animationStartRef.current === null) {
28521
29107
  animationStartRef.current = performance.now();
28522
29108
  }
@@ -28524,7 +29110,18 @@
28524
29110
  const pointerSnapshot = avatarVisual.supportsPointerTracking ? getAvatarPointerSnapshot() : null;
28525
29111
  let interactionState = createIdleAvatarInteractionState();
28526
29112
  if (avatarVisual.supportsPointerTracking && pointerSnapshot) {
28527
- interactionRuntimeStateRef.current = stepAvatarInteractionRuntimeState(interactionRuntimeStateRef.current, resolveAvatarPointerTarget(canvas.getBoundingClientRect(), pointerSnapshot), now);
29113
+ const pointerSnapshotVersion = getAvatarPointerSnapshotVersion();
29114
+ const viewportLayoutVersion = getAvatarViewportLayoutVersion();
29115
+ if (avatarBoundsRef.current === null ||
29116
+ lastResolvedPointerVersionRef.current !== pointerSnapshotVersion ||
29117
+ lastResolvedViewportLayoutVersionRef.current !== viewportLayoutVersion ||
29118
+ now - lastAvatarBoundsRefreshAtRef.current >= ACTIVE_POINTER_BOUNDS_REFRESH_MS) {
29119
+ avatarBoundsRef.current = canvas.getBoundingClientRect();
29120
+ lastResolvedPointerVersionRef.current = pointerSnapshotVersion;
29121
+ lastResolvedViewportLayoutVersionRef.current = viewportLayoutVersion;
29122
+ lastAvatarBoundsRefreshAtRef.current = now;
29123
+ }
29124
+ interactionRuntimeStateRef.current = stepAvatarInteractionRuntimeState(interactionRuntimeStateRef.current, resolveAvatarPointerTarget(avatarBoundsRef.current, pointerSnapshot), now);
28528
29125
  interactionState = interactionRuntimeStateRef.current;
28529
29126
  }
28530
29127
  else if (avatarVisual.supportsPointerTracking) {
@@ -28533,35 +29130,35 @@
28533
29130
  }
28534
29131
  renderAvatarVisual({
28535
29132
  canvas,
28536
- avatarDefinition: normalizedAvatarDefinition,
29133
+ avatarDefinition: resolvedAvatarRenderDefinition.avatarDefinition,
28537
29134
  visualId,
28538
29135
  surface,
28539
29136
  size,
28540
29137
  timeMs: now - animationStartRef.current,
28541
29138
  devicePixelRatio: window.devicePixelRatio || 1,
28542
29139
  interaction: interactionState,
28543
- });
28544
- if (isDynamicAvatar) {
28545
- animationFrameId = window.requestAnimationFrame(renderFrame);
28546
- }
29140
+ }, resolvedAvatarRenderDefinition);
28547
29141
  };
28548
29142
  renderFrame(performance.now());
29143
+ if (!isDynamicAvatar || !isVisible) {
29144
+ return () => {
29145
+ releasePointerTracking === null || releasePointerTracking === void 0 ? void 0 : releasePointerTracking();
29146
+ };
29147
+ }
29148
+ const releaseAnimationListener = retainAvatarAnimationListener(renderFrame);
28549
29149
  return () => {
28550
- if (animationFrameId !== null) {
28551
- window.cancelAnimationFrame(animationFrameId);
28552
- }
29150
+ releaseAnimationListener();
28553
29151
  releasePointerTracking === null || releasePointerTracking === void 0 ? void 0 : releasePointerTracking();
28554
29152
  };
28555
29153
  }, [
28556
29154
  avatarDefinitionKey,
28557
- avatarVisual.isAnimated,
28558
- avatarVisual.supportsPointerTracking,
28559
- normalizedAvatarDefinition,
29155
+ isVisible,
29156
+ resolvedAvatarRenderDefinition,
28560
29157
  size,
28561
29158
  surface,
28562
29159
  visualId,
28563
29160
  ]);
28564
- return (jsxRuntime.jsx("canvas", { ref: canvasRef, title: title || `${normalizedAvatarDefinition.agentName} avatar`, className: className, style: {
29161
+ return (jsxRuntime.jsx("canvas", { ref: canvasRef, title: title || `${resolvedAvatarRenderDefinition.avatarDefinition.agentName} avatar`, className: className, style: {
28565
29162
  width: size,
28566
29163
  height: size,
28567
29164
  display: 'block',
@@ -29970,7 +30567,7 @@
29970
30567
  * @private internal component of `<ChatMessageItem/>`
29971
30568
  */
29972
30569
  function ChatMessageRichContent(props) {
29973
- const { content, contentSegments, streamingFeaturePlaceholderKind, onCreateAgent } = props;
30570
+ const { content, contentSegments, streamingFeaturePlaceholderKind, onCreateAgent, mode } = props;
29974
30571
  if (content === LOADING_INTERACTIVE_IMAGE) {
29975
30572
  return null;
29976
30573
  }
@@ -29979,7 +30576,7 @@
29979
30576
  return (jsxRuntime.jsx(MarkdownContent, { content: segment.content, onCreateAgent: onCreateAgent }, `text-${segmentIndex}`));
29980
30577
  }
29981
30578
  if (segment.type === 'code') {
29982
- return (jsxRuntime.jsx(CodeBlock, { code: segment.code, language: segment.language, onCreateAgent: onCreateAgent }, `code-${segmentIndex}`));
30579
+ return (jsxRuntime.jsx(CodeBlock, { code: segment.code, language: segment.language, onCreateAgent: onCreateAgent, theme: mode }, `code-${segmentIndex}`));
29983
30580
  }
29984
30581
  if (segment.type === 'image') {
29985
30582
  return (jsxRuntime.jsx(ImagePromptRenderer, { alt: segment.alt, prompt: segment.prompt }, `image-${segmentIndex}`));
@@ -46812,6 +47409,8 @@
46812
47409
  const swipeDirectionMultiplier = isMe ? -1 : 1;
46813
47410
  const swipeTranslation = `${isMe ? -replySwipeDistance : replySwipeDistance}px`;
46814
47411
  const isReplySwipeArmed = replySwipeDistance >= REPLY_SWIPE_TRIGGER_PX * 0.5;
47412
+ const articleModeBackgroundColor = mode === 'DARK' ? 'rgba(15, 23, 42, 0.78)' : '#ffffff';
47413
+ const articleModeTextColor = mode === 'DARK' ? '#e2e8f0' : '#0f172a';
46815
47414
  /**
46816
47415
  * Renders the optional message utility buttons used for copy/read actions.
46817
47416
  *
@@ -47013,10 +47612,12 @@
47013
47612
  aspectRatio: '1 / 1',
47014
47613
  borderRadius: '50%',
47015
47614
  } })), isAvatarTooltipVisible && (participant === null || participant === void 0 ? void 0 : participant.agentSource) && avatarTooltipPosition && (jsxRuntime.jsx(AvatarProfileTooltip, { ref: tooltipRef, agentSource: participant.agentSource, position: avatarTooltipPosition }))] })), jsxRuntime.jsxs("div", { className: classNames(styles$5.messageStack, chatCssClassNames.messageStack), children: [shouldShowParticipantLabel && participantLabel && (jsxRuntime.jsx("div", { className: styles$5.participantLabel, children: participantLabel })), jsxRuntime.jsxs("div", { className: classNames(styles$5.messageText, isReplyActionEnabled && styles$5.replyEnabledMessageText, isReplySwipeArmed && styles$5.replySwipeActive, isAgentArticleMode && styles$5.articleModeAgentMessageText, chatCssClassNames.messageContent), style: {
47016
- '--message-bg-color': isAgentArticleMode ? '#ffffff' : color.toHex(),
47017
- '--message-text-color': isAgentArticleMode ? '#0f172a' : colorOfText.toHex(),
47615
+ '--message-bg-color': isAgentArticleMode ? articleModeBackgroundColor : color.toHex(),
47616
+ '--message-text-color': isAgentArticleMode
47617
+ ? articleModeTextColor
47618
+ : colorOfText.toHex(),
47018
47619
  '--chat-message-swipe-offset': swipeTranslation,
47019
- }, onPointerDown: handleReplyPointerDown, onPointerMove: handleReplyPointerMove, onPointerUp: handleReplyPointerEnd, onPointerCancel: resetReplySwipe, children: [isReplyActionEnabled && (jsxRuntime.jsx("div", { className: classNames(styles$5.replySwipeIndicator, isMe && styles$5.replySwipeIndicatorRight, isReplySwipeArmed && styles$5.replySwipeIndicatorActive), "aria-hidden": "true", children: jsxRuntime.jsx(lucideReact.Reply, { className: styles$5.replySwipeIndicatorIcon }) })), !shouldRenderArticleActionsBar && renderMessageReadAndCopyControls(), message.isVoiceCall && (jsxRuntime.jsx("div", { className: styles$5.voiceCallIndicator, children: jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: jsxRuntime.jsx("path", { d: "M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z" }) }) })), replyingToMessage && replyPreviewText && replySenderLabel && (jsxRuntime.jsx(ChatReplyPreview, { label: replyPreviewLabel, senderLabel: replySenderLabel, previewText: replyPreviewText, className: styles$5.replyBubblePreview })), jsxRuntime.jsx("div", { ref: contentWithoutButtonsRef, children: jsxRuntime.jsx(ChatMessageRichContent, { content: message.content, contentSegments: contentSegments, streamingFeaturePlaceholderKind: streamingFeaturePlaceholderKind, onCreateAgent: onCreateAgent }) }), message.attachments && message.attachments.length > 0 && (jsxRuntime.jsx("div", { className: styles$5.attachments, children: message.attachments.map((attachment, index) => (jsxRuntime.jsxs("a", { href: attachment.url, target: "_blank", rel: "noopener noreferrer", className: styles$5.attachment, title: attachment.name, children: [jsxRuntime.jsx("span", { className: styles$5.attachmentIcon, children: "\uD83D\uDCCE" }), jsxRuntime.jsx("span", { className: styles$5.attachmentName, children: attachment.name })] }, index))) })), jsxRuntime.jsx(ChatMessageToolCallChips, { chips: toolCallChips, onToolCallClick: onToolCallClick }), citationFootnoteRenderModel.footnotes.length > 0 && (jsxRuntime.jsx("div", { className: styles$5.citationFootnotes, children: citationFootnoteRenderModel.footnotes.map((footnote) => (jsxRuntime.jsxs("div", { className: styles$5.citationFootnoteItem, children: [jsxRuntime.jsx("span", { className: styles$5.citationFootnoteNumber, children: footnote.number }), jsxRuntime.jsx(SourceChip, { citation: footnote.citation, onClick: onCitationClick, isCitationIdVisible: false })] }, `citation-footnote-${footnote.number}-${footnote.citation.source}`))) })), transitiveCitations.length > 0 && (jsxRuntime.jsx("div", { className: styles$5.sourceCitations, children: transitiveCitations.map((citation, index) => (jsxRuntime.jsx(SourceChip, { citation: citation, suffix: `by ${citation.origin.label}`, onClick: onCitationClick }, `team-source-${citation.source}-${index}`))) })), shouldShowButtons && (jsxRuntime.jsx("div", { className: styles$5.messageButtons, children: renderableButtons.map(({ button, buttonIndex }) => (jsxRuntime.jsx("button", { type: "button", className: classNames(styles$5.messageButton, button.type === 'action' && styles$5.actionMessageButton), onClick: (event) => {
47620
+ }, onPointerDown: handleReplyPointerDown, onPointerMove: handleReplyPointerMove, onPointerUp: handleReplyPointerEnd, onPointerCancel: resetReplySwipe, children: [isReplyActionEnabled && (jsxRuntime.jsx("div", { className: classNames(styles$5.replySwipeIndicator, isMe && styles$5.replySwipeIndicatorRight, isReplySwipeArmed && styles$5.replySwipeIndicatorActive), "aria-hidden": "true", children: jsxRuntime.jsx(lucideReact.Reply, { className: styles$5.replySwipeIndicatorIcon }) })), !shouldRenderArticleActionsBar && renderMessageReadAndCopyControls(), message.isVoiceCall && (jsxRuntime.jsx("div", { className: styles$5.voiceCallIndicator, children: jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: jsxRuntime.jsx("path", { d: "M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z" }) }) })), replyingToMessage && replyPreviewText && replySenderLabel && (jsxRuntime.jsx(ChatReplyPreview, { label: replyPreviewLabel, senderLabel: replySenderLabel, previewText: replyPreviewText, className: styles$5.replyBubblePreview })), jsxRuntime.jsx("div", { ref: contentWithoutButtonsRef, children: jsxRuntime.jsx(ChatMessageRichContent, { content: message.content, contentSegments: contentSegments, streamingFeaturePlaceholderKind: streamingFeaturePlaceholderKind, onCreateAgent: onCreateAgent, mode: mode }) }), message.attachments && message.attachments.length > 0 && (jsxRuntime.jsx("div", { className: styles$5.attachments, children: message.attachments.map((attachment, index) => (jsxRuntime.jsxs("a", { href: attachment.url, target: "_blank", rel: "noopener noreferrer", className: styles$5.attachment, title: attachment.name, children: [jsxRuntime.jsx("span", { className: styles$5.attachmentIcon, children: "\uD83D\uDCCE" }), jsxRuntime.jsx("span", { className: styles$5.attachmentName, children: attachment.name })] }, index))) })), jsxRuntime.jsx(ChatMessageToolCallChips, { chips: toolCallChips, onToolCallClick: onToolCallClick }), citationFootnoteRenderModel.footnotes.length > 0 && (jsxRuntime.jsx("div", { className: styles$5.citationFootnotes, children: citationFootnoteRenderModel.footnotes.map((footnote) => (jsxRuntime.jsxs("div", { className: styles$5.citationFootnoteItem, children: [jsxRuntime.jsx("span", { className: styles$5.citationFootnoteNumber, children: footnote.number }), jsxRuntime.jsx(SourceChip, { citation: footnote.citation, onClick: onCitationClick, isCitationIdVisible: false })] }, `citation-footnote-${footnote.number}-${footnote.citation.source}`))) })), transitiveCitations.length > 0 && (jsxRuntime.jsx("div", { className: styles$5.sourceCitations, children: transitiveCitations.map((citation, index) => (jsxRuntime.jsx(SourceChip, { citation: citation, suffix: `by ${citation.origin.label}`, onClick: onCitationClick }, `team-source-${citation.source}-${index}`))) })), shouldShowButtons && (jsxRuntime.jsx("div", { className: styles$5.messageButtons, children: renderableButtons.map(({ button, buttonIndex }) => (jsxRuntime.jsx("button", { type: "button", className: classNames(styles$5.messageButton, button.type === 'action' && styles$5.actionMessageButton), onClick: (event) => {
47020
47621
  event.stopPropagation();
47021
47622
  if (button.type === 'message') {
47022
47623
  const quickMessageHandler = onQuickMessageButton || onMessage;
@@ -47210,7 +47811,7 @@
47210
47811
  }
47211
47812
  return '';
47212
47813
  })();
47213
- return (jsxRuntime.jsx("div", { className: styles$5.ratingModal, onClick: (event) => {
47814
+ return (jsxRuntime.jsx("div", { className: styles$5.ratingModal, "data-chat-modal": "rating", "data-chat-theme": mode.toLowerCase(), onClick: (event) => {
47214
47815
  if (event.target === event.currentTarget && isMobile) {
47215
47816
  onClose();
47216
47817
  }
@@ -47314,12 +47915,14 @@
47314
47915
  */
47315
47916
  function renderAdvancedToolCallDetails(options) {
47316
47917
  const { toolCall } = options;
47918
+ const mode = options.mode || 'LIGHT';
47317
47919
  const header = resolveAdvancedToolCallHeader(options);
47318
47920
  const payloadSections = createAdvancedToolCallPayloadSections(toolCall, options.availableTools);
47319
47921
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("header", { className: styles$5.toolCallHeader, children: [jsxRuntime.jsx("span", { className: styles$5.toolCallIcon, "aria-hidden": "true", children: header.emoji }), jsxRuntime.jsxs("div", { className: styles$5.toolCallHeaderMeta, children: [jsxRuntime.jsx("p", { className: styles$5.toolCallModalLabel, children: "Advanced" }), jsxRuntime.jsx("h3", { className: styles$5.toolCallTitle, children: header.title }), jsxRuntime.jsxs("p", { className: styles$5.toolCallSubtitle, children: [header.subtitle, " \u00B7 ", resolveToolCallState(toolCall).toLowerCase()] })] })] }), jsxRuntime.jsx("div", { className: styles$5.toolCallGrid, children: payloadSections.map((payloadSection) => (jsxRuntime.jsxs("section", { className: styles$5.toolCallPanel, children: [jsxRuntime.jsx("p", { className: styles$5.toolCallPanelTitle, children: payloadSection.title }), renderAdvancedToolCallPayload({
47320
47922
  toolCall,
47321
47923
  sectionId: payloadSection.id,
47322
47924
  payload: payloadSection.payload,
47925
+ mode,
47323
47926
  })] }, payloadSection.id))) })] }));
47324
47927
  }
47325
47928
  /**
@@ -47453,7 +48056,7 @@
47453
48056
  * @private function of ChatToolCallModal
47454
48057
  */
47455
48058
  function renderAdvancedToolCallPayload(options) {
47456
- const { toolCall, sectionId, payload } = options;
48059
+ const { toolCall, sectionId, payload, mode } = options;
47457
48060
  const formattedPayload = formatToolCallPayload(payload);
47458
48061
  const modelPath = createToolCallPayloadMonacoPath({
47459
48062
  toolCall,
@@ -47461,7 +48064,7 @@
47461
48064
  language: formattedPayload.language,
47462
48065
  });
47463
48066
  const editorHeight = resolveToolCallPayloadEditorHeight(formattedPayload.content);
47464
- return (jsxRuntime.jsx("div", { className: styles$5.toolCallPayloadContainer, children: jsxRuntime.jsx("div", { className: styles$5.toolCallPayloadEditor, children: jsxRuntime.jsx(MonacoEditorWithShadowDom, { height: `${editorHeight}px`, language: formattedPayload.language, path: modelPath, value: formattedPayload.content, theme: "vs-light", options: TOOL_CALL_PAYLOAD_EDITOR_OPTIONS }) }) }));
48067
+ return (jsxRuntime.jsx("div", { className: styles$5.toolCallPayloadContainer, children: jsxRuntime.jsx("div", { className: styles$5.toolCallPayloadEditor, children: jsxRuntime.jsx(MonacoEditorWithShadowDom, { height: `${editorHeight}px`, language: formattedPayload.language, path: modelPath, value: formattedPayload.content, theme: mode === 'DARK' ? 'vs-dark' : 'vs-light', options: TOOL_CALL_PAYLOAD_EDITOR_OPTIONS }) }) }));
47465
48068
  }
47466
48069
  /**
47467
48070
  * Resolves Monaco editor height from payload line count with bounded limits.
@@ -49533,12 +50136,6 @@
49533
50136
  });
49534
50137
  }
49535
50138
  }
49536
- const staticConversationDelayConfig = {
49537
- ...FAST_FLOW,
49538
- beforeFirstMessage: 0,
49539
- // Show the full internal exchange immediately so the modal never opens as a blank panel.
49540
- showIntermediateMessages: messages.length,
49541
- };
49542
50139
  const agentName = ((_c = (_b = teamResult.conversation) === null || _b === void 0 ? void 0 : _b.find((entry) => entry.sender === 'AGENT' || entry.role === 'AGENT')) === null || _c === void 0 ? void 0 : _c.name) || 'Agent';
49543
50140
  const teammateConversationName = ((_e = (_d = teamResult.conversation) === null || _d === void 0 ? void 0 : _d.find((entry) => entry.sender === 'TEAMMATE' || entry.role === 'TEAMMATE')) === null || _e === void 0 ? void 0 : _e.name) || '';
49544
50141
  const teammateProfile = teammateUrl ? teamProfiles[teammateUrl] : undefined;
@@ -49575,7 +50172,12 @@
49575
50172
  avatarSrc: resolvedTeammateAvatar || undefined,
49576
50173
  },
49577
50174
  ];
49578
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: classNames(styles$5.searchModalHeader, styles$5.teamModalHeader), children: jsxRuntime.jsxs("div", { className: styles$5.teamHeaderParticipants, children: [jsxRuntime.jsx(TeamHeaderProfile, { label: resolvedAgentLabel, avatarSrc: resolvedAgentAvatar, avatarDefinition: resolvedAgentAvatarDefinition, avatarVisualId: resolvedAgentAvatarVisualId, fallbackColor: resolvedAgentHeaderColor }), jsxRuntime.jsx("span", { className: styles$5.teamHeaderDivider, children: "talking with" }), jsxRuntime.jsx(TeamHeaderProfile, { label: resolvedTeammateLabel, avatarSrc: resolvedTeammateAvatar, fallbackColor: "#0ea5e9", href: teammateLink })] }) }), jsxRuntime.jsxs("div", { className: styles$5.searchModalContent, children: [messages.length > 0 ? (jsxRuntime.jsx("div", { className: styles$5.teamChatContainer, children: jsxRuntime.jsx(MockedChat, { title: `Chat between ${resolvedAgentLabel} and ${resolvedTeammateLabel}`, messages: messages, participants: participants, isResettable: false, isPausable: false, isSaveButtonEnabled: false, isCopyButtonEnabled: false, visual: "STANDALONE", delayConfig: staticConversationDelayConfig }) })) : (jsxRuntime.jsx("div", { className: styles$5.noResults, children: "No teammate conversation available." })), (hasTeamToolCalls || hasTeamCitations) && (jsxRuntime.jsxs("div", { className: styles$5.teamToolCallSection, children: [hasTeamToolCalls && (jsxRuntime.jsxs("div", { className: styles$5.teamToolCallGroup, children: [jsxRuntime.jsx("div", { className: styles$5.teamToolCallHeading, children: "Actions" }), jsxRuntime.jsx("div", { className: styles$5.teamToolCallChips, children: teamToolCalls.map((toolCallEntry, index) => {
50175
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: classNames(styles$5.searchModalHeader, styles$5.teamModalHeader), children: jsxRuntime.jsxs("div", { className: styles$5.teamHeaderParticipants, children: [jsxRuntime.jsx(TeamHeaderProfile, { label: resolvedAgentLabel, avatarSrc: resolvedAgentAvatar, avatarDefinition: resolvedAgentAvatarDefinition, avatarVisualId: resolvedAgentAvatarVisualId, fallbackColor: resolvedAgentHeaderColor }), jsxRuntime.jsx("span", { className: styles$5.teamHeaderDivider, children: "talking with" }), jsxRuntime.jsx(TeamHeaderProfile, { label: resolvedTeammateLabel, avatarSrc: resolvedTeammateAvatar, fallbackColor: "#0ea5e9", href: teammateLink })] }) }), jsxRuntime.jsxs("div", { className: styles$5.searchModalContent, children: [messages.length > 0 ? (jsxRuntime.jsx("div", { className: styles$5.teamChatContainer, children: jsxRuntime.jsx(MockedChat, { title: `Chat between ${resolvedAgentLabel} and ${resolvedTeammateLabel}`, messages: messages, participants: participants, isResettable: false, isPausable: false, isSaveButtonEnabled: false, isCopyButtonEnabled: false, layout: "STANDALONE", delayConfig: {
50176
+ // Note+TODO: For some strange reason, <MockedChat/> is not running and stays static on the initial frame, so doing this hack to force it to show the entire chat at once. Need to investigate why the animation is not running as expected and then just use `delayConfig={FAST_FLOW}`
50177
+ ...FAST_FLOW,
50178
+ beforeFirstMessage: 0,
50179
+ showIntermediateMessages: messages.length,
50180
+ }, visualMode: "BUBBLE_MODE" }) })) : (jsxRuntime.jsx("div", { className: styles$5.noResults, children: "No teammate conversation available." })), (hasTeamToolCalls || hasTeamCitations) && (jsxRuntime.jsxs("div", { className: styles$5.teamToolCallSection, children: [hasTeamToolCalls && (jsxRuntime.jsxs("div", { className: styles$5.teamToolCallGroup, children: [jsxRuntime.jsx("div", { className: styles$5.teamToolCallHeading, children: "Actions" }), jsxRuntime.jsx("div", { className: styles$5.teamToolCallChips, children: teamToolCalls.map((toolCallEntry, index) => {
49579
50181
  const chipletInfo = getToolCallChipletInfo(toolCallEntry.toolCall, undefined, toolTitles);
49580
50182
  const chipletText = buildToolCallChipText(chipletInfo);
49581
50183
  return (jsxRuntime.jsxs("button", { className: styles$5.completedToolCall, onClick: () => {
@@ -49594,12 +50196,13 @@
49594
50196
  *
49595
50197
  * @private component of `ChatToolCallModal`
49596
50198
  */
49597
- function ChatToolCallModalContent({ agentParticipant, availableTools, buttonColor, chatUiTranslations, focusedToolCall, isAdvancedView, locale, onClearSelectedTeamToolCall, onRequestAdvancedView, onSelectTeamToolCall, selectedTeamToolCall, teamProfiles, teamResult, teamToolCallSummary, toolCall, toolCallDate, toolTitles, }) {
50199
+ function ChatToolCallModalContent({ agentParticipant, availableTools, buttonColor, chatUiTranslations, focusedToolCall, isAdvancedView, locale, mode, onClearSelectedTeamToolCall, onRequestAdvancedView, onSelectTeamToolCall, selectedTeamToolCall, teamProfiles, teamResult, teamToolCallSummary, toolCall, toolCallDate, toolTitles, }) {
49598
50200
  if (isAdvancedView) {
49599
50201
  return renderAdvancedToolCallDetails({
49600
50202
  toolCall: focusedToolCall,
49601
50203
  toolTitles,
49602
50204
  availableTools,
50205
+ mode,
49603
50206
  });
49604
50207
  }
49605
50208
  if (teamResult === null || teamResult === void 0 ? void 0 : teamResult.teammate) {
@@ -49866,7 +50469,7 @@
49866
50469
  * @private component of `<Chat/>`
49867
50470
  */
49868
50471
  function ChatToolCallModal(props) {
49869
- const { isOpen, toolCall, toolCallIdentity, onClose, toolTitles, agentParticipant, buttonColor, teamAgentProfiles, chatUiTranslations, locale, availableTools, } = props;
50472
+ const { isOpen, toolCall, mode = 'LIGHT', toolCallIdentity, onClose, toolTitles, agentParticipant, buttonColor, teamAgentProfiles, chatUiTranslations, locale, availableTools, } = props;
49870
50473
  const { clearSelectedTeamToolCall, exportAdvancedToolCallReport, focusedToolCall, isAdvancedView, modalDialogRef, openAdvancedView, selectTeamToolCall, selectedTeamToolCall, teamProfiles, teamResult, teamToolCallSummary, toggleViewMode, toolCallDate, } = useChatToolCallModalState({
49871
50474
  isOpen,
49872
50475
  toolCall,
@@ -49886,9 +50489,9 @@
49886
50489
  const modeToggleLabel = isAdvancedView
49887
50490
  ? (chatUiTranslations === null || chatUiTranslations === void 0 ? void 0 : chatUiTranslations.toolCallModalSimpleLabel) || 'Simple'
49888
50491
  : (chatUiTranslations === null || chatUiTranslations === void 0 ? void 0 : chatUiTranslations.toolCallModalAdvancedLabel) || 'Advanced';
49889
- return (jsxRuntime.jsx("div", { className: styles$5.ratingModal, onClick: (event) => {
50492
+ return (jsxRuntime.jsx("div", { className: styles$5.ratingModal, "data-chat-modal": "tool-call", "data-chat-theme": mode.toLowerCase(), onClick: (event) => {
49890
50493
  handleModalBackdropClick(event, onClose);
49891
- }, children: jsxRuntime.jsxs("div", { ref: modalDialogRef, className: classNames(styles$5.ratingModalContent, styles$5.toolCallModal), role: "dialog", "aria-modal": "true", "aria-label": modalTitle, tabIndex: -1, children: [jsxRuntime.jsx("button", { type: "button", className: styles$5.modalCloseButton, onClick: onClose, "aria-label": closeButtonLabel, children: jsxRuntime.jsx(CloseIcon, {}) }), jsxRuntime.jsx(ChatToolCallModalContent, { toolCall: toolCall, focusedToolCall: resolvedFocusedToolCall, isAdvancedView: isAdvancedView, teamResult: teamResult, toolCallDate: toolCallDate, teamToolCallSummary: teamToolCallSummary, selectedTeamToolCall: selectedTeamToolCall, onSelectTeamToolCall: selectTeamToolCall, onClearSelectedTeamToolCall: clearSelectedTeamToolCall, teamProfiles: teamProfiles, toolTitles: toolTitles, agentParticipant: agentParticipant, buttonColor: buttonColor, locale: locale, chatUiTranslations: chatUiTranslations, availableTools: availableTools, onRequestAdvancedView: openAdvancedView }), jsxRuntime.jsxs("div", { className: styles$5.toolCallModeFooter, children: [isAdvancedView && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("button", { type: "button", className: styles$5.toolCallModeButton, onClick: () => {
50494
+ }, children: jsxRuntime.jsxs("div", { ref: modalDialogRef, className: classNames(styles$5.ratingModalContent, styles$5.toolCallModal), role: "dialog", "aria-modal": "true", "aria-label": modalTitle, tabIndex: -1, children: [jsxRuntime.jsx("button", { type: "button", className: styles$5.modalCloseButton, onClick: onClose, "aria-label": closeButtonLabel, children: jsxRuntime.jsx(CloseIcon, {}) }), jsxRuntime.jsx(ChatToolCallModalContent, { toolCall: toolCall, focusedToolCall: resolvedFocusedToolCall, isAdvancedView: isAdvancedView, teamResult: teamResult, toolCallDate: toolCallDate, teamToolCallSummary: teamToolCallSummary, selectedTeamToolCall: selectedTeamToolCall, onSelectTeamToolCall: selectTeamToolCall, onClearSelectedTeamToolCall: clearSelectedTeamToolCall, teamProfiles: teamProfiles, toolTitles: toolTitles, agentParticipant: agentParticipant, buttonColor: buttonColor, locale: locale, chatUiTranslations: chatUiTranslations, availableTools: availableTools, onRequestAdvancedView: openAdvancedView, mode: mode }), jsxRuntime.jsxs("div", { className: styles$5.toolCallModeFooter, children: [isAdvancedView && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("button", { type: "button", className: styles$5.toolCallModeButton, onClick: () => {
49892
50495
  void exportAdvancedToolCallReport('clipboard');
49893
50496
  }, children: copyButtonLabel }), jsxRuntime.jsx("button", { type: "button", className: styles$5.toolCallModeButton, onClick: () => {
49894
50497
  void exportAdvancedToolCallReport('file');
@@ -50514,7 +51117,7 @@
50514
51117
  * @public exported from `@promptbook/components`
50515
51118
  */
50516
51119
  function Chat(props) {
50517
- const { title = 'Chat', messages, onChange, onMessage, onActionButton, onQuickMessageButton, onReplyToMessage, onCancelReply, onReset, resetRequiresConfirmation = true, newChatButtonHref, onFeedback, feedbackMode = 'stars', feedbackTranslations, timingTranslations, onFileUpload, chatLocale, speechRecognition, placeholderMessageContent, defaultMessage, enterBehavior, resolveEnterBehavior, children, className, style, isAiTextHumanizedAndPromptbookified = true, isVoiceCalling = false, isFocusedOnLoad, participants = [], canReplyToMessage, replyingToMessage, extraActions, actionsContainer, saveFormats, isSaveButtonEnabled = true, isCopyButtonEnabled = true, buttonColor: buttonColorRaw, onUseTemplate, onCreateAgent, toolTitles, teammates, teamAgentProfiles, visual, visualMode = 'ARTICLE_MODE', effectConfigs, soundSystem, speechRecognitionLanguage, isSpeechPlaybackEnabled = true, elevenLabsVoiceId, chatUiTranslations, } = props;
51120
+ const { title = 'Chat', messages, onChange, onMessage, onActionButton, onQuickMessageButton, onReplyToMessage, onCancelReply, onReset, resetRequiresConfirmation = true, newChatButtonHref, onFeedback, feedbackMode = 'stars', feedbackTranslations, timingTranslations, onFileUpload, chatLocale, speechRecognition, placeholderMessageContent, defaultMessage, enterBehavior, resolveEnterBehavior, children, className, style, isAiTextHumanizedAndPromptbookified = true, isVoiceCalling = false, isFocusedOnLoad, participants = [], canReplyToMessage, replyingToMessage, extraActions, actionsContainer, saveFormats, isSaveButtonEnabled = true, isCopyButtonEnabled = true, buttonColor: buttonColorRaw, onUseTemplate, onCreateAgent, toolTitles, teammates, teamAgentProfiles, layout, visualMode = 'ARTICLE_MODE', theme = 'LIGHT', effectConfigs, soundSystem, speechRecognitionLanguage, isSpeechPlaybackEnabled = true, elevenLabsVoiceId, chatUiTranslations, } = props;
50518
51121
  const buttonColor = react.useMemo(() => Color.from(buttonColorRaw || '#0066cc'), [buttonColorRaw]);
50519
51122
  const agentParticipant = react.useMemo(() => participants.find((participant) => participant.name === 'AGENT'), [participants]);
50520
51123
  const postprocessedMessages = useChatPostprocessedMessages({
@@ -50534,7 +51137,7 @@
50534
51137
  const { citationModalOpen, closeCitationModal, closeToolCallModal, openCitation, openToolCall, selectedCitation, selectedMessageAvailableTools, selectedToolCall, selectedToolCallIdentity, toolCallModalOpen, } = useChatToolCallState({
50535
51138
  messages: postprocessedMessages,
50536
51139
  });
50537
- const mode = 'LIGHT';
51140
+ const mode = theme;
50538
51141
  const scrollToBottomCssClassName = getChatCssClassName('scrollToBottom');
50539
51142
  const handleButtonClick = react.useCallback((originalHandler) => {
50540
51143
  return (event) => {
@@ -50555,11 +51158,11 @@
50555
51158
  extraActions,
50556
51159
  isSaveButtonEnabled,
50557
51160
  });
50558
- const isConstrainedArticleMode = visualMode === 'ARTICLE_MODE' && visual === 'FULL_PAGE';
51161
+ const isConstrainedArticleMode = visualMode === 'ARTICLE_MODE' && layout === 'FULL_PAGE';
50559
51162
  useChatCompleteNotification(messages, soundSystem);
50560
51163
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [feedbackStatus && (jsxRuntime.jsx("div", { className: classNames(styles$5.feedbackStatus, feedbackStatus.variant === 'success'
50561
51164
  ? styles$5.feedbackStatusSuccess
50562
- : styles$5.feedbackStatusError), "aria-live": "polite", role: "status", children: feedbackStatus.message })), effectConfigs && effectConfigs.length > 0 && (jsxRuntime.jsx(ChatEffectsSystem, { messages: postprocessedMessages, effectConfigs: effectConfigs, soundSystem: soundSystem })), jsxRuntime.jsx("div", { className: classNames(className, styles$5.Chat, visual === 'STANDALONE' && styles$5.standaloneVisual, visual === 'FULL_PAGE' && styles$5.fullPageVisual, isConstrainedArticleMode && styles$5.constrainedArticleVisual, getChatCssClassName('Chat'), chatCssClassNames.chat), style, children: jsxRuntime.jsxs("div", { className: classNames(className, styles$5.chatMainFlow, getChatCssClassName('chatMainFlow'), chatCssClassNames.chatMainFlow), children: [children && jsxRuntime.jsx("div", { className: classNames(styles$5.chatChildren), children: children }), shouldShowScrollToBottom && (jsxRuntime.jsx("div", { className: styles$5.scrollToBottomContainer, children: jsxRuntime.jsxs("div", { className: styles$5.scrollToBottomWrapper, children: [jsxRuntime.jsx(SolidArrowButton, { "data-button-type": "custom", direction: "down", iconSize: 33, className: classNames(styles$5.scrollToBottom, scrollToBottomCssClassName), onClick: handleButtonClick(() => scrollToBottom()), "aria-label": ariaLabel, title: ariaLabel }), badgeLabel && (jsxRuntime.jsx("span", { className: styles$5.scrollToBottomBadge, "aria-live": "polite", role: "status", children: badgeLabel }))] }) })), isVoiceCalling && (jsxRuntime.jsx("div", { className: styles$5.voiceCallIndicatorBar, children: jsxRuntime.jsxs("div", { className: styles$5.voiceCallIndicator, children: [jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: jsxRuntime.jsx("path", { d: "M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z" }) }), jsxRuntime.jsx("span", { children: "Voice call active" }), jsxRuntime.jsx("div", { className: styles$5.voiceCallPulse })] }) })), jsxRuntime.jsx(ChatActionsBar, { actionsRef: actionsRef, actionsContainer: actionsContainer, messages: postprocessedMessages, participants: participants, title: title, onReset: onReset, resetRequiresConfirmation: resetRequiresConfirmation, newChatButtonHref: newChatButtonHref, onUseTemplate: onUseTemplate, extraActions: extraActions, saveFormats: saveFormats, isSaveButtonEnabled: isSaveButtonEnabled, shouldFadeActions: shouldFadeActions, shouldDisableActions: shouldDisableActions, chatUiTranslations: chatUiTranslations, onButtonClick: handleButtonClick }), jsxRuntime.jsx(ChatMessageList, { messages: postprocessedMessages, participants: participants, expandedMessageId: expandedMessageId, messageRatings: messageRatings, setExpandedMessageId: setExpandedMessageId, handleRating: handleRating, mode: mode, isCopyButtonEnabled: isCopyButtonEnabled, isFeedbackEnabled: isFeedbackEnabled, feedbackMode: feedbackMode, feedbackTranslations: feedbackTranslations, timingTranslations: timingTranslations, chatLocale: chatLocale, onCopy: handleCopy, onMessage: onMessage, onActionButton: onActionButton, onQuickMessageButton: onQuickMessageButton, onReplyToMessage: onReplyToMessage, canReplyToMessage: canReplyToMessage, onCreateAgent: onCreateAgent, toolTitles: toolTitles, teammates: teammates, teamAgentProfiles: teamAgentProfiles, visualMode: visualMode, soundSystem: soundSystem, onToolCallClick: openToolCall, onCitationClick: openCitation, setChatMessagesElement: setChatMessagesElement, onScroll: handleChatScroll, isSpeechPlaybackEnabled: isSpeechPlaybackEnabled, elevenLabsVoiceId: elevenLabsVoiceId, chatUiTranslations: chatUiTranslations, chatMessagesClassName: classNames(isConstrainedArticleMode && styles$5.articleModeChatMessages, getChatCssClassName('chatMessages'), chatCssClassNames.chatMessages), hasActions: hasActions }), onMessage && (jsxRuntime.jsx(ChatInputArea, { onMessage: onMessage, onChange: onChange, onFileUpload: onFileUpload, speechRecognition: speechRecognition, speechRecognitionLanguage: speechRecognitionLanguage, replyingToMessage: replyingToMessage, onCancelReply: onCancelReply, defaultMessage: defaultMessage, enterBehavior: enterBehavior, resolveEnterBehavior: resolveEnterBehavior, placeholderMessageContent: placeholderMessageContent || (chatUiTranslations === null || chatUiTranslations === void 0 ? void 0 : chatUiTranslations.inputPlaceholder), isFocusedOnLoad: isFocusedOnLoad, isMobile: isMobile, isVoiceCalling: isVoiceCalling, participants: participants, buttonColor: buttonColor, soundSystem: soundSystem, onButtonClick: handleButtonClick, chatUiTranslations: chatUiTranslations, chatInputClassName: classNames(isConstrainedArticleMode && styles$5.articleModeChatInput, getChatCssClassName('chatInput'), chatCssClassNames.chatInput) }))] }) }), jsxRuntime.jsx(ChatToolCallModal, { isOpen: toolCallModalOpen, toolCall: selectedToolCall, toolCallIdentity: selectedToolCallIdentity, onClose: closeToolCallModal, toolTitles: toolTitles, agentParticipant: agentParticipant, buttonColor: buttonColor, teamAgentProfiles: teamAgentProfiles, chatUiTranslations: chatUiTranslations, locale: chatLocale, availableTools: selectedMessageAvailableTools }), jsxRuntime.jsx(ChatCitationModal, { isOpen: citationModalOpen, citation: selectedCitation, participants: participants, soundSystem: soundSystem, onClose: closeCitationModal }), jsxRuntime.jsx(ChatRatingModal, { isOpen: ratingModalOpen, selectedMessage: selectedMessage, postprocessedMessages: postprocessedMessages, messages: messages, hoveredRating: hoveredRating, messageRatings: messageRatings, textRating: textRating, feedbackMode: feedbackMode, feedbackTranslations: feedbackTranslations, mode: mode, isMobile: isMobile, onClose: () => setRatingModalOpen(false), setHoveredRating: setHoveredRating, setMessageRatings: setMessageRatings, setSelectedMessage: setSelectedMessage, setTextRating: setTextRating, submitRating: submitRating })] }));
51165
+ : styles$5.feedbackStatusError), "aria-live": "polite", role: "status", children: feedbackStatus.message })), effectConfigs && effectConfigs.length > 0 && (jsxRuntime.jsx(ChatEffectsSystem, { messages: postprocessedMessages, effectConfigs: effectConfigs, soundSystem: soundSystem })), jsxRuntime.jsx("div", { className: classNames(className, styles$5.Chat, layout === 'STANDALONE' && styles$5.standaloneVisual, layout === 'FULL_PAGE' && styles$5.fullPageVisual, isConstrainedArticleMode && styles$5.constrainedArticleVisual, getChatCssClassName('Chat'), chatCssClassNames.chat), "data-chat-theme": mode.toLowerCase(), style, children: jsxRuntime.jsxs("div", { className: classNames(className, styles$5.chatMainFlow, getChatCssClassName('chatMainFlow'), chatCssClassNames.chatMainFlow), children: [children && jsxRuntime.jsx("div", { className: classNames(styles$5.chatChildren), children: children }), shouldShowScrollToBottom && (jsxRuntime.jsx("div", { className: styles$5.scrollToBottomContainer, children: jsxRuntime.jsxs("div", { className: styles$5.scrollToBottomWrapper, children: [jsxRuntime.jsx(SolidArrowButton, { "data-button-type": "custom", direction: "down", iconSize: 33, className: classNames(styles$5.scrollToBottom, scrollToBottomCssClassName), onClick: handleButtonClick(() => scrollToBottom()), "aria-label": ariaLabel, title: ariaLabel }), badgeLabel && (jsxRuntime.jsx("span", { className: styles$5.scrollToBottomBadge, "aria-live": "polite", role: "status", children: badgeLabel }))] }) })), isVoiceCalling && (jsxRuntime.jsx("div", { className: styles$5.voiceCallIndicatorBar, children: jsxRuntime.jsxs("div", { className: styles$5.voiceCallIndicator, children: [jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: jsxRuntime.jsx("path", { d: "M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z" }) }), jsxRuntime.jsx("span", { children: "Voice call active" }), jsxRuntime.jsx("div", { className: styles$5.voiceCallPulse })] }) })), jsxRuntime.jsx(ChatActionsBar, { actionsRef: actionsRef, actionsContainer: actionsContainer, messages: postprocessedMessages, participants: participants, title: title, onReset: onReset, resetRequiresConfirmation: resetRequiresConfirmation, newChatButtonHref: newChatButtonHref, onUseTemplate: onUseTemplate, extraActions: extraActions, saveFormats: saveFormats, isSaveButtonEnabled: isSaveButtonEnabled, shouldFadeActions: shouldFadeActions, shouldDisableActions: shouldDisableActions, chatUiTranslations: chatUiTranslations, onButtonClick: handleButtonClick }), jsxRuntime.jsx(ChatMessageList, { messages: postprocessedMessages, participants: participants, expandedMessageId: expandedMessageId, messageRatings: messageRatings, setExpandedMessageId: setExpandedMessageId, handleRating: handleRating, mode: mode, isCopyButtonEnabled: isCopyButtonEnabled, isFeedbackEnabled: isFeedbackEnabled, feedbackMode: feedbackMode, feedbackTranslations: feedbackTranslations, timingTranslations: timingTranslations, chatLocale: chatLocale, onCopy: handleCopy, onMessage: onMessage, onActionButton: onActionButton, onQuickMessageButton: onQuickMessageButton, onReplyToMessage: onReplyToMessage, canReplyToMessage: canReplyToMessage, onCreateAgent: onCreateAgent, toolTitles: toolTitles, teammates: teammates, teamAgentProfiles: teamAgentProfiles, visualMode: visualMode, soundSystem: soundSystem, onToolCallClick: openToolCall, onCitationClick: openCitation, setChatMessagesElement: setChatMessagesElement, onScroll: handleChatScroll, isSpeechPlaybackEnabled: isSpeechPlaybackEnabled, elevenLabsVoiceId: elevenLabsVoiceId, chatUiTranslations: chatUiTranslations, chatMessagesClassName: classNames(isConstrainedArticleMode && styles$5.articleModeChatMessages, getChatCssClassName('chatMessages'), chatCssClassNames.chatMessages), hasActions: hasActions }), onMessage && (jsxRuntime.jsx(ChatInputArea, { onMessage: onMessage, onChange: onChange, onFileUpload: onFileUpload, speechRecognition: speechRecognition, speechRecognitionLanguage: speechRecognitionLanguage, replyingToMessage: replyingToMessage, onCancelReply: onCancelReply, defaultMessage: defaultMessage, enterBehavior: enterBehavior, resolveEnterBehavior: resolveEnterBehavior, placeholderMessageContent: placeholderMessageContent || (chatUiTranslations === null || chatUiTranslations === void 0 ? void 0 : chatUiTranslations.inputPlaceholder), isFocusedOnLoad: isFocusedOnLoad, isMobile: isMobile, isVoiceCalling: isVoiceCalling, participants: participants, buttonColor: buttonColor, soundSystem: soundSystem, onButtonClick: handleButtonClick, chatUiTranslations: chatUiTranslations, chatInputClassName: classNames(isConstrainedArticleMode && styles$5.articleModeChatInput, getChatCssClassName('chatInput'), chatCssClassNames.chatInput) }))] }) }), jsxRuntime.jsx(ChatToolCallModal, { isOpen: toolCallModalOpen, toolCall: selectedToolCall, toolCallIdentity: selectedToolCallIdentity, onClose: closeToolCallModal, toolTitles: toolTitles, agentParticipant: agentParticipant, buttonColor: buttonColor, teamAgentProfiles: teamAgentProfiles, chatUiTranslations: chatUiTranslations, locale: chatLocale, availableTools: selectedMessageAvailableTools, mode: mode }), jsxRuntime.jsx(ChatCitationModal, { isOpen: citationModalOpen, citation: selectedCitation, participants: participants, soundSystem: soundSystem, onClose: closeCitationModal }), jsxRuntime.jsx(ChatRatingModal, { isOpen: ratingModalOpen, selectedMessage: selectedMessage, postprocessedMessages: postprocessedMessages, messages: messages, hoveredRating: hoveredRating, messageRatings: messageRatings, textRating: textRating, feedbackMode: feedbackMode, feedbackTranslations: feedbackTranslations, mode: mode, isMobile: isMobile, onClose: () => setRatingModalOpen(false), setHoveredRating: setHoveredRating, setMessageRatings: setMessageRatings, setSelectedMessage: setSelectedMessage, setTextRating: setTextRating, submitRating: submitRating })] }));
50563
51166
  }
50564
51167
 
50565
51168
  /**
@@ -51865,7 +52468,7 @@
51865
52468
  : styles.PromptbookAgentSeamlessIntegrationStatusPending) }), jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationText, children: [jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLabel, children: "Chat" }), jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationHint, children: displayName })] }), jsxRuntime.jsx("span", { className: styles.PromptbookAgentSeamlessIntegrationScreenReaderOnly, children: connectionStatusText })] }), isOpen && (jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationWindow, id: windowId, children: [jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationHeader, style: { backgroundColor: color }, ref: setHeaderElement, children: [jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationTitleWrap, children: [jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationTitle, children: displayName }), jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationSubtitle, children: connectionStatusText })] }), isIframeUsed && (jsxRuntime.jsx("button", { className: styles.PromptbookAgentSeamlessIntegrationClose, onClick: () => setOpen(false), title: "Close", "aria-label": "Close chat", children: jsxRuntime.jsx(CloseIcon, {}) }))] }), jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationContent, children: isIframeUsed ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [!isIframeLoaded && (jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationLoading, children: [jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLoadingShimmer }), jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLoadingSpinner }), jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLoadingTitle, children: "Preparing your chat" }), jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationLoadingText, children: ["Connecting to ", displayName, "..."] })] })), jsxRuntime.jsx("iframe", { src: agentUrl + '/chat?headless', className: styles.PromptbookAgentSeamlessIntegrationIframe, style: { opacity: isIframeLoaded ? 1 : 0 }, tabIndex: -1, onLoad: () => {
51866
52469
  setIsIframeLoaded(true);
51867
52470
  setIsChatConnected(true);
51868
- } })] })) : agent ? (jsxRuntime.jsx(AgentChat, { agent: agent, actionsContainer: headerElement, isFocusedOnLoad: isFocusedOnLoad, extraActions: jsxRuntime.jsx("button", { className: styles.PromptbookAgentSeamlessIntegrationClose, onClick: () => setOpen(false), title: "Close", "aria-label": "Close chat", children: jsxRuntime.jsx(CloseIcon, {}) }), visual: "STANDALONE" })) : error ? (jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationError, children: [jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationErrorTitle, children: "Failed to connect to the agent" }), jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationErrorMessage, children: error.message })] })) : (jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationLoading, children: [jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLoadingShimmer }), jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLoadingSpinner }), jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLoadingTitle, children: "Preparing your chat" }), jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationLoadingText, children: ["Connecting to ", displayName, "..."] })] })) })] }))] }));
52471
+ } })] })) : agent ? (jsxRuntime.jsx(AgentChat, { agent: agent, actionsContainer: headerElement, isFocusedOnLoad: isFocusedOnLoad, extraActions: jsxRuntime.jsx("button", { className: styles.PromptbookAgentSeamlessIntegrationClose, onClick: () => setOpen(false), title: "Close", "aria-label": "Close chat", children: jsxRuntime.jsx(CloseIcon, {}) }), layout: "STANDALONE" })) : error ? (jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationError, children: [jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationErrorTitle, children: "Failed to connect to the agent" }), jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationErrorMessage, children: error.message })] })) : (jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationLoading, children: [jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLoadingShimmer }), jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLoadingSpinner }), jsxRuntime.jsx("div", { className: styles.PromptbookAgentSeamlessIntegrationLoadingTitle, children: "Preparing your chat" }), jsxRuntime.jsxs("div", { className: styles.PromptbookAgentSeamlessIntegrationLoadingText, children: ["Connecting to ", displayName, "..."] })] })) })] }))] }));
51869
52472
  }
51870
52473
 
51871
52474
  /**