{"version":3,"file":"chatbot-f5bc24c8.js","sources":["../../../../app/frontend/components/chatbot/chatbotElementUtils.js","../../../../app/frontend/components/chatbot/chatbotConversationPersitenceUtils.js","../../../../app/frontend/components/chatbot/chatbotMinMaxButtonsController.js","../../../../app/frontend/components/chatbot/chatbotLoadingDotsController.js","../../../../app/frontend/components/chatbot/chatbotMessagingController.js","../../../../app/frontend/components/chatbot/chatbotButtonsAndFormsController.js","../../../../app/frontend/components/chatbot/chatbotWidgetContentController.js","../../../../app/frontend/entrypoints/chatbot.js"],"sourcesContent":["function getWidgetContainer() {\n return document.querySelector('[data-solv-chatbot-container]');\n}\n\nfunction getRequestId() {\n const storedRequestId = getStoredRequestId();\n if (storedRequestId) {\n return storedRequestId;\n }\n return getWidgetContainer().dataset.requestId;\n}\n\nfunction getInvalidRequestId() {\n return getWidgetContainer().dataset.invalidRequestId;\n}\n\nfunction getGroupId() {\n return getWidgetContainer().dataset.groupId;\n}\n\nfunction getStoredRequestId() {\n const groupId = getGroupId();\n const key = \"solvChatId\" + groupId;\n\n let idHashInfo = window.localStorage.getItem(key);\n idHashInfo = JSON.parse(idHashInfo);\n\n if (idHashInfo == null || idHashInfo == undefined) {\n return \"\";\n }\n\n const idHashExpired = idHashInfo.expiry < new Date().getTime()\n\n if (!idHashExpired) {\n return idHashInfo.storedID;\n }\n\n return '';\n}\n\nfunction getWidgetContent() {\n return document.querySelector('[data-solv-chatbot-content-slot]');\n}\n\nfunction widgetIsClosed() {\n return getWidgetContent().classList.contains('solv-chatbot-widget--hidden');\n}\n\nfunction getMinimizeBtn() {\n return document.querySelector('[data-solv-chatbot-widget-minimize-btn]');\n}\n\nfunction getCloseBtn() {\n return document.querySelector('[data-solv-chatbot-widget-close-btn]');\n}\n\nfunction getMaximizeBtn() {\n return document.querySelector('[data-solv-chatbot-widget-maximize-btn]');\n}\n\nfunction getMessagesElement() {\n return document.querySelector('[data-solv-chatbot-messages]');\n}\n\nfunction getGreetingElement() {\n return document.querySelector('[data-solv-chatbot-greeting]');\n}\n\nfunction getMessageFeed() {\n return document.querySelector('[data-solv-chatbot-message-feed]');\n}\n\nfunction getUserMsgInputField() {\n return document.querySelector('[data-solv-chatbot-message-input]');\n}\n\nfunction getMsgInputForm() {\n return document.querySelector('[data-solv-chatbot-message-form]');\n}\n\nfunction getMsgSendBtn() {\n return document.querySelector('[data-solv-chatbot-user-send]');\n}\n\nfunction getGreetingsButtons() {\n return document.querySelectorAll('[data-solv-chatbot-greetings-button]');\n}\n\nfunction getnewUserForm() {\n return document.querySelector('[data-solv-chatbot-phone-form]');\n}\n\nfunction getFirstNameInput() {\n return document.querySelector('[data-solv-chatbot-first-name-input]');\n}\n\nfunction getLastNameInput() {\n return document.querySelector('[data-solv-chatbot-last-name-input]');\n}\n\nfunction getPhoneNumberInput() {\n return document.querySelector('[data-solv-chatbot-phone-number-input]');\n}\n\nfunction getFirstNameErrorMessage() {\n return document.querySelector('[data-solv-chatbot-user-name-error]');\n}\n\nfunction getLastNameErrorMessage() {\n return document.querySelector('[data-solv-chatbot-user-last-name-error]');\n}\n\nfunction getPhoneNumberErrorMessage() {\n return document.querySelector('[data-solv-chatbot-user-phone-error]');\n}\n\nfunction getButtons() {\n return document.querySelectorAll('[data-solv-chatbot-button]');\n}\n\nfunction getButtonContainers() {\n return document.querySelectorAll('[data-solv-chatbot-buttons]');\n}\n\nfunction getMinMaxButtonContainer() {\n return document.querySelector('[data-solv-chatbot-min-max-btn-container]');\n}\n\nfunction getForms() {\n return document.querySelectorAll('[data-solv-chatbot-form]');\n}\n\nfunction getLoadingDots() {\n return document.querySelector('[data-solv-chatbot-loading-dots]');\n}\n\nfunction getHiddenMessages() {\n return document.querySelectorAll('.solv-chatbot-widget__message-wrapper--hidden');\n}\n\nfunction getTestInformation() {\n let testElment = document.querySelector('[data-chat-bot-test]');\n if (testElment) {\n return true;\n } else {\n return false;\n }\n}\n\nfunction getTimeStampElement() {\n return document.querySelector('[data-solv-chatbot-timestamp]');\n}\n\nfunction getTimeStampElementByIntervalID(id) {\n return document.querySelector(`[data-solv-chatbot-timestamp-id=\"${id}\"]`);\n}\n\nfunction getTimeStampInfoElement(id) {\n const timeStampElement = getTimeStampElementByIntervalID(id);\n if (timeStampElement === null || timeStampElement === undefined) {\n return null;\n }\n return timeStampElement.querySelector('[data-solv-chatbot-timestamp-info]');\n}\n\nfunction setTimeStamp(value, id) {\n const timeStamp = getTimeStampInfoElement(id);\n if (timeStamp) {\n timeStamp.innerHTML = value;\n timeStamp.ariaLabel = value;\n }\n}\n\nfunction setTimeStampIntervalID(newID) {\n const timeStamp = getTimeStampElement();\n if (timeStamp === null || timeStamp === undefined) {\n return;\n }\n timeStamp.dataset.solvChatbotTimestampId = newID;\n}\n\nfunction deleteTimestamp() {\n const timeStamp = getTimeStampElement();\n if (timeStamp) {\n timeStamp.remove();\n }\n}\n\nexport {\n getMaximizeBtn,\n getMinimizeBtn,\n getWidgetContainer,\n widgetIsClosed,\n getWidgetContent,\n getMessageFeed,\n getUserMsgInputField,\n getMsgInputForm,\n getMsgSendBtn,\n getMessagesElement,\n getGreetingsButtons,\n getButtonContainers,\n getnewUserForm,\n getPhoneNumberInput,\n getFirstNameInput,\n getButtons,\n getLoadingDots,\n getGreetingElement,\n getRequestId,\n getGroupId,\n getHiddenMessages,\n getForms,\n getPhoneNumberErrorMessage,\n getFirstNameErrorMessage,\n getLastNameInput,\n getLastNameErrorMessage,\n getTestInformation,\n getTimeStampElement,\n getTimeStampInfoElement,\n setTimeStamp,\n deleteTimestamp,\n setTimeStampIntervalID,\n getCloseBtn,\n getMinMaxButtonContainer,\n getInvalidRequestId\n};\n","import {\n getGroupId\n} from '@/components/chatbot/chatbotElementUtils';\n\nfunction setGreetingView() {\n const expirationTime = new Date().getTime(); // one hour from now\n const groupId = getGroupId();\n const key = \"solvGreetingSeen\" + groupId;\n window.localStorage.setItem(key, expirationTime);\n}\n\nfunction getGreetingView() {\n const groupId = getGroupId();\n const key = \"solvGreetingSeen\" + groupId;\n return window.localStorage.getItem(key);\n}\n\nfunction setMinimization() {\n const expirationTime = new Date().getTime(); // one hour from now\n const groupId = getGroupId();\n const key = \"solvMinimize\" + groupId;\n window.localStorage.setItem(key, expirationTime);\n}\n\nfunction getMinimization() {\n const groupId = getGroupId();\n const key = \"solvMinimize\" + groupId;\n return window.localStorage.getItem(key);\n}\n\nfunction setMaximization() {\n const groupId = getGroupId();\n const key = \"solvMinimize\" + groupId;\n window.localStorage.removeItem(key);\n}\n\nfunction isIdHashExpired() {\n let idHashInfo = window.localStorage.getItem(\"solvChatId\");\n idHashInfo = JSON.parse(idHashInfo);\n\n if (idHashInfo == null || idHashInfo == undefined) {\n return false;\n }\n\n const idHashValues = Object.values(idHashInfo);\n const idHashExpired = idHashValues[1] < new Date().getTime()\n\n return idHashExpired;\n}\n\nfunction storeUserInformation(userInformation) {\n if (userInformation) {\n window.localStorage.setItem(\"solvChatUserInformation\", userInformation);\n }\n}\n\n\nfunction getUserInformation() {\n let userInformation = window.localStorage.getItem(\"solvChatUserInformation\");\n\n if (userInformation == null || userInformation == undefined) {\n return null;\n }\n return userInformation;\n}\n\nexport {\n storeUserInformation,\n getUserInformation,\n isIdHashExpired,\n setGreetingView,\n getGreetingView,\n setMinimization,\n setMaximization,\n getMinimization\n};\n","import {\n getMaximizeBtn,\n getMinimizeBtn,\n getWidgetContent,\n getGreetingElement,\n getMessagesElement,\n getUserMsgInputField,\n getRequestId,\n getFirstNameInput,\n getMinMaxButtonContainer,\n getCloseBtn\n} from '@/components/chatbot/chatbotElementUtils';\nimport { autoScrollToBottom } from '@/components/chatbot/chatbotButtonsAndFormsController';\nimport { setMinimization, setMaximization, setGreetingView } from '@/components/chatbot/chatbotConversationPersitenceUtils';\n\n\nfunction minimizeContainer() {\n\n const minimizeBtn = getMinimizeBtn();\n const maximizeBtn = getMaximizeBtn();\n const widgetContent = getWidgetContent();\n const minMaxButtonContainer = getMinMaxButtonContainer();\n\n minMaxButtonContainer.classList.add('solv-chatbot-widget--minimized');\n minMaxButtonContainer.classList.remove('solv-chatbot-widget--maximized');\n\n minimizeBtn.classList.add('solv-chatbot-widget--hidden');\n minimizeBtn.ariaHidden = true;\n\n maximizeBtn.classList.remove('solv-chatbot-widget--hidden');\n maximizeBtn.ariaHidden = false;\n\n widgetContent.classList.add('solv-chatbot-widget--hidden');\n\n widgetContent.ariaHidden = true;\n\n setMinimization();\n trackConversationMinimization()\n}\n\nfunction maximizeContainer() {\n const minimizeBtn = getMinimizeBtn();\n const maximizeBtn = getMaximizeBtn();\n const widgetContent = getWidgetContent();\n const minMaxButtonContainer = getMinMaxButtonContainer();\n\n setMaximization();\n\n minMaxButtonContainer.classList.remove('solv-chatbot-widget--minimized');\n minMaxButtonContainer.classList.add('solv-chatbot-widget--maximized');\n\n minimizeBtn.classList.remove('solv-chatbot-widget--hidden');\n minimizeBtn.ariaHidden = false;\n\n maximizeBtn.classList.add('solv-chatbot-widget--hidden');\n maximizeBtn.ariaHidden = true;\n\n widgetContent.classList.remove('solv-chatbot-widget--hidden');\n widgetContent.ariaHidden = false;\n}\n\nfunction setUpMinimizeButton() {\n const minimizeBtn = getMinimizeBtn();\n minimizeBtn.addEventListener('click', (e) => {\n minimizeContainer();\n });\n const closeBtn = getCloseBtn();\n closeBtn.addEventListener('click', (e) => {\n minimizeContainer();\n });\n}\n\nfunction setUpMaximizeButton() {\n const maximizeBtn = getMaximizeBtn();\n maximizeBtn.addEventListener('click', (e) => {\n const greeting = getGreetingElement();\n if (greeting) {\n removeGreetingElement();\n }\n maximizeContainer();\n const userInputField = getUserMsgInputField();\n const firstNameInput = getFirstNameInput();\n // CHECK FOR MOBILE WIDTH\n const mobileWidth = window.matchMedia('(max-width: 767px)');\n if (mobileWidth.matches) {\n // do nothing\n } else if (firstNameInput) {\n firstNameInput.focus();\n } else if (userInputField) {\n userInputField.focus();\n autoScrollToBottom();\n }\n });\n}\n\nfunction showMessagesTemplate() {\n const messages = getMessagesElement();\n messages.classList.remove('solv-chatbot-widget__messages--hidden');\n messages.ariaHidden = false;\n}\n\nfunction removeGreetingElement() {\n const greeting = getGreetingElement();\n greeting.remove();\n\n const widgetContent = getWidgetContent();\n widgetContent.classList.remove('uninitialized');\n\n // unhide the messages element which is hidden behind the greeting element\n showMessagesTemplate();\n\n // send message to the backend that the user has started the chat for analytics purposes\n trackConversationInitiation()\n}\n\nasync function trackConversationInitiation() {\n // send message to the backend that the user has started the chat for analytics purposes\n const requestId = getRequestId();\n const testURLElement = document.getElementById('testing-chatbot-locally');\n let messageURL = 'https://www.solvhealth.com/dir/chatbot-conversation-started';\n if (testURLElement) {\n messageURL = '/dir/chatbot-conversation-started';\n }\n const data = {\n request_id: requestId,\n };\n await fetch(messageURL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n });\n}\n\nasync function trackConversationMinimization() {\n // send message to the backend that the user has started the chat for analytics purposes\n const requestId = getRequestId();\n const testURLElement = document.getElementById('testing-chatbot-locally');\n let messageURL = 'https://www.solvhealth.com/dir/chatbot-conversation-closed';\n if (testURLElement) {\n messageURL = '/dir/chatbot-conversation-closed';\n }\n const data = {\n request_id: requestId,\n };\n await fetch(messageURL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n });\n}\n\n// change the visibility of the buttons without affecting the container\nfunction switchMinMaxButtonVisibility() {\n const minimizeBtn = getMinimizeBtn();\n const maximizeBtn = getMaximizeBtn();\n\n minimizeBtn.classList.toggle('solv-chatbot-widget--hidden');\n minimizeBtn.ariaHidden = minimizeBtn.classList.contains('solv-chatbot-widget--hidden');\n\n maximizeBtn.classList.toggle('solv-chatbot-widget--hidden');\n maximizeBtn.ariaHidden = maximizeBtn.classList.contains('solv-chatbot-widget--hidden');\n}\n\nexport { setUpMinimizeButton, setUpMaximizeButton, switchMinMaxButtonVisibility, removeGreetingElement, showMessagesTemplate, maximizeContainer };\n","import { getLoadingDots, getMessageFeed } from '@/components/chatbot/chatbotElementUtils';\nimport { autoScrollToBottom } from '@/components/chatbot/chatbotButtonsAndFormsController';\n\nfunction moveLoadingDotsToBottomOfFeed() {\n const dots = getLoadingDots();\n const feed = getMessageFeed();\n\n feed.appendChild(dots);\n}\n\nfunction showLoadingDots() {\n const dots = getLoadingDots();\n dots.ariaHidden = false;\n moveLoadingDotsToBottomOfFeed();\n\n dots.classList.remove('solv-chatbot-widget--hidden');\n autoScrollToBottom(); // loading get cut off when this isn't called here\n}\n\nfunction hideLoadingDots() {\n const dots = getLoadingDots();\n dots.ariaHidden = true;\n dots.classList.add('solv-chatbot-widget--hidden');\n}\n\nexport { showLoadingDots, hideLoadingDots }\n","import {\n getMessageFeed,\n getMsgInputForm,\n getMsgSendBtn,\n getUserMsgInputField,\n getHiddenMessages,\n getRequestId,\n getMessagesElement,\n getTestInformation,\n widgetIsClosed, setTimeStamp, getTimeStampElement, deleteTimestamp, setTimeStampIntervalID\n} from '@/components/chatbot/chatbotElementUtils';\nimport {hideLoadingDots, showLoadingDots} from '@/components/chatbot/chatbotLoadingDotsController';\nimport {\n removeButtons,\n setUpButtons,\n setUpNewUserForm,\n removeForms,\n autoScrollToBottom,\n} from '@/components/chatbot/chatbotButtonsAndFormsController';\nimport {maximizeContainer} from '@/components/chatbot/chatbotMinMaxButtonsController';\nimport {checkForSessionTimeout} from '@/components/chatbot/chatbotWidgetContentController';\n\n\nconst PLACEHOLDER_VALUES = {\n 'introInput': 'Ask a question...',\n 'replyInput': 'Type your reply...',\n 'phoneInput': 'Enter your name and phone above',\n 'timeInput': 'Select a time or ask a question...',\n 'infoInput': 'Enter your information above',\n \"\": \"\"\n};\n\nlet interstitialCount = 0;\n\n/**\n * Sets the placeholder value for the user message input\n * Takes in a key from the PLACEHOLDER_VALUES constant and sets the placeholder to its respective value\n * @param placeholderKey {string}\n */\nfunction setPlaceHolderContent(placeholderKey) {\n const inputField = getUserMsgInputField();\n inputField.placeholder = PLACEHOLDER_VALUES[placeholderKey];\n}\n\nasync function handleUserMessage(message, userInformation = null) {\n\n renderUserMessageOnFeed(message);\n\n initiateSessionTimeoutCheck();\n\n await submitMessage(message, userInformation);\n}\n\nfunction initiateSessionTimeoutCheck() {\n if (!window.solvCheckForSessionTimeout) {\n window.solvCheckForSessionTimeout = setInterval(checkForSessionTimeout, 5000);\n }\n}\n\nasync function submitMessage(message, userInformation = null) {\n interstitialCount = 0;\n showLoadingDots();\n const resData = await sendMessage(message, userInformation);\n\n const request_new_message = resData.request_new_message;\n\n hideLoadingDots();\n\n renderAssistantMessageOnFeed(resData.content, true);\n\n if (resData.user_message_content) {\n setTimeout(() => {\n renderAssistantMessageOnFeed(resData.user_message_content, false);\n }, 500);\n }\n\n if (request_new_message) {\n submitMessage(null);\n }\n\n if (resData.is_conclusion_of_conversation) {\n setPlaceHolderContent(\"\")\n disableMessageInput();\n } else {\n const userInputField = getUserMsgInputField();\n userInputField.focus();\n }\n}\n\nasync function sendMessage(message, userInformation = null) {\n const requestId = getRequestId();\n const data = {\n message,\n request_id: requestId,\n is_test: getTestInformation(),\n user_information: userInformation,\n };\n\n const testURLElement = document.getElementById('testing-chatbot-locally');\n let messageURL = 'https://www.solvhealth.com/dir/chatbot-widget-message';\n if (testURLElement) {\n messageURL = '/dir/chatbot-widget-message';\n }\n\n try {\n const res = await fetch(messageURL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n });\n\n if (res.status == 200) {\n const resData = await res.json();\n if (resData.message == 'assistant') {\n return resData;\n } else if (resData.message == 'function_call') {\n if (resData.content !== null && resData.content !== undefined && resData.content !== \"\" && interstitialCount < 2) {\n interstitialCount++;\n hideLoadingDots();\n renderAssistantMessageOnFeed(resData.content, true);\n showLoadingDots();\n }\n return sendMessage(null);\n }\n } else {\n return sendErrorMessage();\n }\n } catch (err) {\n return sendErrorMessage();\n }\n}\n\nasync function sendErrorMessage(retries = 0) {\n const requestId = getRequestId();\n const data = {\n request_id: requestId,\n retries,\n };\n const testURLElement = document.getElementById('testing-chatbot-locally');\n let errorURL = 'https://www.solvhealth.com/dir/chatbot-widget-message-error';\n if (testURLElement) {\n errorURL = '/dir/chatbot-widget-message-error';\n }\n const res = await fetch(errorURL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(data),\n })\n if (res.status == 200) {\n const resData = await res.json();\n\n if (resData.message == 'waiting') {\n if (resData.content !== null && resData.content !== undefined && resData.content !== \"\" && interstitialCount < 2) {\n interstitialCount++;\n hideLoadingDots();\n renderAssistantMessageOnFeed(resData.content, true);\n showLoadingDots();\n }\n return sendErrorMessage(retries + 1);\n } else if (resData.message == 'assistant') {\n return resData;\n } else if (resData.message == 'function_call') {\n return sendMessage(null);\n }\n }\n}\n\nfunction renderUserMessageOnFeed(message) {\n removeButtons();\n unhideMessages();\n removeForms();\n updateBanner();\n\n const messageFeed = getMessageFeed();\n const newMsgWrapper = document.createElement('div');\n const newMsgContent = document.createElement('div');\n\n newMsgWrapper.classList.add('solv-chatbot-widget__message-wrapper', 'solv-chatbot-widget__user-message-wrapper');\n newMsgWrapper.ariaLabel = 'User message';\n newMsgContent.classList.add('solv-chatbot-widget__message-content', 'solv-chatbot-widget__user-message-content');\n newMsgContent.innerHTML = message;\n newMsgWrapper.appendChild(newMsgContent);\n\n messageFeed.appendChild(newMsgWrapper);\n autoScrollToBottom();\n deleteTimestamp();\n}\n\nfunction updateBanner() {\n const messageElement = getMessagesElement();\n messageElement.dataset.solvChatbotMessagesInit = 'true';\n}\n\nfunction unhideMessages() {\n const hiddenMessages = getHiddenMessages();\n hiddenMessages.forEach(message => {\n message.classList.remove('solv-chatbot-widget__message-wrapper--hidden');\n });\n}\n\nfunction renderAssistantMessageOnFeed(message, showStamp = false) {\n\n // this is for the situation of the chatbot returning consecutive messages, we only want the most recent message to have a timestamp\n if (showStamp) {\n deleteTimestamp();\n }\n\n const messageFeed = getMessageFeed();\n\n const content = document.createRange().createContextualFragment(message);\n messageFeed.appendChild(content);\n autoScrollToBottom();\n if (showStamp) {\n showTimeStamp();\n }\n\n setUpButtons();\n setUpNewUserForm();\n\n if (widgetIsClosed()) {\n maximizeContainer();\n }\n}\n\nfunction autosizeInputField() {\n const inputField = getUserMsgInputField();\n\n setTimeout(() => {\n inputField.style.cssText = 'height:auto;';\n inputField.style.cssText = `height:${inputField.scrollHeight}px`;\n })\n}\n\nfunction setupMessageForm() {\n const userForm = getMsgInputForm();\n const sendBtn = getMsgSendBtn();\n const inputField = getUserMsgInputField();\n\n setPlaceHolderContent('introInput');\n\n userForm.addEventListener('submit', async (e) => {\n e.preventDefault();\n const messageInput = getUserMsgInputField();\n const message = messageInput.value;\n messageInput.value = '';\n\n await handleUserMessage(message);\n });\n\n inputField.addEventListener('keydown', (e) => {\n // for normal inputs, resize the container to allow for mulitiple lines\n autosizeInputField();\n\n // submit the form when the user presses 'enter', but not for 'shift + enter'\n if (e.which === 13 && !e.shiftKey) {\n e.preventDefault();\n userForm.requestSubmit();\n }\n });\n\n sendBtn.addEventListener('click', (e) => {\n userForm.requestSubmit();\n });\n}\n\nfunction hideSendButtonDisplay() {\n const sendBtn = getMsgSendBtn();\n sendBtn.classList.add('solv-chatbot-widget--hidden');\n}\n\nfunction showSendButtonDisplay() {\n const sendBtn = getMsgSendBtn();\n sendBtn.classList.remove('solv-chatbot-widget--hidden');\n}\n\nfunction enableMessageInput() {\n const inputField = getUserMsgInputField();\n inputField.disabled = false;\n inputField.ariaDisabled = false;\n showSendButtonDisplay();\n}\n\nfunction disableMessageInput() {\n const inputField = getUserMsgInputField();\n inputField.disabled = true;\n inputField.ariaDisabled = true;\n hideSendButtonDisplay();\n}\n\nfunction showTimeStamp() {\n const timeStamp = getTimeStampElement();\n timeStamp.classList.remove('solv-chatbot-widget--hidden');\n\n const initialTime = new Date().getMinutes();\n\n const intervalID = setInterval(() => {\n updateTimeStampValue(initialTime, intervalID);\n }, 60000);\n // NOTE: very important that this goes after interval is set\n setTimeStampIntervalID(intervalID);\n}\n\nfunction updateTimeStampValue(initialTime, intervalID) {\n const currentTime = new Date().getMinutes();\n const difference = currentTime - initialTime;\n\n if (difference > 0) {\n if (difference === 1) {\n setTimeStamp(`${difference} minute ago`, intervalID)\n } else {\n setTimeStamp(`${difference} minutes ago`, intervalID)\n }\n }\n}\n\nexport {\n setupMessageForm,\n enableMessageInput,\n disableMessageInput,\n handleUserMessage,\n setPlaceHolderContent,\n initiateSessionTimeoutCheck\n};\n","import {\n getButtonContainers,\n getButtons,\n getForms,\n getGreetingsButtons,\n getMessageFeed,\n getnewUserForm,\n getFirstNameErrorMessage,\n getFirstNameInput,\n getPhoneNumberErrorMessage,\n getPhoneNumberInput,\n getLastNameInput,\n getMinMaxButtonContainer,\n getLastNameErrorMessage,\n} from '@/components/chatbot/chatbotElementUtils';\nimport {\n removeGreetingElement,\n setUpMaximizeButton,\n setUpMinimizeButton,\n switchMinMaxButtonVisibility,\n} from '@/components/chatbot/chatbotMinMaxButtonsController';\nimport {\n disableMessageInput,\n enableMessageInput,\n handleUserMessage,\n setPlaceHolderContent\n} from './chatbotMessagingController';\nimport {setGreetingView} from '@/components/chatbot/chatbotConversationPersitenceUtils';\n\nfunction setUpMinMaxButtons() {\n setUpMinimizeButton();\n setUpMaximizeButton();\n}\n\nfunction setUpGreetingButtons() {\n const greetingsBtns = getGreetingsButtons();\n greetingsBtns.forEach(btn => {\n btn.addEventListener('click', async (e) => {\n const minMaxButtonContainer = getMinMaxButtonContainer();\n setGreetingView();\n if (btn.dataset.book) {\n window.bookAVisitClicked = true;\n }\n minMaxButtonContainer.classList.remove('solv-chatbot-widget--minimized');\n minMaxButtonContainer.classList.add('solv-chatbot-widget--maximized');\n removeGreetingElement();\n switchMinMaxButtonVisibility();\n const firstNameInput = getFirstNameInput();\n firstNameInput.focus();\n\n });\n });\n}\n\nfunction autoScrollToBottom() {\n const messageFeed = getMessageFeed();\n\n setTimeout(() => {\n messageFeed.scrollIntoView(false);\n }, 500);\n}\n\nfunction setUpButtons() {\n const buttons = getButtons();\n buttons.forEach(button => {\n button.addEventListener('click', async (e) => {\n if (button.dataset.viewMoreLocations) {\n handleViewMoreLocationsButtonClick();\n button.remove();\n } else {\n const message = button.dataset.buttonContent;\n if (message) {\n await handleUserMessage(message);\n }\n }\n });\n });\n}\n\nfunction handleViewMoreLocationsButtonClick() {\n const hiddenLocations = document.querySelectorAll('[data-hidden-location]');\n hiddenLocations.forEach(location => {\n location.classList.remove('hidden');\n });\n}\n\nasync function submitUserInfo() {\n const firstName = getFirstNameInput().value\n const lastName = getLastNameInput().value\n const phone = getPhoneNumberInput().value\n\n const userInformation = {\n first_name: firstName,\n last_name: lastName,\n phone_number: phone\n }\n\n let message = `First Name: ${firstName},
Last Name: ${lastName},
Phone: ${phone},`\n\n if (window.bookAVisitClicked) {\n message = `${message}
I would like to book a visit`\n }\n\n setPlaceHolderContent('replyInput');\n enableMessageInput();\n\n await handleUserMessage(message, userInformation);\n\n\n}\n\nfunction removeForms() {\n const forms = getForms();\n forms.forEach(form => {\n form.remove();\n });\n}\n\nfunction isValidPhoneNumber() {\n const phoneNumberInput = getPhoneNumberInput();\n const phoneRegExp = /^[\\+]?[(]?[0-9]{3}[)]?[+\\s\\.]?[0-9]{3}[-\\s\\.]?[0-9]{4,6}$/im;\n return phoneRegExp.test(phoneNumberInput.value);\n}\n\nfunction isValidName(inputElement) {\n const nameRegExp = /^\\s*$/;\n return !nameRegExp.test(inputElement.value);\n}\n\nfunction showErrorMessage(inputElement, messageElement) {\n inputElement.classList.add('invalid');\n inputElement.ariaInvalid = true;\n messageElement.classList.remove('solv-chatbot-widget--hidden');\n messageElement.ariaHidden = false;\n}\n\nfunction hideErrorMessage(inputElement, messageElement) {\n inputElement.classList.remove('invalid');\n inputElement.ariaInvalid = false;\n messageElement.classList.add('solv-chatbot-widget--hidden');\n messageElement.ariaHidden = true;\n}\n\nconst isNumericInput = (event) => {\n const key = event.keyCode;\n return ((key >= 48 && key <= 57) || // Allow number line\n (key >= 96 && key <= 105) // Allow number pad\n );\n};\n\nconst isModifierKey = (event) => {\n const key = event.keyCode;\n return (event.shiftKey === true || key === 35 || key === 36) || // Allow Shift, Home, End\n (key === 8 || key === 9 || key === 13 || key === 46) || // Allow Backspace, Tab, Enter, Delete\n (key > 36 && key < 41) || // Allow left, up, right, down\n (\n // Allow Ctrl/Command + A,C,V,X,Z\n (event.ctrlKey === true || event.metaKey === true) &&\n (key === 65 || key === 67 || key === 86 || key === 88 || key === 90)\n )\n};\n\nconst enforceFormat = (event) => {\n // Input must be of a valid number format or a modifier key, and not longer than ten digits\n if (!isNumericInput(event) && !isModifierKey(event)) {\n event.preventDefault();\n }\n};\n\nconst formatToPhone = (event) => {\n if (isModifierKey(event)) {\n return;\n }\n\n const input = event.target.value.replace(/\\D/g, '').substring(0, 10); // First ten digits of input only\n const areaCode = input.substring(0, 3);\n const middle = input.substring(3, 6);\n const last = input.substring(6, 10);\n\n if (input.length > 6) {\n event.target.value = `(${areaCode}) ${middle}-${last}`;\n } else if (input.length > 3) {\n event.target.value = `(${areaCode}) ${middle}`;\n } else if (input.length > 0) {\n event.target.value = `(${areaCode}`;\n }\n}\n\nfunction setUpNewUserForm() {\n const newUserForm = getnewUserForm();\n const phoneNumberInput = getPhoneNumberInput();\n const firstNameInput = getFirstNameInput();\n const lastNameInput = getLastNameInput();\n\n if (!newUserForm) return;\n\n setPlaceHolderContent('phoneInput');\n\n disableMessageInput();\n\n phoneNumberInput.addEventListener('input', (e) => {\n enforceFormat(e);\n formatToPhone(e);\n\n // This is to help avoid confusing the user if they've inputted an incorrect value. We don't want to show the error anymore if they input a valid value.\n if (isValidPhoneNumber()) {\n hideErrorMessage(phoneNumberInput, getPhoneNumberErrorMessage());\n } else {\n showErrorMessage(phoneNumberInput, getPhoneNumberErrorMessage());\n }\n });\n\n firstNameInput.addEventListener('input', (e) => {\n // This is to help avoid confusing the user if they've inputted an incorrect value. We don't want to show the error anymore if they input a valid value.\n if (isValidName(firstNameInput)) {\n hideErrorMessage(firstNameInput, getFirstNameErrorMessage());\n } else {\n showErrorMessage(firstNameInput, getFirstNameErrorMessage());\n }\n });\n\n lastNameInput.addEventListener('input', (e) => {\n // This is to help avoid confusing the user if they've inputted an incorrect value. We don't want to show the error anymore if they input a valid value.\n if (isValidName(lastNameInput)) {\n hideErrorMessage(lastNameInput, getLastNameErrorMessage());\n } else {\n showErrorMessage(lastNameInput, getLastNameErrorMessage());\n }\n })\n\n newUserForm.addEventListener('submit', async (e) => {\n e.preventDefault();\n\n const phoneValid = isValidPhoneNumber();\n const firstNameValid = isValidName(getFirstNameInput());\n const lastNameValid = isValidName(getLastNameInput());\n\n if (phoneValid && firstNameValid && lastNameValid) {\n await submitUserInfo();\n } else {\n\n if (!phoneValid) {\n showErrorMessage(phoneNumberInput, getPhoneNumberErrorMessage());\n }\n\n if (!firstNameValid) {\n showErrorMessage(firstNameInput, getFirstNameErrorMessage());\n }\n\n if (!lastNameValid) {\n showErrorMessage(lastNameInput, getFirstNameErrorMessage());\n }\n }\n });\n}\n\nfunction removeButtons() {\n const buttonContainers = getButtonContainers();\n buttonContainers.forEach(container => {\n container.remove();\n });\n}\n\n\nexport {\n setUpButtons,\n setUpGreetingButtons,\n setUpMinMaxButtons,\n setUpNewUserForm,\n removeButtons,\n removeForms,\n autoScrollToBottom\n}\n","import {\n getWidgetContainer,\n getRequestId,\n getGreetingElement,\n getInvalidRequestId\n} from '@/components/chatbot/chatbotElementUtils';\nimport {\n setUpGreetingButtons,\n setUpButtons,\n setUpMinMaxButtons,\n setUpNewUserForm,\n autoScrollToBottom\n} from '@/components/chatbot/chatbotButtonsAndFormsController';\nimport {showMessagesTemplate} from '@/components/chatbot/chatbotMinMaxButtonsController';\nimport {setupMessageForm, initiateSessionTimeoutCheck} from '@/components/chatbot/chatbotMessagingController';\nimport {\n storeUserInformation,\n getUserInformation,\n isIdHashExpired,\n getGreetingView,\n getMinimization\n} from '@/components/chatbot/chatbotConversationPersitenceUtils';\n\nfunction checkForSessionTimeout() {\n const idHashExpired = isIdHashExpired()\n\n if (idHashExpired) {\n clearInterval(window.solvCheckForSessionTimeout);\n window.solvCheckForSessionTimeout = null;\n window.localStorage.removeItem(\"solvChatId\");\n reinitializeWidget();\n }\n}\n\nasync function reinitializeWidget() {\n const testURLElement = document.getElementById('testing-chatbot-locally');\n let resetUrl = 'https://www.solvhealth.com/dir/chatbot-new-session';\n if (testURLElement) {\n resetUrl = '/dir/chatbot-new-session';\n }\n\n const userInformation = getUserInformation();\n const oldRequestId = getRequestId();\n\n const res = await fetch(`${resetUrl}?user_information=${userInformation}&request_id=${oldRequestId}`);\n const data = await res.json();\n const requestId = data.request_id;\n\n const widgetContainer = document.querySelector('solv-chatbot-widget');\n widgetContainer.dataset.requestId = requestId;\n\n await loadWidgetInitialContent()\n}\n\nasync function loadWidgetInitialContent() {\n let requestId = getRequestId();\n const invalidRequestId = getInvalidRequestId();\n\n const testURLElement = document.getElementById('testing-chatbot-locally');\n let templateURL = 'https://www.solvhealth.com/dir/chatbot-widget-template';\n if (testURLElement) {\n templateURL = '/dir/chatbot-widget-template';\n }\n\n const userInformation = getUserInformation();\n const greetingView = getGreetingView();\n const minimizationTime = getMinimization();\n\n let url = `${templateURL}?request_id=${requestId}&user_information=${userInformation}`\n if (greetingView) {\n url += `&greeting_view=${greetingView}`;\n }\n if (invalidRequestId && invalidRequestId != requestId) {\n url += `&invalid_request_id=${invalidRequestId}`;\n }\n\n\n // If the user has previously minimized the widget, we check if the minimization time is within the last hour. If it is, we may keep the widget minimized\n if (minimizationTime) {\n url += `&minimized=${minimizationTime}`;\n }\n\n const res = await fetch(url);\n const data = await res.json();\n const template = data.content;\n const newUserInformation = data.user_information;\n if (newUserInformation != userInformation) {\n storeUserInformation(newUserInformation);\n }\n\n const container = getWidgetContainer();\n container.innerHTML = template;\n\n const greetingTemplate = getGreetingElement();\n if (greetingTemplate) {\n setUpGreetingButtons();\n } else {\n initiateSessionTimeoutCheck();\n showMessagesTemplate();\n }\n setUpButtons();\n setUpMinMaxButtons();\n setupMessageForm();\n autoScrollToBottom();\n setUpNewUserForm();\n}\n\nexport {loadWidgetInitialContent, checkForSessionTimeout};\n","import { loadWidgetInitialContent } from '@/components/chatbot/chatbotWidgetContentController';\n\n// the below logic interacts with the JS on the UBS. It is for a better user experience.\nfunction geolocationSucceeded() {\n // we don't want to do anything if geolocate succeeds because the page will be reloaded\n // I'm adding this console.log here to generate a new version of this file in the cdn\n console.log(\"Browser geolocation succeeded\");\n}\n\nfunction geolocationRejected() {\n loadWidgetInitialContent();\n}\n\nif (window.UbsGeolocationPending === true) {\n let options = {\n enableHighAccuracy: false,\n timeout: 10000,\n maximumAge: 0,\n };\n navigator.geolocation.watchPosition(geolocationSucceeded, geolocationRejected, options);\n\n} else {\n loadWidgetInitialContent();\n}\n"],"names":["getWidgetContainer","getRequestId","storedRequestId","getStoredRequestId","getInvalidRequestId","getGroupId","key","idHashInfo","getWidgetContent","widgetIsClosed","getMinimizeBtn","getCloseBtn","getMaximizeBtn","getMessagesElement","getGreetingElement","getMessageFeed","getUserMsgInputField","getMsgInputForm","getMsgSendBtn","getGreetingsButtons","getnewUserForm","getFirstNameInput","getLastNameInput","getPhoneNumberInput","getFirstNameErrorMessage","getLastNameErrorMessage","getPhoneNumberErrorMessage","getButtons","getButtonContainers","getMinMaxButtonContainer","getForms","getLoadingDots","getHiddenMessages","getTestInformation","getTimeStampElement","getTimeStampElementByIntervalID","id","getTimeStampInfoElement","timeStampElement","setTimeStamp","value","timeStamp","setTimeStampIntervalID","newID","deleteTimestamp","setGreetingView","expirationTime","getGreetingView","setMinimization","getMinimization","setMaximization","isIdHashExpired","storeUserInformation","userInformation","getUserInformation","minimizeContainer","minimizeBtn","maximizeBtn","widgetContent","minMaxButtonContainer","trackConversationMinimization","maximizeContainer","setUpMinimizeButton","e","setUpMaximizeButton","removeGreetingElement","userInputField","firstNameInput","autoScrollToBottom","showMessagesTemplate","messages","trackConversationInitiation","requestId","testURLElement","messageURL","switchMinMaxButtonVisibility","moveLoadingDotsToBottomOfFeed","dots","showLoadingDots","hideLoadingDots","PLACEHOLDER_VALUES","interstitialCount","setPlaceHolderContent","placeholderKey","inputField","handleUserMessage","message","renderUserMessageOnFeed","initiateSessionTimeoutCheck","submitMessage","checkForSessionTimeout","resData","sendMessage","request_new_message","renderAssistantMessageOnFeed","disableMessageInput","data","res","sendErrorMessage","retries","errorURL","removeButtons","unhideMessages","removeForms","updateBanner","messageFeed","newMsgWrapper","newMsgContent","messageElement","showStamp","content","showTimeStamp","setUpButtons","setUpNewUserForm","autosizeInputField","setupMessageForm","userForm","sendBtn","messageInput","hideSendButtonDisplay","showSendButtonDisplay","enableMessageInput","initialTime","intervalID","updateTimeStampValue","difference","setUpMinMaxButtons","setUpGreetingButtons","btn","button","handleViewMoreLocationsButtonClick","location","submitUserInfo","firstName","lastName","phone","form","isValidPhoneNumber","phoneNumberInput","isValidName","inputElement","showErrorMessage","hideErrorMessage","isNumericInput","event","isModifierKey","enforceFormat","formatToPhone","input","areaCode","middle","last","newUserForm","lastNameInput","phoneValid","firstNameValid","lastNameValid","container","reinitializeWidget","resetUrl","oldRequestId","widgetContainer","loadWidgetInitialContent","invalidRequestId","templateURL","greetingView","minimizationTime","url","template","newUserInformation","geolocationSucceeded","geolocationRejected","options"],"mappings":"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"}