@crestapps/ai-chat-ui 1.0.0-preview.9 → 1.0.0-rc.2

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.
@@ -387,6 +387,8 @@
387
387
  flex: 0 0 100%;
388
388
  margin: -0.5rem -0.75rem 0.5rem;
389
389
  padding: 0.5rem 0.75rem;
390
+ max-height: 4.5rem;
391
+ overflow-y: auto;
390
392
  }
391
393
 
392
394
  .ai-chat-widget-input textarea {
@@ -1 +1 @@
1
- {"version":3,"sources":["chat-widget.css"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"chat-widget.css","sourcesContent":["/* CrestApps AI Chat Widget */\n:root {\n --ai-widget-primary: var(--bs-secondary, #6c757d);\n --ai-widget-width: 380px;\n --ai-widget-height: 520px;\n}\n\n.ai-chat-widget-toggle {\n position: fixed;\n bottom: 1.25rem;\n right: 1.25rem;\n z-index: 10000;\n width: 52px;\n height: 52px;\n border-radius: 50%;\n background: var(--ai-widget-primary);\n color: white;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n box-shadow: 0 4px 12px rgba(0,0,0,0.2);\n transition: transform 0.2s, box-shadow 0.2s;\n}\n\n.ai-chat-widget-toggle:hover {\n transform: scale(1.1);\n box-shadow: 0 6px 16px rgba(0,0,0,0.3);\n}\n\n.ai-chat-widget-container {\n position: fixed;\n bottom: 5rem;\n right: 1.25rem;\n z-index: 10001;\n width: var(--ai-widget-width);\n height: var(--ai-widget-height);\n background: #fff;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.18);\n display: none;\n flex-direction: column;\n overflow: hidden;\n}\n\n.ai-chat-widget-container.ai-chat-widget-resizable {\n resize: both;\n min-width: 320px;\n min-height: 420px;\n max-width: min(90vw, 960px);\n max-height: min(90vh, 960px);\n}\n\n.ai-chat-widget-container.open {\n display: flex;\n}\n\n.ai-chat-widget-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n background: var(--ai-widget-primary);\n color: white;\n}\n\n.ai-chat-widget-header.ai-chat-widget-drag-handle {\n cursor: move;\n user-select: none;\n touch-action: none;\n}\n\n.ai-chat-widget-header-actions {\n display: flex;\n align-items: center;\n gap: 0.15rem;\n}\n\n.ai-chat-widget-toggle.ai-chat-widget-draggable {\n touch-action: none;\n}\n\n.ai-chat-widget-container.ai-chat-widget-dragging,\n.ai-chat-widget-toggle.ai-chat-widget-dragging {\n transition: none;\n}\n\n.ai-chat-widget-toggle.ai-chat-widget-dragging:hover {\n transform: none;\n}\n\n.ai-chat-widget-header .title {\n font-weight: 600;\n font-size: 0.95rem;\n}\n\n.ai-chat-widget-header button {\n background: none;\n border: none;\n color: white;\n cursor: pointer;\n font-size: 1rem;\n padding: 0 0.25rem;\n opacity: 0.8;\n}\n\n.ai-chat-widget-header button:hover {\n opacity: 1;\n}\n\n.ai-chat-widget-profile-select {\n padding: 0.5rem 0.75rem;\n border-bottom: 1px solid #e9ecef;\n background: #f8f9fa;\n}\n\n.ai-chat-widget-profile-select select {\n width: 100%;\n padding: 0.35rem 0.5rem;\n border: 1px solid #ced4da;\n border-radius: 6px;\n font-size: 0.85rem;\n}\n\n.ai-chat-widget-messages {\n flex: 1;\n overflow-y: auto;\n padding: 0.75rem;\n font-size: 0.9rem;\n}\n\n/* ── Widget message items (ai-chat.js Vue template) ── */\n.ai-chat-widget-messages .ai-chat-messages {\n padding: 0.5rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item {\n position: relative;\n padding: 0.5rem 0;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item + .ai-chat-message-item::before {\n content: '';\n display: block;\n width: 100%;\n margin-bottom: 0.5rem;\n border-top: 1px solid rgba(33, 37, 41, 0.08);\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role {\n font-size: 0.7rem;\n font-weight: 600;\n margin-bottom: 2px;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-user {\n color: #0d6efd;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant {\n color: var(--ai-widget-primary, #6f42c1);\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-streaming-icon {\n animation: ai-widget-pulse 1.5s infinite;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-bot-icon {\n color: currentColor;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body {\n position: relative;\n padding: 0;\n overflow-wrap: break-word;\n word-break: break-word;\n min-width: 0;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body p:last-child {\n margin-bottom: 0;\n}\n\n/* ── Message action buttons (copy, thumbs up/down) ── */\n.ai-chat-widget-messages .message-buttons-container {\n position: absolute;\n right: 0.1rem;\n bottom: 0;\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n width: auto;\n max-width: max-content;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease-in-out;\n background: rgba(255, 255, 255, 0.96);\n padding: 0.2rem 0.35rem;\n border-radius: 999px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n margin-bottom: 1rem;\n transform: translateY(50%);\n z-index: 1;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item:hover .message-buttons-container,\n.ai-chat-widget-messages .ai-chat-message-item:focus-within .message-buttons-container {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-messages .message-buttons-container:has(.tts-playing) {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: 1.75rem;\n height: 1.75rem;\n margin: 0 !important;\n padding: 0 !important;\n border-radius: 50%;\n color: var(--bs-secondary-color, #6c757d) !important;\n text-decoration: none;\n}\n\n.ai-chat-widget-messages .message-buttons-container .ai-chat-message-assistant-feedback {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox:hover,\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox:focus {\n color: var(--bs-body-color, #212529) !important;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.tts-playing {\n color: var(--ai-widget-primary, #6f42c1) !important;\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-history-panel {\n position: absolute;\n top: 3.5rem;\n left: 0;\n right: 0;\n bottom: 0;\n background: #fff;\n padding: 1rem;\n z-index: 10;\n display: none;\n overflow-y: auto;\n flex-direction: column;\n}\n\n.ai-chat-widget-history-panel.show {\n display: flex;\n}\n\n.ai-chat-widget-history-panel .history-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.75rem;\n flex-shrink: 0;\n}\n\n.ai-chat-widget-history-panel .history-header h5 {\n margin: 0;\n font-size: 1rem;\n}\n\n.ai-chat-widget-history-list {\n list-style: none;\n padding: 0;\n margin: 0;\n overflow-y: auto;\n flex: 1 1 auto;\n}\n\n.ai-chat-widget-history-list li {\n margin-bottom: 0;\n}\n\n.ai-chat-widget-history-list .chat-session-history-item {\n display: block;\n padding: 0.5rem 0.75rem;\n text-decoration: none;\n color: var(--bs-body-color, #212529);\n font-size: 0.85rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n transition: background 0.15s;\n cursor: pointer;\n border-bottom: 1px solid var(--bs-border-color, #dee2e6);\n}\n\n.ai-chat-widget-history-list li:last-child .chat-session-history-item {\n border-bottom: none;\n}\n\n.ai-chat-widget-history-list .chat-session-history-item:hover {\n background: var(--bs-tertiary-bg, #f8f9fa);\n}\n\n/* ── Notifications ── */\n.ai-chat-widget-messages .ai-chat-notification {\n margin: 0.75rem 0.5rem 0;\n padding: 0.625rem 0.75rem;\n border: 1px solid rgba(33, 37, 41, 0.12);\n border-radius: 0.5rem;\n background: rgba(248, 249, 250, 0.98);\n}\n\n.ai-chat-widget-messages .ai-chat-notification-content {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-icon {\n margin-top: 0.1rem;\n color: var(--bs-secondary-color, #6c757d);\n}\n\n.ai-chat-widget-messages .ai-chat-notification-text {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-dismiss {\n margin-left: auto !important;\n color: var(--bs-secondary-color, #6c757d) !important;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-actions {\n display: flex;\n gap: 0.5rem;\n margin-top: 0.5rem;\n}\n\n/* ── Chart containers inside widget ── */\n.ai-chat-widget-messages .chart-container {\n width: 100%;\n max-width: 100% !important;\n min-height: 280px;\n}\n\n/* ── Code blocks & inline code ── */\n.ai-chat-widget-messages .ai-chat-message-body pre {\n background: #2d2d2d;\n color: #f8f8f2;\n padding: 0.5rem;\n border-radius: 4px;\n overflow-x: auto;\n font-size: 0.8rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body code {\n font-size: 0.85em;\n}\n\n@keyframes ai-widget-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n\n.ai-chat-widget-input {\n border-top: 1px solid #e9ecef;\n padding: 0.5rem 0.75rem;\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n align-items: flex-end;\n}\n\n.ai-chat-widget-input .ai-chat-doc-bar {\n flex: 0 0 100%;\n margin: -0.5rem -0.75rem 0.5rem;\n padding: 0.5rem 0.75rem;\n}\n\n.ai-chat-widget-input textarea {\n flex: 1;\n min-width: 0;\n border: 1px solid #ced4da;\n border-radius: 8px;\n padding: 0.4rem 0.6rem;\n font-size: 0.9rem;\n resize: none;\n max-height: 80px;\n min-height: 36px;\n line-height: 1.4;\n outline: none;\n}\n\n.ai-chat-widget-input textarea:focus {\n border-color: var(--ai-widget-primary);\n box-shadow: 0 0 0 2px rgba(65,182,112,0.15);\n}\n\n.ai-chat-widget-input button {\n background: var(--ai-widget-primary);\n color: white;\n border: none;\n border-radius: 8px;\n padding: 0.4rem 0.75rem;\n cursor: pointer;\n font-size: 0.9rem;\n white-space: nowrap;\n}\n\n.ai-chat-widget-input .btn {\n background: var(--bs-body-bg, #fff);\n color: var(--bs-body-color, #212529);\n border: 1px solid var(--bs-border-color, #ced4da);\n}\n\n.ai-chat-widget-input .btn.btn-link {\n background: transparent;\n color: var(--bs-secondary-color, #6c757d);\n border: none;\n padding: 0.4rem;\n}\n\n.ai-chat-widget-input .btn.btn-outline-dark {\n background: var(--bs-dark, #212529);\n color: #fff;\n border-color: var(--bs-dark, #212529);\n}\n\n.ai-chat-widget-input .btn.btn-outline-secondary {\n color: var(--bs-secondary-color, #6c757d);\n}\n\n.ai-chat-widget-input button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.ai-chat-widget-status {\n padding: 0.25rem 0.75rem;\n font-size: 0.8rem;\n color: #6c757d;\n display: none;\n}\n\n.ai-chat-widget-status.visible {\n display: block;\n}\n\n.ai-chat-widget-welcome {\n text-align: center;\n color: #6c757d;\n padding: 2rem 1rem;\n font-size: 0.9rem;\n}\n\n@media (max-width: 576px) {\n .ai-chat-widget-container {\n width: calc(100vw - 1rem);\n height: calc(100vh - 6rem);\n right: 0.5rem;\n bottom: 4.5rem;\n }\n}\n"]}
1
+ {"version":3,"sources":["chat-widget.css"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"chat-widget.css","sourcesContent":["/* CrestApps AI Chat Widget */\n:root {\n --ai-widget-primary: var(--bs-secondary, #6c757d);\n --ai-widget-width: 380px;\n --ai-widget-height: 520px;\n}\n\n.ai-chat-widget-toggle {\n position: fixed;\n bottom: 1.25rem;\n right: 1.25rem;\n z-index: 10000;\n width: 52px;\n height: 52px;\n border-radius: 50%;\n background: var(--ai-widget-primary);\n color: white;\n border: none;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n box-shadow: 0 4px 12px rgba(0,0,0,0.2);\n transition: transform 0.2s, box-shadow 0.2s;\n}\n\n.ai-chat-widget-toggle:hover {\n transform: scale(1.1);\n box-shadow: 0 6px 16px rgba(0,0,0,0.3);\n}\n\n.ai-chat-widget-container {\n position: fixed;\n bottom: 5rem;\n right: 1.25rem;\n z-index: 10001;\n width: var(--ai-widget-width);\n height: var(--ai-widget-height);\n background: #fff;\n border-radius: 12px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.18);\n display: none;\n flex-direction: column;\n overflow: hidden;\n}\n\n.ai-chat-widget-container.ai-chat-widget-resizable {\n resize: both;\n min-width: 320px;\n min-height: 420px;\n max-width: min(90vw, 960px);\n max-height: min(90vh, 960px);\n}\n\n.ai-chat-widget-container.open {\n display: flex;\n}\n\n.ai-chat-widget-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n background: var(--ai-widget-primary);\n color: white;\n}\n\n.ai-chat-widget-header.ai-chat-widget-drag-handle {\n cursor: move;\n user-select: none;\n touch-action: none;\n}\n\n.ai-chat-widget-header-actions {\n display: flex;\n align-items: center;\n gap: 0.15rem;\n}\n\n.ai-chat-widget-toggle.ai-chat-widget-draggable {\n touch-action: none;\n}\n\n.ai-chat-widget-container.ai-chat-widget-dragging,\n.ai-chat-widget-toggle.ai-chat-widget-dragging {\n transition: none;\n}\n\n.ai-chat-widget-toggle.ai-chat-widget-dragging:hover {\n transform: none;\n}\n\n.ai-chat-widget-header .title {\n font-weight: 600;\n font-size: 0.95rem;\n}\n\n.ai-chat-widget-header button {\n background: none;\n border: none;\n color: white;\n cursor: pointer;\n font-size: 1rem;\n padding: 0 0.25rem;\n opacity: 0.8;\n}\n\n.ai-chat-widget-header button:hover {\n opacity: 1;\n}\n\n.ai-chat-widget-profile-select {\n padding: 0.5rem 0.75rem;\n border-bottom: 1px solid #e9ecef;\n background: #f8f9fa;\n}\n\n.ai-chat-widget-profile-select select {\n width: 100%;\n padding: 0.35rem 0.5rem;\n border: 1px solid #ced4da;\n border-radius: 6px;\n font-size: 0.85rem;\n}\n\n.ai-chat-widget-messages {\n flex: 1;\n overflow-y: auto;\n padding: 0.75rem;\n font-size: 0.9rem;\n}\n\n/* ── Widget message items (ai-chat.js Vue template) ── */\n.ai-chat-widget-messages .ai-chat-messages {\n padding: 0.5rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item {\n position: relative;\n padding: 0.5rem 0;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item + .ai-chat-message-item::before {\n content: '';\n display: block;\n width: 100%;\n margin-bottom: 0.5rem;\n border-top: 1px solid rgba(33, 37, 41, 0.08);\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role {\n font-size: 0.7rem;\n font-weight: 600;\n margin-bottom: 2px;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-user {\n color: #0d6efd;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant {\n color: var(--ai-widget-primary, #6f42c1);\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-streaming-icon {\n animation: ai-widget-pulse 1.5s infinite;\n}\n\n.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-bot-icon {\n color: currentColor;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body {\n position: relative;\n padding: 0;\n overflow-wrap: break-word;\n word-break: break-word;\n min-width: 0;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body p:last-child {\n margin-bottom: 0;\n}\n\n/* ── Message action buttons (copy, thumbs up/down) ── */\n.ai-chat-widget-messages .message-buttons-container {\n position: absolute;\n right: 0.1rem;\n bottom: 0;\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n width: auto;\n max-width: max-content;\n opacity: 0;\n pointer-events: none;\n transition: opacity 0.15s ease-in-out;\n background: rgba(255, 255, 255, 0.96);\n padding: 0.2rem 0.35rem;\n border-radius: 999px;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);\n margin-bottom: 1rem;\n transform: translateY(50%);\n z-index: 1;\n}\n\n.ai-chat-widget-messages .ai-chat-message-item:hover .message-buttons-container,\n.ai-chat-widget-messages .ai-chat-message-item:focus-within .message-buttons-container {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-messages .message-buttons-container:has(.tts-playing) {\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: 1.75rem;\n height: 1.75rem;\n margin: 0 !important;\n padding: 0 !important;\n border-radius: 50%;\n color: var(--bs-secondary-color, #6c757d) !important;\n text-decoration: none;\n}\n\n.ai-chat-widget-messages .message-buttons-container .ai-chat-message-assistant-feedback {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox:hover,\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox:focus {\n color: var(--bs-body-color, #212529) !important;\n}\n\n.ai-chat-widget-messages .message-buttons-container > .button-message-toolbox.tts-playing {\n color: var(--ai-widget-primary, #6f42c1) !important;\n opacity: 1;\n pointer-events: auto;\n}\n\n.ai-chat-widget-history-panel {\n position: absolute;\n top: 3.5rem;\n left: 0;\n right: 0;\n bottom: 0;\n background: #fff;\n padding: 1rem;\n z-index: 10;\n display: none;\n overflow-y: auto;\n flex-direction: column;\n}\n\n.ai-chat-widget-history-panel.show {\n display: flex;\n}\n\n.ai-chat-widget-history-panel .history-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 0.75rem;\n flex-shrink: 0;\n}\n\n.ai-chat-widget-history-panel .history-header h5 {\n margin: 0;\n font-size: 1rem;\n}\n\n.ai-chat-widget-history-list {\n list-style: none;\n padding: 0;\n margin: 0;\n overflow-y: auto;\n flex: 1 1 auto;\n}\n\n.ai-chat-widget-history-list li {\n margin-bottom: 0;\n}\n\n.ai-chat-widget-history-list .chat-session-history-item {\n display: block;\n padding: 0.5rem 0.75rem;\n text-decoration: none;\n color: var(--bs-body-color, #212529);\n font-size: 0.85rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n transition: background 0.15s;\n cursor: pointer;\n border-bottom: 1px solid var(--bs-border-color, #dee2e6);\n}\n\n.ai-chat-widget-history-list li:last-child .chat-session-history-item {\n border-bottom: none;\n}\n\n.ai-chat-widget-history-list .chat-session-history-item:hover {\n background: var(--bs-tertiary-bg, #f8f9fa);\n}\n\n/* ── Notifications ── */\n.ai-chat-widget-messages .ai-chat-notification {\n margin: 0.75rem 0.5rem 0;\n padding: 0.625rem 0.75rem;\n border: 1px solid rgba(33, 37, 41, 0.12);\n border-radius: 0.5rem;\n background: rgba(248, 249, 250, 0.98);\n}\n\n.ai-chat-widget-messages .ai-chat-notification-content {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-icon {\n margin-top: 0.1rem;\n color: var(--bs-secondary-color, #6c757d);\n}\n\n.ai-chat-widget-messages .ai-chat-notification-text {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-dismiss {\n margin-left: auto !important;\n color: var(--bs-secondary-color, #6c757d) !important;\n}\n\n.ai-chat-widget-messages .ai-chat-notification-actions {\n display: flex;\n gap: 0.5rem;\n margin-top: 0.5rem;\n}\n\n/* ── Chart containers inside widget ── */\n.ai-chat-widget-messages .chart-container {\n width: 100%;\n max-width: 100% !important;\n min-height: 280px;\n}\n\n/* ── Code blocks & inline code ── */\n.ai-chat-widget-messages .ai-chat-message-body pre {\n background: #2d2d2d;\n color: #f8f8f2;\n padding: 0.5rem;\n border-radius: 4px;\n overflow-x: auto;\n font-size: 0.8rem;\n}\n\n.ai-chat-widget-messages .ai-chat-message-body code {\n font-size: 0.85em;\n}\n\n@keyframes ai-widget-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n\n.ai-chat-widget-input {\n border-top: 1px solid #e9ecef;\n padding: 0.5rem 0.75rem;\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n align-items: flex-end;\n}\n\n.ai-chat-widget-input .ai-chat-doc-bar {\n flex: 0 0 100%;\n margin: -0.5rem -0.75rem 0.5rem;\n padding: 0.5rem 0.75rem;\n max-height: 4.5rem;\n overflow-y: auto;\n}\n\n.ai-chat-widget-input textarea {\n flex: 1;\n min-width: 0;\n border: 1px solid #ced4da;\n border-radius: 8px;\n padding: 0.4rem 0.6rem;\n font-size: 0.9rem;\n resize: none;\n max-height: 80px;\n min-height: 36px;\n line-height: 1.4;\n outline: none;\n}\n\n.ai-chat-widget-input textarea:focus {\n border-color: var(--ai-widget-primary);\n box-shadow: 0 0 0 2px rgba(65,182,112,0.15);\n}\n\n.ai-chat-widget-input button {\n background: var(--ai-widget-primary);\n color: white;\n border: none;\n border-radius: 8px;\n padding: 0.4rem 0.75rem;\n cursor: pointer;\n font-size: 0.9rem;\n white-space: nowrap;\n}\n\n.ai-chat-widget-input .btn {\n background: var(--bs-body-bg, #fff);\n color: var(--bs-body-color, #212529);\n border: 1px solid var(--bs-border-color, #ced4da);\n}\n\n.ai-chat-widget-input .btn.btn-link {\n background: transparent;\n color: var(--bs-secondary-color, #6c757d);\n border: none;\n padding: 0.4rem;\n}\n\n.ai-chat-widget-input .btn.btn-outline-dark {\n background: var(--bs-dark, #212529);\n color: #fff;\n border-color: var(--bs-dark, #212529);\n}\n\n.ai-chat-widget-input .btn.btn-outline-secondary {\n color: var(--bs-secondary-color, #6c757d);\n}\n\n.ai-chat-widget-input button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.ai-chat-widget-status {\n padding: 0.25rem 0.75rem;\n font-size: 0.8rem;\n color: #6c757d;\n display: none;\n}\n\n.ai-chat-widget-status.visible {\n display: block;\n}\n\n.ai-chat-widget-welcome {\n text-align: center;\n color: #6c757d;\n padding: 2rem 1rem;\n font-size: 0.9rem;\n}\n\n@media (max-width: 576px) {\n .ai-chat-widget-container {\n width: calc(100vw - 1rem);\n height: calc(100vh - 6rem);\n right: 0.5rem;\n bottom: 4.5rem;\n }\n}\n"]}
@@ -1 +1 @@
1
- :root{--ai-widget-primary:var(--bs-secondary, #6c757d);--ai-widget-width:380px;--ai-widget-height:520px}.ai-chat-widget-toggle{position:fixed;bottom:1.25rem;right:1.25rem;z-index:10000;width:52px;height:52px;border-radius:50%;background:var(--ai-widget-primary);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:1.5rem;box-shadow:0 4px 12px rgba(0,0,0,.2);transition:transform .2s,box-shadow .2s}.ai-chat-widget-toggle:hover{transform:scale(1.1);box-shadow:0 6px 16px rgba(0,0,0,.3)}.ai-chat-widget-container{position:fixed;bottom:5rem;right:1.25rem;z-index:10001;width:var(--ai-widget-width);height:var(--ai-widget-height);background:#fff;border-radius:12px;box-shadow:0 8px 32px rgba(0,0,0,.18);display:none;flex-direction:column;overflow:hidden}.ai-chat-widget-container.ai-chat-widget-resizable{resize:both;min-width:320px;min-height:420px;max-width:min(90vw,960px);max-height:min(90vh,960px)}.ai-chat-widget-container.open{display:flex}.ai-chat-widget-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;background:var(--ai-widget-primary);color:#fff}.ai-chat-widget-header.ai-chat-widget-drag-handle{cursor:move;user-select:none;touch-action:none}.ai-chat-widget-header-actions{display:flex;align-items:center;gap:.15rem}.ai-chat-widget-toggle.ai-chat-widget-draggable{touch-action:none}.ai-chat-widget-container.ai-chat-widget-dragging,.ai-chat-widget-toggle.ai-chat-widget-dragging{transition:none}.ai-chat-widget-toggle.ai-chat-widget-dragging:hover{transform:none}.ai-chat-widget-header .title{font-weight:600;font-size:.95rem}.ai-chat-widget-header button{background:0 0;border:none;color:#fff;cursor:pointer;font-size:1rem;padding:0 .25rem;opacity:.8}.ai-chat-widget-header button:hover{opacity:1}.ai-chat-widget-profile-select{padding:.5rem .75rem;border-bottom:1px solid #e9ecef;background:#f8f9fa}.ai-chat-widget-profile-select select{width:100%;padding:.35rem .5rem;border:1px solid #ced4da;border-radius:6px;font-size:.85rem}.ai-chat-widget-messages{flex:1;overflow-y:auto;padding:.75rem;font-size:.9rem}.ai-chat-widget-messages .ai-chat-messages{padding:.5rem}.ai-chat-widget-messages .ai-chat-message-item{position:relative;padding:.5rem 0}.ai-chat-widget-messages .ai-chat-message-item+.ai-chat-message-item::before{content:'';display:block;width:100%;margin-bottom:.5rem;border-top:1px solid rgba(33,37,41,.08)}.ai-chat-widget-messages .ai-chat-msg-role{font-size:.7rem;font-weight:600;margin-bottom:2px}.ai-chat-widget-messages .ai-chat-msg-role-user{color:#0d6efd}.ai-chat-widget-messages .ai-chat-msg-role-assistant{color:var(--ai-widget-primary,#6f42c1)}.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-streaming-icon{animation:ai-widget-pulse 1.5s infinite}.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-bot-icon{color:currentColor}.ai-chat-widget-messages .ai-chat-message-body{position:relative;padding:0;overflow-wrap:break-word;word-break:break-word;min-width:0}.ai-chat-widget-messages .ai-chat-message-body p:last-child{margin-bottom:0}.ai-chat-widget-messages .message-buttons-container{position:absolute;right:.1rem;bottom:0;display:inline-flex;align-items:center;gap:.35rem;width:auto;max-width:max-content;opacity:0;pointer-events:none;transition:opacity .15s ease-in-out;background:rgba(255,255,255,.96);padding:.2rem .35rem;border-radius:999px;box-shadow:0 1px 3px rgba(0,0,0,.08);margin-bottom:1rem;transform:translateY(50%);z-index:1}.ai-chat-widget-messages .ai-chat-message-item:focus-within .message-buttons-container,.ai-chat-widget-messages .ai-chat-message-item:hover .message-buttons-container{opacity:1;pointer-events:auto}.ai-chat-widget-messages .message-buttons-container:has(.tts-playing){opacity:1;pointer-events:auto}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:1.75rem;height:1.75rem;margin:0!important;padding:0!important;border-radius:50%;color:var(--bs-secondary-color,#6c757d)!important;text-decoration:none}.ai-chat-widget-messages .message-buttons-container .ai-chat-message-assistant-feedback{display:inline-flex;align-items:center;gap:.35rem}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox:focus,.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox:hover{color:var(--bs-body-color,#212529)!important}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox.tts-playing{color:var(--ai-widget-primary,#6f42c1)!important;opacity:1;pointer-events:auto}.ai-chat-widget-history-panel{position:absolute;top:3.5rem;left:0;right:0;bottom:0;background:#fff;padding:1rem;z-index:10;display:none;overflow-y:auto;flex-direction:column}.ai-chat-widget-history-panel.show{display:flex}.ai-chat-widget-history-panel .history-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem;flex-shrink:0}.ai-chat-widget-history-panel .history-header h5{margin:0;font-size:1rem}.ai-chat-widget-history-list{list-style:none;padding:0;margin:0;overflow-y:auto;flex:1 1 auto}.ai-chat-widget-history-list li{margin-bottom:0}.ai-chat-widget-history-list .chat-session-history-item{display:block;padding:.5rem .75rem;text-decoration:none;color:var(--bs-body-color,#212529);font-size:.85rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:background .15s;cursor:pointer;border-bottom:1px solid var(--bs-border-color,#dee2e6)}.ai-chat-widget-history-list li:last-child .chat-session-history-item{border-bottom:none}.ai-chat-widget-history-list .chat-session-history-item:hover{background:var(--bs-tertiary-bg,#f8f9fa)}.ai-chat-widget-messages .ai-chat-notification{margin:.75rem .5rem 0;padding:.625rem .75rem;border:1px solid rgba(33,37,41,.12);border-radius:.5rem;background:rgba(248,249,250,.98)}.ai-chat-widget-messages .ai-chat-notification-content{display:flex;align-items:flex-start;gap:.5rem}.ai-chat-widget-messages .ai-chat-notification-icon{margin-top:.1rem;color:var(--bs-secondary-color,#6c757d)}.ai-chat-widget-messages .ai-chat-notification-text{flex:1 1 auto;min-width:0}.ai-chat-widget-messages .ai-chat-notification-dismiss{margin-left:auto!important;color:var(--bs-secondary-color,#6c757d)!important}.ai-chat-widget-messages .ai-chat-notification-actions{display:flex;gap:.5rem;margin-top:.5rem}.ai-chat-widget-messages .chart-container{width:100%;max-width:100%!important;min-height:280px}.ai-chat-widget-messages .ai-chat-message-body pre{background:#2d2d2d;color:#f8f8f2;padding:.5rem;border-radius:4px;overflow-x:auto;font-size:.8rem}.ai-chat-widget-messages .ai-chat-message-body code{font-size:.85em}@keyframes ai-widget-pulse{0%,100%{opacity:1}50%{opacity:.4}}.ai-chat-widget-input{border-top:1px solid #e9ecef;padding:.5rem .75rem;display:flex;flex-wrap:wrap;gap:.5rem;align-items:flex-end}.ai-chat-widget-input .ai-chat-doc-bar{flex:0 0 100%;margin:-.5rem -.75rem .5rem;padding:.5rem .75rem}.ai-chat-widget-input textarea{flex:1;min-width:0;border:1px solid #ced4da;border-radius:8px;padding:.4rem .6rem;font-size:.9rem;resize:none;max-height:80px;min-height:36px;line-height:1.4;outline:0}.ai-chat-widget-input textarea:focus{border-color:var(--ai-widget-primary);box-shadow:0 0 0 2px rgba(65,182,112,.15)}.ai-chat-widget-input button{background:var(--ai-widget-primary);color:#fff;border:none;border-radius:8px;padding:.4rem .75rem;cursor:pointer;font-size:.9rem;white-space:nowrap}.ai-chat-widget-input .btn{background:var(--bs-body-bg,#fff);color:var(--bs-body-color,#212529);border:1px solid var(--bs-border-color,#ced4da)}.ai-chat-widget-input .btn.btn-link{background:0 0;color:var(--bs-secondary-color,#6c757d);border:none;padding:.4rem}.ai-chat-widget-input .btn.btn-outline-dark{background:var(--bs-dark,#212529);color:#fff;border-color:var(--bs-dark,#212529)}.ai-chat-widget-input .btn.btn-outline-secondary{color:var(--bs-secondary-color,#6c757d)}.ai-chat-widget-input button:disabled{opacity:.5;cursor:not-allowed}.ai-chat-widget-status{padding:.25rem .75rem;font-size:.8rem;color:#6c757d;display:none}.ai-chat-widget-status.visible{display:block}.ai-chat-widget-welcome{text-align:center;color:#6c757d;padding:2rem 1rem;font-size:.9rem}@media (max-width:576px){.ai-chat-widget-container{width:calc(100vw - 1rem);height:calc(100vh - 6rem);right:.5rem;bottom:4.5rem}}
1
+ :root{--ai-widget-primary:var(--bs-secondary, #6c757d);--ai-widget-width:380px;--ai-widget-height:520px}.ai-chat-widget-toggle{position:fixed;bottom:1.25rem;right:1.25rem;z-index:10000;width:52px;height:52px;border-radius:50%;background:var(--ai-widget-primary);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:1.5rem;box-shadow:0 4px 12px rgba(0,0,0,.2);transition:transform .2s,box-shadow .2s}.ai-chat-widget-toggle:hover{transform:scale(1.1);box-shadow:0 6px 16px rgba(0,0,0,.3)}.ai-chat-widget-container{position:fixed;bottom:5rem;right:1.25rem;z-index:10001;width:var(--ai-widget-width);height:var(--ai-widget-height);background:#fff;border-radius:12px;box-shadow:0 8px 32px rgba(0,0,0,.18);display:none;flex-direction:column;overflow:hidden}.ai-chat-widget-container.ai-chat-widget-resizable{resize:both;min-width:320px;min-height:420px;max-width:min(90vw,960px);max-height:min(90vh,960px)}.ai-chat-widget-container.open{display:flex}.ai-chat-widget-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;background:var(--ai-widget-primary);color:#fff}.ai-chat-widget-header.ai-chat-widget-drag-handle{cursor:move;user-select:none;touch-action:none}.ai-chat-widget-header-actions{display:flex;align-items:center;gap:.15rem}.ai-chat-widget-toggle.ai-chat-widget-draggable{touch-action:none}.ai-chat-widget-container.ai-chat-widget-dragging,.ai-chat-widget-toggle.ai-chat-widget-dragging{transition:none}.ai-chat-widget-toggle.ai-chat-widget-dragging:hover{transform:none}.ai-chat-widget-header .title{font-weight:600;font-size:.95rem}.ai-chat-widget-header button{background:0 0;border:none;color:#fff;cursor:pointer;font-size:1rem;padding:0 .25rem;opacity:.8}.ai-chat-widget-header button:hover{opacity:1}.ai-chat-widget-profile-select{padding:.5rem .75rem;border-bottom:1px solid #e9ecef;background:#f8f9fa}.ai-chat-widget-profile-select select{width:100%;padding:.35rem .5rem;border:1px solid #ced4da;border-radius:6px;font-size:.85rem}.ai-chat-widget-messages{flex:1;overflow-y:auto;padding:.75rem;font-size:.9rem}.ai-chat-widget-messages .ai-chat-messages{padding:.5rem}.ai-chat-widget-messages .ai-chat-message-item{position:relative;padding:.5rem 0}.ai-chat-widget-messages .ai-chat-message-item+.ai-chat-message-item::before{content:'';display:block;width:100%;margin-bottom:.5rem;border-top:1px solid rgba(33,37,41,.08)}.ai-chat-widget-messages .ai-chat-msg-role{font-size:.7rem;font-weight:600;margin-bottom:2px}.ai-chat-widget-messages .ai-chat-msg-role-user{color:#0d6efd}.ai-chat-widget-messages .ai-chat-msg-role-assistant{color:var(--ai-widget-primary,#6f42c1)}.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-streaming-icon{animation:ai-widget-pulse 1.5s infinite}.ai-chat-widget-messages .ai-chat-msg-role-assistant i.ai-bot-icon{color:currentColor}.ai-chat-widget-messages .ai-chat-message-body{position:relative;padding:0;overflow-wrap:break-word;word-break:break-word;min-width:0}.ai-chat-widget-messages .ai-chat-message-body p:last-child{margin-bottom:0}.ai-chat-widget-messages .message-buttons-container{position:absolute;right:.1rem;bottom:0;display:inline-flex;align-items:center;gap:.35rem;width:auto;max-width:max-content;opacity:0;pointer-events:none;transition:opacity .15s ease-in-out;background:rgba(255,255,255,.96);padding:.2rem .35rem;border-radius:999px;box-shadow:0 1px 3px rgba(0,0,0,.08);margin-bottom:1rem;transform:translateY(50%);z-index:1}.ai-chat-widget-messages .ai-chat-message-item:focus-within .message-buttons-container,.ai-chat-widget-messages .ai-chat-message-item:hover .message-buttons-container{opacity:1;pointer-events:auto}.ai-chat-widget-messages .message-buttons-container:has(.tts-playing){opacity:1;pointer-events:auto}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:1.75rem;height:1.75rem;margin:0!important;padding:0!important;border-radius:50%;color:var(--bs-secondary-color,#6c757d)!important;text-decoration:none}.ai-chat-widget-messages .message-buttons-container .ai-chat-message-assistant-feedback{display:inline-flex;align-items:center;gap:.35rem}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox:focus,.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox:hover{color:var(--bs-body-color,#212529)!important}.ai-chat-widget-messages .message-buttons-container>.button-message-toolbox.tts-playing{color:var(--ai-widget-primary,#6f42c1)!important;opacity:1;pointer-events:auto}.ai-chat-widget-history-panel{position:absolute;top:3.5rem;left:0;right:0;bottom:0;background:#fff;padding:1rem;z-index:10;display:none;overflow-y:auto;flex-direction:column}.ai-chat-widget-history-panel.show{display:flex}.ai-chat-widget-history-panel .history-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:.75rem;flex-shrink:0}.ai-chat-widget-history-panel .history-header h5{margin:0;font-size:1rem}.ai-chat-widget-history-list{list-style:none;padding:0;margin:0;overflow-y:auto;flex:1 1 auto}.ai-chat-widget-history-list li{margin-bottom:0}.ai-chat-widget-history-list .chat-session-history-item{display:block;padding:.5rem .75rem;text-decoration:none;color:var(--bs-body-color,#212529);font-size:.85rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:background .15s;cursor:pointer;border-bottom:1px solid var(--bs-border-color,#dee2e6)}.ai-chat-widget-history-list li:last-child .chat-session-history-item{border-bottom:none}.ai-chat-widget-history-list .chat-session-history-item:hover{background:var(--bs-tertiary-bg,#f8f9fa)}.ai-chat-widget-messages .ai-chat-notification{margin:.75rem .5rem 0;padding:.625rem .75rem;border:1px solid rgba(33,37,41,.12);border-radius:.5rem;background:rgba(248,249,250,.98)}.ai-chat-widget-messages .ai-chat-notification-content{display:flex;align-items:flex-start;gap:.5rem}.ai-chat-widget-messages .ai-chat-notification-icon{margin-top:.1rem;color:var(--bs-secondary-color,#6c757d)}.ai-chat-widget-messages .ai-chat-notification-text{flex:1 1 auto;min-width:0}.ai-chat-widget-messages .ai-chat-notification-dismiss{margin-left:auto!important;color:var(--bs-secondary-color,#6c757d)!important}.ai-chat-widget-messages .ai-chat-notification-actions{display:flex;gap:.5rem;margin-top:.5rem}.ai-chat-widget-messages .chart-container{width:100%;max-width:100%!important;min-height:280px}.ai-chat-widget-messages .ai-chat-message-body pre{background:#2d2d2d;color:#f8f8f2;padding:.5rem;border-radius:4px;overflow-x:auto;font-size:.8rem}.ai-chat-widget-messages .ai-chat-message-body code{font-size:.85em}@keyframes ai-widget-pulse{0%,100%{opacity:1}50%{opacity:.4}}.ai-chat-widget-input{border-top:1px solid #e9ecef;padding:.5rem .75rem;display:flex;flex-wrap:wrap;gap:.5rem;align-items:flex-end}.ai-chat-widget-input .ai-chat-doc-bar{flex:0 0 100%;margin:-.5rem -.75rem .5rem;padding:.5rem .75rem;max-height:4.5rem;overflow-y:auto}.ai-chat-widget-input textarea{flex:1;min-width:0;border:1px solid #ced4da;border-radius:8px;padding:.4rem .6rem;font-size:.9rem;resize:none;max-height:80px;min-height:36px;line-height:1.4;outline:0}.ai-chat-widget-input textarea:focus{border-color:var(--ai-widget-primary);box-shadow:0 0 0 2px rgba(65,182,112,.15)}.ai-chat-widget-input button{background:var(--ai-widget-primary);color:#fff;border:none;border-radius:8px;padding:.4rem .75rem;cursor:pointer;font-size:.9rem;white-space:nowrap}.ai-chat-widget-input .btn{background:var(--bs-body-bg,#fff);color:var(--bs-body-color,#212529);border:1px solid var(--bs-border-color,#ced4da)}.ai-chat-widget-input .btn.btn-link{background:0 0;color:var(--bs-secondary-color,#6c757d);border:none;padding:.4rem}.ai-chat-widget-input .btn.btn-outline-dark{background:var(--bs-dark,#212529);color:#fff;border-color:var(--bs-dark,#212529)}.ai-chat-widget-input .btn.btn-outline-secondary{color:var(--bs-secondary-color,#6c757d)}.ai-chat-widget-input button:disabled{opacity:.5;cursor:not-allowed}.ai-chat-widget-status{padding:.25rem .75rem;font-size:.8rem;color:#6c757d;display:none}.ai-chat-widget-status.visible{display:block}.ai-chat-widget-welcome{text-align:center;color:#6c757d;padding:2rem 1rem;font-size:.9rem}@media (max-width:576px){.ai-chat-widget-container{width:calc(100vw - 1rem);height:calc(100vh - 6rem);right:.5rem;bottom:4.5rem}}
@@ -16,26 +16,54 @@
16
16
  }
17
17
  function initAutoGenerateTechnicalName(displayId, nameId) {
18
18
  if (!displayId || !nameId) return;
19
- document.addEventListener('DOMContentLoaded', function () {
19
+ function attach() {
20
20
  var displayEl = document.getElementById(displayId);
21
21
  var nameEl = document.getElementById(nameId);
22
22
  if (!displayEl || !nameEl) return;
23
+ if (nameEl.dataset.techNameInitialized === 'true') return;
24
+ nameEl.dataset.techNameInitialized = 'true';
23
25
 
24
26
  // Track whether the user has entered a non-empty value in the Name field.
25
27
  var userEdited = nameEl.value.trim() !== '';
28
+ // Set while we synthesize input/change events on the name field so we can
29
+ // distinguish programmatic updates from real user typing.
30
+ var suppressUserEditedTracking = false;
26
31
 
27
32
  // Resume auto-generation only when the Name field is empty again.
28
- nameEl.addEventListener('input', function () {
33
+ nameEl.addEventListener('input', function (e) {
34
+ if (suppressUserEditedTracking || e && e.isTrusted === false) {
35
+ return;
36
+ }
29
37
  userEdited = nameEl.value.trim() !== '';
30
38
  });
31
-
32
- // Generate on keyup as requested
33
- displayEl.addEventListener('keyup', function () {
39
+ function updateGeneratedValue() {
34
40
  if (userEdited) return;
35
41
  var generated = toTitleCaseNoSpaces(displayEl.value || '');
36
- nameEl.value = generated;
37
- });
38
- });
42
+ if (nameEl.value === generated) {
43
+ return;
44
+ }
45
+ suppressUserEditedTracking = true;
46
+ try {
47
+ nameEl.value = generated;
48
+ nameEl.dispatchEvent(new Event('input', {
49
+ bubbles: true
50
+ }));
51
+ nameEl.dispatchEvent(new Event('change', {
52
+ bubbles: true
53
+ }));
54
+ } finally {
55
+ suppressUserEditedTracking = false;
56
+ }
57
+ }
58
+ displayEl.addEventListener('input', updateGeneratedValue);
59
+ displayEl.addEventListener('keyup', updateGeneratedValue);
60
+ displayEl.addEventListener('change', updateGeneratedValue);
61
+ }
62
+ if (document.readyState === 'loading') {
63
+ document.addEventListener('DOMContentLoaded', attach);
64
+ } else {
65
+ attach();
66
+ }
39
67
  }
40
68
 
41
69
  // Automatically initialize for any elements using the data attributes.
@@ -1 +1 @@
1
- {"version":3,"sources":["technical-name-generator.js"],"names":["toTitleCaseNoSpaces","value","trim","split","filter","w","length","map","charAt","toUpperCase","slice","toLowerCase","join","initAutoGenerateTechnicalName","displayId","nameId","document","addEventListener","displayEl","getElementById","nameEl","userEdited","generated","autoEls","querySelectorAll","i","el","getAttribute","window"],"mappings":";;;;;AAAA,CAAC,YAAY;EACX;EACA,SAASA,mBAAmBA,CAACC,KAAK,EAAE;IAClC,OAAO,CAACA,KAAK,IAAI,EAAE,EAChBC,IAAI,CAAC;IACN;IAAA,CACCC,KAAK,CAAC,eAAe,CAAC,CACtBC,MAAM,CAAC,UAAUC,CAAC,EAAE;MAAE,OAAOA,CAAC,CAACC,MAAM,GAAG,CAAC;IAAE,CAAC,CAAC,CAC7CC,GAAG,CAAC,UAAUF,CAAC,EAAE;MAAE,OAAOA,CAAC,CAACG,MAAM,CAAC,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC,GAAGJ,CAAC,CAACK,KAAK,CAAC,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC;IAAE,CAAC,CAAC,CAClFC,IAAI,CAAC,EAAE,CAAC;EACb;EAEA,SAASC,6BAA6BA,CAACC,SAAS,EAAEC,MAAM,EAAE;IACxD,IAAI,CAACD,SAAS,IAAI,CAACC,MAAM,EAAE;IAC3BC,QAAQ,CAACC,gBAAgB,CAAC,kBAAkB,EAAE,YAAY;MACxD,IAAIC,SAAS,GAAGF,QAAQ,CAACG,cAAc,CAACL,SAAS,CAAC;MAClD,IAAIM,MAAM,GAAGJ,QAAQ,CAACG,cAAc,CAACJ,MAAM,CAAC;MAC5C,IAAI,CAACG,SAAS,IAAI,CAACE,MAAM,EAAE;;MAE3B;MACA,IAAIC,UAAU,GAAGD,MAAM,CAACnB,KAAK,CAACC,IAAI,CAAC,CAAC,KAAK,EAAE;;MAE3C;MACAkB,MAAM,CAACH,gBAAgB,CAAC,OAAO,EAAE,YAAY;QAC3CI,UAAU,GAAGD,MAAM,CAACnB,KAAK,CAACC,IAAI,CAAC,CAAC,KAAK,EAAE;MACzC,CAAC,CAAC;;MAEF;MACAgB,SAAS,CAACD,gBAAgB,CAAC,OAAO,EAAE,YAAY;QAC9C,IAAII,UAAU,EAAE;QAChB,IAAIC,SAAS,GAAGtB,mBAAmB,CAACkB,SAAS,CAACjB,KAAK,IAAI,EAAE,CAAC;QAC1DmB,MAAM,CAACnB,KAAK,GAAGqB,SAAS;MAC1B,CAAC,CAAC;IACJ,CAAC,CAAC;EACJ;;EAEA;EACAN,QAAQ,CAACC,gBAAgB,CAAC,kBAAkB,EAAE,YAAY;IACxD,IAAIM,OAAO,GAAGP,QAAQ,CAACQ,gBAAgB,CAAC,uBAAuB,CAAC;IAChE,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGF,OAAO,CAACjB,MAAM,EAAEmB,CAAC,EAAE,EAAE;MACvC,IAAIC,EAAE,GAAGH,OAAO,CAACE,CAAC,CAAC;MACnB,IAAIX,SAAS,GAAGY,EAAE,CAACC,YAAY,CAAC,iBAAiB,CAAC;MAClD,IAAIZ,MAAM,GAAGW,EAAE,CAACC,YAAY,CAAC,cAAc,CAAC;MAC5C,IAAIb,SAAS,IAAIC,MAAM,EAAE;QACvB;QACAF,6BAA6B,CAACC,SAAS,EAAEC,MAAM,CAAC;MAClD;IACF;EACF,CAAC,CAAC;EAEFa,MAAM,CAACf,6BAA6B,GAAGA,6BAA6B;AACtE,CAAC,EAAE,CAAC","file":"technical-name-generator.js","sourcesContent":["(function () {\n // Expose initializer globally so views can call it with specific field IDs.\n function toTitleCaseNoSpaces(value) {\n return (value || '')\n .trim()\n // split on whitespace or common separators or any non-alphanumeric\n .split(/[^A-Za-z0-9]+/)\n .filter(function (w) { return w.length > 0; })\n .map(function (w) { return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase(); })\n .join('');\n }\n\n function initAutoGenerateTechnicalName(displayId, nameId) {\n if (!displayId || !nameId) return;\n document.addEventListener('DOMContentLoaded', function () {\n var displayEl = document.getElementById(displayId);\n var nameEl = document.getElementById(nameId);\n if (!displayEl || !nameEl) return;\n\n // Track whether the user has entered a non-empty value in the Name field.\n var userEdited = nameEl.value.trim() !== '';\n\n // Resume auto-generation only when the Name field is empty again.\n nameEl.addEventListener('input', function () {\n userEdited = nameEl.value.trim() !== '';\n });\n\n // Generate on keyup as requested\n displayEl.addEventListener('keyup', function () {\n if (userEdited) return;\n var generated = toTitleCaseNoSpaces(displayEl.value || '');\n nameEl.value = generated;\n });\n });\n }\n\n // Automatically initialize for any elements using the data attributes.\n document.addEventListener('DOMContentLoaded', function () {\n var autoEls = document.querySelectorAll('[data-auto-tech-name]');\n for (var i = 0; i < autoEls.length; i++) {\n var el = autoEls[i];\n var displayId = el.getAttribute('data-display-id');\n var nameId = el.getAttribute('data-name-id');\n if (displayId && nameId) {\n // call initializer immediately (it will attach listeners)\n initAutoGenerateTechnicalName(displayId, nameId);\n }\n }\n });\n\n window.initAutoGenerateTechnicalName = initAutoGenerateTechnicalName;\n})();\n"]}
1
+ {"version":3,"sources":["technical-name-generator.js"],"names":["toTitleCaseNoSpaces","value","trim","split","filter","w","length","map","charAt","toUpperCase","slice","toLowerCase","join","initAutoGenerateTechnicalName","displayId","nameId","attach","displayEl","document","getElementById","nameEl","dataset","techNameInitialized","userEdited","suppressUserEditedTracking","addEventListener","e","isTrusted","updateGeneratedValue","generated","dispatchEvent","Event","bubbles","readyState","autoEls","querySelectorAll","i","el","getAttribute","window"],"mappings":";;;;;AAAA,CAAC,YAAY;EACX;EACA,SAASA,mBAAmBA,CAACC,KAAK,EAAE;IAClC,OAAO,CAACA,KAAK,IAAI,EAAE,EAChBC,IAAI,CAAC;IACN;IAAA,CACCC,KAAK,CAAC,eAAe,CAAC,CACtBC,MAAM,CAAC,UAAUC,CAAC,EAAE;MAAE,OAAOA,CAAC,CAACC,MAAM,GAAG,CAAC;IAAE,CAAC,CAAC,CAC7CC,GAAG,CAAC,UAAUF,CAAC,EAAE;MAAE,OAAOA,CAAC,CAACG,MAAM,CAAC,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC,GAAGJ,CAAC,CAACK,KAAK,CAAC,CAAC,CAAC,CAACC,WAAW,CAAC,CAAC;IAAE,CAAC,CAAC,CAClFC,IAAI,CAAC,EAAE,CAAC;EACb;EAEA,SAASC,6BAA6BA,CAACC,SAAS,EAAEC,MAAM,EAAE;IACxD,IAAI,CAACD,SAAS,IAAI,CAACC,MAAM,EAAE;IAE3B,SAASC,MAAMA,CAAA,EAAG;MAChB,IAAIC,SAAS,GAAGC,QAAQ,CAACC,cAAc,CAACL,SAAS,CAAC;MAClD,IAAIM,MAAM,GAAGF,QAAQ,CAACC,cAAc,CAACJ,MAAM,CAAC;MAC5C,IAAI,CAACE,SAAS,IAAI,CAACG,MAAM,EAAE;MAC3B,IAAIA,MAAM,CAACC,OAAO,CAACC,mBAAmB,KAAK,MAAM,EAAE;MAEnDF,MAAM,CAACC,OAAO,CAACC,mBAAmB,GAAG,MAAM;;MAE3C;MACA,IAAIC,UAAU,GAAGH,MAAM,CAACnB,KAAK,CAACC,IAAI,CAAC,CAAC,KAAK,EAAE;MAC3C;MACA;MACA,IAAIsB,0BAA0B,GAAG,KAAK;;MAEtC;MACAJ,MAAM,CAACK,gBAAgB,CAAC,OAAO,EAAE,UAAUC,CAAC,EAAE;QAC5C,IAAIF,0BAA0B,IAAKE,CAAC,IAAIA,CAAC,CAACC,SAAS,KAAK,KAAM,EAAE;UAC9D;QACF;QAEAJ,UAAU,GAAGH,MAAM,CAACnB,KAAK,CAACC,IAAI,CAAC,CAAC,KAAK,EAAE;MACzC,CAAC,CAAC;MAEF,SAAS0B,oBAAoBA,CAAA,EAAG;QAC9B,IAAIL,UAAU,EAAE;QAEhB,IAAIM,SAAS,GAAG7B,mBAAmB,CAACiB,SAAS,CAAChB,KAAK,IAAI,EAAE,CAAC;QAE1D,IAAImB,MAAM,CAACnB,KAAK,KAAK4B,SAAS,EAAE;UAC9B;QACF;QAEAL,0BAA0B,GAAG,IAAI;QACjC,IAAI;UACFJ,MAAM,CAACnB,KAAK,GAAG4B,SAAS;UACxBT,MAAM,CAACU,aAAa,CAAC,IAAIC,KAAK,CAAC,OAAO,EAAE;YAAEC,OAAO,EAAE;UAAK,CAAC,CAAC,CAAC;UAC3DZ,MAAM,CAACU,aAAa,CAAC,IAAIC,KAAK,CAAC,QAAQ,EAAE;YAAEC,OAAO,EAAE;UAAK,CAAC,CAAC,CAAC;QAC9D,CAAC,SAAS;UACRR,0BAA0B,GAAG,KAAK;QACpC;MACF;MAEAP,SAAS,CAACQ,gBAAgB,CAAC,OAAO,EAAEG,oBAAoB,CAAC;MACzDX,SAAS,CAACQ,gBAAgB,CAAC,OAAO,EAAEG,oBAAoB,CAAC;MACzDX,SAAS,CAACQ,gBAAgB,CAAC,QAAQ,EAAEG,oBAAoB,CAAC;IAC5D;IAEA,IAAIV,QAAQ,CAACe,UAAU,KAAK,SAAS,EAAE;MACrCf,QAAQ,CAACO,gBAAgB,CAAC,kBAAkB,EAAET,MAAM,CAAC;IACvD,CAAC,MAAM;MACLA,MAAM,CAAC,CAAC;IACV;EACF;;EAEA;EACAE,QAAQ,CAACO,gBAAgB,CAAC,kBAAkB,EAAE,YAAY;IACxD,IAAIS,OAAO,GAAGhB,QAAQ,CAACiB,gBAAgB,CAAC,uBAAuB,CAAC;IAChE,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGF,OAAO,CAAC5B,MAAM,EAAE8B,CAAC,EAAE,EAAE;MACvC,IAAIC,EAAE,GAAGH,OAAO,CAACE,CAAC,CAAC;MACnB,IAAItB,SAAS,GAAGuB,EAAE,CAACC,YAAY,CAAC,iBAAiB,CAAC;MAClD,IAAIvB,MAAM,GAAGsB,EAAE,CAACC,YAAY,CAAC,cAAc,CAAC;MAC5C,IAAIxB,SAAS,IAAIC,MAAM,EAAE;QACvB;QACAF,6BAA6B,CAACC,SAAS,EAAEC,MAAM,CAAC;MAClD;IACF;EACF,CAAC,CAAC;EAEFwB,MAAM,CAAC1B,6BAA6B,GAAGA,6BAA6B;AACtE,CAAC,EAAE,CAAC","file":"technical-name-generator.js","sourcesContent":["(function () {\n // Expose initializer globally so views can call it with specific field IDs.\n function toTitleCaseNoSpaces(value) {\n return (value || '')\n .trim()\n // split on whitespace or common separators or any non-alphanumeric\n .split(/[^A-Za-z0-9]+/)\n .filter(function (w) { return w.length > 0; })\n .map(function (w) { return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase(); })\n .join('');\n }\n\n function initAutoGenerateTechnicalName(displayId, nameId) {\n if (!displayId || !nameId) return;\n\n function attach() {\n var displayEl = document.getElementById(displayId);\n var nameEl = document.getElementById(nameId);\n if (!displayEl || !nameEl) return;\n if (nameEl.dataset.techNameInitialized === 'true') return;\n\n nameEl.dataset.techNameInitialized = 'true';\n\n // Track whether the user has entered a non-empty value in the Name field.\n var userEdited = nameEl.value.trim() !== '';\n // Set while we synthesize input/change events on the name field so we can\n // distinguish programmatic updates from real user typing.\n var suppressUserEditedTracking = false;\n\n // Resume auto-generation only when the Name field is empty again.\n nameEl.addEventListener('input', function (e) {\n if (suppressUserEditedTracking || (e && e.isTrusted === false)) {\n return;\n }\n\n userEdited = nameEl.value.trim() !== '';\n });\n\n function updateGeneratedValue() {\n if (userEdited) return;\n\n var generated = toTitleCaseNoSpaces(displayEl.value || '');\n\n if (nameEl.value === generated) {\n return;\n }\n\n suppressUserEditedTracking = true;\n try {\n nameEl.value = generated;\n nameEl.dispatchEvent(new Event('input', { bubbles: true }));\n nameEl.dispatchEvent(new Event('change', { bubbles: true }));\n } finally {\n suppressUserEditedTracking = false;\n }\n }\n\n displayEl.addEventListener('input', updateGeneratedValue);\n displayEl.addEventListener('keyup', updateGeneratedValue);\n displayEl.addEventListener('change', updateGeneratedValue);\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', attach);\n } else {\n attach();\n }\n }\n\n // Automatically initialize for any elements using the data attributes.\n document.addEventListener('DOMContentLoaded', function () {\n var autoEls = document.querySelectorAll('[data-auto-tech-name]');\n for (var i = 0; i < autoEls.length; i++) {\n var el = autoEls[i];\n var displayId = el.getAttribute('data-display-id');\n var nameId = el.getAttribute('data-name-id');\n if (displayId && nameId) {\n // call initializer immediately (it will attach listeners)\n initAutoGenerateTechnicalName(displayId, nameId);\n }\n }\n });\n\n window.initAutoGenerateTechnicalName = initAutoGenerateTechnicalName;\n})();\n"]}
@@ -1,2 +1,2 @@
1
- !function(){function t(t,e){t&&e&&document.addEventListener("DOMContentLoaded",function(){var n=document.getElementById(t),a=document.getElementById(e);if(n&&a){var i=""!==a.value.trim();a.addEventListener("input",function(){i=""!==a.value.trim()}),n.addEventListener("keyup",function(){if(!i){var t=(n.value||""||"").trim().split(/[^A-Za-z0-9]+/).filter(function(t){return t.length>0}).map(function(t){return t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()}).join("");a.value=t}})}})}document.addEventListener("DOMContentLoaded",function(){for(var e=document.querySelectorAll("[data-auto-tech-name]"),n=0;n<e.length;n++){var a=e[n],i=a.getAttribute("data-display-id"),d=a.getAttribute("data-name-id");i&&d&&t(i,d)}}),window.initAutoGenerateTechnicalName=t}();
1
+ !function(){function e(e,t){function n(){var n=document.getElementById(e),a=document.getElementById(t);if(n&&a&&"true"!==a.dataset.techNameInitialized){a.dataset.techNameInitialized="true";var i=""!==a.value.trim(),d=!1;a.addEventListener("input",function(e){d||e&&!1===e.isTrusted||(i=""!==a.value.trim())}),n.addEventListener("input",u),n.addEventListener("keyup",u),n.addEventListener("change",u)}function u(){if(!i){var e=(n.value||""||"").trim().split(/[^A-Za-z0-9]+/).filter(function(e){return e.length>0}).map(function(e){return e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()}).join("");if(a.value!==e){d=!0;try{a.value=e,a.dispatchEvent(new Event("input",{bubbles:!0})),a.dispatchEvent(new Event("change",{bubbles:!0}))}finally{d=!1}}}}}e&&t&&("loading"===document.readyState?document.addEventListener("DOMContentLoaded",n):n())}document.addEventListener("DOMContentLoaded",function(){for(var t=document.querySelectorAll("[data-auto-tech-name]"),n=0;n<t.length;n++){var a=t[n],i=a.getAttribute("data-display-id"),d=a.getAttribute("data-name-id");i&&d&&e(i,d)}}),window.initAutoGenerateTechnicalName=e}();
2
2
  //# sourceMappingURL=technical-name-generator.min.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["technical-name-generator.js"],"names":["initAutoGenerateTechnicalName","displayId","nameId","document","addEventListener","displayEl","getElementById","nameEl","userEdited","value","trim","generated","split","filter","w","length","map","charAt","toUpperCase","slice","toLowerCase","join","autoEls","querySelectorAll","i","el","getAttribute","window"],"mappings":"CAAA,WAYE,SAASA,EAA8BC,EAAWC,GAC3CD,GAAcC,GACnBC,SAASC,iBAAiB,mBAAoB,WAC5C,IAAIC,EAAYF,SAASG,eAAeL,GACpCM,EAASJ,SAASG,eAAeJ,GACrC,GAAKG,GAAcE,EAAnB,CAGA,IAAIC,EAAqC,KAAxBD,EAAOE,MAAMC,OAG9BH,EAAOH,iBAAiB,QAAS,WAC/BI,EAAqC,KAAxBD,EAAOE,MAAMC,MAC5B,GAGAL,EAAUD,iBAAiB,QAAS,WAClC,IAAII,EAAJ,CACA,IAAIG,GAAgCN,EAAUI,OAAS,IA3B1C,IACdC,OAEAE,MAAM,iBACNC,OAAO,SAAUC,GAAK,OAAOA,EAAEC,OAAS,CAAG,GAC3CC,IAAI,SAAUF,GAAK,OAAOA,EAAEG,OAAO,GAAGC,cAAgBJ,EAAEK,MAAM,GAAGC,aAAe,GAChFC,KAAK,IAsBJd,EAAOE,MAAQE,CAFC,CAGlB,EAf2B,CAgB7B,EACF,CAGAR,SAASC,iBAAiB,mBAAoB,WAE5C,IADA,IAAIkB,EAAUnB,SAASoB,iBAAiB,yBAC/BC,EAAI,EAAGA,EAAIF,EAAQP,OAAQS,IAAK,CACvC,IAAIC,EAAKH,EAAQE,GACbvB,EAAYwB,EAAGC,aAAa,mBAC5BxB,EAASuB,EAAGC,aAAa,gBACzBzB,GAAaC,GAEfF,EAA8BC,EAAWC,EAE7C,CACF,GAEAyB,OAAO3B,8BAAgCA,CACxC,CAnDD","file":"technical-name-generator.min.js","sourcesContent":["(function () {\n // Expose initializer globally so views can call it with specific field IDs.\n function toTitleCaseNoSpaces(value) {\n return (value || '')\n .trim()\n // split on whitespace or common separators or any non-alphanumeric\n .split(/[^A-Za-z0-9]+/)\n .filter(function (w) { return w.length > 0; })\n .map(function (w) { return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase(); })\n .join('');\n }\n\n function initAutoGenerateTechnicalName(displayId, nameId) {\n if (!displayId || !nameId) return;\n document.addEventListener('DOMContentLoaded', function () {\n var displayEl = document.getElementById(displayId);\n var nameEl = document.getElementById(nameId);\n if (!displayEl || !nameEl) return;\n\n // Track whether the user has entered a non-empty value in the Name field.\n var userEdited = nameEl.value.trim() !== '';\n\n // Resume auto-generation only when the Name field is empty again.\n nameEl.addEventListener('input', function () {\n userEdited = nameEl.value.trim() !== '';\n });\n\n // Generate on keyup as requested\n displayEl.addEventListener('keyup', function () {\n if (userEdited) return;\n var generated = toTitleCaseNoSpaces(displayEl.value || '');\n nameEl.value = generated;\n });\n });\n }\n\n // Automatically initialize for any elements using the data attributes.\n document.addEventListener('DOMContentLoaded', function () {\n var autoEls = document.querySelectorAll('[data-auto-tech-name]');\n for (var i = 0; i < autoEls.length; i++) {\n var el = autoEls[i];\n var displayId = el.getAttribute('data-display-id');\n var nameId = el.getAttribute('data-name-id');\n if (displayId && nameId) {\n // call initializer immediately (it will attach listeners)\n initAutoGenerateTechnicalName(displayId, nameId);\n }\n }\n });\n\n window.initAutoGenerateTechnicalName = initAutoGenerateTechnicalName;\n})();\n"]}
1
+ {"version":3,"sources":["technical-name-generator.js"],"names":["initAutoGenerateTechnicalName","displayId","nameId","attach","displayEl","document","getElementById","nameEl","dataset","techNameInitialized","userEdited","value","trim","suppressUserEditedTracking","addEventListener","e","isTrusted","updateGeneratedValue","generated","split","filter","w","length","map","charAt","toUpperCase","slice","toLowerCase","join","dispatchEvent","Event","bubbles","readyState","autoEls","querySelectorAll","i","el","getAttribute","window"],"mappings":"CAAA,WAYE,SAASA,EAA8BC,EAAWC,GAGhD,SAASC,IACP,IAAIC,EAAYC,SAASC,eAAeL,GACpCM,EAASF,SAASC,eAAeJ,GACrC,GAAKE,GAAcG,GACwB,SAAvCA,EAAOC,QAAQC,oBAAnB,CAEAF,EAAOC,QAAQC,oBAAsB,OAGrC,IAAIC,EAAqC,KAAxBH,EAAOI,MAAMC,OAG1BC,GAA6B,EAGjCN,EAAOO,iBAAiB,QAAS,SAAUC,GACrCF,GAA+BE,IAAqB,IAAhBA,EAAEC,YAI1CN,EAAqC,KAAxBH,EAAOI,MAAMC,OAC5B,GAqBAR,EAAUU,iBAAiB,QAASG,GACpCb,EAAUU,iBAAiB,QAASG,GACpCb,EAAUU,iBAAiB,SAAUG,EAxCc,CAmBnD,SAASA,IACP,IAAIP,EAAJ,CAEA,IAAIQ,GAAgCd,EAAUO,OAAS,IAtC1C,IACdC,OAEAO,MAAM,iBACNC,OAAO,SAAUC,GAAK,OAAOA,EAAEC,OAAS,CAAG,GAC3CC,IAAI,SAAUF,GAAK,OAAOA,EAAEG,OAAO,GAAGC,cAAgBJ,EAAEK,MAAM,GAAGC,aAAe,GAChFC,KAAK,IAkCJ,GAAIrB,EAAOI,QAAUO,EAArB,CAIAL,GAA6B,EAC7B,IACEN,EAAOI,MAAQO,EACfX,EAAOsB,cAAc,IAAIC,MAAM,QAAS,CAAEC,SAAS,KACnDxB,EAAOsB,cAAc,IAAIC,MAAM,SAAU,CAAEC,SAAS,IACtD,CAAC,QACClB,GAA6B,CAC/B,CATA,CANgB,CAgBlB,CAKF,CA/CKZ,GAAcC,IAiDS,YAAxBG,SAAS2B,WACX3B,SAASS,iBAAiB,mBAAoBX,GAE9CA,IAEJ,CAGAE,SAASS,iBAAiB,mBAAoB,WAE5C,IADA,IAAImB,EAAU5B,SAAS6B,iBAAiB,yBAC/BC,EAAI,EAAGA,EAAIF,EAAQX,OAAQa,IAAK,CACvC,IAAIC,EAAKH,EAAQE,GACblC,EAAYmC,EAAGC,aAAa,mBAC5BnC,EAASkC,EAAGC,aAAa,gBACzBpC,GAAaC,GAEfF,EAA8BC,EAAWC,EAE7C,CACF,GAEAoC,OAAOtC,8BAAgCA,CACxC,CApFD","file":"technical-name-generator.min.js","sourcesContent":["(function () {\n // Expose initializer globally so views can call it with specific field IDs.\n function toTitleCaseNoSpaces(value) {\n return (value || '')\n .trim()\n // split on whitespace or common separators or any non-alphanumeric\n .split(/[^A-Za-z0-9]+/)\n .filter(function (w) { return w.length > 0; })\n .map(function (w) { return w.charAt(0).toUpperCase() + w.slice(1).toLowerCase(); })\n .join('');\n }\n\n function initAutoGenerateTechnicalName(displayId, nameId) {\n if (!displayId || !nameId) return;\n\n function attach() {\n var displayEl = document.getElementById(displayId);\n var nameEl = document.getElementById(nameId);\n if (!displayEl || !nameEl) return;\n if (nameEl.dataset.techNameInitialized === 'true') return;\n\n nameEl.dataset.techNameInitialized = 'true';\n\n // Track whether the user has entered a non-empty value in the Name field.\n var userEdited = nameEl.value.trim() !== '';\n // Set while we synthesize input/change events on the name field so we can\n // distinguish programmatic updates from real user typing.\n var suppressUserEditedTracking = false;\n\n // Resume auto-generation only when the Name field is empty again.\n nameEl.addEventListener('input', function (e) {\n if (suppressUserEditedTracking || (e && e.isTrusted === false)) {\n return;\n }\n\n userEdited = nameEl.value.trim() !== '';\n });\n\n function updateGeneratedValue() {\n if (userEdited) return;\n\n var generated = toTitleCaseNoSpaces(displayEl.value || '');\n\n if (nameEl.value === generated) {\n return;\n }\n\n suppressUserEditedTracking = true;\n try {\n nameEl.value = generated;\n nameEl.dispatchEvent(new Event('input', { bubbles: true }));\n nameEl.dispatchEvent(new Event('change', { bubbles: true }));\n } finally {\n suppressUserEditedTracking = false;\n }\n }\n\n displayEl.addEventListener('input', updateGeneratedValue);\n displayEl.addEventListener('keyup', updateGeneratedValue);\n displayEl.addEventListener('change', updateGeneratedValue);\n }\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', attach);\n } else {\n attach();\n }\n }\n\n // Automatically initialize for any elements using the data attributes.\n document.addEventListener('DOMContentLoaded', function () {\n var autoEls = document.querySelectorAll('[data-auto-tech-name]');\n for (var i = 0; i < autoEls.length; i++) {\n var el = autoEls[i];\n var displayId = el.getAttribute('data-display-id');\n var nameId = el.getAttribute('data-name-id');\n if (displayId && nameId) {\n // call initializer immediately (it will attach listeners)\n initAutoGenerateTechnicalName(displayId, nameId);\n }\n }\n });\n\n window.initAutoGenerateTechnicalName = initAutoGenerateTechnicalName;\n})();\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crestapps/ai-chat-ui",
3
- "version": "1.0.0-preview.9",
3
+ "version": "1.0.0-rc.2",
4
4
  "description": "Browser-ready JavaScript widgets and CSS for CrestApps AI chat sessions and chat interactions. Supports streaming responses, image generation, Chart.js interactive charts, document uploads, copy-to-clipboard, and feedback buttons.",
5
5
  "license": "MIT",
6
6
  "author": "CrestApps",
@@ -35,6 +35,10 @@
35
35
  "./ai-chat.min": "./dist/ai-chat.min.js",
36
36
  "./ai-chat.js.map": "./dist/ai-chat.js.map",
37
37
  "./ai-chat.min.js.map": "./dist/ai-chat.min.js.map",
38
+ "./ai-chat-widget": "./dist/ai-chat-widget.js",
39
+ "./ai-chat-widget.min": "./dist/ai-chat-widget.min.js",
40
+ "./ai-chat-widget.js.map": "./dist/ai-chat-widget.js.map",
41
+ "./ai-chat-widget.min.js.map": "./dist/ai-chat-widget.min.js.map",
38
42
  "./chat-interaction": "./dist/chat-interaction.js",
39
43
  "./chat-interaction.min": "./dist/chat-interaction.min.js",
40
44
  "./chat-interaction.js.map": "./dist/chat-interaction.js.map",
package/README.md DELETED
@@ -1,145 +0,0 @@
1
- # @crestapps/ai-chat-ui
2
-
3
- Browser-ready JavaScript widgets and CSS for **CrestApps AI** chat sessions and chat interactions. Drop them into any page that uses the [CrestApps.Core](https://github.com/CrestApps/CrestApps.Core) backend to get a fully functional AI chat experience with streaming responses, document uploads, image generation, interactive charts, copy-to-clipboard, and user feedback buttons.
4
-
5
- ## Features
6
-
7
- | Feature | Details |
8
- |---------|---------|
9
- | **Streaming responses** | Real-time token-by-token output via SignalR or REST |
10
- | **Image generation** | Inline rendering of images produced by `GenerateImageTool` |
11
- | **Interactive charts** | [Chart.js](https://www.chartjs.org/) rendering of charts produced by `GenerateChartTool` (optional peer dependency) |
12
- | **Document uploads** | Drag-and-drop or file-picker uploads attached to chat sessions |
13
- | **Copy to clipboard** | One-click copy of any assistant message |
14
- | **Feedback buttons** | Thumbs-up / thumbs-down per message |
15
- | **Markdown rendering** | Powered by [marked](https://github.com/markedjs/marked) and [DOMPurify](https://github.com/cure53/DOMPurify) |
16
-
17
- ## Installation
18
-
19
- ```bash
20
- npm install @crestapps/ai-chat-ui
21
- ```
22
-
23
- ### Optional: Chart.js Support
24
-
25
- To render interactive charts, also install Chart.js:
26
-
27
- ```bash
28
- npm install chart.js
29
- ```
30
-
31
- ## Included Files
32
-
33
- After installation the `dist/` directory contains:
34
-
35
- | File | Description |
36
- |------|-------------|
37
- | `ai-chat.js` / `.min.js` | AI Chat widget — manages sessions, uploads, streaming, and the full chat UI |
38
- | `chat-interaction.js` / `.min.js` | Chat Interaction widget — lighter standalone chat experience |
39
- | `document-drop-zone.js` / `.min.js` | Drag-and-drop file upload component |
40
- | `technical-name-generator.js` / `.min.js` | Auto-generates URL-safe technical names from display names |
41
- | `chat-widget.css` / `.min.css` | Styles for the floating AI Chat widget |
42
- | `document-drop-zone.css` / `.min.css` | Styles for the document drop-zone component |
43
-
44
- ## Usage
45
-
46
- ### Via CDN (simplest)
47
-
48
- Use [jsDelivr](https://www.jsdelivr.com/) to load files directly — no install required:
49
-
50
- ```html
51
- <!-- CSS -->
52
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/chat-widget.min.css" />
53
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/document-drop-zone.min.css" />
54
-
55
- <!-- Required dependencies -->
56
- <script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
57
- <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
58
- <script src="https://cdn.jsdelivr.net/npm/dompurify/dist/purify.min.js"></script>
59
- <script src="https://cdn.jsdelivr.net/npm/@microsoft/signalr/dist/browser/signalr.min.js"></script>
60
-
61
- <!-- Optional: Chart.js for interactive charts -->
62
- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
63
-
64
- <!-- CrestApps AI Chat UI -->
65
- <script src="https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/ai-chat.min.js"></script>
66
- <script src="https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/document-drop-zone.min.js"></script>
67
- ```
68
-
69
- > **Tip:** Replace `@1.0.0-preview-22` with the version you want, or omit it to always get the latest release.
70
-
71
- ### Via npm
72
-
73
- ```bash
74
- npm install @crestapps/ai-chat-ui
75
- ```
76
-
77
- Then copy the files from `node_modules/@crestapps/ai-chat-ui/dist/` into your web application's static assets folder and reference them with `<script>` and `<link>` tags.
78
-
79
- ### CDN URL Pattern
80
-
81
- All files in the package are available via jsDelivr using this pattern:
82
-
83
- ```
84
- https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@<version>/dist/<file>
85
- ```
86
-
87
- | Asset | CDN URL |
88
- |-------|---------|
89
- | `ai-chat.min.js` | `https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/ai-chat.min.js` |
90
- | `chat-interaction.min.js` | `https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/chat-interaction.min.js` |
91
- | `document-drop-zone.min.js` | `https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/document-drop-zone.min.js` |
92
- | `technical-name-generator.min.js` | `https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/technical-name-generator.min.js` |
93
- | `chat-widget.min.css` | `https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/chat-widget.min.css` |
94
- | `document-drop-zone.min.css` | `https://cdn.jsdelivr.net/npm/@crestapps/ai-chat-ui@1.0.0-preview-22/dist/document-drop-zone.min.css` |
95
-
96
- ### Initializing the AI Chat Widget
97
-
98
- ```javascript
99
- var chatManager = window.openAIChatManager();
100
- chatManager.createInstance({
101
- containerEl: '#ai-chat-container',
102
- profileId: 'your-profile-id',
103
- baseUrl: '/ai/chat-sessions',
104
- hubUrl: '/ai-chat-hub'
105
- });
106
- ```
107
-
108
- ### Initializing the Chat Interaction Widget
109
-
110
- ```javascript
111
- var interactionManager = window.chatInteractionManager();
112
- interactionManager.createInstance({
113
- containerEl: '#chat-interaction-container',
114
- deploymentName: 'your-deployment-name',
115
- baseUrl: '/chat-interactions',
116
- hubUrl: '/chat-interaction-hub'
117
- });
118
- ```
119
-
120
- ## Client-Side Dependencies
121
-
122
- Both widgets expect these libraries to be loaded on the page **before** the CrestApps script:
123
-
124
- | Library | Required | Purpose |
125
- |---------|----------|---------|
126
- | [Vue 3](https://vuejs.org/) | ✅ Yes | Reactive UI rendering |
127
- | [marked](https://github.com/markedjs/marked) | ✅ Yes | Markdown → HTML conversion |
128
- | [DOMPurify](https://github.com/cure53/DOMPurify) | ✅ Yes | HTML sanitization |
129
- | [SignalR](https://learn.microsoft.com/aspnet/core/signalr/) | ✅ Yes | Real-time streaming |
130
- | [Chart.js](https://www.chartjs.org/) | ❌ Optional | Interactive chart rendering |
131
- | [highlight.js](https://highlightjs.org/) | ❌ Optional | Code syntax highlighting |
132
-
133
- ## Backend Requirements
134
-
135
- These widgets are designed to work with the [CrestApps.Core](https://github.com/CrestApps/CrestApps.Core) .NET backend. You need:
136
-
137
- 1. **AI Chat sessions** — register with `.AddAISuite(ai => ai.AddChatInteractions(...))` or AI Profiles
138
- 2. **At least one AI provider** — e.g., `.AddOpenAI()`, `.AddAzureOpenAI()`, `.AddOllama()`
139
- 3. **SignalR hubs** — register with `.AddSignalR()`
140
-
141
- See the [CrestApps.Core documentation](https://crestapps.com/docs/core/chat) for full backend setup instructions.
142
-
143
- ## License
144
-
145
- [MIT](https://github.com/CrestApps/CrestApps.Core/blob/main/LICENSE)