@product7/feedback-sdk 1.1.8 → 1.2.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"feedback-sdk.min.js","sources":["../src/utils/errors.js","../src/core/APIService.js","../src/core/EventBus.js","../src/utils/helpers.js","../src/widgets/BaseWidget.js","../src/widgets/ButtonWidget.js","../src/widgets/InlineWidget.js","../src/widgets/SurveyWidget.js","../src/widgets/TabWidget.js","../src/widgets/WidgetFactory.js","../src/core/FeedbackSDK.js","../src/index.js","../src/styles/styles.js"],"sourcesContent":["export class SDKError extends Error {\n\tconstructor(message, cause) {\n\t\tsuper(message);\n\t\tthis.name = 'SDKError';\n\t\tthis.cause = cause;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, SDKError);\n\t\t}\n\t}\n}\n\nexport class APIError extends Error {\n\tconstructor(status, message, response) {\n\t\tsuper(message);\n\t\tthis.name = 'APIError';\n\t\tthis.status = status;\n\t\tthis.response = response;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, APIError);\n\t\t}\n\t}\n\n\tisNetworkError() {\n\t\treturn this.status === 0;\n\t}\n\n\tisClientError() {\n\t\treturn this.status >= 400 && this.status < 500;\n\t}\n\n\tisServerError() {\n\t\treturn this.status >= 500 && this.status < 600;\n\t}\n}\n\nexport class WidgetError extends Error {\n\tconstructor(message, widgetType, widgetId) {\n\t\tsuper(message);\n\t\tthis.name = 'WidgetError';\n\t\tthis.widgetType = widgetType;\n\t\tthis.widgetId = widgetId;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, WidgetError);\n\t\t}\n\t}\n}\n\nexport class ConfigError extends Error {\n\tconstructor(message, configKey) {\n\t\tsuper(message);\n\t\tthis.name = 'ConfigError';\n\t\tthis.configKey = configKey;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, ConfigError);\n\t\t}\n\t}\n}\n\nexport class ValidationError extends Error {\n\tconstructor(message, field, value) {\n\t\tsuper(message);\n\t\tthis.name = 'ValidationError';\n\t\tthis.field = field;\n\t\tthis.value = value;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, ValidationError);\n\t\t}\n\t}\n}\n\nexport class ErrorHandler {\n\tconstructor(debug = false) {\n\t\tthis.debug = debug;\n\t}\n\n\thandle(error, context = '') {\n\t\tconst errorInfo = {\n\t\t\tname: error.name,\n\t\t\tmessage: error.message,\n\t\t\tcontext,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\n\t\tif (error instanceof APIError) {\n\t\t\terrorInfo.status = error.status;\n\t\t\terrorInfo.type = 'api';\n\t\t} else if (error instanceof WidgetError) {\n\t\t\terrorInfo.widgetType = error.widgetType;\n\t\t\terrorInfo.widgetId = error.widgetId;\n\t\t\terrorInfo.type = 'widget';\n\t\t} else if (error instanceof ConfigError) {\n\t\t\terrorInfo.configKey = error.configKey;\n\t\t\terrorInfo.type = 'config';\n\t\t} else if (error instanceof ValidationError) {\n\t\t\terrorInfo.field = error.field;\n\t\t\terrorInfo.value = error.value;\n\t\t\terrorInfo.type = 'validation';\n\t\t} else {\n\t\t\terrorInfo.type = 'unknown';\n\t\t}\n\n\t\tif (this.debug) {\n\t\t\tconsole.error('[FeedbackSDK Error]', errorInfo, error);\n\t\t} else {\n\t\t\tconsole.error('[FeedbackSDK Error]', error.message);\n\t\t}\n\n\t\treturn errorInfo;\n\t}\n\n\tgetUserMessage(error) {\n\t\tif (error instanceof APIError) {\n\t\t\tif (error.isNetworkError()) {\n\t\t\t\treturn 'Network error. Please check your connection and try again.';\n\t\t\t} else if (error.isClientError()) {\n\t\t\t\treturn 'Invalid request. Please check your input and try again.';\n\t\t\t} else if (error.isServerError()) {\n\t\t\t\treturn 'Server error. Please try again later.';\n\t\t\t}\n\t\t\treturn 'Failed to submit feedback. Please try again.';\n\t\t}\n\n\t\tif (error instanceof ValidationError) {\n\t\t\treturn `Please check your ${error.field}: ${error.message}`;\n\t\t}\n\n\t\tif (error instanceof ConfigError) {\n\t\t\treturn 'Configuration error. Please check your SDK setup.';\n\t\t}\n\n\t\tif (error instanceof WidgetError) {\n\t\t\treturn 'Widget error. Please try refreshing the page.';\n\t\t}\n\n\t\treturn 'An unexpected error occurred. Please try again.';\n\t}\n}\n","import { APIError } from '../utils/errors.js';\n\nconst MOCK_CONFIG = {\n\tprimaryColor: '#21244A',\n\tbackgroundColor: '#ffffff',\n\ttextColor: '#1F2937',\n\tboardId: 'feature-requests',\n\tsize: 'medium',\n\tdisplayMode: 'modal',\n};\n\nconst ENV_URLS = {\n\tproduction: {\n\t\tbase: 'https://api.product7.io/api/v1',\n\t\twithWorkspace: (workspace) => `https://${workspace}.api.product7.io/api/v1`,\n\t},\n\tstaging: {\n\t\tbase: 'https://staging.api.product7.io/api/v1',\n\t\twithWorkspace: (workspace) =>\n\t\t\t`https://${workspace}.staging.api.product7.io/api/v1`,\n\t},\n};\n\nexport class APIService {\n\tconstructor(config = {}) {\n\t\tthis.workspace = config.workspace;\n\t\tthis.sessionToken = null;\n\t\tthis.sessionExpiry = null;\n\t\tthis.userContext = config.userContext || null;\n\t\tthis.mock = config.mock || false;\n\t\tthis.env = config.env || 'production';\n\n\t\tif (config.apiUrl) {\n\t\t\tthis.baseURL = config.apiUrl;\n\t\t} else {\n\t\t\tconst envConfig = ENV_URLS[this.env] || ENV_URLS.production;\n\t\t\tthis.baseURL = this.workspace\n\t\t\t\t? envConfig.withWorkspace(this.workspace)\n\t\t\t\t: envConfig.base;\n\t\t}\n\n\t\tthis._loadStoredSession();\n\t}\n\n\tasync init(userContext = null) {\n\t\tif (userContext) {\n\t\t\tthis.userContext = userContext;\n\t\t}\n\n\t\tif (this.isSessionValid()) {\n\t\t\treturn { sessionToken: this.sessionToken };\n\t\t}\n\n\t\tif (!this.userContext || !this.workspace) {\n\t\t\tconst error = `Missing ${!this.workspace ? 'workspace' : 'user context'} for initialization`;\n\t\t\tthrow new APIError(400, error);\n\t\t}\n\n\t\t// Mock mode - return fake session\n\t\tif (this.mock) {\n\t\t\tthis.sessionToken = 'mock_session_' + Date.now();\n\t\t\tthis.sessionExpiry = new Date(Date.now() + 3600 * 1000);\n\t\t\tthis._storeSession();\n\t\t\treturn {\n\t\t\t\tsessionToken: this.sessionToken,\n\t\t\t\tconfig: MOCK_CONFIG,\n\t\t\t\texpiresIn: 3600,\n\t\t\t};\n\t\t}\n\n\t\tconst payload = {\n\t\t\tworkspace: this.workspace,\n\t\t\tuser: this.userContext,\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await this._makeRequest('/widget/init', {\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: JSON.stringify(payload),\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tthis.sessionToken = response.session_token;\n\t\t\tthis.sessionExpiry = new Date(Date.now() + response.expires_in * 1000);\n\t\t\tthis._storeSession();\n\n\t\t\treturn {\n\t\t\t\tsessionToken: this.sessionToken,\n\t\t\t\tconfig: response.config || {},\n\t\t\t\texpiresIn: response.expires_in,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthrow new APIError(\n\t\t\t\terror.status || 500,\n\t\t\t\t`Failed to initialize widget: ${error.message}`,\n\t\t\t\terror.response\n\t\t\t);\n\t\t}\n\t}\n\n\tasync submitFeedback(feedbackData) {\n\t\tif (!this.isSessionValid()) {\n\t\t\tawait this.init();\n\t\t}\n\n\t\tif (!this.sessionToken) {\n\t\t\tthrow new APIError(401, 'No valid session token available');\n\t\t}\n\n\t\t// Mock mode - simulate success\n\t\tif (this.mock) {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 500));\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tid: 'mock_post_' + Date.now(),\n\t\t\t\t\ttitle: feedbackData.title,\n\t\t\t\t\tcontent: feedbackData.content,\n\t\t\t\t},\n\t\t\t\tmessage: 'Feedback submitted successfully!',\n\t\t\t};\n\t\t}\n\n\t\tconst payload = {\n\t\t\tboard:\n\t\t\t\tfeedbackData.board_id || feedbackData.board || feedbackData.boardId,\n\t\t\ttitle: feedbackData.title,\n\t\t\tcontent: feedbackData.content,\n\t\t\tattachments: feedbackData.attachments || [],\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await this._makeRequest('/widget/feedback', {\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: JSON.stringify(payload),\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\tAuthorization: `Bearer ${this.sessionToken}`,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tif (error.status === 401) {\n\t\t\t\tthis.sessionToken = null;\n\t\t\t\tthis.sessionExpiry = null;\n\t\t\t\tawait this.init();\n\t\t\t\treturn this.submitFeedback(feedbackData);\n\t\t\t}\n\n\t\t\tthrow new APIError(\n\t\t\t\terror.status || 500,\n\t\t\t\t`Failed to submit feedback: ${error.message}`,\n\t\t\t\terror.response\n\t\t\t);\n\t\t}\n\t}\n\n\tisSessionValid() {\n\t\treturn (\n\t\t\tthis.sessionToken && this.sessionExpiry && new Date() < this.sessionExpiry\n\t\t);\n\t}\n\n\tsetUserContext(userContext) {\n\t\tthis.userContext = userContext;\n\t\tif (typeof localStorage !== 'undefined') {\n\t\t\tlocalStorage.setItem(\n\t\t\t\t'feedbackSDK_userContext',\n\t\t\t\tJSON.stringify(userContext)\n\t\t\t);\n\t\t}\n\t}\n\n\tgetUserContext() {\n\t\treturn this.userContext;\n\t}\n\n\tclearSession() {\n\t\tthis.sessionToken = null;\n\t\tthis.sessionExpiry = null;\n\t\tif (typeof localStorage !== 'undefined') {\n\t\t\tlocalStorage.removeItem('feedbackSDK_session');\n\t\t\tlocalStorage.removeItem('feedbackSDK_userContext');\n\t\t}\n\t}\n\n\t_storeSession() {\n\t\tif (typeof localStorage === 'undefined') return;\n\n\t\ttry {\n\t\t\tconst sessionData = {\n\t\t\t\ttoken: this.sessionToken,\n\t\t\t\texpiry: this.sessionExpiry.toISOString(),\n\t\t\t\tworkspace: this.workspace,\n\t\t\t};\n\t\t\tlocalStorage.setItem('feedbackSDK_session', JSON.stringify(sessionData));\n\t\t} catch (error) {\n\t\t\t// Silently fail if localStorage is not available\n\t\t}\n\t}\n\n\t_loadStoredSession() {\n\t\tif (typeof localStorage === 'undefined') return false;\n\n\t\ttry {\n\t\t\tconst stored = localStorage.getItem('feedbackSDK_session');\n\t\t\tif (!stored) return false;\n\n\t\t\tconst sessionData = JSON.parse(stored);\n\t\t\tthis.sessionToken = sessionData.token;\n\t\t\tthis.sessionExpiry = new Date(sessionData.expiry);\n\n\t\t\treturn this.isSessionValid();\n\t\t} catch (error) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync _makeRequest(endpoint, options = {}) {\n\t\tconst url = `${this.baseURL}${endpoint}`;\n\n\t\ttry {\n\t\t\tconst response = await fetch(url, options);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlet errorMessage = `HTTP ${response.status}`;\n\t\t\t\tlet responseData = null;\n\n\t\t\t\ttry {\n\t\t\t\t\tresponseData = await response.json();\n\t\t\t\t\terrorMessage =\n\t\t\t\t\t\tresponseData.message || responseData.error || errorMessage;\n\t\t\t\t} catch (e) {\n\t\t\t\t\terrorMessage = (await response.text()) || errorMessage;\n\t\t\t\t}\n\n\t\t\t\tthrow new APIError(response.status, errorMessage, responseData);\n\t\t\t}\n\n\t\t\tconst contentType = response.headers.get('content-type');\n\t\t\tif (contentType && contentType.includes('application/json')) {\n\t\t\t\treturn await response.json();\n\t\t\t}\n\n\t\t\treturn await response.text();\n\t\t} catch (error) {\n\t\t\tif (error instanceof APIError) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tthrow new APIError(0, error.message, null);\n\t\t}\n\t}\n}\n","export class EventBus {\n\tconstructor() {\n\t\tthis.events = new Map();\n\t}\n\n\ton(event, callback) {\n\t\tif (!this.events.has(event)) {\n\t\t\tthis.events.set(event, []);\n\t\t}\n\t\tthis.events.get(event).push(callback);\n\n\t\treturn () => this.off(event, callback);\n\t}\n\n\toff(event, callback) {\n\t\tconst callbacks = this.events.get(event);\n\t\tif (callbacks) {\n\t\t\tconst index = callbacks.indexOf(callback);\n\t\t\tif (index > -1) {\n\t\t\t\tcallbacks.splice(index, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\temit(event, data) {\n\t\tconst callbacks = this.events.get(event);\n\t\tif (callbacks) {\n\t\t\tcallbacks.forEach((callback) => {\n\t\t\t\ttry {\n\t\t\t\t\tcallback(data);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error('[FeedbackSDK] Event callback error:', error);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tonce(event, callback) {\n\t\tconst unsubscribe = this.on(event, (data) => {\n\t\t\tcallback(data);\n\t\t\tunsubscribe();\n\t\t});\n\t\treturn unsubscribe;\n\t}\n\n\tclear() {\n\t\tthis.events.clear();\n\t}\n\n\tgetListenerCount(event) {\n\t\tconst callbacks = this.events.get(event);\n\t\treturn callbacks ? callbacks.length : 0;\n\t}\n}\n","export function generateId(prefix = 'feedback') {\n\tconst timestamp = Date.now();\n\tconst random = Math.random().toString(36).substring(2, 9);\n\treturn `${prefix}_${timestamp}_${random}`;\n}\n\nexport function deepMerge(target, source) {\n\tconst result = { ...target };\n\n\tfor (const key in source) {\n\t\tif (source.hasOwnProperty(key)) {\n\t\t\tif (\n\t\t\t\tsource[key] &&\n\t\t\t\ttypeof source[key] === 'object' &&\n\t\t\t\t!Array.isArray(source[key])\n\t\t\t) {\n\t\t\t\tresult[key] = deepMerge(target[key] || {}, source[key]);\n\t\t\t} else {\n\t\t\t\tresult[key] = source[key];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function debounce(func, wait) {\n\tlet timeout;\n\treturn function executedFunction(...args) {\n\t\tconst later = () => {\n\t\t\tclearTimeout(timeout);\n\t\t\tfunc(...args);\n\t\t};\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(later, wait);\n\t};\n}\n\nexport function throttle(func, limit) {\n\tlet lastFunc;\n\tlet lastRan;\n\treturn function (...args) {\n\t\tif (!lastRan) {\n\t\t\tfunc(...args);\n\t\t\tlastRan = Date.now();\n\t\t} else {\n\t\t\tclearTimeout(lastFunc);\n\t\t\tlastFunc = setTimeout(\n\t\t\t\t() => {\n\t\t\t\t\tif (Date.now() - lastRan >= limit) {\n\t\t\t\t\t\tfunc(...args);\n\t\t\t\t\t\tlastRan = Date.now();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tlimit - (Date.now() - lastRan)\n\t\t\t);\n\t\t}\n\t};\n}\n\nexport function isValidEmail(email) {\n\tif (!email || typeof email !== 'string') return false;\n\n\tconst emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\treturn emailRegex.test(email.trim());\n}\n\nexport function sanitizeHTML(str) {\n\tif (!str || typeof str !== 'string') return '';\n\n\tconst div = document.createElement('div');\n\tdiv.textContent = str;\n\treturn div.innerHTML;\n}\n\nexport function getCSSProperty(element, property, fallback = '') {\n\tif (!element || !property) return fallback;\n\n\ttry {\n\t\tconst style = window.getComputedStyle(element);\n\t\treturn style.getPropertyValue(property) || fallback;\n\t} catch (error) {\n\t\treturn fallback;\n\t}\n}\n\nexport function isInViewport(element) {\n\tif (!element) return false;\n\n\tconst rect = element.getBoundingClientRect();\n\treturn (\n\t\trect.top >= 0 &&\n\t\trect.left >= 0 &&\n\t\trect.bottom <=\n\t\t\t(window.innerHeight || document.documentElement.clientHeight) &&\n\t\trect.right <= (window.innerWidth || document.documentElement.clientWidth)\n\t);\n}\n\nexport function scrollToElement(element, options = {}) {\n\tif (!element) return;\n\n\tconst defaultOptions = {\n\t\tbehavior: 'smooth',\n\t\tblock: 'center',\n\t\tinline: 'nearest',\n\t};\n\n\telement.scrollIntoView({ ...defaultOptions, ...options });\n}\n\nexport function getBrowserInfo() {\n\tconst userAgent = navigator.userAgent;\n\tconst platform = navigator.platform;\n\n\treturn {\n\t\tuserAgent,\n\t\tplatform,\n\t\tlanguage: navigator.language || navigator.userLanguage,\n\t\tcookieEnabled: navigator.cookieEnabled,\n\t\tscreenResolution: `${screen.width}x${screen.height}`,\n\t\twindowSize: `${window.innerWidth}x${window.innerHeight}`,\n\t\ttimezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n\t};\n}\n\nexport function formatFileSize(bytes) {\n\tif (bytes === 0) return '0 Bytes';\n\n\tconst k = 1024;\n\tconst sizes = ['Bytes', 'KB', 'MB', 'GB'];\n\tconst i = Math.floor(Math.log(bytes) / Math.log(k));\n\n\treturn parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n}\n\nexport function delay(ms) {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function safeJsonParse(str, fallback = null) {\n\ttry {\n\t\treturn JSON.parse(str);\n\t} catch (error) {\n\t\treturn fallback;\n\t}\n}\n\nexport function escapeRegex(string) {\n\treturn string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function getNestedProperty(obj, path, defaultValue = undefined) {\n\tif (!obj || !path) return defaultValue;\n\n\tconst keys = path.split('.');\n\tlet current = obj;\n\n\tfor (const key of keys) {\n\t\tif (current === null || current === undefined || !(key in current)) {\n\t\t\treturn defaultValue;\n\t\t}\n\t\tcurrent = current[key];\n\t}\n\n\treturn current;\n}\n\nexport function setNestedProperty(obj, path, value) {\n\tif (!obj || !path) return obj;\n\n\tconst keys = path.split('.');\n\tconst lastKey = keys.pop();\n\tlet current = obj;\n\n\tfor (const key of keys) {\n\t\tif (!(key in current) || typeof current[key] !== 'object') {\n\t\t\tcurrent[key] = {};\n\t\t}\n\t\tcurrent = current[key];\n\t}\n\n\tcurrent[lastKey] = value;\n\treturn obj;\n}\n\nexport function isBrowser() {\n\treturn typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nexport function isMobile() {\n\tif (!isBrowser()) return false;\n\n\treturn (\n\t\t/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(\n\t\t\tnavigator.userAgent\n\t\t) || window.innerWidth <= 768\n\t);\n}\n\nexport function getCurrentTimestamp() {\n\treturn new Date().toISOString();\n}\n\nexport function validateConfig(config, required = []) {\n\tconst missing = [];\n\n\tfor (const key of required) {\n\t\tif (!config[key]) {\n\t\t\tmissing.push(key);\n\t\t}\n\t}\n\n\tif (missing.length > 0) {\n\t\tthrow new Error(`Missing required configuration: ${missing.join(', ')}`);\n\t}\n\n\treturn true;\n}\n","export class BaseWidget {\n\tconstructor(options = {}) {\n\t\tthis.id = options.id;\n\t\tthis.sdk = options.sdk;\n\t\tthis.apiService = options.apiService;\n\t\tthis.type = options.type || 'base';\n\n\t\tthis.options = {\n\t\t\tcontainer: null,\n\t\t\tposition: this.sdk.config.position,\n\t\t\tboardId: this.sdk.config.boardId,\n\t\t\tdisplayMode: options.displayMode || 'panel',\n\t\t\tsize: options.size || 'medium',\n\t\t\tprimaryColor: options.primaryColor || '#21244A',\n\t\t\tbackgroundColor: options.backgroundColor || '#ffffff',\n\t\t\ttextColor: options.textColor || '#1F2937',\n\t\t\tautoShow: false,\n\t\t\tshowBackdrop: true,\n\t\t\tcustomStyles: {},\n\t\t\t...options,\n\t\t};\n\n\t\tthis.element = null;\n\t\tthis.panelElement = null;\n\t\tthis.backdropElement = null;\n\t\tthis.mounted = false;\n\t\tthis.destroyed = false;\n\n\t\tthis.state = {\n\t\t\tisOpen: false,\n\t\t\tisLoading: false,\n\t\t\tisSubmitting: false,\n\t\t\ttitle: '',\n\t\t\tcontent: '',\n\t\t\temail: '',\n\t\t\tattachments: [],\n\t\t\terrors: {},\n\t\t};\n\n\t\tthis._bindMethods();\n\t}\n\n\tmount(container) {\n\t\tif (this.mounted || this.destroyed) return this;\n\n\t\tif (typeof container === 'string') {\n\t\t\tcontainer = document.querySelector(container);\n\t\t}\n\n\t\tif (!container) {\n\t\t\tcontainer = document.body;\n\t\t}\n\n\t\tthis.container = container;\n\t\tthis.element = this._render();\n\t\tthis.container.appendChild(this.element);\n\n\t\tthis.mounted = true;\n\t\tthis._attachEvents();\n\t\tthis.onMount();\n\n\t\tif (this.options.autoShow) {\n\t\t\tthis.show();\n\t\t}\n\n\t\tthis.sdk.eventBus.emit('widget:mounted', { widget: this });\n\t\treturn this;\n\t}\n\n\tshow() {\n\t\tif (this.element) {\n\t\t\tthis.element.style.display = 'block';\n\t\t}\n\t\treturn this;\n\t}\n\n\thide() {\n\t\tif (this.element) {\n\t\t\tthis.element.style.display = 'none';\n\t\t}\n\t\treturn this;\n\t}\n\n\topenPanel() {\n\t\tthis.state.isOpen = true;\n\n\t\tif (this.options.displayMode === 'modal') {\n\t\t\tthis._showLoadingModal();\n\t\t\t// Simulate loading delay then show form\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis._hideLoadingModal();\n\t\t\t\tthis._renderPanel();\n\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\tif (this.panelElement) {\n\t\t\t\t\t\tthis.panelElement.classList.add('open');\n\t\t\t\t\t}\n\t\t\t\t\tif (this.backdropElement) {\n\t\t\t\t\t\tthis.backdropElement.classList.add('show');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}, 600);\n\t\t} else {\n\t\t\tthis._renderPanel();\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tif (this.panelElement) {\n\t\t\t\t\tthis.panelElement.classList.add('open');\n\t\t\t\t}\n\t\t\t\tif (this.backdropElement) {\n\t\t\t\t\tthis.backdropElement.classList.add('show');\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t_showLoadingModal() {\n\t\tthis.state.isLoading = true;\n\n\t\t// Create backdrop\n\t\tthis.backdropElement = document.createElement('div');\n\t\tthis.backdropElement.className = 'feedback-panel-backdrop';\n\t\tdocument.body.appendChild(this.backdropElement);\n\n\t\t// Create loading modal\n\t\tthis.loadingElement = document.createElement('div');\n\t\tthis.loadingElement.className = `feedback-loading-modal theme-${this.options.theme}`;\n\t\tthis.loadingElement.innerHTML = `\n\t\t\t<div class=\"feedback-loading-spinner\"></div>\n\t\t`;\n\t\tdocument.body.appendChild(this.loadingElement);\n\n\t\trequestAnimationFrame(() => {\n\t\t\tthis.backdropElement.classList.add('show');\n\t\t\tthis.loadingElement.classList.add('show');\n\t\t});\n\t}\n\n\t_hideLoadingModal() {\n\t\tthis.state.isLoading = false;\n\t\tif (this.loadingElement) {\n\t\t\tthis.loadingElement.remove();\n\t\t\tthis.loadingElement = null;\n\t\t}\n\t}\n\n\tclosePanel() {\n\t\tif (this.panelElement) {\n\t\t\tthis.panelElement.classList.remove('open');\n\t\t}\n\t\tif (this.backdropElement) {\n\t\t\tthis.backdropElement.classList.remove('show');\n\t\t}\n\n\t\tsetTimeout(() => {\n\t\t\tthis.state.isOpen = false;\n\t\t\tif (this.panelElement && this.panelElement.parentNode) {\n\t\t\t\tthis.panelElement.parentNode.removeChild(this.panelElement);\n\t\t\t\tthis.panelElement = null;\n\t\t\t}\n\t\t\tif (this.backdropElement && this.backdropElement.parentNode) {\n\t\t\t\tthis.backdropElement.parentNode.removeChild(this.backdropElement);\n\t\t\t\tthis.backdropElement = null;\n\t\t\t}\n\t\t\tthis._resetForm();\n\t\t}, 300);\n\t}\n\n\tasync submitFeedback() {\n\t\tif (this.state.isSubmitting) return;\n\n\t\tthis._hideError();\n\n\t\ttry {\n\t\t\tthis.state.isSubmitting = true;\n\t\t\tthis._updateSubmitButton();\n\n\t\t\tconst payload = {\n\t\t\t\ttitle: this.state.title || 'Feedback',\n\t\t\t\tcontent: this.state.content,\n\t\t\t\temail: this.state.email,\n\t\t\t\tboard_id: this.options.boardId,\n\t\t\t\tattachments: this.state.attachments,\n\t\t\t};\n\n\t\t\tif (!this.state.content.trim()) {\n\t\t\t\tthis._showError('Please enter your feedback message.');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst response = await this.apiService.submitFeedback(payload);\n\n\t\t\tthis._showSuccessMessage();\n\t\t\tthis.closePanel();\n\n\t\t\tthis.sdk.eventBus.emit('feedback:submitted', {\n\t\t\t\twidget: this,\n\t\t\t\tfeedback: response,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis._showError('Failed to submit feedback. Please try again.');\n\t\t\tthis.sdk.eventBus.emit('feedback:error', { widget: this, error });\n\t\t} finally {\n\t\t\tthis.state.isSubmitting = false;\n\t\t\tthis._updateSubmitButton();\n\t\t}\n\t}\n\n\thandleConfigUpdate(newConfig) {\n\t\tthis.options.theme = newConfig.theme;\n\t\tif (this.element) {\n\t\t\tthis._updateTheme();\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this.destroyed) return;\n\n\t\tthis.onDestroy();\n\t\tthis.closePanel();\n\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\n\t\tthis.destroyed = true;\n\t\tthis.mounted = false;\n\t\tthis.sdk.eventBus.emit('widget:destroyed', { widget: this });\n\t}\n\n\tonMount() {}\n\tonDestroy() {}\n\n\t_render() {\n\t\tthrow new Error('_render() must be implemented by concrete widget');\n\t}\n\n\t_attachEvents() {\n\t\t// Override in concrete widgets\n\t}\n\n\t_bindMethods() {\n\t\tthis.openPanel = this.openPanel.bind(this);\n\t\tthis.closePanel = this.closePanel.bind(this);\n\t\tthis.submitFeedback = this.submitFeedback.bind(this);\n\t}\n\n\t_renderPanel() {\n\t\tif (this.panelElement) return;\n\n\t\tif (this.options.showBackdrop && !this.backdropElement) {\n\t\t\tthis.backdropElement = document.createElement('div');\n\t\t\tthis.backdropElement.className = 'feedback-panel-backdrop';\n\t\t\tdocument.body.appendChild(this.backdropElement);\n\n\t\t\tthis.backdropElement.addEventListener('click', this.closePanel);\n\t\t}\n\n\t\tconst modeClass =\n\t\t\tthis.options.displayMode === 'modal'\n\t\t\t\t? 'feedback-modal'\n\t\t\t\t: 'feedback-panel';\n\t\tconst sizeClass = `size-${this.options.size}`;\n\t\tthis.panelElement = document.createElement('div');\n\t\tthis.panelElement.className = `${modeClass} ${sizeClass}`;\n\t\tthis.panelElement.style.setProperty(\n\t\t\t'--primary-color',\n\t\t\tthis.options.primaryColor\n\t\t);\n\t\tthis.panelElement.style.setProperty(\n\t\t\t'--bg-color',\n\t\t\tthis.options.backgroundColor\n\t\t);\n\t\tthis.panelElement.style.setProperty('--text-color', this.options.textColor);\n\t\tthis.panelElement.innerHTML = this._getPanelHTML();\n\n\t\tdocument.body.appendChild(this.panelElement);\n\t\tthis._attachPanelEvents();\n\n\t\tconst firstInput = this.panelElement.querySelector('input, textarea');\n\t\tif (firstInput) {\n\t\t\tsetTimeout(() => firstInput.focus(), 350);\n\t\t}\n\t}\n\n\t_getPanelHTML() {\n\t\treturn `\n <div class=\"feedback-panel-content\">\n <div class=\"feedback-panel-header\">\n <h3>Send Feedback</h3>\n <button class=\"feedback-panel-close\" type=\"button\" aria-label=\"Close\">&times;</button>\n </div>\n <div class=\"feedback-panel-body\">\n <form class=\"feedback-form\">\n <div class=\"feedback-form-group\">\n <label for=\"feedback-title-${this.id}\">Title (optional)</label>\n <input \n type=\"text\" \n id=\"feedback-title-${this.id}\" \n name=\"title\" \n placeholder=\"Brief description of your feedback\"\n value=\"${this.state.title}\"\n />\n </div>\n <div class=\"feedback-form-group\">\n <label for=\"feedback-content-${this.id}\">Message *</label>\n <textarea \n id=\"feedback-content-${this.id}\" \n name=\"content\" \n placeholder=\"Tell us what you think...\"\n required\n >${this.state.content}</textarea>\n </div>\n <div class=\"feedback-error\" role=\"alert\"></div>\n <div class=\"feedback-form-actions\">\n <button type=\"submit\" class=\"feedback-btn feedback-btn-submit\">\n ${this.state.isSubmitting ? 'Sending...' : 'Send Feedback'}\n </button>\n </div>\n </form>\n </div>\n </div>\n `;\n\t}\n\t\n\t_attachPanelEvents() {\n\t\tconst panel = this.panelElement;\n\n\t\tpanel\n\t\t\t.querySelector('.feedback-panel-close')\n\t\t\t.addEventListener('click', this.closePanel);\n\n\t\tconst form = panel.querySelector('.feedback-form');\n\t\tform.addEventListener('submit', (e) => {\n\t\t\te.preventDefault();\n\t\t\tthis.submitFeedback();\n\t\t});\n\n\t\tpanel\n\t\t\t.querySelector('input[name=\"title\"]')\n\t\t\t.addEventListener('input', (e) => {\n\t\t\t\tthis.state.title = e.target.value;\n\t\t\t});\n\n\t\tpanel\n\t\t\t.querySelector('textarea[name=\"content\"]')\n\t\t\t.addEventListener('input', (e) => {\n\t\t\t\tthis.state.content = e.target.value;\n\t\t\t});\n\n\t\tconst handleEscape = (e) => {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\tthis.closePanel();\n\t\t\t\tdocument.removeEventListener('keydown', handleEscape);\n\t\t\t}\n\t\t};\n\t\tdocument.addEventListener('keydown', handleEscape);\n\t}\n\n\t_updateSubmitButton() {\n\t\tif (this.panelElement) {\n\t\t\tconst submitBtn = this.panelElement.querySelector('.feedback-btn-submit');\n\t\t\tif (submitBtn) {\n\t\t\t\tsubmitBtn.textContent = this.state.isSubmitting\n\t\t\t\t\t? 'Sending...'\n\t\t\t\t\t: 'Send Feedback';\n\t\t\t\tsubmitBtn.disabled = this.state.isSubmitting;\n\t\t\t}\n\t\t}\n\t}\n\n\t_showError(message) {\n\t\tif (this.panelElement) {\n\t\t\tconst errorElement = this.panelElement.querySelector('.feedback-error');\n\t\t\tif (errorElement) {\n\t\t\t\terrorElement.textContent = message;\n\t\t\t\terrorElement.classList.add('show');\n\t\t\t}\n\t\t}\n\t}\n\n\t_hideError() {\n\t\tif (this.panelElement) {\n\t\t\tconst errorElement = this.panelElement.querySelector('.feedback-error');\n\t\t\tif (errorElement) {\n\t\t\t\terrorElement.classList.remove('show');\n\t\t\t}\n\t\t}\n\t}\n\n\t_showSuccessMessage() {\n\t\tconst notification = document.createElement('div');\n\t\tnotification.className = 'feedback-success-notification';\n\t\tnotification.innerHTML = `\n <div class=\"feedback-success-content\">\n <div class=\"feedback-success-icon\">✓</div>\n <span>Feedback submitted successfully!</span>\n <button class=\"feedback-success-close\" aria-label=\"Close\">&times;</button>\n </div>\n `;\n\n\t\tdocument.body.appendChild(notification);\n\n\t\tconst closeBtn = notification.querySelector('.feedback-success-close');\n\t\tconst closeNotification = () => {\n\t\t\tif (notification.parentNode) {\n\t\t\t\tnotification.style.opacity = '0';\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tif (notification.parentNode) {\n\t\t\t\t\t\tnotification.parentNode.removeChild(notification);\n\t\t\t\t\t}\n\t\t\t\t}, 300);\n\t\t\t}\n\t\t};\n\n\t\tcloseBtn.addEventListener('click', closeNotification);\n\n\t\tsetTimeout(closeNotification, 4000);\n\t}\n\n\t_resetForm() {\n\t\tthis.state.title = '';\n\t\tthis.state.content = '';\n\t\tthis.state.email = '';\n\t\tthis.state.errors = {};\n\t}\n\n\t_updateTheme() {\n\t\tif (this.element) {\n\t\t\tthis.element.className = this.element.className.replace(\n\t\t\t\t/theme-\\w+/,\n\t\t\t\t`theme-${this.options.theme}`\n\t\t\t);\n\t\t}\n\t\tif (this.panelElement) {\n\t\t\tthis.panelElement.className = this.panelElement.className.replace(\n\t\t\t\t/theme-\\w+/,\n\t\t\t\t`theme-${this.options.theme}`\n\t\t\t);\n\t\t}\n\t}\n\n\topenModal() {\n\t\tthis.openPanel();\n\t}\n\n\tcloseModal() {\n\t\tthis.closePanel();\n\t}\n}\n","import { BaseWidget } from './BaseWidget.js';\n\nexport class ButtonWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'button' });\n\t}\n\n\t_render() {\n\t\tconst button = document.createElement('div');\n\t\tbutton.className = `feedback-widget feedback-widget-button theme-${this.options.theme} position-${this.options.position}`;\n\t\tbutton.innerHTML = `\n <button class=\"feedback-trigger-btn\" type=\"button\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path d=\"M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z\"/>\n <path d=\"M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z\"/>\n </svg>\n Feedback\n </button>\n `;\n\n\t\tif (this.options.customStyles) {\n\t\t\tObject.assign(button.style, this.options.customStyles);\n\t\t}\n\n\t\treturn button;\n\t}\n\n\t_attachEvents() {\n\t\tconst button = this.element.querySelector('.feedback-trigger-btn');\n\t\tbutton.addEventListener('click', this.openPanel);\n\n\t\tbutton.addEventListener('mouseenter', () => {\n\t\t\tif (!this.state.isSubmitting) {\n\t\t\t\tbutton.style.transform = 'translateY(-2px)';\n\t\t\t}\n\t\t});\n\n\t\tbutton.addEventListener('mouseleave', () => {\n\t\t\tbutton.style.transform = 'translateY(0)';\n\t\t});\n\t}\n\n\tupdateText(text) {\n\t\tconst button = this.element?.querySelector('.feedback-trigger-btn');\n\t\tif (button) {\n\t\t\tconst textNode = button.childNodes[button.childNodes.length - 1];\n\t\t\tif (textNode && textNode.nodeType === Node.TEXT_NODE) {\n\t\t\t\ttextNode.textContent = text;\n\t\t\t}\n\t\t}\n\t}\n\n\tupdatePosition(position) {\n\t\tthis.options.position = position;\n\t\tif (this.element) {\n\t\t\tthis.element.className = this.element.className.replace(\n\t\t\t\t/position-\\w+-\\w+/,\n\t\t\t\t`position-${position}`\n\t\t\t);\n\t\t}\n\t}\n}","import { BaseWidget } from './BaseWidget.js';\n\nexport class InlineWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'inline' });\n\t}\n\n\t_render() {\n\t\tconst widget = document.createElement('div');\n\t\twidget.className = `feedback-widget feedback-widget-inline theme-${this.options.theme}`;\n\t\twidget.innerHTML = `\n <div class=\"feedback-inline-content\">\n <h3>Send us your feedback</h3>\n <form class=\"feedback-inline-form\">\n <div class=\"feedback-form-group\">\n <input \n type=\"text\" \n name=\"title\" \n placeholder=\"Title (optional)\"\n value=\"${this.state.title}\"\n />\n </div>\n <div class=\"feedback-form-group\">\n <textarea \n name=\"content\" \n placeholder=\"Your feedback...\"\n required\n >${this.state.content}</textarea>\n </div>\n <div class=\"feedback-form-group\">\n <input \n type=\"email\" \n name=\"email\" \n placeholder=\"Email (optional)\"\n value=\"${this.state.email}\"\n />\n </div>\n <button type=\"submit\" class=\"feedback-btn feedback-btn-submit\">\n Send Feedback\n </button>\n <div class=\"feedback-error\" style=\"display: none;\"></div>\n </form>\n </div>\n `;\n\n\t\tif (this.options.customStyles) {\n\t\t\tObject.assign(widget.style, this.options.customStyles);\n\t\t}\n\n\t\treturn widget;\n\t}\n\n\t_attachEvents() {\n\t\tconst form = this.element.querySelector('.feedback-inline-form');\n\n\t\tform.addEventListener('submit', (e) => {\n\t\t\te.preventDefault();\n\t\t\tthis.submitFeedback();\n\t\t});\n\n\t\tform.querySelector('input[name=\"title\"]').addEventListener('input', (e) => {\n\t\t\tthis.state.title = e.target.value;\n\t\t});\n\n\t\tform\n\t\t\t.querySelector('textarea[name=\"content\"]')\n\t\t\t.addEventListener('input', (e) => {\n\t\t\t\tthis.state.content = e.target.value;\n\t\t\t});\n\n\t\tform.querySelector('input[name=\"email\"]').addEventListener('input', (e) => {\n\t\t\tthis.state.email = e.target.value;\n\t\t});\n\t}\n\n\topenModal() {\n\t\tconst textarea = this.element.querySelector('textarea[name=\"content\"]');\n\t\tif (textarea) {\n\t\t\ttextarea.focus();\n\t\t}\n\t}\n\n\tcloseModal() {\n\t\t// Inline widget doesn't use modal\n\t}\n\n\t_showSuccessMessage() {\n\t\tconst widget = this.element.querySelector('.feedback-inline-content');\n\t\tconst originalContent = widget.innerHTML;\n\n\t\twidget.innerHTML = `\n <div class=\"feedback-success\">\n <div class=\"feedback-success-icon\">✓</div>\n <h3>Thank you!</h3>\n <p>Your feedback has been submitted successfully.</p>\n <button class=\"feedback-btn feedback-btn-reset\">Send Another</button>\n </div>\n `;\n\n\t\tconst resetBtn = widget.querySelector('.feedback-btn-reset');\n\t\tresetBtn.addEventListener('click', () => {\n\t\t\twidget.innerHTML = originalContent;\n\t\t\tthis._attachEvents();\n\t\t\tthis._resetForm();\n\t\t});\n\t}\n\n\t_showError(message) {\n\t\tconst errorElement = this.element.querySelector('.feedback-error');\n\t\tif (errorElement) {\n\t\t\terrorElement.textContent = message;\n\t\t\terrorElement.style.display = 'block';\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (errorElement) {\n\t\t\t\t\terrorElement.style.display = 'none';\n\t\t\t\t}\n\t\t\t}, 5000);\n\t\t}\n\t}\n\n\t_updateSubmitButton() {\n\t\tconst submitBtn = this.element.querySelector('.feedback-btn-submit');\n\t\tif (submitBtn) {\n\t\t\tsubmitBtn.textContent = this.state.isSubmitting\n\t\t\t\t? 'Sending...'\n\t\t\t\t: 'Send Feedback';\n\t\t\tsubmitBtn.disabled = this.state.isSubmitting;\n\t\t}\n\t}\n\n\tupdateTitle(title) {\n\t\tconst titleElement = this.element?.querySelector('h3');\n\t\tif (titleElement) {\n\t\t\ttitleElement.textContent = title;\n\t\t}\n\t}\n\n\tsetPlaceholder(field, placeholder) {\n\t\tconst input = this.element?.querySelector(`[name=\"${field}\"]`);\n\t\tif (input) {\n\t\t\tinput.placeholder = placeholder;\n\t\t}\n\t}\n}\n","import { BaseWidget } from './BaseWidget.js';\n\nexport class SurveyWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'survey' });\n\n\t\tthis.surveyOptions = {\n\t\t\tsurveyType: options.surveyType || 'nps', // 'nps', 'csat', 'ces', 'custom'\n\t\t\tposition: options.position || 'bottom-right', // 'bottom-right', 'bottom-left', 'center', 'bottom'\n\t\t\ttitle: options.title || null,\n\t\t\tdescription: options.description || null,\n\t\t\tlowLabel: options.lowLabel || null,\n\t\t\thighLabel: options.highLabel || null,\n\t\t\tcustomQuestions: options.customQuestions || [],\n\t\t\ttheme: options.theme || 'light',\n\t\t\tonSubmit: options.onSubmit || null,\n\t\t\tonDismiss: options.onDismiss || null,\n\t\t};\n\n\t\tthis.surveyState = {\n\t\t\tscore: null,\n\t\t\tfeedback: '',\n\t\t\tcustomAnswers: {},\n\t\t\tisVisible: false,\n\t\t};\n\t}\n\n\t_render() {\n\t\t// Survey widget doesn't render a trigger button, it's shown programmatically\n\t\tconst container = document.createElement('div');\n\t\tcontainer.className = 'feedback-survey-container';\n\t\tcontainer.style.display = 'none';\n\t\treturn container;\n\t}\n\n\t_attachEvents() {\n\t\t// Events are attached when survey is shown\n\t}\n\n\tshow() {\n\t\tthis._renderSurvey();\n\t\tthis.surveyState.isVisible = true;\n\t\tthis.sdk.eventBus.emit('survey:shown', {\n\t\t\twidget: this,\n\t\t\ttype: this.surveyOptions.surveyType,\n\t\t});\n\t\treturn this;\n\t}\n\n\thide() {\n\t\tthis._closeSurvey();\n\t\treturn this;\n\t}\n\n\t_renderSurvey() {\n\t\t// Remove any existing survey\n\t\tthis._closeSurvey();\n\n\t\tconst config = this._getSurveyConfig();\n\t\tconst positionStyles = this._getPositionStyles();\n\t\tconst themeStyles =\n\t\t\tthis.surveyOptions.theme === 'dark'\n\t\t\t\t? 'background: #1a1a1a; color: #fff;'\n\t\t\t\t: 'background: #fff; color: #1d1d1f;';\n\n\t\t// Create backdrop for center position\n\t\tif (this.surveyOptions.position === 'center') {\n\t\t\tthis.backdropElement = document.createElement('div');\n\t\t\tthis.backdropElement.className = 'feedback-survey-backdrop';\n\t\t\tdocument.body.appendChild(this.backdropElement);\n\t\t\tthis.backdropElement.addEventListener('click', () =>\n\t\t\t\tthis._handleDismiss()\n\t\t\t);\n\t\t}\n\n\t\tthis.surveyElement = document.createElement('div');\n\t\tthis.surveyElement.className = `feedback-survey feedback-survey-${this.surveyOptions.position} theme-${this.surveyOptions.theme}`;\n\t\tthis.surveyElement.style.cssText = `position: fixed; ${positionStyles} z-index: 10000; ${themeStyles} border-radius: 16px; box-shadow: 0 20px 60px rgba(0,0,0,0.3); padding: 24px; min-width: 320px; max-width: 400px; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;`;\n\n\t\tthis.surveyElement.innerHTML = `\n\t\t\t<button class=\"feedback-survey-close\" style=\"position: absolute; top: 12px; right: 12px; background: none; border: none; font-size: 20px; cursor: pointer; color: ${this.surveyOptions.theme === 'dark' ? '#888' : '#86868b'}; line-height: 1;\">&times;</button>\n\t\t\t<h3 class=\"feedback-survey-title\" style=\"margin: 0 0 8px 0; font-size: 18px; font-weight: 600; padding-right: 24px;\">${config.title}</h3>\n\t\t\t<p class=\"feedback-survey-description\" style=\"color: ${this.surveyOptions.theme === 'dark' ? '#aaa' : '#86868b'}; margin: 0 0 20px 0; font-size: 14px;\">${config.description}</p>\n\t\t\t<div class=\"feedback-survey-content\">${config.html}</div>\n\t\t\t<div class=\"feedback-survey-feedback\" style=\"margin-top: 16px;\">\n\t\t\t\t<textarea class=\"feedback-survey-textarea\" placeholder=\"Any additional feedback? (optional)\" style=\"width: 100%; padding: 12px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#333' : '#d2d2d7'}; border-radius: 8px; font-size: 14px; resize: none; height: 80px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#fff'}; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; font-family: inherit; box-sizing: border-box;\"></textarea>\n\t\t\t</div>\n\t\t\t<button class=\"feedback-survey-submit\" style=\"width: 100%; margin-top: 12px; padding: 12px; background: #007aff; color: white; border: none; border-radius: 8px; font-size: 14px; font-weight: 500; cursor: pointer; font-family: inherit;\">Submit</button>\n\t\t`;\n\n\t\tdocument.body.appendChild(this.surveyElement);\n\t\tthis._attachSurveyEvents();\n\n\t\t// Animate in\n\t\trequestAnimationFrame(() => {\n\t\t\tthis.surveyElement.style.opacity = '1';\n\t\t\tthis.surveyElement.style.transform =\n\t\t\t\tthis.surveyOptions.position === 'center'\n\t\t\t\t\t? 'translate(-50%, -50%) scale(1)'\n\t\t\t\t\t: 'translateY(0)';\n\t\t});\n\t}\n\n\t_getSurveyConfig() {\n\t\tconst configs = {\n\t\t\tnps: {\n\t\t\t\ttitle:\n\t\t\t\t\tthis.surveyOptions.title || 'How likely are you to recommend us?',\n\t\t\t\tdescription:\n\t\t\t\t\tthis.surveyOptions.description ||\n\t\t\t\t\t'On a scale of 0-10, how likely are you to recommend our product to a friend or colleague?',\n\t\t\t\thtml: `\n\t\t\t\t\t<div class=\"feedback-survey-nps\" style=\"display: flex; justify-content: space-between; gap: 4px;\">\n\t\t\t\t\t\t${[...Array(11).keys()]\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(n) => `\n\t\t\t\t\t\t\t<button class=\"feedback-survey-nps-btn\" data-score=\"${n}\" style=\"width: 28px; height: 36px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 6px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa'}; cursor: pointer; font-size: 12px; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; transition: all 0.15s;\">${n}</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style=\"display: flex; justify-content: space-between; margin-top: 8px; font-size: 11px; color: ${this.surveyOptions.theme === 'dark' ? '#888' : '#86868b'};\">\n\t\t\t\t\t\t<span>${this.surveyOptions.lowLabel || 'Not likely'}</span>\n\t\t\t\t\t\t<span>${this.surveyOptions.highLabel || 'Very likely'}</span>\n\t\t\t\t\t</div>\n\t\t\t\t`,\n\t\t\t},\n\t\t\tcsat: {\n\t\t\t\ttitle: this.surveyOptions.title || 'How satisfied are you?',\n\t\t\t\tdescription:\n\t\t\t\t\tthis.surveyOptions.description ||\n\t\t\t\t\t'How would you rate your overall satisfaction with our product?',\n\t\t\t\thtml: `\n\t\t\t\t\t<div class=\"feedback-survey-csat\" style=\"display: flex; justify-content: center; gap: 16px;\">\n\t\t\t\t\t\t${['😞', '😕', '😐', '🙂', '😄']\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(emoji, i) => `\n\t\t\t\t\t\t\t<button class=\"feedback-survey-csat-btn\" data-score=\"${i + 1}\" style=\"background: none; border: none; cursor: pointer; font-size: 36px; transition: transform 0.15s; padding: 8px;\">${emoji}</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style=\"display: flex; justify-content: space-between; margin-top: 8px; font-size: 11px; color: ${this.surveyOptions.theme === 'dark' ? '#888' : '#86868b'};\">\n\t\t\t\t\t\t<span>${this.surveyOptions.lowLabel || 'Very dissatisfied'}</span>\n\t\t\t\t\t\t<span>${this.surveyOptions.highLabel || 'Very satisfied'}</span>\n\t\t\t\t\t</div>\n\t\t\t\t`,\n\t\t\t},\n\t\t\tces: {\n\t\t\t\ttitle: this.surveyOptions.title || 'How easy was it?',\n\t\t\t\tdescription:\n\t\t\t\t\tthis.surveyOptions.description ||\n\t\t\t\t\t'How easy was it to accomplish your task today?',\n\t\t\t\thtml: `\n\t\t\t\t\t<div class=\"feedback-survey-ces\" style=\"display: flex; justify-content: space-between; gap: 8px;\">\n\t\t\t\t\t\t${['Very Difficult', 'Difficult', 'Neutral', 'Easy', 'Very Easy']\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(label, i) => `\n\t\t\t\t\t\t\t<button class=\"feedback-survey-ces-btn\" data-score=\"${i + 1}\" style=\"flex: 1; padding: 12px 8px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa'}; cursor: pointer; font-size: 11px; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; transition: all 0.15s;\">${label}</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t</div>\n\t\t\t\t`,\n\t\t\t},\n\t\t\tcustom: {\n\t\t\t\ttitle: this.surveyOptions.title || 'Quick Feedback',\n\t\t\t\tdescription:\n\t\t\t\t\tthis.surveyOptions.description ||\n\t\t\t\t\t'Help us improve by answering a few questions.',\n\t\t\t\thtml: this._renderCustomQuestions(),\n\t\t\t},\n\t\t};\n\n\t\treturn configs[this.surveyOptions.surveyType] || configs.nps;\n\t}\n\n\t_renderCustomQuestions() {\n\t\tif (\n\t\t\t!this.surveyOptions.customQuestions ||\n\t\t\tthis.surveyOptions.customQuestions.length === 0\n\t\t) {\n\t\t\t// Default custom questions\n\t\t\treturn `\n\t\t\t\t<div style=\"margin-bottom: 16px;\">\n\t\t\t\t\t<label style=\"display: block; margin-bottom: 6px; font-size: 13px; font-weight: 500;\">What feature do you use most?</label>\n\t\t\t\t\t<select class=\"feedback-survey-select\" data-question=\"feature\" style=\"width: 100%; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; font-size: 14px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#fff'}; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'};\">\n\t\t\t\t\t\t<option value=\"\">Select a feature</option>\n\t\t\t\t\t\t<option value=\"feedback\">Feedback Collection</option>\n\t\t\t\t\t\t<option value=\"surveys\">Surveys</option>\n\t\t\t\t\t\t<option value=\"analytics\">Analytics</option>\n\t\t\t\t\t\t<option value=\"integrations\">Integrations</option>\n\t\t\t\t\t</select>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<label style=\"display: block; margin-bottom: 6px; font-size: 13px; font-weight: 500;\">How often do you use it?</label>\n\t\t\t\t\t<div class=\"feedback-survey-frequency\" style=\"display: flex; gap: 8px;\">\n\t\t\t\t\t\t${['Daily', 'Weekly', 'Monthly', 'Rarely']\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(freq) => `\n\t\t\t\t\t\t\t<button class=\"feedback-survey-freq-btn\" data-freq=\"${freq}\" style=\"flex: 1; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa'}; cursor: pointer; font-size: 12px; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; transition: all 0.15s;\">${freq}</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\treturn this.surveyOptions.customQuestions\n\t\t\t.map(\n\t\t\t\t(q, index) => `\n\t\t\t<div style=\"margin-bottom: 16px;\">\n\t\t\t\t<label style=\"display: block; margin-bottom: 6px; font-size: 13px; font-weight: 500;\">${q.label}</label>\n\t\t\t\t${this._renderQuestionInput(q, index)}\n\t\t\t</div>\n\t\t`\n\t\t\t)\n\t\t\t.join('');\n\t}\n\n\t_renderQuestionInput(question, index) {\n\t\tswitch (question.type) {\n\t\t\tcase 'select':\n\t\t\t\treturn `\n\t\t\t\t\t<select class=\"feedback-survey-select\" data-question=\"${question.id || index}\" style=\"width: 100%; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; font-size: 14px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#fff'}; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'};\">\n\t\t\t\t\t\t<option value=\"\">${question.placeholder || 'Select an option'}</option>\n\t\t\t\t\t\t${question.options.map((opt) => `<option value=\"${opt.value}\">${opt.label}</option>`).join('')}\n\t\t\t\t\t</select>\n\t\t\t\t`;\n\t\t\tcase 'text':\n\t\t\t\treturn `\n\t\t\t\t\t<input type=\"text\" class=\"feedback-survey-input\" data-question=\"${question.id || index}\" placeholder=\"${question.placeholder || ''}\" style=\"width: 100%; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; font-size: 14px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#fff'}; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; box-sizing: border-box;\">\n\t\t\t\t`;\n\t\t\tdefault:\n\t\t\t\treturn '';\n\t\t}\n\t}\n\n\t_getPositionStyles() {\n\t\tconst positions = {\n\t\t\t'bottom-right':\n\t\t\t\t'bottom: 24px; right: 24px; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;',\n\t\t\t'bottom-left':\n\t\t\t\t'bottom: 24px; left: 24px; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;',\n\t\t\tcenter:\n\t\t\t\t'top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.95); opacity: 0; transition: all 0.3s ease;',\n\t\t\tbottom:\n\t\t\t\t'bottom: 0; left: 0; right: 0; border-radius: 16px 16px 0 0; max-width: none; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;',\n\t\t};\n\t\treturn positions[this.surveyOptions.position] || positions['bottom-right'];\n\t}\n\n\t_attachSurveyEvents() {\n\t\tif (!this.surveyElement) return;\n\n\t\t// Close button\n\t\tconst closeBtn = this.surveyElement.querySelector('.feedback-survey-close');\n\t\tcloseBtn.addEventListener('click', () => this._handleDismiss());\n\n\t\t// Submit button\n\t\tconst submitBtn = this.surveyElement.querySelector(\n\t\t\t'.feedback-survey-submit'\n\t\t);\n\t\tsubmitBtn.addEventListener('click', () => this._handleSubmit());\n\n\t\t// Feedback textarea\n\t\tconst textarea = this.surveyElement.querySelector(\n\t\t\t'.feedback-survey-textarea'\n\t\t);\n\t\ttextarea.addEventListener('input', (e) => {\n\t\t\tthis.surveyState.feedback = e.target.value;\n\t\t});\n\n\t\t// Survey type specific events\n\t\tthis._attachTypeSpecificEvents();\n\n\t\t// Escape key\n\t\tthis._escapeHandler = (e) => {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\tthis._handleDismiss();\n\t\t\t}\n\t\t};\n\t\tdocument.addEventListener('keydown', this._escapeHandler);\n\t}\n\n\t_attachTypeSpecificEvents() {\n\t\tconst type = this.surveyOptions.surveyType;\n\n\t\tif (type === 'nps') {\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-nps-btn')\n\t\t\t\t.forEach((btn) => {\n\t\t\t\t\tbtn.addEventListener('click', () =>\n\t\t\t\t\t\tthis._selectNPS(parseInt(btn.dataset.score))\n\t\t\t\t\t);\n\t\t\t\t\tbtn.addEventListener('mouseenter', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tbtn.addEventListener('mouseleave', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t}\n\n\t\tif (type === 'csat') {\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-csat-btn')\n\t\t\t\t.forEach((btn) => {\n\t\t\t\t\tbtn.addEventListener('click', () =>\n\t\t\t\t\t\tthis._selectCSAT(parseInt(btn.dataset.score))\n\t\t\t\t\t);\n\t\t\t\t\tbtn.addEventListener('mouseenter', () => {\n\t\t\t\t\t\tbtn.style.transform = 'scale(1.1)';\n\t\t\t\t\t});\n\t\t\t\t\tbtn.addEventListener('mouseleave', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.transform = 'scale(1)';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t}\n\n\t\tif (type === 'ces') {\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-ces-btn')\n\t\t\t\t.forEach((btn) => {\n\t\t\t\t\tbtn.addEventListener('click', () =>\n\t\t\t\t\t\tthis._selectCES(parseInt(btn.dataset.score))\n\t\t\t\t\t);\n\t\t\t\t\tbtn.addEventListener('mouseenter', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tbtn.addEventListener('mouseleave', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t}\n\n\t\tif (type === 'custom') {\n\t\t\t// Frequency buttons\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-freq-btn')\n\t\t\t\t.forEach((btn) => {\n\t\t\t\t\tbtn.addEventListener('click', () =>\n\t\t\t\t\t\tthis._selectFrequency(btn.dataset.freq)\n\t\t\t\t\t);\n\t\t\t\t});\n\n\t\t\t// Select inputs\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-select')\n\t\t\t\t.forEach((select) => {\n\t\t\t\t\tselect.addEventListener('change', (e) => {\n\t\t\t\t\t\tthis.surveyState.customAnswers[select.dataset.question] =\n\t\t\t\t\t\t\te.target.value;\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t// Text inputs\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-input')\n\t\t\t\t.forEach((input) => {\n\t\t\t\t\tinput.addEventListener('input', (e) => {\n\t\t\t\t\t\tthis.surveyState.customAnswers[input.dataset.question] =\n\t\t\t\t\t\t\te.target.value;\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t}\n\t}\n\n\t_selectNPS(score) {\n\t\tthis.surveyState.score = score;\n\t\tthis.surveyElement\n\t\t\t.querySelectorAll('.feedback-survey-nps-btn')\n\t\t\t.forEach((btn) => {\n\t\t\t\tconst btnScore = parseInt(btn.dataset.score);\n\t\t\t\tif (btnScore === score) {\n\t\t\t\t\tbtn.style.background = '#007aff';\n\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\tbtn.style.color = '#fff';\n\t\t\t\t} else {\n\t\t\t\t\tbtn.style.background =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';\n\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\tbtn.style.color =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\t_selectCSAT(score) {\n\t\tthis.surveyState.score = score;\n\t\tthis.surveyElement\n\t\t\t.querySelectorAll('.feedback-survey-csat-btn')\n\t\t\t.forEach((btn) => {\n\t\t\t\tconst btnScore = parseInt(btn.dataset.score);\n\t\t\t\tbtn.style.transform = btnScore === score ? 'scale(1.2)' : 'scale(1)';\n\t\t\t});\n\t}\n\n\t_selectCES(score) {\n\t\tthis.surveyState.score = score;\n\t\tthis.surveyElement\n\t\t\t.querySelectorAll('.feedback-survey-ces-btn')\n\t\t\t.forEach((btn) => {\n\t\t\t\tconst btnScore = parseInt(btn.dataset.score);\n\t\t\t\tif (btnScore === score) {\n\t\t\t\t\tbtn.style.background = '#007aff';\n\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\tbtn.style.color = '#fff';\n\t\t\t\t} else {\n\t\t\t\t\tbtn.style.background =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';\n\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\tbtn.style.color =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\t_selectFrequency(freq) {\n\t\tthis.surveyState.customAnswers.frequency = freq;\n\t\tthis.surveyElement\n\t\t\t.querySelectorAll('.feedback-survey-freq-btn')\n\t\t\t.forEach((btn) => {\n\t\t\t\tif (btn.dataset.freq === freq) {\n\t\t\t\t\tbtn.style.background = '#007aff';\n\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\tbtn.style.color = '#fff';\n\t\t\t\t} else {\n\t\t\t\t\tbtn.style.background =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';\n\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\tbtn.style.color =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\tasync _handleSubmit() {\n\t\tconst type = this.surveyOptions.surveyType;\n\n\t\t// Validate\n\t\tif (\n\t\t\t(type === 'nps' || type === 'csat' || type === 'ces') &&\n\t\t\tthis.surveyState.score === null\n\t\t) {\n\t\t\tthis._showError('Please select a rating');\n\t\t\treturn;\n\t\t}\n\n\t\tconst response = {\n\t\t\ttype: type,\n\t\t\tscore: this.surveyState.score,\n\t\t\tfeedback: this.surveyState.feedback,\n\t\t\tcustomAnswers: this.surveyState.customAnswers,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\n\t\t// Call onSubmit callback if provided\n\t\tif (this.surveyOptions.onSubmit) {\n\t\t\tthis.surveyOptions.onSubmit(response);\n\t\t}\n\n\t\t// Submit to API if not in mock mode\n\t\tif (!this.sdk.config.mock) {\n\t\t\ttry {\n\t\t\t\tawait this.apiService.submitSurveyResponse(response);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[SurveyWidget] Failed to submit survey:', error);\n\t\t\t}\n\t\t}\n\n\t\tthis.sdk.eventBus.emit('survey:submitted', { widget: this, response });\n\n\t\tthis._closeSurvey();\n\t\tthis._showSuccessNotification();\n\t}\n\n\t_handleDismiss() {\n\t\tif (this.surveyOptions.onDismiss) {\n\t\t\tthis.surveyOptions.onDismiss();\n\t\t}\n\t\tthis.sdk.eventBus.emit('survey:dismissed', { widget: this });\n\t\tthis._closeSurvey();\n\t}\n\n\t_showError(message) {\n\t\t// Simple error display - could be enhanced\n\t\tconst existing = this.surveyElement.querySelector('.feedback-survey-error');\n\t\tif (existing) existing.remove();\n\n\t\tconst error = document.createElement('div');\n\t\terror.className = 'feedback-survey-error';\n\t\terror.style.cssText =\n\t\t\t'color: #ef4444; font-size: 13px; margin-top: 8px; text-align: center;';\n\t\terror.textContent = message;\n\n\t\tconst submitBtn = this.surveyElement.querySelector(\n\t\t\t'.feedback-survey-submit'\n\t\t);\n\t\tsubmitBtn.parentNode.insertBefore(error, submitBtn);\n\n\t\tsetTimeout(() => error.remove(), 3000);\n\t}\n\n\t_showSuccessNotification() {\n\t\tconst notification = document.createElement('div');\n\t\tnotification.className = 'feedback-survey-success';\n\t\tnotification.style.cssText = `\n\t\t\tposition: fixed;\n\t\t\ttop: 24px;\n\t\t\tright: 24px;\n\t\t\tbackground: #10b981;\n\t\t\tcolor: white;\n\t\t\tpadding: 16px 24px;\n\t\t\tborder-radius: 12px;\n\t\t\tfont-size: 14px;\n\t\t\tfont-weight: 500;\n\t\t\tz-index: 10001;\n\t\t\tbox-shadow: 0 10px 40px rgba(0,0,0,0.2);\n\t\t\tfont-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n\t\t`;\n\t\tnotification.innerHTML = `\n\t\t\t<div style=\"display: flex; align-items: center; gap: 8px;\">\n\t\t\t\t<span style=\"font-size: 18px;\">✓</span>\n\t\t\t\t<span>Thank you for your feedback!</span>\n\t\t\t</div>\n\t\t`;\n\t\tdocument.body.appendChild(notification);\n\n\t\tsetTimeout(() => {\n\t\t\tnotification.style.opacity = '0';\n\t\t\tnotification.style.transition = 'opacity 0.3s ease';\n\t\t\tsetTimeout(() => notification.remove(), 300);\n\t\t}, 3000);\n\t}\n\n\t_closeSurvey() {\n\t\tif (this._escapeHandler) {\n\t\t\tdocument.removeEventListener('keydown', this._escapeHandler);\n\t\t\tthis._escapeHandler = null;\n\t\t}\n\n\t\t// Capture references to avoid race conditions with setTimeout\n\t\tconst surveyEl = this.surveyElement;\n\t\tconst backdropEl = this.backdropElement;\n\n\t\tif (surveyEl) {\n\t\t\tsurveyEl.style.opacity = '0';\n\t\t\tsurveyEl.style.transform =\n\t\t\t\tthis.surveyOptions.position === 'center'\n\t\t\t\t\t? 'translate(-50%, -50%) scale(0.95)'\n\t\t\t\t\t: 'translateY(20px)';\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (surveyEl && surveyEl.parentNode) {\n\t\t\t\t\tsurveyEl.parentNode.removeChild(surveyEl);\n\t\t\t\t}\n\t\t\t}, 300);\n\t\t\tthis.surveyElement = null;\n\t\t}\n\n\t\tif (backdropEl) {\n\t\t\tbackdropEl.style.opacity = '0';\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (backdropEl && backdropEl.parentNode) {\n\t\t\t\t\tbackdropEl.parentNode.removeChild(backdropEl);\n\t\t\t\t}\n\t\t\t}, 300);\n\t\t\tthis.backdropElement = null;\n\t\t}\n\n\t\tthis.surveyState = {\n\t\t\tscore: null,\n\t\t\tfeedback: '',\n\t\t\tcustomAnswers: {},\n\t\t\tisVisible: false,\n\t\t};\n\t}\n\n\tdestroy() {\n\t\tthis._closeSurvey();\n\t\tsuper.destroy();\n\t}\n}\n","import { BaseWidget } from './BaseWidget.js';\n\nexport class TabWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'tab' });\n\t}\n\n\t_render() {\n\t\tconst tab = document.createElement('div');\n\t\ttab.className = `feedback-widget feedback-widget-tab theme-${this.options.theme} position-${this.options.position}`;\n\t\ttab.innerHTML = `\n <div class=\"feedback-tab-trigger\">\n <span class=\"feedback-tab-text\">Feedback</span>\n </div>\n `;\n\n\t\tif (this.options.customStyles) {\n\t\t\tObject.assign(tab.style, this.options.customStyles);\n\t\t}\n\n\t\treturn tab;\n\t}\n\n\t_attachEvents() {\n\t\tconst tab = this.element.querySelector('.feedback-tab-trigger');\n\t\ttab.addEventListener('click', this.openModal);\n\n\t\ttab.addEventListener('mouseenter', () => {\n\t\t\tif (!this.state.isSubmitting) {\n\t\t\t\ttab.style.transform = this._getHoverTransform();\n\t\t\t}\n\t\t});\n\n\t\ttab.addEventListener('mouseleave', () => {\n\t\t\ttab.style.transform = 'none';\n\t\t});\n\t}\n\n\t_getHoverTransform() {\n\t\tconst position = this.options.position;\n\t\tif (position.includes('right')) {\n\t\t\treturn 'translateX(-5px)';\n\t\t} else if (position.includes('left')) {\n\t\t\treturn 'translateX(5px)';\n\t\t}\n\t\treturn 'none';\n\t}\n\n\tupdateText(text) {\n\t\tconst textElement = this.element?.querySelector('.feedback-tab-text');\n\t\tif (textElement) {\n\t\t\ttextElement.textContent = text;\n\t\t}\n\t}\n\n\tupdatePosition(position) {\n\t\tthis.options.position = position;\n\t\tif (this.element) {\n\t\t\tthis.element.className = this.element.className.replace(\n\t\t\t\t/position-\\w+-\\w+/,\n\t\t\t\t`position-${position}`\n\t\t\t);\n\t\t}\n\t}\n}\n","import { SDKError } from '../utils/errors.js';\nimport { ButtonWidget } from './ButtonWidget.js';\nimport { InlineWidget } from './InlineWidget.js';\nimport { SurveyWidget } from './SurveyWidget.js';\nimport { TabWidget } from './TabWidget.js';\n\nexport class WidgetFactory {\n\tstatic widgets = new Map([\n\t\t['button', ButtonWidget],\n\t\t['tab', TabWidget],\n\t\t['inline', InlineWidget],\n\t\t['survey', SurveyWidget],\n\t]);\n\n\tstatic register(type, WidgetClass) {\n\t\tif (typeof type !== 'string' || !type.trim()) {\n\t\t\tthrow new SDKError('Widget type must be a non-empty string');\n\t\t}\n\n\t\tif (typeof WidgetClass !== 'function') {\n\t\t\tthrow new SDKError('Widget class must be a constructor function');\n\t\t}\n\n\t\tthis.widgets.set(type, WidgetClass);\n\t}\n\n\tstatic create(type, options = {}) {\n\t\tconst WidgetClass = this.widgets.get(type);\n\n\t\tif (!WidgetClass) {\n\t\t\tconst availableTypes = Array.from(this.widgets.keys()).join(', ');\n\t\t\tthrow new SDKError(\n\t\t\t\t`Unknown widget type: ${type}. Available types: ${availableTypes}`\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\treturn new WidgetClass(options);\n\t\t} catch (error) {\n\t\t\tthrow new SDKError(\n\t\t\t\t`Failed to create widget of type '${type}': ${error.message}`,\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t}\n\n\tstatic getAvailableTypes() {\n\t\treturn Array.from(this.widgets.keys());\n\t}\n\n\tstatic isTypeRegistered(type) {\n\t\treturn this.widgets.has(type);\n\t}\n\n\tstatic unregister(type) {\n\t\treturn this.widgets.delete(type);\n\t}\n\n\tstatic clear() {\n\t\tthis.widgets.clear();\n\t}\n\n\tstatic getWidgetClass(type) {\n\t\treturn this.widgets.get(type);\n\t}\n}\n","import { ConfigError, SDKError } from '../utils/errors.js';\nimport { deepMerge, generateId } from '../utils/helpers.js';\nimport { WidgetFactory } from '../widgets/WidgetFactory.js';\nimport { APIService } from './APIService.js';\nimport { EventBus } from './EventBus.js';\n\nexport class FeedbackSDK {\n\tconstructor(config = {}) {\n\t\tthis.config = this._validateAndMergeConfig(config);\n\t\tthis.initialized = false;\n\t\tthis.widgets = new Map();\n\t\tthis.eventBus = new EventBus();\n\n\t\tthis.apiService = new APIService({\n\t\t\tapiUrl: this.config.apiUrl,\n\t\t\tworkspace: this.config.workspace,\n\t\t\tuserContext: this.config.userContext,\n\t\t\tmock: this.config.mock,\n\t\t\tenv: this.config.env,\n\t\t});\n\n\t\tthis._bindMethods();\n\t}\n\n\tasync init() {\n\t\tif (this.initialized) {\n\t\t\treturn { alreadyInitialized: true };\n\t\t}\n\n\t\ttry {\n\t\t\tconst initData = await this.apiService.init(this.config.userContext);\n\n\t\t\t// Merge backend config as base, local config overrides\n\t\t\tif (initData.config) {\n\t\t\t\tthis.config = deepMerge(initData.config, this.config);\n\t\t\t}\n\n\t\t\tthis.initialized = true;\n\t\t\tthis.eventBus.emit('sdk:initialized', {\n\t\t\t\tconfig: this.config,\n\t\t\t\tsessionToken: initData.sessionToken,\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tinitialized: true,\n\t\t\t\tconfig: initData.config || {},\n\t\t\t\tsessionToken: initData.sessionToken,\n\t\t\t\texpiresIn: initData.expiresIn,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthis.eventBus.emit('sdk:error', { error });\n\t\t\tthrow new SDKError(`Failed to initialize SDK: ${error.message}`, error);\n\t\t}\n\t}\n\n\tcreateWidget(type = 'button', options = {}) {\n\t\tif (!this.initialized) {\n\t\t\tthrow new SDKError(\n\t\t\t\t'SDK must be initialized before creating widgets. Call init() first.'\n\t\t\t);\n\t\t}\n\n\t\tconst widgetId = generateId('widget');\n\t\tconst widgetOptions = {\n\t\t\tid: widgetId,\n\t\t\tsdk: this,\n\t\t\tapiService: this.apiService,\n\t\t\t...this.config,\n\t\t\t...options,\n\t\t};\n\n\t\ttry {\n\t\t\tconst widget = WidgetFactory.create(type, widgetOptions);\n\t\t\tthis.widgets.set(widgetId, widget);\n\t\t\tthis.eventBus.emit('widget:created', { widget, type });\n\t\t\treturn widget;\n\t\t} catch (error) {\n\t\t\tthrow new SDKError(`Failed to create widget: ${error.message}`, error);\n\t\t}\n\t}\n\n\tgetWidget(id) {\n\t\treturn this.widgets.get(id);\n\t}\n\n\t/**\n\t * Show a survey widget\n\t * @param {Object} options - Survey options\n\t * @param {string} options.surveyType - Type of survey: 'nps', 'csat', 'ces', 'custom'\n\t * @param {string} options.position - Position: 'bottom-right', 'bottom-left', 'center', 'bottom'\n\t * @param {string} options.theme - Theme: 'light', 'dark'\n\t * @param {string} options.title - Custom title\n\t * @param {string} options.description - Custom description\n\t * @param {string} options.lowLabel - Low end label\n\t * @param {string} options.highLabel - High end label\n\t * @param {Function} options.onSubmit - Callback when survey is submitted\n\t * @param {Function} options.onDismiss - Callback when survey is dismissed\n\t * @returns {SurveyWidget} The survey widget instance\n\t */\n\tshowSurvey(options = {}) {\n\t\tif (!this.initialized) {\n\t\t\tthrow new SDKError(\n\t\t\t\t'SDK must be initialized before showing surveys. Call init() first.'\n\t\t\t);\n\t\t}\n\n\t\tconst surveyWidget = this.createWidget('survey', {\n\t\t\tsurveyType: options.surveyType || options.type || 'nps',\n\t\t\tposition: options.position || 'bottom-right',\n\t\t\ttheme: options.theme || this.config.theme || 'light',\n\t\t\ttitle: options.title,\n\t\t\tdescription: options.description,\n\t\t\tlowLabel: options.lowLabel,\n\t\t\thighLabel: options.highLabel,\n\t\t\tcustomQuestions: options.customQuestions,\n\t\t\tonSubmit: options.onSubmit,\n\t\t\tonDismiss: options.onDismiss,\n\t\t});\n\n\t\tsurveyWidget.mount();\n\t\tsurveyWidget.show();\n\n\t\treturn surveyWidget;\n\t}\n\n\tgetAllWidgets() {\n\t\treturn Array.from(this.widgets.values());\n\t}\n\n\tdestroyWidget(id) {\n\t\tconst widget = this.widgets.get(id);\n\t\tif (widget) {\n\t\t\twidget.destroy();\n\t\t\tthis.widgets.delete(id);\n\t\t\tthis.eventBus.emit('widget:removed', { widgetId: id });\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tdestroyAllWidgets() {\n\t\tfor (const widget of this.widgets.values()) {\n\t\t\twidget.destroy();\n\t\t}\n\t\tthis.widgets.clear();\n\t\tthis.eventBus.emit('widgets:cleared');\n\t}\n\n\tupdateConfig(newConfig) {\n\t\tconst oldConfig = { ...this.config };\n\t\tthis.config = this._validateAndMergeConfig(newConfig, this.config);\n\n\t\tfor (const widget of this.widgets.values()) {\n\t\t\twidget.handleConfigUpdate(this.config);\n\t\t}\n\n\t\tthis.eventBus.emit('config:updated', {\n\t\t\toldConfig,\n\t\t\tnewConfig: this.config,\n\t\t});\n\t}\n\n\tsetUserContext(userContext) {\n\t\tthis.config.userContext = userContext;\n\t\tif (this.apiService) {\n\t\t\tthis.apiService.setUserContext(userContext);\n\t\t}\n\t\tthis.eventBus.emit('user:updated', { userContext });\n\t}\n\n\tgetUserContext() {\n\t\treturn (\n\t\t\tthis.config.userContext ||\n\t\t\t(this.apiService ? this.apiService.getUserContext() : null)\n\t\t);\n\t}\n\n\tasync reinitialize(newUserContext = null) {\n\t\tthis.apiService.clearSession();\n\t\tthis.initialized = false;\n\n\t\tif (newUserContext) {\n\t\t\tthis.setUserContext(newUserContext);\n\t\t}\n\n\t\treturn this.init();\n\t}\n\n\ton(event, callback) {\n\t\tthis.eventBus.on(event, callback);\n\t\treturn this;\n\t}\n\n\toff(event, callback) {\n\t\tthis.eventBus.off(event, callback);\n\t\treturn this;\n\t}\n\n\tonce(event, callback) {\n\t\tthis.eventBus.once(event, callback);\n\t\treturn this;\n\t}\n\n\temit(event, data) {\n\t\tthis.eventBus.emit(event, data);\n\t\treturn this;\n\t}\n\n\tdestroy() {\n\t\tthis.destroyAllWidgets();\n\t\tthis.eventBus.removeAllListeners();\n\t\tthis.apiService.clearSession();\n\t\tthis.initialized = false;\n\t\tthis.eventBus.emit('sdk:destroyed');\n\t}\n\n\t_validateAndMergeConfig(newConfig, existingConfig = {}) {\n\t\tconst defaultConfig = {\n\t\t\tapiUrl: null,\n\t\t\tworkspace: null,\n\t\t\tuserContext: null,\n\t\t\tposition: 'bottom-right',\n\t\t\ttheme: 'light',\n\t\t\tboardId: 'general',\n\t\t\tautoShow: true,\n\t\t\tdebug: false,\n\t\t\tmock: false,\n\t\t\tenv: 'production', // 'production' or 'staging'\n\t\t};\n\n\t\tconst mergedConfig = deepMerge(\n\t\t\tdeepMerge(defaultConfig, existingConfig),\n\t\t\tnewConfig\n\t\t);\n\n\t\tif (!mergedConfig.workspace) {\n\t\t\tthrow new ConfigError('Missing required configuration: workspace');\n\t\t}\n\n\t\tif (mergedConfig.userContext) {\n\t\t\tthis._validateUserContext(mergedConfig.userContext);\n\t\t}\n\n\t\treturn mergedConfig;\n\t}\n\n\t_validateUserContext(userContext) {\n\t\tif (!userContext.user_id && !userContext.email) {\n\t\t\tthrow new ConfigError(\n\t\t\t\t'User context must include at least user_id or email'\n\t\t\t);\n\t\t}\n\n\t\tconst validStructure = {\n\t\t\tuser_id: 'string',\n\t\t\temail: 'string',\n\t\t\tname: 'string',\n\t\t\tcustom_fields: 'object',\n\t\t\tcompany: 'object',\n\t\t};\n\n\t\tfor (const [key, expectedType] of Object.entries(validStructure)) {\n\t\t\tif (userContext[key] && typeof userContext[key] !== expectedType) {\n\t\t\t\tthrow new ConfigError(\n\t\t\t\t\t`User context field '${key}' must be of type '${expectedType}'`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t_bindMethods() {\n\t\tthis.createWidget = this.createWidget.bind(this);\n\t\tthis.destroyWidget = this.destroyWidget.bind(this);\n\t\tthis.updateConfig = this.updateConfig.bind(this);\n\t}\n\n\tstatic create(config) {\n\t\treturn new FeedbackSDK(config);\n\t}\n\n\tstatic async createAndInit(config) {\n\t\tconst sdk = new FeedbackSDK(config);\n\t\tawait sdk.init();\n\t\treturn sdk;\n\t}\n\n\tstatic extractUserContextFromAuth(authData) {\n\t\tif (!authData) return null;\n\n\t\treturn {\n\t\t\tuser_id: authData.sub || authData.id || authData.user_id,\n\t\t\temail: authData.email,\n\t\t\tname: authData.name || authData.display_name || authData.full_name,\n\t\t\tcustom_fields: {\n\t\t\t\trole: authData.role,\n\t\t\t\tplan: authData.plan || authData.subscription?.plan,\n\t\t\t\t...(authData.custom_fields || {}),\n\t\t\t},\n\t\t\tcompany:\n\t\t\t\tauthData.company || authData.organization\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tid: authData.company?.id || authData.organization?.id,\n\t\t\t\t\t\t\tname: authData.company?.name || authData.organization?.name,\n\t\t\t\t\t\t\tmonthly_spend: authData.company?.monthly_spend,\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t};\n\t}\n}\n","import { APIService } from './core/APIService.js';\nimport { EventBus } from './core/EventBus.js';\nimport { FeedbackSDK } from './core/FeedbackSDK.js';\nimport { CSS_STYLES } from './styles/styles.js';\nimport {\n\tAPIError,\n\tConfigError,\n\tSDKError,\n\tValidationError,\n\tWidgetError,\n} from './utils/errors.js';\nimport * as helpers from './utils/helpers.js';\nimport { BaseWidget } from './widgets/BaseWidget.js';\nimport { ButtonWidget } from './widgets/ButtonWidget.js';\nimport { InlineWidget } from './widgets/InlineWidget.js';\nimport { SurveyWidget } from './widgets/SurveyWidget.js';\nimport { TabWidget } from './widgets/TabWidget.js';\nimport { WidgetFactory } from './widgets/WidgetFactory.js';\n\nfunction injectStyles() {\n\tif (\n\t\ttypeof document !== 'undefined' &&\n\t\t!document.querySelector('#feedback-sdk-styles')\n\t) {\n\t\tconst style = document.createElement('style');\n\t\tstyle.id = 'feedback-sdk-styles';\n\t\tstyle.textContent = CSS_STYLES;\n\t\tdocument.head.appendChild(style);\n\t}\n}\n\nfunction autoInit() {\n\tif (typeof window !== 'undefined' && window.FeedbackSDKConfig) {\n\t\tinjectStyles();\n\n\t\tconst config = { ...window.FeedbackSDKConfig };\n\t\tconst sdk = new FeedbackSDK(config);\n\n\t\tsdk\n\t\t\t.init()\n\t\t\t.then((initData) => {\n\t\t\t\twindow.FeedbackSDK.instance = sdk;\n\n\t\t\t\tif (window.FeedbackSDKConfig.autoCreate) {\n\t\t\t\t\tconst widgets = Array.isArray(window.FeedbackSDKConfig.autoCreate)\n\t\t\t\t\t\t? window.FeedbackSDKConfig.autoCreate\n\t\t\t\t\t\t: [window.FeedbackSDKConfig.autoCreate];\n\n\t\t\t\t\twidgets.forEach((widgetConfig) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst widget = sdk.createWidget(\n\t\t\t\t\t\t\t\twidgetConfig.type || 'button',\n\t\t\t\t\t\t\t\twidgetConfig\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\twidget.mount(widgetConfig.container);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tconsole.error('[FeedbackSDK] Failed to create widget:', error);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif (typeof CustomEvent !== 'undefined') {\n\t\t\t\t\tconst event = new CustomEvent('FeedbackSDKReady', {\n\t\t\t\t\t\tdetail: { sdk, config, initData },\n\t\t\t\t\t});\n\t\t\t\t\twindow.dispatchEvent(event);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error('[FeedbackSDK] Auto-initialization failed:', error);\n\n\t\t\t\tif (typeof CustomEvent !== 'undefined') {\n\t\t\t\t\tconst event = new CustomEvent('FeedbackSDKError', {\n\t\t\t\t\t\tdetail: { error, config, phase: 'initialization' },\n\t\t\t\t\t});\n\t\t\t\t\twindow.dispatchEvent(event);\n\t\t\t\t}\n\t\t\t});\n\t}\n}\n\nfunction handleDOMReady() {\n\tif (typeof document !== 'undefined') {\n\t\tif (document.readyState === 'loading') {\n\t\t\tdocument.addEventListener('DOMContentLoaded', autoInit);\n\t\t} else {\n\t\t\tsetTimeout(autoInit, 0);\n\t\t}\n\t}\n}\n\nconst FeedbackSDKExport = {\n\tFeedbackSDK,\n\tBaseWidget,\n\tButtonWidget,\n\tTabWidget,\n\tInlineWidget,\n\tSurveyWidget,\n\tWidgetFactory,\n\tEventBus,\n\tAPIService,\n\tSDKError,\n\tAPIError,\n\tWidgetError,\n\tConfigError,\n\tValidationError,\n\thelpers,\n\tcreate: (config) => {\n\t\tinjectStyles();\n\t\treturn new FeedbackSDK(config);\n\t},\n\tversion: '1.0.0',\n\tinstance: null,\n\n\tisReady: () => Boolean(FeedbackSDKExport.instance),\n\tgetInstance: () => FeedbackSDKExport.instance,\n\n\tsetUserContext: (userContext) => {\n\t\tif (FeedbackSDKExport.instance) {\n\t\t\tFeedbackSDKExport.instance.setUserContext(userContext);\n\t\t} else {\n\t\t\tif (typeof window !== 'undefined') {\n\t\t\t\twindow.FeedbackSDKUserContext = userContext;\n\t\t\t}\n\t\t}\n\t},\n\n\tinitWithUser: async (config, userContext) => {\n\t\tinjectStyles();\n\t\tconst fullConfig = { ...config, userContext };\n\t\tconst sdk = new FeedbackSDK(fullConfig);\n\t\tawait sdk.init();\n\n\t\tif (typeof window !== 'undefined') {\n\t\t\twindow.FeedbackSDK.instance = sdk;\n\t\t}\n\n\t\treturn sdk;\n\t},\n\n\tonReady: (callback) => {\n\t\tif (typeof window !== 'undefined') {\n\t\t\tif (FeedbackSDKExport.isReady()) {\n\t\t\t\tcallback(FeedbackSDKExport.instance);\n\t\t\t} else {\n\t\t\t\twindow.addEventListener(\n\t\t\t\t\t'FeedbackSDKReady',\n\t\t\t\t\t(event) => {\n\t\t\t\t\t\tcallback(event.detail.sdk, event.detail);\n\t\t\t\t\t},\n\t\t\t\t\t{ once: true }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t},\n\n\tonError: (callback) => {\n\t\tif (typeof window !== 'undefined') {\n\t\t\twindow.addEventListener('FeedbackSDKError', (event) => {\n\t\t\t\tcallback(event.detail.error, event.detail);\n\t\t\t});\n\t\t}\n\t},\n\n\textractUserContext: FeedbackSDK.extractUserContextFromAuth,\n};\n\nif (typeof window !== 'undefined') {\n\twindow.FeedbackSDK = FeedbackSDKExport;\n\thandleDOMReady();\n}\n\nexport default FeedbackSDKExport;\n\nexport {\n\tAPIError,\n\tAPIService,\n\tBaseWidget,\n\tButtonWidget,\n\tConfigError,\n\tEventBus,\n\tFeedbackSDK,\n\thelpers,\n\tInlineWidget,\n\tSDKError,\n\tSurveyWidget,\n\tTabWidget,\n\tValidationError,\n\tWidgetError,\n\tWidgetFactory,\n};\n","export const CSS_STYLES = `\n.feedback-widget {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', Oxygen, Ubuntu, Cantarell, sans-serif;\n font-size: 14px;\n line-height: 1.4;\n z-index: 999999;\n box-sizing: border-box;\n}\n\n.feedback-widget *,\n.feedback-widget *::before,\n.feedback-widget *::after {\n box-sizing: border-box;\n}\n\n.feedback-widget-button {\n position: fixed;\n z-index: 999999;\n}\n\n.feedback-widget-button.position-bottom-right {\n bottom: 20px;\n right: 20px;\n}\n\n.feedback-widget-button.position-bottom-left {\n bottom: 20px;\n left: 20px;\n}\n\n.feedback-widget-button.position-top-right {\n top: 20px;\n right: 20px;\n}\n\n.feedback-widget-button.position-top-left {\n top: 20px;\n left: 20px;\n}\n\n.feedback-trigger-btn {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n height: 44px;\n overflow: hidden;\n border-radius: 0.5rem;\n border: none;\n padding: 10px 16px;\n font-size: 14px;\n font-weight: 500;\n font-family: inherit;\n cursor: pointer;\n transition: all 0.3s ease;\n color: white;\n background: #155EEF;\n box-shadow: 0 1px 2px 0 rgba(16, 24, 40, 0.05);\n}\n\n.feedback-trigger-btn:hover:not(:disabled) {\n background: #004EEB;\n box-shadow: 0 1px 2px 0 rgba(16, 24, 40, 0.1);\n}\n\n.feedback-trigger-btn:disabled {\n opacity: 0.7;\n cursor: not-allowed;\n}\n\n.feedback-trigger-btn:focus-visible {\n outline: 2px solid #155EEF;\n outline-offset: 2px;\n}\n\n/* Side Panel Styles */\n.feedback-panel {\n position: fixed;\n bottom: 80px;\n right: 24px;\n width: 420px;\n max-height: 500px;\n z-index: 1000000;\n transform: translateX(calc(100% + 24px));\n transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);\n font-family: inherit;\n}\n\n.feedback-panel.open {\n transform: translateX(0);\n}\n\n.feedback-panel-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.1);\n opacity: 0;\n transition: opacity 0.3s ease;\n pointer-events: none;\n z-index: 999999;\n}\n\n.feedback-panel-backdrop.show {\n opacity: 1;\n pointer-events: auto;\n}\n\n.feedback-panel-content {\n background: white;\n height: 100%;\n display: flex;\n flex-direction: column;\n border-radius: 16px;\n box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), \n 0 10px 10px -5px rgba(0, 0, 0, 0.04),\n 0 0 0 1px rgba(0, 0, 0, 0.05);\n}\n\n.feedback-panel.theme-dark .feedback-panel-content {\n background: #1F2937;\n color: white;\n}\n\n.feedback-panel-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 24px;\n border-bottom: 1px solid #E5E7EB;\n flex-shrink: 0;\n}\n\n.feedback-panel.theme-dark .feedback-panel-header {\n border-bottom-color: #374151;\n}\n\n.feedback-panel-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: #111827;\n}\n\n.feedback-panel.theme-dark .feedback-panel-header h3 {\n color: white;\n}\n\n.feedback-panel-close {\n background: none;\n border: none;\n font-size: 24px;\n cursor: pointer;\n color: #6B7280;\n padding: 4px;\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 6px;\n transition: all 0.2s ease;\n}\n\n.feedback-panel-close:hover {\n background: #F3F4F6;\n color: #111827;\n}\n\n.feedback-panel-close:focus-visible {\n outline: 2px solid #155EEF;\n outline-offset: 2px;\n}\n\n.feedback-panel.theme-dark .feedback-panel-close {\n color: #9CA3AF;\n}\n\n.feedback-panel.theme-dark .feedback-panel-close:hover {\n background: #374151;\n color: white;\n}\n\n.feedback-panel-body {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n}\n\n.feedback-form {\n display: flex;\n flex-direction: column;\n height: 100%;\n}\n\n.feedback-form-group {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin-bottom: 20px;\n}\n\n.feedback-form-group:last-child {\n margin-bottom: 0;\n}\n\n.feedback-form-group label {\n font-size: 14px;\n font-weight: 500;\n line-height: 1.25;\n color: #374151;\n}\n\n.feedback-panel.theme-dark .feedback-form-group label {\n color: #D1D5DB;\n}\n\n.feedback-form-group input {\n height: 44px;\n width: 100%;\n border-radius: 8px;\n border: 1px solid #D1D5DB;\n padding: 10px 14px;\n font-size: 15px;\n font-weight: 400;\n line-height: 1.5;\n color: #1F2937;\n font-family: inherit;\n outline: none;\n transition: all 0.2s ease;\n}\n\n.feedback-form-group input::placeholder {\n font-size: 15px;\n color: #9CA3AF;\n}\n\n.feedback-form-group input:focus {\n border-color: #155EEF;\n box-shadow: 0 0 0 3px rgba(21, 94, 239, 0.1);\n}\n\n.feedback-form-group input:focus-visible {\n outline: none;\n}\n\n.feedback-form-group textarea {\n min-height: 200px;\n width: 100%;\n resize: vertical;\n border-radius: 8px;\n border: 1px solid #D1D5DB;\n padding: 10px 14px;\n font-size: 15px;\n font-weight: 400;\n line-height: 1.5;\n color: #1F2937;\n font-family: inherit;\n outline: none;\n transition: all 0.2s ease;\n}\n\n.feedback-form-group textarea::placeholder {\n font-size: 15px;\n color: #9CA3AF;\n}\n\n.feedback-form-group textarea:focus {\n border-color: #155EEF;\n box-shadow: 0 0 0 3px rgba(21, 94, 239, 0.1);\n}\n\n.feedback-form-group textarea:focus-visible {\n outline: none;\n}\n\n.feedback-panel.theme-dark .feedback-form-group input,\n.feedback-panel.theme-dark .feedback-form-group textarea {\n background: #374151;\n border-color: #4B5563;\n color: white;\n}\n\n.feedback-panel.theme-dark .feedback-form-group input::placeholder,\n.feedback-panel.theme-dark .feedback-form-group textarea::placeholder {\n color: #6B7280;\n}\n\n.feedback-btn {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n border-radius: 8px;\n border: none;\n height: 44px;\n padding: 10px 18px;\n font-size: 15px;\n font-weight: 500;\n font-family: inherit;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.feedback-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.feedback-btn:focus-visible {\n outline: 2px solid #155EEF;\n outline-offset: 2px;\n}\n\n.feedback-btn-submit {\n background: #155EEF;\n color: white;\n width: 100%;\n}\n\n.feedback-btn-submit:hover:not(:disabled) {\n background: #1A56DB;\n}\n\n.feedback-btn-submit:active:not(:disabled) {\n background: #1E429F;\n}\n\n.feedback-btn-cancel {\n background: transparent;\n color: #6B7280;\n border: 1px solid #D1D5DB;\n}\n\n.feedback-btn-cancel:hover:not(:disabled) {\n background: #F9FAFB;\n border-color: #9CA3AF;\n color: #374151;\n}\n\n.feedback-panel.theme-dark .feedback-btn-cancel {\n color: #D1D5DB;\n border-color: #4B5563;\n}\n\n.feedback-panel.theme-dark .feedback-btn-cancel:hover:not(:disabled) {\n background: #374151;\n}\n\n.feedback-form-actions {\n display: flex;\n flex-direction: column;\n gap: 12px;\n margin-top: auto;\n padding-top: 24px;\n}\n\n.feedback-error {\n color: #DC2626;\n font-size: 14px;\n font-weight: 400;\n margin-top: 8px;\n padding: 12px;\n background: #FEE2E2;\n border: 1px solid #FECACA;\n border-radius: 8px;\n display: none;\n}\n\n.feedback-error.show {\n display: block;\n}\n\n.feedback-panel.theme-dark .feedback-error {\n background: #7F1D1D;\n border-color: #991B1B;\n color: #FCA5A5;\n}\n\n.feedback-success-notification {\n position: fixed;\n top: 24px;\n right: 24px;\n z-index: 1000002;\n background: white;\n border: 1px solid #D1FAE5;\n border-radius: 12px;\n box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n animation: slideInRight 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 320px;\n}\n\n.feedback-success-content {\n display: flex;\n align-items: center;\n padding: 16px 20px;\n gap: 12px;\n}\n\n.feedback-success-icon {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: #10B981;\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 600;\n flex-shrink: 0;\n}\n\n.feedback-success-content span {\n color: #065F46;\n font-weight: 500;\n font-size: 14px;\n flex: 1;\n}\n\n.feedback-success-close {\n background: none;\n border: none;\n color: #6B7280;\n cursor: pointer;\n font-size: 20px;\n padding: 0;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n border-radius: 4px;\n flex-shrink: 0;\n}\n\n.feedback-success-close:hover {\n background: #F3F4F6;\n color: #374151;\n}\n\n.feedback-success-close:focus-visible {\n outline: 2px solid #155EEF;\n outline-offset: 2px;\n}\n\n@keyframes slideInRight {\n from {\n transform: translateX(400px);\n opacity: 0;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.feedback-panel-backdrop {\n animation: fadeIn 0.3s ease;\n}\n\n@media (max-width: 768px) {\n .feedback-panel {\n width: 100%;\n top: auto;\n bottom: 0;\n right: 0;\n left: 0;\n height: 85vh;\n max-height: 85vh;\n transform: translateY(100%);\n border-radius: 20px 20px 0 0;\n }\n \n .feedback-panel.open {\n transform: translateY(0);\n }\n \n .feedback-panel-content {\n border-radius: 20px 20px 0 0;\n }\n \n .feedback-panel-header {\n padding: 20px;\n position: relative;\n }\n \n .feedback-panel-header::before {\n content: '';\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translateX(-50%);\n width: 40px;\n height: 4px;\n background: #D1D5DB;\n border-radius: 2px;\n }\n \n .feedback-panel.theme-dark .feedback-panel-header::before {\n background: #4B5563;\n }\n \n .feedback-panel-body {\n padding: 20px;\n }\n \n .feedback-form-group textarea {\n min-height: 150px;\n }\n \n .feedback-widget-button {\n bottom: 16px;\n right: 16px;\n }\n \n .feedback-widget-button.position-bottom-left {\n left: 16px;\n }\n \n .feedback-success-notification {\n top: 16px;\n right: 16px;\n left: 16px;\n min-width: auto;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .feedback-trigger-btn,\n .feedback-btn,\n .feedback-panel,\n .feedback-panel-backdrop,\n .feedback-success-notification {\n transition: none;\n animation: none;\n }\n}\n\n@media print {\n .feedback-widget,\n .feedback-panel,\n .feedback-panel-backdrop,\n .feedback-success-notification {\n display: none !important;\n }\n}\n`;"],"names":["SDKError","Error","constructor","message","cause","super","this","name","captureStackTrace","APIError","status","response","isNetworkError","isClientError","isServerError","WidgetError","widgetType","widgetId","ConfigError","configKey","ValidationError","field","value","MOCK_CONFIG","primaryColor","backgroundColor","textColor","boardId","size","displayMode","ENV_URLS","production","base","withWorkspace","workspace","staging","APIService","config","sessionToken","sessionExpiry","userContext","mock","env","apiUrl","baseURL","envConfig","_loadStoredSession","init","isSessionValid","error","Date","now","_storeSession","expiresIn","payload","user","_makeRequest","method","body","JSON","stringify","headers","session_token","expires_in","submitFeedback","feedbackData","Promise","resolve","setTimeout","success","data","id","title","content","board","board_id","attachments","Authorization","setUserContext","localStorage","setItem","getUserContext","clearSession","removeItem","sessionData","token","expiry","toISOString","stored","getItem","parse","endpoint","options","url","fetch","ok","errorMessage","responseData","json","e","text","contentType","get","includes","EventBus","events","Map","on","event","callback","has","set","push","off","callbacks","index","indexOf","splice","emit","forEach","console","once","unsubscribe","clear","getListenerCount","length","generateId","prefix","Math","random","toString","substring","deepMerge","target","source","result","key","hasOwnProperty","Array","isArray","isBrowser","window","document","func","wait","timeout","args","clearTimeout","ms","string","replace","bytes","i","floor","log","parseFloat","pow","toFixed","userAgent","navigator","platform","language","userLanguage","cookieEnabled","screenResolution","screen","width","height","windowSize","innerWidth","innerHeight","timezone","Intl","DateTimeFormat","resolvedOptions","timeZone","element","property","fallback","getComputedStyle","getPropertyValue","obj","path","defaultValue","undefined","keys","split","current","rect","getBoundingClientRect","top","left","bottom","documentElement","clientHeight","right","clientWidth","test","email","trim","str","div","createElement","textContent","innerHTML","scrollIntoView","behavior","block","inline","lastKey","pop","limit","lastFunc","lastRan","required","missing","join","BaseWidget","sdk","apiService","type","container","position","autoShow","showBackdrop","customStyles","panelElement","backdropElement","mounted","destroyed","state","isOpen","isLoading","isSubmitting","errors","_bindMethods","mount","querySelector","_render","appendChild","_attachEvents","onMount","show","eventBus","widget","style","display","hide","openPanel","_showLoadingModal","_hideLoadingModal","_renderPanel","requestAnimationFrame","classList","add","className","loadingElement","theme","remove","closePanel","parentNode","removeChild","_resetForm","_hideError","_updateSubmitButton","_showError","_showSuccessMessage","feedback","handleConfigUpdate","newConfig","_updateTheme","destroy","onDestroy","bind","addEventListener","modeClass","sizeClass","setProperty","_getPanelHTML","_attachPanelEvents","firstInput","focus","panel","preventDefault","handleEscape","removeEventListener","submitBtn","disabled","errorElement","notification","closeNotification","opacity","openModal","closeModal","ButtonWidget","button","Object","assign","transform","updateText","textNode","childNodes","nodeType","Node","TEXT_NODE","updatePosition","InlineWidget","form","textarea","originalContent","updateTitle","titleElement","setPlaceholder","placeholder","input","SurveyWidget","surveyOptions","surveyType","description","lowLabel","highLabel","customQuestions","onSubmit","onDismiss","surveyState","score","customAnswers","isVisible","_renderSurvey","_closeSurvey","_getSurveyConfig","positionStyles","_getPositionStyles","themeStyles","_handleDismiss","surveyElement","cssText","html","_attachSurveyEvents","configs","nps","map","n","csat","emoji","ces","label","custom","_renderCustomQuestions","q","_renderQuestionInput","freq","question","opt","positions","center","_handleSubmit","_attachTypeSpecificEvents","_escapeHandler","querySelectorAll","btn","_selectNPS","parseInt","dataset","borderColor","_selectCSAT","_selectCES","_selectFrequency","select","background","color","btnScore","frequency","timestamp","submitSurveyResponse","_showSuccessNotification","existing","insertBefore","transition","surveyEl","backdropEl","TabWidget","tab","_getHoverTransform","textElement","WidgetFactory","static","register","WidgetClass","widgets","create","availableTypes","from","getAvailableTypes","isTypeRegistered","unregister","delete","getWidgetClass","FeedbackSDK","_validateAndMergeConfig","initialized","alreadyInitialized","initData","createWidget","widgetOptions","getWidget","showSurvey","surveyWidget","getAllWidgets","values","destroyWidget","destroyAllWidgets","updateConfig","oldConfig","reinitialize","newUserContext","removeAllListeners","existingConfig","mergedConfig","debug","_validateUserContext","user_id","validStructure","custom_fields","company","expectedType","entries","createAndInit","extractUserContextFromAuth","authData","sub","display_name","full_name","role","plan","subscription","organization","monthly_spend","injectStyles","head","autoInit","FeedbackSDKConfig","then","instance","autoCreate","widgetConfig","CustomEvent","detail","dispatchEvent","catch","phase","FeedbackSDKExport","helpers","version","isReady","Boolean","getInstance","FeedbackSDKUserContext","initWithUser","async","fullConfig","onReady","onError","extractUserContext","readyState"],"mappings":"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"}
1
+ {"version":3,"file":"feedback-sdk.min.js","sources":["../src/utils/errors.js","../src/core/APIService.js","../src/core/EventBus.js","../src/utils/helpers.js","../src/widgets/BaseWidget.js","../src/widgets/ButtonWidget.js","../src/widgets/InlineWidget.js","../src/widgets/messenger/MessengerState.js","../src/widgets/messenger/components/MessengerLauncher.js","../src/widgets/messenger/components/NavigationTabs.js","../src/widgets/messenger/components/MessengerPanel.js","../src/widgets/messenger/views/ChangelogView.js","../src/widgets/messenger/views/ChatView.js","../src/widgets/messenger/views/ConversationsView.js","../src/widgets/messenger/views/HelpView.js","../src/widgets/messenger/views/HomeView.js","../src/widgets/MessengerWidget.js","../src/widgets/SurveyWidget.js","../src/widgets/TabWidget.js","../src/widgets/WidgetFactory.js","../src/core/FeedbackSDK.js","../src/index.js"],"sourcesContent":["export class SDKError extends Error {\n\tconstructor(message, cause) {\n\t\tsuper(message);\n\t\tthis.name = 'SDKError';\n\t\tthis.cause = cause;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, SDKError);\n\t\t}\n\t}\n}\n\nexport class APIError extends Error {\n\tconstructor(status, message, response) {\n\t\tsuper(message);\n\t\tthis.name = 'APIError';\n\t\tthis.status = status;\n\t\tthis.response = response;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, APIError);\n\t\t}\n\t}\n\n\tisNetworkError() {\n\t\treturn this.status === 0;\n\t}\n\n\tisClientError() {\n\t\treturn this.status >= 400 && this.status < 500;\n\t}\n\n\tisServerError() {\n\t\treturn this.status >= 500 && this.status < 600;\n\t}\n}\n\nexport class WidgetError extends Error {\n\tconstructor(message, widgetType, widgetId) {\n\t\tsuper(message);\n\t\tthis.name = 'WidgetError';\n\t\tthis.widgetType = widgetType;\n\t\tthis.widgetId = widgetId;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, WidgetError);\n\t\t}\n\t}\n}\n\nexport class ConfigError extends Error {\n\tconstructor(message, configKey) {\n\t\tsuper(message);\n\t\tthis.name = 'ConfigError';\n\t\tthis.configKey = configKey;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, ConfigError);\n\t\t}\n\t}\n}\n\nexport class ValidationError extends Error {\n\tconstructor(message, field, value) {\n\t\tsuper(message);\n\t\tthis.name = 'ValidationError';\n\t\tthis.field = field;\n\t\tthis.value = value;\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, ValidationError);\n\t\t}\n\t}\n}\n\nexport class ErrorHandler {\n\tconstructor(debug = false) {\n\t\tthis.debug = debug;\n\t}\n\n\thandle(error, context = '') {\n\t\tconst errorInfo = {\n\t\t\tname: error.name,\n\t\t\tmessage: error.message,\n\t\t\tcontext,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\n\t\tif (error instanceof APIError) {\n\t\t\terrorInfo.status = error.status;\n\t\t\terrorInfo.type = 'api';\n\t\t} else if (error instanceof WidgetError) {\n\t\t\terrorInfo.widgetType = error.widgetType;\n\t\t\terrorInfo.widgetId = error.widgetId;\n\t\t\terrorInfo.type = 'widget';\n\t\t} else if (error instanceof ConfigError) {\n\t\t\terrorInfo.configKey = error.configKey;\n\t\t\terrorInfo.type = 'config';\n\t\t} else if (error instanceof ValidationError) {\n\t\t\terrorInfo.field = error.field;\n\t\t\terrorInfo.value = error.value;\n\t\t\terrorInfo.type = 'validation';\n\t\t} else {\n\t\t\terrorInfo.type = 'unknown';\n\t\t}\n\n\t\tif (this.debug) {\n\t\t\tconsole.error('[FeedbackSDK Error]', errorInfo, error);\n\t\t} else {\n\t\t\tconsole.error('[FeedbackSDK Error]', error.message);\n\t\t}\n\n\t\treturn errorInfo;\n\t}\n\n\tgetUserMessage(error) {\n\t\tif (error instanceof APIError) {\n\t\t\tif (error.isNetworkError()) {\n\t\t\t\treturn 'Network error. Please check your connection and try again.';\n\t\t\t} else if (error.isClientError()) {\n\t\t\t\treturn 'Invalid request. Please check your input and try again.';\n\t\t\t} else if (error.isServerError()) {\n\t\t\t\treturn 'Server error. Please try again later.';\n\t\t\t}\n\t\t\treturn 'Failed to submit feedback. Please try again.';\n\t\t}\n\n\t\tif (error instanceof ValidationError) {\n\t\t\treturn `Please check your ${error.field}: ${error.message}`;\n\t\t}\n\n\t\tif (error instanceof ConfigError) {\n\t\t\treturn 'Configuration error. Please check your SDK setup.';\n\t\t}\n\n\t\tif (error instanceof WidgetError) {\n\t\t\treturn 'Widget error. Please try refreshing the page.';\n\t\t}\n\n\t\treturn 'An unexpected error occurred. Please try again.';\n\t}\n}\n","import { APIError } from '../utils/errors.js';\n\nconst MOCK_CONFIG = {\n\tprimaryColor: '#21244A',\n\tbackgroundColor: '#ffffff',\n\ttextColor: '#1F2937',\n\tboardId: 'feature-requests',\n\tsize: 'medium',\n\tdisplayMode: 'modal',\n};\n\n// Mock surveys for development\nconst MOCK_SURVEYS = [\n\t{\n\t\tid: 'mock_nps_survey',\n\t\ttype: 'nps',\n\t\ttitle: 'How likely are you to recommend us?',\n\t\tdescription: 'Your feedback helps us improve',\n\t\tlow_label: 'Not likely',\n\t\thigh_label: 'Very likely',\n\t\ttrigger: 'manual',\n\t\tstatus: 'active',\n\t},\n\t{\n\t\tid: 'mock_csat_survey',\n\t\ttype: 'csat',\n\t\ttitle: 'How satisfied are you?',\n\t\tdescription: 'Rate your experience with our product',\n\t\ttrigger: 'manual',\n\t\tstatus: 'active',\n\t},\n\t{\n\t\tid: 'mock_ces_survey',\n\t\ttype: 'ces',\n\t\ttitle: 'How easy was it?',\n\t\tdescription: 'Rate the ease of completing your task',\n\t\tlow_label: 'Very difficult',\n\t\thigh_label: 'Very easy',\n\t\ttrigger: 'manual',\n\t\tstatus: 'active',\n\t},\n];\n\n// Environment URLs\nconst ENV_URLS = {\n\tproduction: {\n\t\tbase: 'https://api.product7.io/api/v1',\n\t\twithWorkspace: (workspace) => `https://${workspace}.api.product7.io/api/v1`,\n\t},\n\tstaging: {\n\t\tbase: 'https://staging.api.product7.io/api/v1',\n\t\twithWorkspace: (workspace) =>\n\t\t\t`https://${workspace}.staging.api.product7.io/api/v1`,\n\t},\n};\n\nexport class APIService {\n\tconstructor(config = {}) {\n\t\tthis.workspace = config.workspace;\n\t\tthis.sessionToken = null;\n\t\tthis.sessionExpiry = null;\n\t\tthis.userContext = config.userContext || null;\n\t\tthis.mock = config.mock || false;\n\t\tthis.env = config.env || 'production';\n\n\t\tif (config.apiUrl) {\n\t\t\tthis.baseURL = config.apiUrl;\n\t\t} else {\n\t\t\tconst envConfig = ENV_URLS[this.env] || ENV_URLS.production;\n\t\t\tthis.baseURL = this.workspace\n\t\t\t\t? envConfig.withWorkspace(this.workspace)\n\t\t\t\t: envConfig.base;\n\t\t}\n\n\t\tthis._loadStoredSession();\n\t}\n\n\tasync init(userContext = null) {\n\t\tif (userContext) {\n\t\t\tthis.userContext = userContext;\n\t\t}\n\n\t\tif (this.isSessionValid()) {\n\t\t\treturn { sessionToken: this.sessionToken };\n\t\t}\n\n\t\tif (!this.userContext || !this.workspace) {\n\t\t\tconst error = `Missing ${!this.workspace ? 'workspace' : 'user context'} for initialization`;\n\t\t\tthrow new APIError(400, error);\n\t\t}\n\n\t\t// Mock mode - return fake session\n\t\tif (this.mock) {\n\t\t\tthis.sessionToken = 'mock_session_' + Date.now();\n\t\t\tthis.sessionExpiry = new Date(Date.now() + 3600 * 1000);\n\t\t\tthis._storeSession();\n\t\t\treturn {\n\t\t\t\tsessionToken: this.sessionToken,\n\t\t\t\tconfig: MOCK_CONFIG,\n\t\t\t\texpiresIn: 3600,\n\t\t\t};\n\t\t}\n\n\t\tconst payload = {\n\t\t\tworkspace: this.workspace,\n\t\t\tuser: this.userContext,\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await this._makeRequest('/widget/init', {\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: JSON.stringify(payload),\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tthis.sessionToken = response.session_token;\n\t\t\tthis.sessionExpiry = new Date(Date.now() + response.expires_in * 1000);\n\t\t\tthis._storeSession();\n\n\t\t\treturn {\n\t\t\t\tsessionToken: this.sessionToken,\n\t\t\t\tconfig: response.config || {},\n\t\t\t\texpiresIn: response.expires_in,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthrow new APIError(\n\t\t\t\terror.status || 500,\n\t\t\t\t`Failed to initialize widget: ${error.message}`,\n\t\t\t\terror.response\n\t\t\t);\n\t\t}\n\t}\n\n\tasync submitFeedback(feedbackData) {\n\t\tif (!this.isSessionValid()) {\n\t\t\tawait this.init();\n\t\t}\n\n\t\tif (!this.sessionToken) {\n\t\t\tthrow new APIError(401, 'No valid session token available');\n\t\t}\n\n\t\t// Mock mode - simulate success\n\t\tif (this.mock) {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 500));\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tid: 'mock_post_' + Date.now(),\n\t\t\t\t\ttitle: feedbackData.title,\n\t\t\t\t\tcontent: feedbackData.content,\n\t\t\t\t},\n\t\t\t\tmessage: 'Feedback submitted successfully!',\n\t\t\t};\n\t\t}\n\n\t\tconst payload = {\n\t\t\tboard:\n\t\t\t\tfeedbackData.board_id || feedbackData.board || feedbackData.boardId,\n\t\t\ttitle: feedbackData.title,\n\t\t\tcontent: feedbackData.content,\n\t\t\tattachments: feedbackData.attachments || [],\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await this._makeRequest('/widget/feedback', {\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: JSON.stringify(payload),\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\tAuthorization: `Bearer ${this.sessionToken}`,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tif (error.status === 401) {\n\t\t\t\tthis.sessionToken = null;\n\t\t\t\tthis.sessionExpiry = null;\n\t\t\t\tawait this.init();\n\t\t\t\treturn this.submitFeedback(feedbackData);\n\t\t\t}\n\n\t\t\tthrow new APIError(\n\t\t\t\terror.status || 500,\n\t\t\t\t`Failed to submit feedback: ${error.message}`,\n\t\t\t\terror.response\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Get active surveys for the current user/context\n\t * @param {Object} context - Optional context overrides for targeting\n\t * @param {string} context.url - Override current URL\n\t * @param {Object} context.userProperties - Additional user properties\n\t * @returns {Promise<Array>} Array of active surveys matching targeting rules\n\t */\n\tasync getActiveSurveys(context = {}) {\n\t\tif (!this.isSessionValid()) {\n\t\t\tawait this.init();\n\t\t}\n\n\t\tif (!this.sessionToken) {\n\t\t\tthrow new APIError(401, 'No valid session token available');\n\t\t}\n\n\t\t// Mock mode - return mock surveys\n\t\tif (this.mock) {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 200));\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: MOCK_SURVEYS,\n\t\t\t};\n\t\t}\n\n\t\ttry {\n\t\t\tconst queryParams = new URLSearchParams();\n\n\t\t\t// Auto-detect current URL or use provided override\n\t\t\tconst currentUrl =\n\t\t\t\tcontext.url ||\n\t\t\t\t(typeof window !== 'undefined' ? window.location.href : '');\n\t\t\tif (currentUrl) {\n\t\t\t\tqueryParams.append('url', currentUrl);\n\t\t\t}\n\n\t\t\t// Auto-detect device info\n\t\t\tconst deviceInfo = this._getDeviceInfo();\n\t\t\tif (deviceInfo.device) queryParams.append('device', deviceInfo.device);\n\t\t\tif (deviceInfo.browser) queryParams.append('browser', deviceInfo.browser);\n\t\t\tif (deviceInfo.os) queryParams.append('os', deviceInfo.os);\n\n\t\t\t// Add user properties if provided\n\t\t\tif (context.userProperties) {\n\t\t\t\tqueryParams.append(\n\t\t\t\t\t'user_properties',\n\t\t\t\t\tJSON.stringify(context.userProperties)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst endpoint = `/widget/surveys/active${queryParams.toString() ? '?' + queryParams.toString() : ''}`;\n\n\t\t\tconst response = await this._makeRequest(endpoint, {\n\t\t\t\tmethod: 'GET',\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${this.sessionToken}`,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tif (error.status === 401) {\n\t\t\t\tthis.sessionToken = null;\n\t\t\t\tthis.sessionExpiry = null;\n\t\t\t\tawait this.init();\n\t\t\t\treturn this.getActiveSurveys(context);\n\t\t\t}\n\n\t\t\tthrow new APIError(\n\t\t\t\terror.status || 500,\n\t\t\t\t`Failed to get active surveys: ${error.message}`,\n\t\t\t\terror.response\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Auto-detect device, browser, and OS info\n\t * @returns {Object} Device info object\n\t */\n\t_getDeviceInfo() {\n\t\tif (typeof navigator === 'undefined') {\n\t\t\treturn { device: null, browser: null, os: null };\n\t\t}\n\n\t\tconst ua = navigator.userAgent;\n\n\t\t// Detect device type\n\t\tlet device = 'desktop';\n\t\tif (/Mobi|Android/i.test(ua)) {\n\t\t\tdevice = /Tablet|iPad/i.test(ua) ? 'tablet' : 'mobile';\n\t\t}\n\n\t\t// Detect browser\n\t\tlet browser = 'unknown';\n\t\tif (ua.includes('Firefox')) browser = 'firefox';\n\t\telse if (ua.includes('Edg')) browser = 'edge';\n\t\telse if (ua.includes('Chrome')) browser = 'chrome';\n\t\telse if (ua.includes('Safari')) browser = 'safari';\n\t\telse if (ua.includes('Opera') || ua.includes('OPR')) browser = 'opera';\n\n\t\t// Detect OS\n\t\tlet os = 'unknown';\n\t\tif (ua.includes('Windows')) os = 'windows';\n\t\telse if (ua.includes('Mac')) os = 'macos';\n\t\telse if (ua.includes('Linux')) os = 'linux';\n\t\telse if (ua.includes('Android')) os = 'android';\n\t\telse if (ua.includes('iPhone') || ua.includes('iPad')) os = 'ios';\n\n\t\treturn { device, browser, os };\n\t}\n\n\t/**\n\t * Submit a survey response\n\t * @param {string} surveyId - The survey ID\n\t * @param {Object} responseData - The survey response data\n\t * @param {number|string} responseData.rating - The rating/score value\n\t * @param {string} responseData.feedback - Optional text feedback\n\t * @param {Object} responseData.answers - For custom surveys, key-value pairs\n\t * @returns {Promise<Object>} Submission result\n\t */\n\tasync submitSurveyResponse(surveyId, responseData) {\n\t\tif (!this.isSessionValid()) {\n\t\t\tawait this.init();\n\t\t}\n\n\t\tif (!this.sessionToken) {\n\t\t\tthrow new APIError(401, 'No valid session token available');\n\t\t}\n\n\t\tif (!surveyId) {\n\t\t\tthrow new APIError(400, 'Survey ID is required');\n\t\t}\n\n\t\t// Mock mode - simulate success\n\t\tif (this.mock) {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 300));\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tdata: {\n\t\t\t\t\tid: 'mock_response_' + Date.now(),\n\t\t\t\t\tsurvey_id: surveyId,\n\t\t\t\t\t...responseData,\n\t\t\t\t},\n\t\t\t\tmessage: 'Survey response submitted successfully!',\n\t\t\t};\n\t\t}\n\n\t\tconst payload = {\n\t\t\trating: responseData.rating,\n\t\t\tfeedback: responseData.feedback || '',\n\t\t\tanswers: responseData.answers || {},\n\t\t};\n\n\t\ttry {\n\t\t\tconst response = await this._makeRequest(\n\t\t\t\t`/widget/surveys/${surveyId}/responses`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\tbody: JSON.stringify(payload),\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\t\tAuthorization: `Bearer ${this.sessionToken}`,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t);\n\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tif (error.status === 401) {\n\t\t\t\tthis.sessionToken = null;\n\t\t\t\tthis.sessionExpiry = null;\n\t\t\t\tawait this.init();\n\t\t\t\treturn this.submitSurveyResponse(surveyId, responseData);\n\t\t\t}\n\n\t\t\tthrow new APIError(\n\t\t\t\terror.status || 500,\n\t\t\t\t`Failed to submit survey response: ${error.message}`,\n\t\t\t\terror.response\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Dismiss a survey (mark as seen but not completed)\n\t * @param {string} surveyId - The survey ID to dismiss\n\t * @returns {Promise<Object>} Dismissal result\n\t */\n\tasync dismissSurvey(surveyId) {\n\t\tif (!this.isSessionValid()) {\n\t\t\tawait this.init();\n\t\t}\n\n\t\tif (!this.sessionToken) {\n\t\t\tthrow new APIError(401, 'No valid session token available');\n\t\t}\n\n\t\tif (!surveyId) {\n\t\t\tthrow new APIError(400, 'Survey ID is required');\n\t\t}\n\n\t\t// Mock mode - simulate success\n\t\tif (this.mock) {\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 100));\n\t\t\treturn {\n\t\t\t\tsuccess: true,\n\t\t\t\tmessage: 'Survey dismissed successfully',\n\t\t\t};\n\t\t}\n\n\t\ttry {\n\t\t\tconst response = await this._makeRequest(\n\t\t\t\t`/widget/surveys/${surveyId}/dismiss`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: {\n\t\t\t\t\t\tAuthorization: `Bearer ${this.sessionToken}`,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t);\n\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tif (error.status === 401) {\n\t\t\t\tthis.sessionToken = null;\n\t\t\t\tthis.sessionExpiry = null;\n\t\t\t\tawait this.init();\n\t\t\t\treturn this.dismissSurvey(surveyId);\n\t\t\t}\n\n\t\t\tthrow new APIError(\n\t\t\t\terror.status || 500,\n\t\t\t\t`Failed to dismiss survey: ${error.message}`,\n\t\t\t\terror.response\n\t\t\t);\n\t\t}\n\t}\n\n\tisSessionValid() {\n\t\treturn (\n\t\t\tthis.sessionToken && this.sessionExpiry && new Date() < this.sessionExpiry\n\t\t);\n\t}\n\n\tsetUserContext(userContext) {\n\t\tthis.userContext = userContext;\n\t\tif (typeof localStorage !== 'undefined') {\n\t\t\tlocalStorage.setItem(\n\t\t\t\t'feedbackSDK_userContext',\n\t\t\t\tJSON.stringify(userContext)\n\t\t\t);\n\t\t}\n\t}\n\n\tgetUserContext() {\n\t\treturn this.userContext;\n\t}\n\n\tclearSession() {\n\t\tthis.sessionToken = null;\n\t\tthis.sessionExpiry = null;\n\t\tif (typeof localStorage !== 'undefined') {\n\t\t\tlocalStorage.removeItem('feedbackSDK_session');\n\t\t\tlocalStorage.removeItem('feedbackSDK_userContext');\n\t\t}\n\t}\n\n\t_storeSession() {\n\t\tif (typeof localStorage === 'undefined') return;\n\n\t\ttry {\n\t\t\tconst sessionData = {\n\t\t\t\ttoken: this.sessionToken,\n\t\t\t\texpiry: this.sessionExpiry.toISOString(),\n\t\t\t\tworkspace: this.workspace,\n\t\t\t};\n\t\t\tlocalStorage.setItem('feedbackSDK_session', JSON.stringify(sessionData));\n\t\t} catch (error) {\n\t\t\t// Silently fail if localStorage is not available\n\t\t}\n\t}\n\n\t_loadStoredSession() {\n\t\tif (typeof localStorage === 'undefined') return false;\n\n\t\ttry {\n\t\t\tconst stored = localStorage.getItem('feedbackSDK_session');\n\t\t\tif (!stored) return false;\n\n\t\t\tconst sessionData = JSON.parse(stored);\n\t\t\tthis.sessionToken = sessionData.token;\n\t\t\tthis.sessionExpiry = new Date(sessionData.expiry);\n\n\t\t\treturn this.isSessionValid();\n\t\t} catch (error) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync _makeRequest(endpoint, options = {}) {\n\t\tconst url = `${this.baseURL}${endpoint}`;\n\n\t\ttry {\n\t\t\tconst response = await fetch(url, options);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlet errorMessage = `HTTP ${response.status}`;\n\t\t\t\tlet responseData = null;\n\n\t\t\t\ttry {\n\t\t\t\t\tresponseData = await response.json();\n\t\t\t\t\terrorMessage =\n\t\t\t\t\t\tresponseData.message || responseData.error || errorMessage;\n\t\t\t\t} catch (e) {\n\t\t\t\t\terrorMessage = (await response.text()) || errorMessage;\n\t\t\t\t}\n\n\t\t\t\tthrow new APIError(response.status, errorMessage, responseData);\n\t\t\t}\n\n\t\t\tconst contentType = response.headers.get('content-type');\n\t\t\tif (contentType && contentType.includes('application/json')) {\n\t\t\t\treturn await response.json();\n\t\t\t}\n\n\t\t\treturn await response.text();\n\t\t} catch (error) {\n\t\t\tif (error instanceof APIError) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tthrow new APIError(0, error.message, null);\n\t\t}\n\t}\n}\n","export class EventBus {\n\tconstructor() {\n\t\tthis.events = new Map();\n\t}\n\n\ton(event, callback) {\n\t\tif (!this.events.has(event)) {\n\t\t\tthis.events.set(event, []);\n\t\t}\n\t\tthis.events.get(event).push(callback);\n\n\t\treturn () => this.off(event, callback);\n\t}\n\n\toff(event, callback) {\n\t\tconst callbacks = this.events.get(event);\n\t\tif (callbacks) {\n\t\t\tconst index = callbacks.indexOf(callback);\n\t\t\tif (index > -1) {\n\t\t\t\tcallbacks.splice(index, 1);\n\t\t\t}\n\t\t}\n\t}\n\n\temit(event, data) {\n\t\tconst callbacks = this.events.get(event);\n\t\tif (callbacks) {\n\t\t\tcallbacks.forEach((callback) => {\n\t\t\t\ttry {\n\t\t\t\t\tcallback(data);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error('[FeedbackSDK] Event callback error:', error);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tonce(event, callback) {\n\t\tconst unsubscribe = this.on(event, (data) => {\n\t\t\tcallback(data);\n\t\t\tunsubscribe();\n\t\t});\n\t\treturn unsubscribe;\n\t}\n\n\tclear() {\n\t\tthis.events.clear();\n\t}\n\n\tgetListenerCount(event) {\n\t\tconst callbacks = this.events.get(event);\n\t\treturn callbacks ? callbacks.length : 0;\n\t}\n}\n","export function generateId(prefix = 'feedback') {\n\tconst timestamp = Date.now();\n\tconst random = Math.random().toString(36).substring(2, 9);\n\treturn `${prefix}_${timestamp}_${random}`;\n}\n\nexport function deepMerge(target, source) {\n\tconst result = { ...target };\n\n\tfor (const key in source) {\n\t\tif (source.hasOwnProperty(key)) {\n\t\t\tif (\n\t\t\t\tsource[key] &&\n\t\t\t\ttypeof source[key] === 'object' &&\n\t\t\t\t!Array.isArray(source[key])\n\t\t\t) {\n\t\t\t\tresult[key] = deepMerge(target[key] || {}, source[key]);\n\t\t\t} else {\n\t\t\t\tresult[key] = source[key];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function debounce(func, wait) {\n\tlet timeout;\n\treturn function executedFunction(...args) {\n\t\tconst later = () => {\n\t\t\tclearTimeout(timeout);\n\t\t\tfunc(...args);\n\t\t};\n\t\tclearTimeout(timeout);\n\t\ttimeout = setTimeout(later, wait);\n\t};\n}\n\nexport function throttle(func, limit) {\n\tlet lastFunc;\n\tlet lastRan;\n\treturn function (...args) {\n\t\tif (!lastRan) {\n\t\t\tfunc(...args);\n\t\t\tlastRan = Date.now();\n\t\t} else {\n\t\t\tclearTimeout(lastFunc);\n\t\t\tlastFunc = setTimeout(\n\t\t\t\t() => {\n\t\t\t\t\tif (Date.now() - lastRan >= limit) {\n\t\t\t\t\t\tfunc(...args);\n\t\t\t\t\t\tlastRan = Date.now();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tlimit - (Date.now() - lastRan)\n\t\t\t);\n\t\t}\n\t};\n}\n\nexport function isValidEmail(email) {\n\tif (!email || typeof email !== 'string') return false;\n\n\tconst emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\treturn emailRegex.test(email.trim());\n}\n\nexport function sanitizeHTML(str) {\n\tif (!str || typeof str !== 'string') return '';\n\n\tconst div = document.createElement('div');\n\tdiv.textContent = str;\n\treturn div.innerHTML;\n}\n\nexport function getCSSProperty(element, property, fallback = '') {\n\tif (!element || !property) return fallback;\n\n\ttry {\n\t\tconst style = window.getComputedStyle(element);\n\t\treturn style.getPropertyValue(property) || fallback;\n\t} catch (error) {\n\t\treturn fallback;\n\t}\n}\n\nexport function isInViewport(element) {\n\tif (!element) return false;\n\n\tconst rect = element.getBoundingClientRect();\n\treturn (\n\t\trect.top >= 0 &&\n\t\trect.left >= 0 &&\n\t\trect.bottom <=\n\t\t\t(window.innerHeight || document.documentElement.clientHeight) &&\n\t\trect.right <= (window.innerWidth || document.documentElement.clientWidth)\n\t);\n}\n\nexport function scrollToElement(element, options = {}) {\n\tif (!element) return;\n\n\tconst defaultOptions = {\n\t\tbehavior: 'smooth',\n\t\tblock: 'center',\n\t\tinline: 'nearest',\n\t};\n\n\telement.scrollIntoView({ ...defaultOptions, ...options });\n}\n\nexport function getBrowserInfo() {\n\tconst userAgent = navigator.userAgent;\n\tconst platform = navigator.platform;\n\n\treturn {\n\t\tuserAgent,\n\t\tplatform,\n\t\tlanguage: navigator.language || navigator.userLanguage,\n\t\tcookieEnabled: navigator.cookieEnabled,\n\t\tscreenResolution: `${screen.width}x${screen.height}`,\n\t\twindowSize: `${window.innerWidth}x${window.innerHeight}`,\n\t\ttimezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n\t};\n}\n\nexport function formatFileSize(bytes) {\n\tif (bytes === 0) return '0 Bytes';\n\n\tconst k = 1024;\n\tconst sizes = ['Bytes', 'KB', 'MB', 'GB'];\n\tconst i = Math.floor(Math.log(bytes) / Math.log(k));\n\n\treturn parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n}\n\nexport function delay(ms) {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function safeJsonParse(str, fallback = null) {\n\ttry {\n\t\treturn JSON.parse(str);\n\t} catch (error) {\n\t\treturn fallback;\n\t}\n}\n\nexport function escapeRegex(string) {\n\treturn string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function getNestedProperty(obj, path, defaultValue = undefined) {\n\tif (!obj || !path) return defaultValue;\n\n\tconst keys = path.split('.');\n\tlet current = obj;\n\n\tfor (const key of keys) {\n\t\tif (current === null || current === undefined || !(key in current)) {\n\t\t\treturn defaultValue;\n\t\t}\n\t\tcurrent = current[key];\n\t}\n\n\treturn current;\n}\n\nexport function setNestedProperty(obj, path, value) {\n\tif (!obj || !path) return obj;\n\n\tconst keys = path.split('.');\n\tconst lastKey = keys.pop();\n\tlet current = obj;\n\n\tfor (const key of keys) {\n\t\tif (!(key in current) || typeof current[key] !== 'object') {\n\t\t\tcurrent[key] = {};\n\t\t}\n\t\tcurrent = current[key];\n\t}\n\n\tcurrent[lastKey] = value;\n\treturn obj;\n}\n\nexport function isBrowser() {\n\treturn typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nexport function isMobile() {\n\tif (!isBrowser()) return false;\n\n\treturn (\n\t\t/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(\n\t\t\tnavigator.userAgent\n\t\t) || window.innerWidth <= 768\n\t);\n}\n\nexport function getCurrentTimestamp() {\n\treturn new Date().toISOString();\n}\n\nexport function validateConfig(config, required = []) {\n\tconst missing = [];\n\n\tfor (const key of required) {\n\t\tif (!config[key]) {\n\t\t\tmissing.push(key);\n\t\t}\n\t}\n\n\tif (missing.length > 0) {\n\t\tthrow new Error(`Missing required configuration: ${missing.join(', ')}`);\n\t}\n\n\treturn true;\n}\n","export class BaseWidget {\n\tconstructor(options = {}) {\n\t\tthis.id = options.id;\n\t\tthis.sdk = options.sdk;\n\t\tthis.apiService = options.apiService;\n\t\tthis.type = options.type || 'base';\n\n\t\tthis.options = {\n\t\t\tcontainer: null,\n\t\t\tposition: this.sdk.config.position,\n\t\t\tboardId: this.sdk.config.boardId,\n\t\t\tdisplayMode: options.displayMode || 'panel',\n\t\t\tsize: options.size || 'medium',\n\t\t\tprimaryColor: options.primaryColor || '#21244A',\n\t\t\tbackgroundColor: options.backgroundColor || '#ffffff',\n\t\t\ttextColor: options.textColor || '#1F2937',\n\t\t\tautoShow: false,\n\t\t\tshowBackdrop: true,\n\t\t\tcustomStyles: {},\n\t\t\t...options,\n\t\t};\n\n\t\tthis.element = null;\n\t\tthis.panelElement = null;\n\t\tthis.backdropElement = null;\n\t\tthis.mounted = false;\n\t\tthis.destroyed = false;\n\n\t\tthis.state = {\n\t\t\tisOpen: false,\n\t\t\tisLoading: false,\n\t\t\tisSubmitting: false,\n\t\t\ttitle: '',\n\t\t\tcontent: '',\n\t\t\temail: '',\n\t\t\tattachments: [],\n\t\t\terrors: {},\n\t\t};\n\n\t\tthis._bindMethods();\n\t}\n\n\tmount(container) {\n\t\tif (this.mounted || this.destroyed) return this;\n\n\t\tif (typeof container === 'string') {\n\t\t\tcontainer = document.querySelector(container);\n\t\t}\n\n\t\tif (!container) {\n\t\t\tcontainer = document.body;\n\t\t}\n\n\t\tthis.container = container;\n\t\tthis.element = this._render();\n\t\tthis.container.appendChild(this.element);\n\n\t\tthis.mounted = true;\n\t\tthis._attachEvents();\n\t\tthis.onMount();\n\n\t\tif (this.options.autoShow) {\n\t\t\tthis.show();\n\t\t}\n\n\t\tthis.sdk.eventBus.emit('widget:mounted', { widget: this });\n\t\treturn this;\n\t}\n\n\tshow() {\n\t\tif (this.element) {\n\t\t\tthis.element.style.display = 'block';\n\t\t}\n\t\treturn this;\n\t}\n\n\thide() {\n\t\tif (this.element) {\n\t\t\tthis.element.style.display = 'none';\n\t\t}\n\t\treturn this;\n\t}\n\n\topenPanel() {\n\t\tthis.state.isOpen = true;\n\n\t\tif (this.options.displayMode === 'modal') {\n\t\t\tthis._showLoadingModal();\n\t\t\t// Simulate loading delay then show form\n\t\t\tsetTimeout(() => {\n\t\t\t\tthis._hideLoadingModal();\n\t\t\t\tthis._renderPanel();\n\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\tif (this.panelElement) {\n\t\t\t\t\t\tthis.panelElement.classList.add('open');\n\t\t\t\t\t}\n\t\t\t\t\tif (this.backdropElement) {\n\t\t\t\t\t\tthis.backdropElement.classList.add('show');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}, 600);\n\t\t} else {\n\t\t\tthis._renderPanel();\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tif (this.panelElement) {\n\t\t\t\t\tthis.panelElement.classList.add('open');\n\t\t\t\t}\n\t\t\t\tif (this.backdropElement) {\n\t\t\t\t\tthis.backdropElement.classList.add('show');\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\t_showLoadingModal() {\n\t\tthis.state.isLoading = true;\n\n\t\t// Create backdrop\n\t\tthis.backdropElement = document.createElement('div');\n\t\tthis.backdropElement.className = 'feedback-panel-backdrop';\n\t\tdocument.body.appendChild(this.backdropElement);\n\n\t\t// Create loading modal\n\t\tthis.loadingElement = document.createElement('div');\n\t\tthis.loadingElement.className = `feedback-loading-modal theme-${this.options.theme}`;\n\t\tthis.loadingElement.innerHTML = `\n\t\t\t<div class=\"feedback-loading-spinner\"></div>\n\t\t`;\n\t\tdocument.body.appendChild(this.loadingElement);\n\n\t\trequestAnimationFrame(() => {\n\t\t\tthis.backdropElement.classList.add('show');\n\t\t\tthis.loadingElement.classList.add('show');\n\t\t});\n\t}\n\n\t_hideLoadingModal() {\n\t\tthis.state.isLoading = false;\n\t\tif (this.loadingElement) {\n\t\t\tthis.loadingElement.remove();\n\t\t\tthis.loadingElement = null;\n\t\t}\n\t}\n\n\tclosePanel() {\n\t\tif (this.panelElement) {\n\t\t\tthis.panelElement.classList.remove('open');\n\t\t}\n\t\tif (this.backdropElement) {\n\t\t\tthis.backdropElement.classList.remove('show');\n\t\t}\n\n\t\tsetTimeout(() => {\n\t\t\tthis.state.isOpen = false;\n\t\t\tif (this.panelElement && this.panelElement.parentNode) {\n\t\t\t\tthis.panelElement.parentNode.removeChild(this.panelElement);\n\t\t\t\tthis.panelElement = null;\n\t\t\t}\n\t\t\tif (this.backdropElement && this.backdropElement.parentNode) {\n\t\t\t\tthis.backdropElement.parentNode.removeChild(this.backdropElement);\n\t\t\t\tthis.backdropElement = null;\n\t\t\t}\n\t\t\tthis._resetForm();\n\t\t}, 300);\n\t}\n\n\tasync submitFeedback() {\n\t\tif (this.state.isSubmitting) return;\n\n\t\tthis._hideError();\n\n\t\ttry {\n\t\t\tthis.state.isSubmitting = true;\n\t\t\tthis._updateSubmitButton();\n\n\t\t\tconst payload = {\n\t\t\t\ttitle: this.state.title || 'Feedback',\n\t\t\t\tcontent: this.state.content,\n\t\t\t\temail: this.state.email,\n\t\t\t\tboard_id: this.options.boardId,\n\t\t\t\tattachments: this.state.attachments,\n\t\t\t};\n\n\t\t\tif (!this.state.content.trim()) {\n\t\t\t\tthis._showError('Please enter your feedback message.');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst response = await this.apiService.submitFeedback(payload);\n\n\t\t\tthis._showSuccessMessage();\n\t\t\tthis.closePanel();\n\n\t\t\tthis.sdk.eventBus.emit('feedback:submitted', {\n\t\t\t\twidget: this,\n\t\t\t\tfeedback: response,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tthis._showError('Failed to submit feedback. Please try again.');\n\t\t\tthis.sdk.eventBus.emit('feedback:error', { widget: this, error });\n\t\t} finally {\n\t\t\tthis.state.isSubmitting = false;\n\t\t\tthis._updateSubmitButton();\n\t\t}\n\t}\n\n\thandleConfigUpdate(newConfig) {\n\t\tthis.options.theme = newConfig.theme;\n\t\tif (this.element) {\n\t\t\tthis._updateTheme();\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this.destroyed) return;\n\n\t\tthis.onDestroy();\n\t\tthis.closePanel();\n\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\n\t\tthis.destroyed = true;\n\t\tthis.mounted = false;\n\t\tthis.sdk.eventBus.emit('widget:destroyed', { widget: this });\n\t}\n\n\tonMount() {}\n\tonDestroy() {}\n\n\t_render() {\n\t\tthrow new Error('_render() must be implemented by concrete widget');\n\t}\n\n\t_attachEvents() {\n\t\t// Override in concrete widgets\n\t}\n\n\t_bindMethods() {\n\t\tthis.openPanel = this.openPanel.bind(this);\n\t\tthis.closePanel = this.closePanel.bind(this);\n\t\tthis.submitFeedback = this.submitFeedback.bind(this);\n\t}\n\n\t_renderPanel() {\n\t\tif (this.panelElement) return;\n\n\t\tif (this.options.showBackdrop && !this.backdropElement) {\n\t\t\tthis.backdropElement = document.createElement('div');\n\t\t\tthis.backdropElement.className = 'feedback-panel-backdrop';\n\t\t\tdocument.body.appendChild(this.backdropElement);\n\n\t\t\tthis.backdropElement.addEventListener('click', this.closePanel);\n\t\t}\n\n\t\tconst modeClass =\n\t\t\tthis.options.displayMode === 'modal'\n\t\t\t\t? 'feedback-modal'\n\t\t\t\t: 'feedback-panel';\n\t\tconst sizeClass = `size-${this.options.size}`;\n\t\tthis.panelElement = document.createElement('div');\n\t\tthis.panelElement.className = `${modeClass} ${sizeClass}`;\n\t\tthis.panelElement.style.setProperty(\n\t\t\t'--primary-color',\n\t\t\tthis.options.primaryColor\n\t\t);\n\t\tthis.panelElement.style.setProperty(\n\t\t\t'--bg-color',\n\t\t\tthis.options.backgroundColor\n\t\t);\n\t\tthis.panelElement.style.setProperty('--text-color', this.options.textColor);\n\t\tthis.panelElement.innerHTML = this._getPanelHTML();\n\n\t\tdocument.body.appendChild(this.panelElement);\n\t\tthis._attachPanelEvents();\n\n\t\tconst firstInput = this.panelElement.querySelector('input, textarea');\n\t\tif (firstInput) {\n\t\t\tsetTimeout(() => firstInput.focus(), 350);\n\t\t}\n\t}\n\n\t_getPanelHTML() {\n\t\treturn `\n <div class=\"feedback-panel-content\">\n <div class=\"feedback-panel-header\">\n <h3>Send Feedback</h3>\n <button class=\"feedback-panel-close\" type=\"button\" aria-label=\"Close\">&times;</button>\n </div>\n <div class=\"feedback-panel-body\">\n <form class=\"feedback-form\">\n <div class=\"feedback-form-group\">\n <label for=\"feedback-title-${this.id}\">Title (optional)</label>\n <input \n type=\"text\" \n id=\"feedback-title-${this.id}\" \n name=\"title\" \n placeholder=\"Brief description of your feedback\"\n value=\"${this.state.title}\"\n />\n </div>\n <div class=\"feedback-form-group\">\n <label for=\"feedback-content-${this.id}\">Message *</label>\n <textarea \n id=\"feedback-content-${this.id}\" \n name=\"content\" \n placeholder=\"Tell us what you think...\"\n required\n >${this.state.content}</textarea>\n </div>\n <div class=\"feedback-error\" role=\"alert\"></div>\n <div class=\"feedback-form-actions\">\n <button type=\"submit\" class=\"feedback-btn feedback-btn-submit\">\n ${this.state.isSubmitting ? 'Sending...' : 'Send Feedback'}\n </button>\n </div>\n </form>\n </div>\n </div>\n `;\n\t}\n\n\t_attachPanelEvents() {\n\t\tconst panel = this.panelElement;\n\n\t\tpanel\n\t\t\t.querySelector('.feedback-panel-close')\n\t\t\t.addEventListener('click', this.closePanel);\n\n\t\tconst form = panel.querySelector('.feedback-form');\n\t\tform.addEventListener('submit', (e) => {\n\t\t\te.preventDefault();\n\t\t\tthis.submitFeedback();\n\t\t});\n\n\t\tpanel\n\t\t\t.querySelector('input[name=\"title\"]')\n\t\t\t.addEventListener('input', (e) => {\n\t\t\t\tthis.state.title = e.target.value;\n\t\t\t});\n\n\t\tpanel\n\t\t\t.querySelector('textarea[name=\"content\"]')\n\t\t\t.addEventListener('input', (e) => {\n\t\t\t\tthis.state.content = e.target.value;\n\t\t\t});\n\n\t\tconst handleEscape = (e) => {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\tthis.closePanel();\n\t\t\t\tdocument.removeEventListener('keydown', handleEscape);\n\t\t\t}\n\t\t};\n\t\tdocument.addEventListener('keydown', handleEscape);\n\t}\n\n\t_updateSubmitButton() {\n\t\tif (this.panelElement) {\n\t\t\tconst submitBtn = this.panelElement.querySelector('.feedback-btn-submit');\n\t\t\tif (submitBtn) {\n\t\t\t\tsubmitBtn.textContent = this.state.isSubmitting\n\t\t\t\t\t? 'Sending...'\n\t\t\t\t\t: 'Send Feedback';\n\t\t\t\tsubmitBtn.disabled = this.state.isSubmitting;\n\t\t\t}\n\t\t}\n\t}\n\n\t_showError(message) {\n\t\tif (this.panelElement) {\n\t\t\tconst errorElement = this.panelElement.querySelector('.feedback-error');\n\t\t\tif (errorElement) {\n\t\t\t\terrorElement.textContent = message;\n\t\t\t\terrorElement.classList.add('show');\n\t\t\t}\n\t\t}\n\t}\n\n\t_hideError() {\n\t\tif (this.panelElement) {\n\t\t\tconst errorElement = this.panelElement.querySelector('.feedback-error');\n\t\t\tif (errorElement) {\n\t\t\t\terrorElement.classList.remove('show');\n\t\t\t}\n\t\t}\n\t}\n\n\t_showSuccessMessage() {\n\t\tconst notification = document.createElement('div');\n\t\tnotification.className = 'feedback-success-notification';\n\t\tnotification.innerHTML = `\n <div class=\"feedback-success-content\">\n <div class=\"feedback-success-icon\">✓</div>\n <span>Feedback submitted successfully!</span>\n <button class=\"feedback-success-close\" aria-label=\"Close\">&times;</button>\n </div>\n `;\n\n\t\tdocument.body.appendChild(notification);\n\n\t\tconst closeBtn = notification.querySelector('.feedback-success-close');\n\t\tconst closeNotification = () => {\n\t\t\tif (notification.parentNode) {\n\t\t\t\tnotification.style.opacity = '0';\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tif (notification.parentNode) {\n\t\t\t\t\t\tnotification.parentNode.removeChild(notification);\n\t\t\t\t\t}\n\t\t\t\t}, 300);\n\t\t\t}\n\t\t};\n\n\t\tcloseBtn.addEventListener('click', closeNotification);\n\n\t\tsetTimeout(closeNotification, 4000);\n\t}\n\n\t_resetForm() {\n\t\tthis.state.title = '';\n\t\tthis.state.content = '';\n\t\tthis.state.email = '';\n\t\tthis.state.errors = {};\n\t}\n\n\t_updateTheme() {\n\t\tif (this.element) {\n\t\t\tthis.element.className = this.element.className.replace(\n\t\t\t\t/theme-\\w+/,\n\t\t\t\t`theme-${this.options.theme}`\n\t\t\t);\n\t\t}\n\t\tif (this.panelElement) {\n\t\t\tthis.panelElement.className = this.panelElement.className.replace(\n\t\t\t\t/theme-\\w+/,\n\t\t\t\t`theme-${this.options.theme}`\n\t\t\t);\n\t\t}\n\t}\n\n\topenModal() {\n\t\tthis.openPanel();\n\t}\n\n\tcloseModal() {\n\t\tthis.closePanel();\n\t}\n}\n","import { BaseWidget } from './BaseWidget.js';\n\nexport class ButtonWidget extends BaseWidget {\n constructor(options) {\n super({ ...options, type: 'button' });\n this.isMinimized = false;\n }\n\n _render() {\n const button = document.createElement('div');\n button.className = `feedback-widget feedback-widget-button theme-${this.options.theme} position-${this.options.position}`;\n button.innerHTML = `\n <button class=\"feedback-trigger-btn\" type=\"button\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path d=\"M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z\"/>\n <path d=\"M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z\"/>\n </svg>\n Feedback\n </button>\n <button class=\"feedback-close-btn\" type=\"button\" title=\"Hide feedback button\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"currentColor\">\n <path d=\"M14 1.41L12.59 0L7 5.59L1.41 0L0 1.41L5.59 7L0 12.59L1.41 14L7 8.41L12.59 14L14 12.59L8.41 7L14 1.41Z\"/>\n </svg>\n </button>\n `;\n\n if (this.options.customStyles) {\n Object.assign(button.style, this.options.customStyles);\n }\n\n return button;\n }\n\n _attachEvents() {\n const button = this.element.querySelector('.feedback-trigger-btn');\n const closeBtn = this.element.querySelector('.feedback-close-btn');\n\n button.addEventListener('click', this.openPanel);\n \n closeBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.toggleMinimize();\n });\n\n button.addEventListener('mouseenter', () => {\n if (!this.state.isSubmitting) {\n button.style.transform = 'translateY(-2px)';\n }\n });\n\n button.addEventListener('mouseleave', () => {\n button.style.transform = 'translateY(0)';\n });\n }\n\n toggleMinimize() {\n this.isMinimized = !this.isMinimized;\n \n if (this.isMinimized) {\n this.element.classList.add('minimized');\n localStorage.setItem('feedback-widget-minimized', 'true');\n } else {\n this.element.classList.remove('minimized');\n localStorage.removeItem('feedback-widget-minimized');\n }\n }\n\n mount(container) {\n super.mount(container);\n \n // Check if it was previously minimized\n if (localStorage.getItem('feedback-widget-minimized') === 'true') {\n this.isMinimized = true;\n this.element.classList.add('minimized');\n }\n }\n\n updateText(text) {\n const button = this.element?.querySelector('.feedback-trigger-btn');\n if (button) {\n const textNode = button.childNodes[button.childNodes.length - 1];\n if (textNode && textNode.nodeType === Node.TEXT_NODE) {\n textNode.textContent = text;\n }\n }\n }\n\n updatePosition(position) {\n this.options.position = position;\n if (this.element) {\n this.element.className = this.element.className.replace(\n /position-\\w+-\\w+/,\n `position-${position}`\n );\n }\n }\n}","import { BaseWidget } from './BaseWidget.js';\n\nexport class InlineWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'inline' });\n\t}\n\n\t_render() {\n\t\tconst widget = document.createElement('div');\n\t\twidget.className = `feedback-widget feedback-widget-inline theme-${this.options.theme}`;\n\t\twidget.innerHTML = `\n <div class=\"feedback-inline-content\">\n <h3>Send us your feedback</h3>\n <form class=\"feedback-inline-form\">\n <div class=\"feedback-form-group\">\n <input \n type=\"text\" \n name=\"title\" \n placeholder=\"Title (optional)\"\n value=\"${this.state.title}\"\n />\n </div>\n <div class=\"feedback-form-group\">\n <textarea \n name=\"content\" \n placeholder=\"Your feedback...\"\n required\n >${this.state.content}</textarea>\n </div>\n <div class=\"feedback-form-group\">\n <input \n type=\"email\" \n name=\"email\" \n placeholder=\"Email (optional)\"\n value=\"${this.state.email}\"\n />\n </div>\n <button type=\"submit\" class=\"feedback-btn feedback-btn-submit\">\n Send Feedback\n </button>\n <div class=\"feedback-error\" style=\"display: none;\"></div>\n </form>\n </div>\n `;\n\n\t\tif (this.options.customStyles) {\n\t\t\tObject.assign(widget.style, this.options.customStyles);\n\t\t}\n\n\t\treturn widget;\n\t}\n\n\t_attachEvents() {\n\t\tconst form = this.element.querySelector('.feedback-inline-form');\n\n\t\tform.addEventListener('submit', (e) => {\n\t\t\te.preventDefault();\n\t\t\tthis.submitFeedback();\n\t\t});\n\n\t\tform.querySelector('input[name=\"title\"]').addEventListener('input', (e) => {\n\t\t\tthis.state.title = e.target.value;\n\t\t});\n\n\t\tform\n\t\t\t.querySelector('textarea[name=\"content\"]')\n\t\t\t.addEventListener('input', (e) => {\n\t\t\t\tthis.state.content = e.target.value;\n\t\t\t});\n\n\t\tform.querySelector('input[name=\"email\"]').addEventListener('input', (e) => {\n\t\t\tthis.state.email = e.target.value;\n\t\t});\n\t}\n\n\topenModal() {\n\t\tconst textarea = this.element.querySelector('textarea[name=\"content\"]');\n\t\tif (textarea) {\n\t\t\ttextarea.focus();\n\t\t}\n\t}\n\n\tcloseModal() {\n\t\t// Inline widget doesn't use modal\n\t}\n\n\t_showSuccessMessage() {\n\t\tconst widget = this.element.querySelector('.feedback-inline-content');\n\t\tconst originalContent = widget.innerHTML;\n\n\t\twidget.innerHTML = `\n <div class=\"feedback-success\">\n <div class=\"feedback-success-icon\">✓</div>\n <h3>Thank you!</h3>\n <p>Your feedback has been submitted successfully.</p>\n <button class=\"feedback-btn feedback-btn-reset\">Send Another</button>\n </div>\n `;\n\n\t\tconst resetBtn = widget.querySelector('.feedback-btn-reset');\n\t\tresetBtn.addEventListener('click', () => {\n\t\t\twidget.innerHTML = originalContent;\n\t\t\tthis._attachEvents();\n\t\t\tthis._resetForm();\n\t\t});\n\t}\n\n\t_showError(message) {\n\t\tconst errorElement = this.element.querySelector('.feedback-error');\n\t\tif (errorElement) {\n\t\t\terrorElement.textContent = message;\n\t\t\terrorElement.style.display = 'block';\n\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (errorElement) {\n\t\t\t\t\terrorElement.style.display = 'none';\n\t\t\t\t}\n\t\t\t}, 5000);\n\t\t}\n\t}\n\n\t_updateSubmitButton() {\n\t\tconst submitBtn = this.element.querySelector('.feedback-btn-submit');\n\t\tif (submitBtn) {\n\t\t\tsubmitBtn.textContent = this.state.isSubmitting\n\t\t\t\t? 'Sending...'\n\t\t\t\t: 'Send Feedback';\n\t\t\tsubmitBtn.disabled = this.state.isSubmitting;\n\t\t}\n\t}\n\n\tupdateTitle(title) {\n\t\tconst titleElement = this.element?.querySelector('h3');\n\t\tif (titleElement) {\n\t\t\ttitleElement.textContent = title;\n\t\t}\n\t}\n\n\tsetPlaceholder(field, placeholder) {\n\t\tconst input = this.element?.querySelector(`[name=\"${field}\"]`);\n\t\tif (input) {\n\t\t\tinput.placeholder = placeholder;\n\t\t}\n\t}\n}\n","/**\n * MessengerState - State management for the Messenger widget\n */\nexport class MessengerState {\n\tconstructor(options = {}) {\n\t\tthis.currentView = 'home'; // 'home', 'messages', 'chat', 'help', 'changelog'\n\t\tthis.isOpen = false;\n\t\tthis.unreadCount = 0;\n\t\tthis.activeConversationId = null;\n\n\t\t// Conversations\n\t\tthis.conversations = [];\n\t\tthis.messages = {}; // { conversationId: [messages] }\n\n\t\t// Help articles\n\t\tthis.helpArticles = [];\n\t\tthis.helpSearchQuery = '';\n\n\t\t// Changelog\n\t\tthis.homeChangelogItems = [];\n\t\tthis.changelogItems = [];\n\n\t\t// Team info\n\t\tthis.teamName = options.teamName || 'Support';\n\t\tthis.teamAvatars = options.teamAvatars || [];\n\t\tthis.welcomeMessage = options.welcomeMessage || 'How can we help?';\n\n\t\t// User info\n\t\tthis.userContext = options.userContext || null;\n\n\t\t// Feature flags\n\t\tthis.enableHelp = options.enableHelp !== false;\n\t\tthis.enableChangelog = options.enableChangelog !== false;\n\n\t\t// Listeners\n\t\tthis._listeners = new Set();\n\t}\n\n\t/**\n\t * Subscribe to state changes\n\t */\n\tsubscribe(callback) {\n\t\tthis._listeners.add(callback);\n\t\treturn () => this._listeners.delete(callback);\n\t}\n\n\t/**\n\t * Notify all listeners of state change\n\t */\n\t_notify(changeType, data) {\n\t\tthis._listeners.forEach((cb) => cb(changeType, data, this));\n\t}\n\n\t/**\n\t * Set current view\n\t */\n\tsetView(view) {\n\t\tconst previousView = this.currentView;\n\t\tthis.currentView = view;\n\t\tthis._notify('viewChange', { previousView, currentView: view });\n\t}\n\n\t/**\n\t * Toggle panel open/closed\n\t */\n\tsetOpen(isOpen) {\n\t\tthis.isOpen = isOpen;\n\t\tthis._notify('openChange', { isOpen });\n\t}\n\n\t/**\n\t * Set active conversation for chat view\n\t */\n\tsetActiveConversation(conversationId) {\n\t\tthis.activeConversationId = conversationId;\n\t\tthis._notify('conversationChange', { conversationId });\n\t}\n\n\t/**\n\t * Update conversations list\n\t */\n\tsetConversations(conversations) {\n\t\tthis.conversations = conversations;\n\t\tthis._updateUnreadCount();\n\t\tthis._notify('conversationsUpdate', { conversations });\n\t}\n\n\t/**\n\t * Add a new conversation\n\t */\n\taddConversation(conversation) {\n\t\tthis.conversations.unshift(conversation);\n\t\tthis._updateUnreadCount();\n\t\tthis._notify('conversationAdded', { conversation });\n\t}\n\n\t/**\n\t * Update messages for a conversation\n\t */\n\tsetMessages(conversationId, messages) {\n\t\tthis.messages[conversationId] = messages;\n\t\tthis._notify('messagesUpdate', { conversationId, messages });\n\t}\n\n\t/**\n\t * Add a message to a conversation\n\t */\n\taddMessage(conversationId, message) {\n\t\tif (!this.messages[conversationId]) {\n\t\t\tthis.messages[conversationId] = [];\n\t\t}\n\t\tthis.messages[conversationId].push(message);\n\n\t\t// Update conversation preview\n\t\tconst conv = this.conversations.find((c) => c.id === conversationId);\n\t\tif (conv) {\n\t\t\tconv.lastMessage = message.content;\n\t\t\tconv.lastMessageTime = message.timestamp;\n\t\t\tif (!message.isOwn) {\n\t\t\t\tconv.unread = (conv.unread || 0) + 1;\n\t\t\t\tthis._updateUnreadCount();\n\t\t\t}\n\t\t}\n\n\t\tthis._notify('messageAdded', { conversationId, message });\n\t}\n\n\t/**\n\t * Mark conversation as read\n\t */\n\tmarkAsRead(conversationId) {\n\t\tconst conv = this.conversations.find((c) => c.id === conversationId);\n\t\tif (conv && conv.unread > 0) {\n\t\t\tconv.unread = 0;\n\t\t\tthis._updateUnreadCount();\n\t\t\tthis._notify('conversationRead', { conversationId });\n\t\t}\n\t}\n\n\t/**\n\t * Update unread count\n\t */\n\t_updateUnreadCount() {\n\t\tthis.unreadCount = this.conversations.reduce(\n\t\t\t(sum, c) => sum + (c.unread || 0),\n\t\t\t0\n\t\t);\n\t\tthis._notify('unreadCountChange', { count: this.unreadCount });\n\t}\n\n\t/**\n\t * Set help articles\n\t */\n\tsetHelpArticles(articles) {\n\t\tthis.helpArticles = articles;\n\t\tthis._notify('helpArticlesUpdate', { articles });\n\t}\n\n\t/**\n\t * Set help search query\n\t */\n\tsetHelpSearchQuery(query) {\n\t\tthis.helpSearchQuery = query;\n\t\tthis._notify('helpSearchChange', { query });\n\t}\n\n\t/**\n\t * Set home changelog items\n\t */\n\tsetHomeChangelogItems(items) {\n\t\tthis.homeChangelogItems = items;\n\t\tthis._notify('homeChangelogUpdate', { items });\n\t}\n\n\t/**\n\t * Set changelog items\n\t */\n\tsetChangelogItems(items) {\n\t\tthis.changelogItems = items;\n\t\tthis._notify('changelogUpdate', { items });\n\t}\n\n\t/**\n\t * Get current conversation\n\t */\n\tgetActiveConversation() {\n\t\treturn this.conversations.find((c) => c.id === this.activeConversationId);\n\t}\n\n\t/**\n\t * Get messages for active conversation\n\t */\n\tgetActiveMessages() {\n\t\treturn this.messages[this.activeConversationId] || [];\n\t}\n\n\t/**\n\t * Get filtered help articles\n\t */\n\tgetFilteredHelpArticles() {\n\t\tif (!this.helpSearchQuery) {\n\t\t\treturn this.helpArticles;\n\t\t}\n\t\tconst query = this.helpSearchQuery.toLowerCase();\n\t\treturn this.helpArticles.filter(\n\t\t\t(article) =>\n\t\t\t\tarticle.title.toLowerCase().includes(query) ||\n\t\t\t\t(article.description &&\n\t\t\t\t\tarticle.description.toLowerCase().includes(query))\n\t\t);\n\t}\n\n\t/**\n\t * Reset state\n\t */\n\treset() {\n\t\tthis.currentView = 'home';\n\t\tthis.activeConversationId = null;\n\t\tthis.helpSearchQuery = '';\n\t\tthis._notify('reset', {});\n\t}\n}\n","/**\n * MessengerLauncher - Floating trigger button for messenger\n */\nexport class MessengerLauncher {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = {\n\t\t\tposition: options.position || 'bottom-right',\n\t\t\tprimaryColor: options.primaryColor || '#1c1c1e',\n\t\t\t...options,\n\t\t};\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = `messenger-launcher messenger-launcher-${this.options.position}`;\n\n\t\tthis._updateContent();\n\t\tthis._attachEvents();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type, data) => {\n\t\t\tif (type === 'openChange') {\n\t\t\t\tthis._updateIcon();\n\t\t\t}\n\t\t\tif (type === 'unreadCountChange') {\n\t\t\t\tthis._updateBadge();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst badgeHtml =\n\t\t\tthis.state.unreadCount > 0\n\t\t\t\t? `<span class=\"messenger-launcher-badge\">${this.state.unreadCount > 9 ? '9+' : this.state.unreadCount}</span>`\n\t\t\t\t: '';\n\n\t\tthis.element.innerHTML = `\n\t\t\t<button class=\"messenger-launcher-btn\" aria-label=\"Open messenger\" style=\"background: ${this.options.primaryColor};\">\n\t\t\t\t<span class=\"messenger-launcher-icon messenger-launcher-icon-chat\">\n\t\t\t\t\t<i class=\"ph ph-chat-circle-dots\" style=\"font-size: 24px;\"></i>\n\t\t\t\t</span>\n\t\t\t\t<span class=\"messenger-launcher-icon messenger-launcher-icon-close\" style=\"display: none;\">\n\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 24px;\"></i>\n\t\t\t\t</span>\n\t\t\t\t${badgeHtml}\n\t\t\t</button>\n\t\t`;\n\t}\n\n\t_attachEvents() {\n\t\tthis.element\n\t\t\t.querySelector('.messenger-launcher-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(!this.state.isOpen);\n\t\t\t});\n\t}\n\n\t_updateIcon() {\n\t\tconst chatIcon = this.element.querySelector(\n\t\t\t'.messenger-launcher-icon-chat'\n\t\t);\n\t\tconst closeIcon = this.element.querySelector(\n\t\t\t'.messenger-launcher-icon-close'\n\t\t);\n\n\t\tif (this.state.isOpen) {\n\t\t\tchatIcon.style.display = 'none';\n\t\t\tcloseIcon.style.display = 'flex';\n\t\t\tthis.element.classList.add('messenger-launcher-open');\n\t\t} else {\n\t\t\tchatIcon.style.display = 'flex';\n\t\t\tcloseIcon.style.display = 'none';\n\t\t\tthis.element.classList.remove('messenger-launcher-open');\n\t\t}\n\t}\n\n\t_updateBadge() {\n\t\tconst existingBadge = this.element.querySelector(\n\t\t\t'.messenger-launcher-badge'\n\t\t);\n\t\tif (existingBadge) {\n\t\t\texistingBadge.remove();\n\t\t}\n\n\t\tif (this.state.unreadCount > 0 && !this.state.isOpen) {\n\t\t\tconst badge = document.createElement('span');\n\t\t\tbadge.className = 'messenger-launcher-badge';\n\t\t\tbadge.textContent =\n\t\t\t\tthis.state.unreadCount > 9 ? '9+' : this.state.unreadCount;\n\t\t\tthis.element.querySelector('.messenger-launcher-btn').appendChild(badge);\n\t\t}\n\t}\n\n\tshow() {\n\t\tif (this.element) {\n\t\t\tthis.element.style.display = 'block';\n\t\t}\n\t}\n\n\thide() {\n\t\tif (this.element) {\n\t\t\tthis.element.style.display = 'none';\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * NavigationTabs - Bottom navigation for messenger\n */\nexport class NavigationTabs {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-nav';\n\n\t\tthis._updateContent();\n\t\tthis._attachEvents();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (type === 'viewChange' || type === 'unreadCountChange') {\n\t\t\t\tthis._updateActiveTab();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_getTabs() {\n\t\tconst tabs = [\n\t\t\t{ id: 'home', label: 'Home', icon: this._getHomeIcon() },\n\t\t\t{\n\t\t\t\tid: 'messages',\n\t\t\t\tlabel: 'Messages',\n\t\t\t\ticon: this._getMessagesIcon(),\n\t\t\t\tbadge: this.state.unreadCount,\n\t\t\t},\n\t\t];\n\n\t\tif (this.state.enableHelp) {\n\t\t\ttabs.push({ id: 'help', label: 'Help', icon: this._getHelpIcon() });\n\t\t}\n\n\t\tif (this.state.enableChangelog) {\n\t\t\ttabs.push({\n\t\t\t\tid: 'changelog',\n\t\t\t\tlabel: 'Changelog',\n\t\t\t\ticon: this._getChangelogIcon(),\n\t\t\t});\n\t\t}\n\n\t\treturn tabs;\n\t}\n\n\t_updateContent() {\n\t\tconst tabs = this._getTabs();\n\t\tconst tabsHtml = tabs\n\t\t\t.map((tab) => {\n\t\t\t\tconst isActive = this.state.currentView === tab.id;\n\t\t\t\tconst badgeHtml =\n\t\t\t\t\ttab.badge && tab.badge > 0\n\t\t\t\t\t\t? `<span class=\"messenger-nav-badge\">${tab.badge > 9 ? '9+' : tab.badge}</span>`\n\t\t\t\t\t\t: '';\n\n\t\t\t\treturn `\n\t\t\t\t<button class=\"messenger-nav-tab ${isActive ? 'active' : ''}\" data-tab=\"${tab.id}\">\n\t\t\t\t\t<span class=\"messenger-nav-icon\">${tab.icon}</span>\n\t\t\t\t\t<span class=\"messenger-nav-label\">${tab.label}</span>\n\t\t\t\t\t${badgeHtml}\n\t\t\t\t</button>\n\t\t\t`;\n\t\t\t})\n\t\t\t.join('');\n\n\t\tthis.element.innerHTML = tabsHtml;\n\t}\n\n\t_attachEvents() {\n\t\tthis.element.addEventListener('click', (e) => {\n\t\t\tconst tab = e.target.closest('.messenger-nav-tab');\n\t\t\tif (tab) {\n\t\t\t\tconst tabId = tab.dataset.tab;\n\t\t\t\tthis.state.setView(tabId);\n\t\t\t}\n\t\t});\n\t}\n\n\t_updateActiveTab() {\n\t\tconst tabs = this.element.querySelectorAll('.messenger-nav-tab');\n\t\ttabs.forEach((tab) => {\n\t\t\tconst isActive = tab.dataset.tab === this.state.currentView;\n\t\t\ttab.classList.toggle('active', isActive);\n\n\t\t\t// Update badge if messages tab\n\t\t\tif (tab.dataset.tab === 'messages') {\n\t\t\t\tconst existingBadge = tab.querySelector('.messenger-nav-badge');\n\t\t\t\tif (existingBadge) existingBadge.remove();\n\n\t\t\t\tif (this.state.unreadCount > 0) {\n\t\t\t\t\tconst badge = document.createElement('span');\n\t\t\t\t\tbadge.className = 'messenger-nav-badge';\n\t\t\t\t\tbadge.textContent =\n\t\t\t\t\t\tthis.state.unreadCount > 9 ? '9+' : this.state.unreadCount;\n\t\t\t\t\ttab.appendChild(badge);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\t_getHomeIcon() {\n\t\treturn `<i class=\"ph-duotone ph-house-simple\" style=\"font-size: 24px;\"></i>`;\n\t}\n\n\t_getMessagesIcon() {\n\t\treturn `<i class=\"ph-duotone ph-chat\" style=\"font-size: 24px;\"></i>`;\n\t}\n\n\t_getHelpIcon() {\n\t\treturn `<i class=\"ph-duotone ph-question\" style=\"font-size: 24px;\"></i>`;\n\t}\n\n\t_getChangelogIcon() {\n\t\treturn `<i class=\"ph-duotone ph-megaphone\" style=\"font-size: 24px;\"></i>`;\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * MessengerPanel - Main panel container for messenger\n */\nimport { NavigationTabs } from './NavigationTabs.js';\n\nexport class MessengerPanel {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = {\n\t\t\tposition: options.position || 'bottom-right',\n\t\t\ttheme: options.theme || 'dark',\n\t\t\t...options,\n\t\t};\n\t\tthis.element = null;\n\t\tthis.navigationTabs = null;\n\t\tthis.currentViewComponent = null;\n\t\tthis.viewRegistry = {};\n\t\tthis._unsubscribe = null;\n\t}\n\n\t/**\n\t * Register view components\n\t */\n\tregisterView(name, ViewClass) {\n\t\tthis.viewRegistry[name] = ViewClass;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = `messenger-panel messenger-panel-${this.options.position} theme-${this.options.theme}`;\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-panel-content\">\n\t\t\t\t<div class=\"messenger-panel-views\"></div>\n\t\t\t\t<div class=\"messenger-panel-nav\"></div>\n\t\t\t</div>\n\t\t`;\n\n\t\t// Render navigation tabs\n\t\tthis.navigationTabs = new NavigationTabs(this.state, this.options);\n\t\tconst navContainer = this.element.querySelector('.messenger-panel-nav');\n\t\tnavContainer.appendChild(this.navigationTabs.render());\n\n\t\t// Render initial view\n\t\tthis._renderCurrentView();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (type === 'viewChange') {\n\t\t\t\tthis._renderCurrentView();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_renderCurrentView() {\n\t\tconst viewsContainer = this.element.querySelector('.messenger-panel-views');\n\n\t\t// Destroy current view if exists\n\t\tif (this.currentViewComponent && this.currentViewComponent.destroy) {\n\t\t\tthis.currentViewComponent.destroy();\n\t\t}\n\n\t\t// Clear container\n\t\tviewsContainer.innerHTML = '';\n\n\t\t// Get view class\n\t\tconst ViewClass = this.viewRegistry[this.state.currentView];\n\t\tif (ViewClass) {\n\t\t\tthis.currentViewComponent = new ViewClass(this.state, this.options);\n\t\t\tviewsContainer.appendChild(this.currentViewComponent.render());\n\t\t} else {\n\t\t\tviewsContainer.innerHTML = `<div class=\"messenger-view-placeholder\">View not found: ${this.state.currentView}</div>`;\n\t\t}\n\t}\n\n\t/**\n\t * Show the panel with animation\n\t */\n\tshow() {\n\t\tif (this.element) {\n\t\t\tthis.element.style.display = 'block';\n\t\t\t// Trigger animation\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tthis.element.classList.add('open');\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Hide the panel with animation\n\t */\n\thide() {\n\t\tif (this.element) {\n\t\t\tthis.element.classList.remove('open');\n\t\t\t// Wait for animation to complete\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (this.element) {\n\t\t\t\t\tthis.element.style.display = 'none';\n\t\t\t\t}\n\t\t\t}, 300);\n\t\t}\n\t}\n\n\t/**\n\t * Set panel header content (used by views)\n\t */\n\tsetHeader(headerContent) {\n\t\tconst header = this.element.querySelector('.messenger-panel-header');\n\t\tif (header) {\n\t\t\theader.innerHTML = headerContent;\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.navigationTabs) {\n\t\t\tthis.navigationTabs.destroy();\n\t\t}\n\t\tif (this.currentViewComponent && this.currentViewComponent.destroy) {\n\t\t\tthis.currentViewComponent.destroy();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * ChangelogView - Changelog and announcements\n */\nexport class ChangelogView {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-view messenger-changelog-view';\n\n\t\tthis._updateContent();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (type === 'changelogUpdate') {\n\t\t\t\tthis._updateChangelogList();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst avatarsHtml = this._renderTeamAvatars();\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-changelog-header\">\n\t\t\t\t<h2>Changelog</h2>\n\t\t\t\t<button class=\"messenger-close-btn\" aria-label=\"Close\">\n\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-changelog-subheader\">\n\t\t\t\t<span class=\"messenger-changelog-latest\">Latest</span>\n\t\t\t\t<div class=\"messenger-changelog-team\">\n\t\t\t\t\t<span>From ${this.state.teamName}</span>\n\t\t\t\t\t${avatarsHtml}\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-changelog-body\">\n\t\t\t\t<div class=\"messenger-changelog-list\"></div>\n\t\t\t</div>\n\t\t`;\n\n\t\tthis._updateChangelogList();\n\t\tthis._attachEvents();\n\t}\n\n\t_updateChangelogList() {\n\t\tconst changelogContainer = this.element.querySelector(\n\t\t\t'.messenger-changelog-list'\n\t\t);\n\t\tconst changelogItems = this.state.changelogItems;\n\n\t\tif (changelogItems.length === 0) {\n\t\t\tchangelogContainer.innerHTML = this._renderEmptyState();\n\t\t\treturn;\n\t\t}\n\n\t\tchangelogContainer.innerHTML = changelogItems\n\t\t\t.map((item) => this._renderChangelogCard(item))\n\t\t\t.join('');\n\n\t\t// Attach click events\n\t\tthis._attachChangelogEvents();\n\t}\n\n\t_renderChangelogCard(item) {\n\t\tconst tagsHtml =\n\t\t\titem.tags && item.tags.length > 0\n\t\t\t\t? `<div class=\"messenger-changelog-tags\">\n\t\t\t\t${item.tags.map((tag) => `<span class=\"messenger-changelog-tag\">${tag}</span>`).join('')}\n\t\t\t</div>`\n\t\t\t\t: '';\n\n\t\tconst dateStr = this._formatDate(item.publishedAt || item.date);\n\n\t\treturn `\n\t\t\t<div class=\"messenger-changelog-card\" data-changelog-id=\"${item.id}\">\n\t\t\t\t${\n\t\t\t\t\titem.coverImage\n\t\t\t\t\t\t? `\n\t\t\t\t\t<div class=\"messenger-changelog-cover\">\n\t\t\t\t\t\t<img src=\"${item.coverImage}\" alt=\"${item.title}\" onerror=\"this.style.display='none';\" />\n\t\t\t\t\t</div>\n\t\t\t\t`\n\t\t\t\t\t\t: ''\n\t\t\t\t}\n\t\t\t\t<div class=\"messenger-changelog-content\">\n\t\t\t\t\t${tagsHtml}\n\t\t\t\t\t<h3 class=\"messenger-changelog-title\">${item.title}</h3>\n\t\t\t\t\t${item.description ? `<p class=\"messenger-changelog-description\">${this._truncateText(item.description, 100)}</p>` : ''}\n\t\t\t\t\t<div class=\"messenger-changelog-meta\">\n\t\t\t\t\t\t<span class=\"messenger-changelog-date\">${dateStr}</span>\n\t\t\t\t\t\t<i class=\"ph ph-caret-right messenger-changelog-arrow\" style=\"font-size: 16px;\"></i>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderTeamAvatars() {\n\t\tconst avatars = this.state.teamAvatars;\n\t\tif (!avatars || avatars.length === 0) {\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-avatar-stack messenger-avatar-stack-tiny\">\n\t\t\t\t\t<div class=\"messenger-avatar messenger-avatar-tiny\" style=\"background: #5856d6;\">S</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tconst colors = ['#5856d6', '#007aff', '#34c759'];\n\t\tconst avatarItems = avatars\n\t\t\t.slice(0, 2)\n\t\t\t.map((avatar, i) => {\n\t\t\t\tif (typeof avatar === 'string' && avatar.startsWith('http')) {\n\t\t\t\t\treturn `<img class=\"messenger-avatar messenger-avatar-tiny\" src=\"${avatar}\" alt=\"Team member\" style=\"z-index: ${2 - i};\" />`;\n\t\t\t\t}\n\t\t\t\treturn `<div class=\"messenger-avatar messenger-avatar-tiny\" style=\"background: ${colors[i % colors.length]}; z-index: ${2 - i};\">${avatar.charAt(0).toUpperCase()}</div>`;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn `<div class=\"messenger-avatar-stack messenger-avatar-stack-tiny\">${avatarItems}</div>`;\n\t}\n\n\t_renderEmptyState() {\n\t\treturn `\n\t\t\t<div class=\"messenger-changelog-empty\">\n\t\t\t\t<div class=\"messenger-changelog-empty-icon\">\n\t\t\t\t\t<i class=\"ph ph-megaphone\" style=\"font-size: 48px;\"></i>\n\t\t\t\t</div>\n\t\t\t\t<h3>No changelog yet</h3>\n\t\t\t\t<p>Check back later for updates</p>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_formatDate(dateString) {\n\t\tif (!dateString) return '';\n\t\tconst date = new Date(dateString);\n\t\treturn date.toLocaleDateString('en-US', {\n\t\t\tmonth: 'short',\n\t\t\tday: 'numeric',\n\t\t\tyear: 'numeric',\n\t\t});\n\t}\n\n\t_truncateText(text, maxLength) {\n\t\tif (!text) return '';\n\t\tif (text.length <= maxLength) return text;\n\t\treturn text.substring(0, maxLength).trim() + '...';\n\t}\n\n\t_attachEvents() {\n\t\t// Close button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-close-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(false);\n\t\t\t});\n\n\t\tthis._attachChangelogEvents();\n\t}\n\n\t_attachChangelogEvents() {\n\t\tthis.element\n\t\t\t.querySelectorAll('.messenger-changelog-card')\n\t\t\t.forEach((card) => {\n\t\t\t\tcard.addEventListener('click', () => {\n\t\t\t\t\tconst changelogId = card.dataset.changelogId;\n\t\t\t\t\tconst changelogItem = this.state.changelogItems.find(\n\t\t\t\t\t\t(n) => n.id === changelogId\n\t\t\t\t\t);\n\t\t\t\t\tif (changelogItem && changelogItem.url) {\n\t\t\t\t\t\twindow.open(changelogItem.url, '_blank');\n\t\t\t\t\t} else if (this.options.onChangelogClick) {\n\t\t\t\t\t\tthis.options.onChangelogClick(changelogItem);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * ChatView - Individual conversation chat\n */\nexport class ChatView {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-view messenger-chat-view';\n\n\t\tthis._updateContent();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type, data) => {\n\t\t\tif (\n\t\t\t\ttype === 'messageAdded' &&\n\t\t\t\tdata.conversationId === this.state.activeConversationId\n\t\t\t) {\n\t\t\t\tthis._appendMessage(data.message);\n\t\t\t\tthis._scrollToBottom();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst conversation = this.state.getActiveConversation();\n\t\tconst messages = this.state.getActiveMessages();\n\n\t\tconst messagesHtml =\n\t\t\tmessages.length === 0\n\t\t\t\t? this._renderEmptyState()\n\t\t\t\t: messages.map((msg) => this._renderMessage(msg)).join('');\n\n\t\tconst avatarHtml = this._renderConversationAvatar(conversation);\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-chat-header\">\n\t\t\t\t<button class=\"messenger-back-btn\" aria-label=\"Back\">\n\t\t\t\t\t<i class=\"ph ph-caret-left\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t\t<div class=\"messenger-chat-header-info\">\n\t\t\t\t\t${avatarHtml}\n\t\t\t\t\t<span class=\"messenger-chat-title\">${conversation?.title || 'Chat with team'}</span>\n\t\t\t\t</div>\n\t\t\t\t<button class=\"messenger-close-btn\" aria-label=\"Close\">\n\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-chat-messages\">\n\t\t\t\t${messagesHtml}\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-chat-compose\">\n\t\t\t\t<div class=\"messenger-compose-input-wrapper\">\n\t\t\t\t\t<textarea class=\"messenger-compose-input\" placeholder=\"Write a message...\" rows=\"1\"></textarea>\n\t\t\t\t</div>\n\t\t\t\t<button class=\"messenger-compose-send\" aria-label=\"Send\" disabled>\n\t\t\t\t\t<i class=\"ph ph-paper-plane-tilt\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t`;\n\n\t\tthis._attachEvents();\n\t\tthis._scrollToBottom();\n\t}\n\n\t_renderEmptyState() {\n\t\tconst avatarHtml = this._renderTeamAvatars();\n\t\treturn `\n\t\t\t<div class=\"messenger-chat-empty\">\n\t\t\t\t<div class=\"messenger-chat-empty-avatars\">${avatarHtml}</div>\n\t\t\t\t<h3>Start the conversation</h3>\n\t\t\t\t<p>Send us a message and we'll get back to you as soon as possible.</p>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderMessage(message) {\n\t\tconst isOwn = message.isOwn;\n\t\tconst messageClass = isOwn\n\t\t\t? 'messenger-message-own'\n\t\t\t: 'messenger-message-received';\n\t\tconst timeStr = this._formatMessageTime(message.timestamp);\n\n\t\tif (isOwn) {\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-message ${messageClass}\">\n\t\t\t\t\t<div class=\"messenger-message-bubble\">\n\t\t\t\t\t\t<div class=\"messenger-message-content\">${this._formatMessageContent(message.content)}</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"messenger-message-time\">${timeStr}</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tconst avatarHtml = this._renderSenderAvatar(message.sender);\n\t\treturn `\n\t\t\t<div class=\"messenger-message ${messageClass}\">\n\t\t\t\t<div class=\"messenger-message-avatar\">${avatarHtml}</div>\n\t\t\t\t<div class=\"messenger-message-wrapper\">\n\t\t\t\t\t<div class=\"messenger-message-sender\">${message.sender?.name || 'Support'}</div>\n\t\t\t\t\t<div class=\"messenger-message-bubble\">\n\t\t\t\t\t\t<div class=\"messenger-message-content\">${this._formatMessageContent(message.content)}</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"messenger-message-time\">${timeStr}</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderSenderAvatar(sender) {\n\t\tif (sender?.avatarUrl) {\n\t\t\treturn `<img class=\"messenger-avatar messenger-avatar-small\" src=\"${sender.avatarUrl}\" alt=\"${sender.name}\" />`;\n\t\t}\n\t\tconst initial = (sender?.name || 'S').charAt(0).toUpperCase();\n\t\treturn `<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: #5856d6;\">${initial}</div>`;\n\t}\n\n\t_renderConversationAvatar(conversation) {\n\t\tif (!conversation?.participants?.length) {\n\t\t\treturn `<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: #5856d6;\">S</div>`;\n\t\t}\n\t\tconst p = conversation.participants[0];\n\t\tif (p.avatarUrl) {\n\t\t\treturn `<img class=\"messenger-avatar messenger-avatar-small\" src=\"${p.avatarUrl}\" alt=\"${p.name}\" />`;\n\t\t}\n\t\treturn `<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: #5856d6;\">${(p.name || 'S').charAt(0).toUpperCase()}</div>`;\n\t}\n\n\t_renderTeamAvatars() {\n\t\tconst avatars = this.state.teamAvatars;\n\t\tif (!avatars || avatars.length === 0) {\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-avatar-stack\">\n\t\t\t\t\t<div class=\"messenger-avatar\" style=\"background: #5856d6;\">S</div>\n\t\t\t\t\t<div class=\"messenger-avatar\" style=\"background: #007aff;\">T</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tconst colors = ['#5856d6', '#007aff', '#34c759', '#ff9500', '#ff3b30'];\n\t\tconst avatarItems = avatars\n\t\t\t.slice(0, 3)\n\t\t\t.map((avatar, i) => {\n\t\t\t\tif (typeof avatar === 'string' && avatar.startsWith('http')) {\n\t\t\t\t\treturn `<img class=\"messenger-avatar\" src=\"${avatar}\" alt=\"Team member\" style=\"z-index: ${3 - i};\" />`;\n\t\t\t\t}\n\t\t\t\treturn `<div class=\"messenger-avatar\" style=\"background: ${colors[i % colors.length]}; z-index: ${3 - i};\">${avatar.charAt(0).toUpperCase()}</div>`;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn `<div class=\"messenger-avatar-stack\">${avatarItems}</div>`;\n\t}\n\n\t_formatMessageTime(timestamp) {\n\t\tif (!timestamp) return '';\n\t\tconst date = new Date(timestamp);\n\t\treturn date.toLocaleTimeString('en-US', {\n\t\t\thour: 'numeric',\n\t\t\tminute: '2-digit',\n\t\t\thour12: true,\n\t\t});\n\t}\n\n\t_formatMessageContent(content) {\n\t\tif (!content) return '';\n\t\t// Basic HTML escaping and line breaks\n\t\treturn content\n\t\t\t.replace(/&/g, '&amp;')\n\t\t\t.replace(/</g, '&lt;')\n\t\t\t.replace(/>/g, '&gt;')\n\t\t\t.replace(/\\n/g, '<br>');\n\t}\n\n\t_appendMessage(message) {\n\t\tconst messagesContainer = this.element.querySelector(\n\t\t\t'.messenger-chat-messages'\n\t\t);\n\t\tconst emptyState = messagesContainer.querySelector('.messenger-chat-empty');\n\t\tif (emptyState) {\n\t\t\temptyState.remove();\n\t\t}\n\n\t\tconst messageHtml = this._renderMessage(message);\n\t\tconst tempDiv = document.createElement('div');\n\t\ttempDiv.innerHTML = messageHtml;\n\t\tmessagesContainer.appendChild(tempDiv.firstElementChild);\n\t}\n\n\t_scrollToBottom() {\n\t\tconst messagesContainer = this.element.querySelector(\n\t\t\t'.messenger-chat-messages'\n\t\t);\n\t\tif (messagesContainer) {\n\t\t\tsetTimeout(() => {\n\t\t\t\tmessagesContainer.scrollTop = messagesContainer.scrollHeight;\n\t\t\t}, 50);\n\t\t}\n\t}\n\n\t_attachEvents() {\n\t\t// Back button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-back-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setView('messages');\n\t\t\t});\n\n\t\t// Close button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-close-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(false);\n\t\t\t});\n\n\t\t// Compose input\n\t\tconst input = this.element.querySelector('.messenger-compose-input');\n\t\tconst sendBtn = this.element.querySelector('.messenger-compose-send');\n\n\t\tinput.addEventListener('input', () => {\n\t\t\t// Auto-resize textarea\n\t\t\tinput.style.height = 'auto';\n\t\t\tinput.style.height = Math.min(input.scrollHeight, 120) + 'px';\n\n\t\t\t// Enable/disable send button\n\t\t\tsendBtn.disabled = !input.value.trim();\n\t\t});\n\n\t\tinput.addEventListener('keydown', (e) => {\n\t\t\tif (e.key === 'Enter' && !e.shiftKey) {\n\t\t\t\te.preventDefault();\n\t\t\t\tthis._sendMessage();\n\t\t\t}\n\t\t});\n\n\t\tsendBtn.addEventListener('click', () => {\n\t\t\tthis._sendMessage();\n\t\t});\n\t}\n\n\t_sendMessage() {\n\t\tconst input = this.element.querySelector('.messenger-compose-input');\n\t\tconst content = input.value.trim();\n\n\t\tif (!content) return;\n\n\t\t// Add message to state\n\t\tconst message = {\n\t\t\tid: 'msg_' + Date.now(),\n\t\t\tcontent: content,\n\t\t\tisOwn: true,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\n\t\tthis.state.addMessage(this.state.activeConversationId, message);\n\n\t\t// Clear input\n\t\tinput.value = '';\n\t\tinput.style.height = 'auto';\n\t\tthis.element.querySelector('.messenger-compose-send').disabled = true;\n\n\t\t// Emit event for API integration\n\t\tif (this.options.onSendMessage) {\n\t\t\tthis.options.onSendMessage(this.state.activeConversationId, message);\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * ConversationsView - Message thread list\n */\nexport class ConversationsView {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-view messenger-conversations-view';\n\n\t\tthis._updateContent();\n\t\tthis._attachEvents();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (\n\t\t\t\ttype === 'conversationsUpdate' ||\n\t\t\t\ttype === 'conversationAdded' ||\n\t\t\t\ttype === 'conversationRead'\n\t\t\t) {\n\t\t\t\tthis._updateContent();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst conversations = this.state.conversations;\n\t\tconst avatarsHtml = this._renderAvatarStack();\n\n\t\tlet conversationsHtml;\n\t\tif (conversations.length === 0) {\n\t\t\tconversationsHtml = `\n\t\t\t\t<div class=\"messenger-conversations-empty\">\n\t\t\t\t\t<div class=\"messenger-conversations-empty-icon\">\n\t\t\t\t\t\t<i class=\"ph ph-chat\" style=\"font-size: 48px;\"></i>\n\t\t\t\t\t</div>\n\t\t\t\t\t<h3>No conversations yet</h3>\n\t\t\t\t\t<p>Start a new conversation with our team</p>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t} else {\n\t\t\tconversationsHtml = `\n\t\t\t\t<div class=\"messenger-conversations-list\">\n\t\t\t\t\t${conversations.map((conv) => this._renderConversationItem(conv)).join('')}\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-conversations-header\">\n\t\t\t\t<h2>Messages</h2>\n\t\t\t\t<button class=\"messenger-close-btn\" aria-label=\"Close\">\n\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-conversations-body\">\n\t\t\t\t${conversationsHtml}\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-conversations-footer\">\n\t\t\t\t<button class=\"messenger-new-message-btn\">\n\t\t\t\t\t<div class=\"messenger-new-message-avatars\">${avatarsHtml}</div>\n\t\t\t\t\t<span>Send us a message</span>\n\t\t\t\t\t<i class=\"ph ph-arrow-right\" style=\"font-size: 16px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t`;\n\n\t\tthis._attachEvents();\n\t}\n\n\t_renderConversationItem(conversation) {\n\t\tconst unreadClass = conversation.unread > 0 ? 'unread' : '';\n\t\tconst timeAgo = this._formatTimeAgo(conversation.lastMessageTime);\n\t\tconst avatarsHtml = this._renderConversationAvatars(\n\t\t\tconversation.participants\n\t\t);\n\n\t\treturn `\n\t\t\t<div class=\"messenger-conversation-item ${unreadClass}\" data-conversation-id=\"${conversation.id}\">\n\t\t\t\t<div class=\"messenger-conversation-avatars\">\n\t\t\t\t\t${avatarsHtml}\n\t\t\t\t</div>\n\t\t\t\t<div class=\"messenger-conversation-content\">\n\t\t\t\t\t<div class=\"messenger-conversation-header\">\n\t\t\t\t\t\t<span class=\"messenger-conversation-title\">${conversation.title || 'Chat with team'}</span>\n\t\t\t\t\t\t<span class=\"messenger-conversation-time\">${timeAgo}</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"messenger-conversation-preview\">\n\t\t\t\t\t\t${conversation.unread > 0 ? '<span class=\"messenger-unread-dot\"></span>' : ''}\n\t\t\t\t\t\t<span class=\"messenger-conversation-message\">${this._truncateMessage(conversation.lastMessage)}</span>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderConversationAvatars(participants) {\n\t\tif (!participants || participants.length === 0) {\n\t\t\treturn `<div class=\"messenger-avatar messenger-avatar-medium\" style=\"background: #5856d6;\">S</div>`;\n\t\t}\n\n\t\tconst p = participants[0];\n\t\tif (p.avatarUrl) {\n\t\t\treturn `<img class=\"messenger-avatar messenger-avatar-medium\" src=\"${p.avatarUrl}\" alt=\"${p.name}\" />`;\n\t\t}\n\t\treturn `<div class=\"messenger-avatar messenger-avatar-medium\" style=\"background: ${this._getAvatarColor(0)};\">${(p.name || 'S').charAt(0).toUpperCase()}</div>`;\n\t}\n\n\t_renderAvatarStack() {\n\t\tconst avatars = this.state.teamAvatars;\n\t\tif (!avatars || avatars.length === 0) {\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-avatar-stack messenger-avatar-stack-small\">\n\t\t\t\t\t<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: #5856d6;\">S</div>\n\t\t\t\t\t<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: #007aff;\">T</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tconst avatarItems = avatars\n\t\t\t.slice(0, 2)\n\t\t\t.map((avatar, i) => {\n\t\t\t\tif (typeof avatar === 'string' && avatar.startsWith('http')) {\n\t\t\t\t\treturn `<img class=\"messenger-avatar messenger-avatar-small\" src=\"${avatar}\" alt=\"Team member\" style=\"z-index: ${2 - i};\" />`;\n\t\t\t\t}\n\t\t\t\treturn `<div class=\"messenger-avatar messenger-avatar-small\" style=\"background: ${this._getAvatarColor(i)}; z-index: ${2 - i};\">${avatar.charAt(0).toUpperCase()}</div>`;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn `<div class=\"messenger-avatar-stack messenger-avatar-stack-small\">${avatarItems}</div>`;\n\t}\n\n\t_getAvatarColor(index) {\n\t\tconst colors = ['#5856d6', '#007aff', '#34c759', '#ff9500', '#ff3b30'];\n\t\treturn colors[index % colors.length];\n\t}\n\n\t_formatTimeAgo(timestamp) {\n\t\tif (!timestamp) return '';\n\t\tconst date = new Date(timestamp);\n\t\tconst now = new Date();\n\t\tconst diffMs = now - date;\n\t\tconst diffMins = Math.floor(diffMs / 60000);\n\t\tconst diffHours = Math.floor(diffMs / 3600000);\n\t\tconst diffDays = Math.floor(diffMs / 86400000);\n\n\t\tif (diffMins < 1) return 'now';\n\t\tif (diffMins < 60) return `${diffMins}m`;\n\t\tif (diffHours < 24) return `${diffHours}h`;\n\t\tif (diffDays < 7) return `${diffDays}d`;\n\t\treturn date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n\t}\n\n\t_truncateMessage(message) {\n\t\tif (!message) return 'No messages yet';\n\t\tconst maxLength = 50;\n\t\tif (message.length <= maxLength) return message;\n\t\treturn message.substring(0, maxLength) + '...';\n\t}\n\n\t_attachEvents() {\n\t\t// Close button\n\t\tconst closeBtn = this.element.querySelector('.messenger-close-btn');\n\t\tif (closeBtn) {\n\t\t\tcloseBtn.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(false);\n\t\t\t});\n\t\t}\n\n\t\t// Conversation items\n\t\tthis.element\n\t\t\t.querySelectorAll('.messenger-conversation-item')\n\t\t\t.forEach((item) => {\n\t\t\t\titem.addEventListener('click', () => {\n\t\t\t\t\tconst convId = item.dataset.conversationId;\n\t\t\t\t\tthis.state.setActiveConversation(convId);\n\t\t\t\t\tthis.state.markAsRead(convId);\n\t\t\t\t\tthis.state.setView('chat');\n\t\t\t\t});\n\t\t\t});\n\n\t\t// New message button\n\t\tconst newMsgBtn = this.element.querySelector('.messenger-new-message-btn');\n\t\tif (newMsgBtn) {\n\t\t\tnewMsgBtn.addEventListener('click', () => {\n\t\t\t\tthis._startNewConversation();\n\t\t\t});\n\t\t}\n\t}\n\n\t_startNewConversation() {\n\t\t// Create a new conversation and navigate to chat\n\t\tconst newConv = {\n\t\t\tid: 'conv_' + Date.now(),\n\t\t\ttitle: 'New conversation',\n\t\t\tparticipants: [],\n\t\t\tlastMessage: null,\n\t\t\tlastMessageTime: new Date().toISOString(),\n\t\t\tunread: 0,\n\t\t};\n\t\tthis.state.addConversation(newConv);\n\t\tthis.state.setActiveConversation(newConv.id);\n\t\tthis.state.setView('chat');\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * HelpView - Help collections browse with Intercom-style design\n */\nexport class HelpView {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-view messenger-help-view';\n\n\t\tthis._updateContent();\n\n\t\t// Subscribe to state changes\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (type === 'helpArticlesUpdate' || type === 'helpSearchChange') {\n\t\t\t\tthis._updateCollectionsList();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst searchQuery = this.state.helpSearchQuery || '';\n\t\tconst collections = this.state.helpArticles || [];\n\t\tconst collectionCount = collections.length;\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-help-header\">\n\t\t\t\t<h2>Help</h2>\n\t\t\t\t<button class=\"messenger-close-btn\" aria-label=\"Close\">\n\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 20px;\"></i>\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-help-search\">\n\t\t\t\t<div class=\"messenger-help-search-wrapper\">\n\t\t\t\t\t<input\n\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\tclass=\"messenger-help-search-input\"\n\t\t\t\t\t\tplaceholder=\"Search for help\"\n\t\t\t\t\t\tvalue=\"${searchQuery}\"\n\t\t\t\t\t/>\n\t\t\t\t\t<i class=\"ph ph-magnifying-glass messenger-help-search-icon\" style=\"font-size: 18px;\"></i>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-help-body\">\n\t\t\t\t<div class=\"messenger-help-collections-header\">\n\t\t\t\t\t${collectionCount} collections\n\t\t\t\t</div>\n\t\t\t\t<div class=\"messenger-help-collections\"></div>\n\t\t\t</div>\n\t\t`;\n\n\t\tthis._updateCollectionsList();\n\t\tthis._attachEvents();\n\t}\n\n\t_updateCollectionsList() {\n\t\tconst collectionsContainer = this.element.querySelector(\n\t\t\t'.messenger-help-collections'\n\t\t);\n\t\tconst collections = this.state.helpArticles || [];\n\t\tconst searchQuery = (this.state.helpSearchQuery || '').toLowerCase();\n\n\t\t// Filter collections by search\n\t\tconst filteredCollections = searchQuery\n\t\t\t? collections.filter(\n\t\t\t\t\t(c) =>\n\t\t\t\t\t\tc.title.toLowerCase().includes(searchQuery) ||\n\t\t\t\t\t\t(c.description && c.description.toLowerCase().includes(searchQuery))\n\t\t\t\t)\n\t\t\t: collections;\n\n\t\t// Update collection count\n\t\tconst headerEl = this.element.querySelector(\n\t\t\t'.messenger-help-collections-header'\n\t\t);\n\t\tif (headerEl) {\n\t\t\theaderEl.textContent = `${filteredCollections.length} collections`;\n\t\t}\n\n\t\tif (filteredCollections.length === 0) {\n\t\t\tcollectionsContainer.innerHTML = this._renderEmptyState();\n\t\t\treturn;\n\t\t}\n\n\t\tcollectionsContainer.innerHTML = filteredCollections\n\t\t\t.map((collection) => this._renderCollectionItem(collection))\n\t\t\t.join('');\n\n\t\t// Attach click events\n\t\tthis._attachCollectionEvents();\n\t}\n\n\t_renderCollectionItem(collection) {\n\t\tconst articleCount = collection.articleCount || 0;\n\t\treturn `\n\t\t\t<div class=\"messenger-help-collection\" data-collection-id=\"${collection.id}\">\n\t\t\t\t<div class=\"messenger-help-collection-content\">\n\t\t\t\t\t<h3 class=\"messenger-help-collection-title\">${collection.title}</h3>\n\t\t\t\t\t<p class=\"messenger-help-collection-desc\">${collection.description || ''}</p>\n\t\t\t\t\t<span class=\"messenger-help-collection-count\">${articleCount} articles</span>\n\t\t\t\t</div>\n\t\t\t\t<i class=\"ph ph-caret-right messenger-help-collection-arrow\" style=\"font-size: 20px;\"></i>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderEmptyState() {\n\t\tconst isSearching = this.state.helpSearchQuery;\n\n\t\tif (isSearching) {\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-help-empty\">\n\t\t\t\t\t<div class=\"messenger-help-empty-icon\">\n\t\t\t\t\t\t<i class=\"ph ph-magnifying-glass\" style=\"font-size: 48px;\"></i>\n\t\t\t\t\t</div>\n\t\t\t\t\t<h3>No results found</h3>\n\t\t\t\t\t<p>Try a different search term</p>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\treturn `\n\t\t\t<div class=\"messenger-help-empty\">\n\t\t\t\t<div class=\"messenger-help-empty-icon\">\n\t\t\t\t\t<i class=\"ph ph-question\" style=\"font-size: 48px;\"></i>\n\t\t\t\t</div>\n\t\t\t\t<h3>Help collections</h3>\n\t\t\t\t<p>No collections available yet</p>\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_attachEvents() {\n\t\t// Close button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-close-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(false);\n\t\t\t});\n\n\t\t// Search input\n\t\tconst searchInput = this.element.querySelector(\n\t\t\t'.messenger-help-search-input'\n\t\t);\n\t\tlet searchTimeout;\n\t\tsearchInput.addEventListener('input', (e) => {\n\t\t\tclearTimeout(searchTimeout);\n\t\t\tsearchTimeout = setTimeout(() => {\n\t\t\t\tthis.state.setHelpSearchQuery(e.target.value);\n\t\t\t}, 300);\n\t\t});\n\n\t\tthis._attachCollectionEvents();\n\t}\n\n\t_attachCollectionEvents() {\n\t\tthis.element\n\t\t\t.querySelectorAll('.messenger-help-collection')\n\t\t\t.forEach((item) => {\n\t\t\t\titem.addEventListener('click', () => {\n\t\t\t\t\tconst collectionId = item.dataset.collectionId;\n\t\t\t\t\tconst collection = this.state.helpArticles.find(\n\t\t\t\t\t\t(c) => c.id === collectionId\n\t\t\t\t\t);\n\t\t\t\t\tif (collection && collection.url) {\n\t\t\t\t\t\twindow.open(collection.url, '_blank');\n\t\t\t\t\t} else if (this.options.onArticleClick) {\n\t\t\t\t\t\tthis.options.onArticleClick(collection);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * HomeView - Welcome screen with team info and quick actions\n */\nexport class HomeView {\n\tconstructor(state, options = {}) {\n\t\tthis.state = state;\n\t\tthis.options = options;\n\t\tthis.element = null;\n\t\tthis._unsubscribe = null;\n\t}\n\n\trender() {\n\t\tthis.element = document.createElement('div');\n\t\tthis.element.className = 'messenger-view messenger-home-view';\n\n\t\tthis._updateContent();\n\n\t\t// Subscribe to state changes to re-render when data loads\n\t\tthis._unsubscribe = this.state.subscribe((type) => {\n\t\t\tif (type === 'homeChangelogUpdate' || type === 'conversationsUpdate') {\n\t\t\t\tthis._updateContent();\n\t\t\t}\n\t\t});\n\n\t\treturn this.element;\n\t}\n\n\t_updateContent() {\n\t\tconst avatarsHtml = this._renderAvatarStack();\n\t\tconst recentChangelogHtml = this._renderRecentChangelog();\n\n\t\tthis.element.innerHTML = `\n\t\t\t<div class=\"messenger-home-header\">\n\t\t\t\t<div class=\"messenger-home-header-top\">\n\t\t\t\t\t<div class=\"messenger-home-logo\">\n\t\t\t\t\t\t${this.options.logoUrl ? `<img src=\"${this.options.logoUrl}\" alt=\"${this.state.teamName}\" />` : ''}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"messenger-home-avatars\">${avatarsHtml}</div>\n\t\t\t\t\t<button class=\"messenger-close-btn\" aria-label=\"Close\">\n\t\t\t\t\t\t<i class=\"ph ph-x\" style=\"font-size: 20px;\"></i>\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"messenger-home-welcome\">\n\t\t\t\t\t<span class=\"messenger-home-greeting\">Hello there.</span>\n\t\t\t\t\t<span class=\"messenger-home-question\">${this.state.welcomeMessage}</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"messenger-home-body\">\n\t\t\t\t<button class=\"messenger-home-message-btn\">\n\t\t\t\t\t<span>Send us a message</span>\n\t\t\t\t\t<i class=\"ph ph-arrow-right\" style=\"font-size: 16px;\"></i>\n\t\t\t\t</button>\n\n\t\t\t\t${this._renderFeaturedCard()}\n\n\t\t\t\t${recentChangelogHtml}\n\t\t\t</div>\n\t\t`;\n\n\t\tthis._attachEvents();\n\t}\n\n\t_renderAvatarStack() {\n\t\tconst avatars = this.state.teamAvatars;\n\t\tif (!avatars || avatars.length === 0) {\n\t\t\t// Default avatars with initials\n\t\t\treturn `\n\t\t\t\t<div class=\"messenger-avatar-stack\">\n\t\t\t\t\t<div class=\"messenger-avatar\" style=\"background: #5856d6;\">S</div>\n\t\t\t\t\t<div class=\"messenger-avatar\" style=\"background: #007aff;\">T</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\tconst avatarItems = avatars\n\t\t\t.slice(0, 3)\n\t\t\t.map((avatar, i) => {\n\t\t\t\tif (typeof avatar === 'string' && avatar.startsWith('http')) {\n\t\t\t\t\treturn `<img class=\"messenger-avatar\" src=\"${avatar}\" alt=\"Team member\" style=\"z-index: ${3 - i};\" />`;\n\t\t\t\t}\n\t\t\t\treturn `<div class=\"messenger-avatar\" style=\"background: ${this._getAvatarColor(i)}; z-index: ${3 - i};\">${avatar.charAt(0).toUpperCase()}</div>`;\n\t\t\t})\n\t\t\t.join('');\n\n\t\treturn `<div class=\"messenger-avatar-stack\">${avatarItems}</div>`;\n\t}\n\n\t_getAvatarColor(index) {\n\t\tconst colors = ['#5856d6', '#007aff', '#34c759', '#ff9500', '#ff3b30'];\n\t\treturn colors[index % colors.length];\n\t}\n\n\t_renderFeaturedCard() {\n\t\t// Only show if there's featured content configured\n\t\tif (!this.options.featuredContent) {\n\t\t\treturn '';\n\t\t}\n\n\t\tconst { title, description, imageUrl, action } =\n\t\t\tthis.options.featuredContent;\n\n\t\treturn `\n\t\t\t<div class=\"messenger-home-featured\">\n\t\t\t\t${imageUrl ? `<img src=\"${imageUrl}\" alt=\"${title}\" class=\"messenger-home-featured-image\" onerror=\"this.style.display='none';\" />` : ''}\n\t\t\t\t<div class=\"messenger-home-featured-content\">\n\t\t\t\t\t<h3>${title}</h3>\n\t\t\t\t\t<p>${description}</p>\n\t\t\t\t</div>\n\t\t\t\t${action ? `<button class=\"messenger-home-featured-btn\" data-action=\"${action.type}\" data-value=\"${action.value}\">${action.label}</button>` : ''}\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_renderRecentChangelog() {\n\t\t// Show recent changelog preview as cards with images\n\t\tconst changelogItems = this.state.homeChangelogItems;\n\t\tif (changelogItems.length === 0) {\n\t\t\treturn '';\n\t\t}\n\n\t\tconst changelogHtml = changelogItems\n\t\t\t.map(\n\t\t\t\t(item) => `\n\t\t\t<div class=\"messenger-home-changelog-card\" data-changelog-id=\"${item.id}\">\n\t\t\t\t${\n\t\t\t\t\titem.coverImage\n\t\t\t\t\t\t? `\n\t\t\t\t\t<div class=\"messenger-home-changelog-cover\">\n\t\t\t\t\t\t<img src=\"${item.coverImage}\" alt=\"${item.title}\" onerror=\"this.style.display='none';\" />\n\t\t\t\t\t\t${item.coverText ? `<span class=\"messenger-home-changelog-cover-text\">${item.coverText}</span>` : ''}\n\t\t\t\t\t</div>\n\t\t\t\t`\n\t\t\t\t\t\t: ''\n\t\t\t\t}\n\t\t\t\t<div class=\"messenger-home-changelog-card-content\">\n\t\t\t\t\t<h4 class=\"messenger-home-changelog-card-title\">${item.title}</h4>\n\t\t\t\t\t<p class=\"messenger-home-changelog-card-desc\">${item.description || ''}</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t`\n\t\t\t)\n\t\t\t.join('');\n\n\t\treturn `\n\t\t\t<div class=\"messenger-home-changelog-section\">\n\t\t\t\t${changelogHtml}\n\t\t\t</div>\n\t\t`;\n\t}\n\n\t_formatDate(dateString) {\n\t\tif (!dateString) return '';\n\t\tconst date = new Date(dateString);\n\t\tconst now = new Date();\n\t\tconst diffDays = Math.floor((now - date) / (1000 * 60 * 60 * 24));\n\n\t\tif (diffDays === 0) return 'Today';\n\t\tif (diffDays === 1) return 'Yesterday';\n\t\tif (diffDays < 7) return `${diffDays}d ago`;\n\t\treturn date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n\t}\n\n\t_attachEvents() {\n\t\t// Close button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-close-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setOpen(false);\n\t\t\t});\n\n\t\t// Send message button\n\t\tthis.element\n\t\t\t.querySelector('.messenger-home-message-btn')\n\t\t\t.addEventListener('click', () => {\n\t\t\t\tthis.state.setView('messages');\n\t\t\t});\n\n\t\t// Changelog items\n\t\tthis.element\n\t\t\t.querySelectorAll('.messenger-home-changelog-item')\n\t\t\t.forEach((item) => {\n\t\t\t\titem.addEventListener('click', () => {\n\t\t\t\t\t// Navigate to changelog view with specific item selected\n\t\t\t\t\tthis.state.setView('changelog');\n\t\t\t\t});\n\t\t\t});\n\n\t\t// See all changelog\n\t\tconst seeAllBtn = this.element.querySelector(\n\t\t\t'.messenger-home-changelog-all'\n\t\t);\n\t\tif (seeAllBtn) {\n\t\t\tseeAllBtn.addEventListener('click', () => {\n\t\t\t\tthis.state.setView('changelog');\n\t\t\t});\n\t\t}\n\n\t\t// Featured card action\n\t\tconst featuredBtn = this.element.querySelector(\n\t\t\t'.messenger-home-featured-btn'\n\t\t);\n\t\tif (featuredBtn) {\n\t\t\tfeaturedBtn.addEventListener('click', () => {\n\t\t\t\tconst action = featuredBtn.dataset.action;\n\t\t\t\tconst value = featuredBtn.dataset.value;\n\t\t\t\tif (action === 'url') {\n\t\t\t\t\twindow.open(value, '_blank');\n\t\t\t\t} else if (action === 'view') {\n\t\t\t\t\tthis.state.setView(value);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this._unsubscribe) {\n\t\t\tthis._unsubscribe();\n\t\t}\n\t\tif (this.element && this.element.parentNode) {\n\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t}\n\t}\n}\n","/**\n * MessengerWidget - Full-featured Messenger/Chat widget\n */\nimport { BaseWidget } from './BaseWidget.js';\nimport { MessengerState } from './messenger/MessengerState.js';\nimport { MessengerLauncher } from './messenger/components/MessengerLauncher.js';\nimport { MessengerPanel } from './messenger/components/MessengerPanel.js';\nimport { ChangelogView } from './messenger/views/ChangelogView.js';\nimport { ChatView } from './messenger/views/ChatView.js';\nimport { ConversationsView } from './messenger/views/ConversationsView.js';\nimport { HelpView } from './messenger/views/HelpView.js';\nimport { HomeView } from './messenger/views/HomeView.js';\n\nexport class MessengerWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'messenger' });\n\n\t\tthis.messengerOptions = {\n\t\t\tposition: options.position || 'bottom-right',\n\t\t\ttheme: options.theme || 'light',\n\t\t\tteamName: options.teamName || 'Support',\n\t\t\tteamAvatars: options.teamAvatars || [],\n\t\t\twelcomeMessage: options.welcomeMessage || 'How can we help?',\n\t\t\tenableHelp: options.enableHelp !== false,\n\t\t\tenableChangelog: options.enableChangelog !== false,\n\t\t\tlogoUrl: options.logoUrl || 'https://feedback-sdk.product7.io/p7.png',\n\t\t\tfeaturedContent: options.featuredContent || null,\n\t\t\tprimaryColor: options.primaryColor || '#1c1c1e',\n\t\t\t// Callbacks\n\t\t\tonSendMessage: options.onSendMessage || null,\n\t\t\tonArticleClick: options.onArticleClick || null,\n\t\t\tonChangelogClick: options.onChangelogClick || null,\n\t\t};\n\n\t\t// Create state\n\t\tthis.messengerState = new MessengerState({\n\t\t\tteamName: this.messengerOptions.teamName,\n\t\t\tteamAvatars: this.messengerOptions.teamAvatars,\n\t\t\twelcomeMessage: this.messengerOptions.welcomeMessage,\n\t\t\tenableHelp: this.messengerOptions.enableHelp,\n\t\t\tenableChangelog: this.messengerOptions.enableChangelog,\n\t\t\tuserContext: this.sdk?.apiService?.getUserContext() || null,\n\t\t});\n\n\t\tthis.launcher = null;\n\t\tthis.panel = null;\n\n\t\t// Bind methods\n\t\tthis._handleOpenChange = this._handleOpenChange.bind(this);\n\t}\n\n\t_render() {\n\t\t// Create container\n\t\tconst container = document.createElement('div');\n\t\tcontainer.className = `messenger-widget theme-${this.messengerOptions.theme}`;\n\t\tcontainer.style.zIndex = '999999';\n\n\t\t// Create launcher\n\t\tthis.launcher = new MessengerLauncher(this.messengerState, {\n\t\t\tposition: this.messengerOptions.position,\n\t\t\tprimaryColor: this.messengerOptions.primaryColor,\n\t\t});\n\t\tcontainer.appendChild(this.launcher.render());\n\n\t\t// Create panel\n\t\tthis.panel = new MessengerPanel(this.messengerState, {\n\t\t\tposition: this.messengerOptions.position,\n\t\t\ttheme: this.messengerOptions.theme,\n\t\t\tprimaryColor: this.messengerOptions.primaryColor,\n\t\t\tlogoUrl: this.messengerOptions.logoUrl,\n\t\t\tfeaturedContent: this.messengerOptions.featuredContent,\n\t\t\tonSendMessage:\n\t\t\t\tthis.messengerOptions.onSendMessage ||\n\t\t\t\tthis._handleSendMessage.bind(this),\n\t\t\tonArticleClick: this.messengerOptions.onArticleClick,\n\t\t\tonChangelogClick: this.messengerOptions.onChangelogClick,\n\t\t});\n\n\t\t// Register views\n\t\tthis.panel.registerView('home', HomeView);\n\t\tthis.panel.registerView('messages', ConversationsView);\n\t\tthis.panel.registerView('chat', ChatView);\n\t\tthis.panel.registerView('help', HelpView);\n\t\tthis.panel.registerView('changelog', ChangelogView);\n\n\t\tcontainer.appendChild(this.panel.render());\n\t\tthis.panel.hide();\n\n\t\treturn container;\n\t}\n\n\t_attachEvents() {\n\t\t// Subscribe to state changes\n\t\tthis._stateUnsubscribe = this.messengerState.subscribe((type, data) => {\n\t\t\tif (type === 'openChange') {\n\t\t\t\tthis._handleOpenChange(data.isOpen);\n\t\t\t}\n\t\t});\n\t}\n\n\t_handleOpenChange(isOpen) {\n\t\tif (isOpen) {\n\t\t\tthis.panel.show();\n\t\t\tthis.sdk.eventBus.emit('messenger:opened', { widget: this });\n\t\t} else {\n\t\t\tthis.panel.hide();\n\t\t\tthis.messengerState.reset();\n\t\t\tthis.sdk.eventBus.emit('messenger:closed', { widget: this });\n\t\t}\n\t}\n\n\tasync _handleSendMessage(conversationId, message) {\n\t\t// Default message handler - can be overridden\n\t\tthis.sdk.eventBus.emit('messenger:messageSent', {\n\t\t\twidget: this,\n\t\t\tconversationId,\n\t\t\tmessage,\n\t\t});\n\n\t\t// In mock mode, simulate a response\n\t\tif (this.apiService?.mock) {\n\t\t\tsetTimeout(() => {\n\t\t\t\tconst response = {\n\t\t\t\t\tid: 'msg_' + Date.now(),\n\t\t\t\t\tcontent: \"Thanks for your message! We'll get back to you soon.\",\n\t\t\t\t\tisOwn: false,\n\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t\tsender: {\n\t\t\t\t\t\tname: 'Support Team',\n\t\t\t\t\t\tavatarUrl: null,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\tthis.messengerState.addMessage(conversationId, response);\n\t\t\t}, 1500);\n\t\t}\n\t}\n\n\t/**\n\t * Open the messenger panel\n\t */\n\topen() {\n\t\tthis.messengerState.setOpen(true);\n\t}\n\n\t/**\n\t * Close the messenger panel\n\t */\n\tclose() {\n\t\tthis.messengerState.setOpen(false);\n\t}\n\n\t/**\n\t * Toggle the messenger panel\n\t */\n\ttoggle() {\n\t\tthis.messengerState.setOpen(!this.messengerState.isOpen);\n\t}\n\n\t/**\n\t * Navigate to a specific view\n\t */\n\tnavigateTo(view) {\n\t\tthis.messengerState.setView(view);\n\t\tif (!this.messengerState.isOpen) {\n\t\t\tthis.open();\n\t\t}\n\t}\n\n\t/**\n\t * Set conversations\n\t */\n\tsetConversations(conversations) {\n\t\tthis.messengerState.setConversations(conversations);\n\t}\n\n\t/**\n\t * Add a message to a conversation\n\t */\n\taddMessage(conversationId, message) {\n\t\tthis.messengerState.addMessage(conversationId, message);\n\t}\n\n\t/**\n\t * Set help articles\n\t */\n\tsetHelpArticles(articles) {\n\t\tthis.messengerState.setHelpArticles(articles);\n\t}\n\n\t/**\n\t * Set home changelog items\n\t */\n\tsetHomeChangelogItems(items) {\n\t\tthis.messengerState.setHomeChangelogItems(items);\n\t}\n\n\t/**\n\t * Set changelog items\n\t */\n\tsetChangelogItems(items) {\n\t\tthis.messengerState.setChangelogItems(items);\n\t}\n\n\t/**\n\t * Update unread count (for external updates)\n\t */\n\tsetUnreadCount(count) {\n\t\tthis.messengerState.unreadCount = count;\n\t\tthis.messengerState._notify('unreadCountChange', { count });\n\t}\n\n\t/**\n\t * Get current state\n\t */\n\tgetState() {\n\t\treturn {\n\t\t\tisOpen: this.messengerState.isOpen,\n\t\t\tcurrentView: this.messengerState.currentView,\n\t\t\tunreadCount: this.messengerState.unreadCount,\n\t\t\tconversations: this.messengerState.conversations,\n\t\t};\n\t}\n\n\t/**\n\t * Load initial data (mock or API)\n\t */\n\tasync loadInitialData() {\n\t\t// Load conversations\n\t\ttry {\n\t\t\tconst conversations = await this._fetchConversations();\n\t\t\tthis.messengerState.setConversations(conversations);\n\t\t} catch (error) {\n\t\t\tconsole.error('[MessengerWidget] Failed to load conversations:', error);\n\t\t}\n\n\t\t// Load help articles if enabled\n\t\tif (this.messengerOptions.enableHelp) {\n\t\t\ttry {\n\t\t\t\tconst articles = await this._fetchHelpArticles();\n\t\t\t\tthis.messengerState.setHelpArticles(articles);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[MessengerWidget] Failed to load help articles:', error);\n\t\t\t}\n\t\t}\n\n\t\t// Load changelog if enabled\n\t\tif (this.messengerOptions.enableChangelog) {\n\t\t\ttry {\n\t\t\t\tconst { homeItems, changelogItems } = await this._fetchChangelog();\n\t\t\t\tthis.messengerState.setHomeChangelogItems(homeItems);\n\t\t\t\tthis.messengerState.setChangelogItems(changelogItems);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[MessengerWidget] Failed to load changelog:', error);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync _fetchConversations() {\n\t\t// Mock data for now\n\t\tif (this.apiService?.mock) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tid: 'conv_1',\n\t\t\t\t\ttitle: 'Chat with Sarah',\n\t\t\t\t\tparticipants: [{ name: 'Sarah', avatarUrl: null }],\n\t\t\t\t\tlastMessage: \"Sarah: Hi 👋 I'm Sarah. How can I help today?\",\n\t\t\t\t\tlastMessageTime: new Date(Date.now() - 49 * 60 * 1000).toISOString(),\n\t\t\t\t\tunread: 1,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 'conv_2',\n\t\t\t\t\ttitle: 'Chat with Tom',\n\t\t\t\t\tparticipants: [{ name: 'Tom', avatarUrl: null }],\n\t\t\t\t\tlastMessage: 'Tom: The feature will be available next week.',\n\t\t\t\t\tlastMessageTime: new Date(\n\t\t\t\t\t\tDate.now() - 6 * 24 * 60 * 60 * 1000\n\t\t\t\t\t).toISOString(),\n\t\t\t\t\tunread: 0,\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\n\t\t// TODO: Implement API call\n\t\treturn [];\n\t}\n\n\tasync _fetchHelpArticles() {\n\t\t// Mock data for collections\n\t\tif (this.apiService?.mock) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tid: 'collection_1',\n\t\t\t\t\ttitle: 'Product Overview',\n\t\t\t\t\tdescription: 'See how your AI-first customer service solution works.',\n\t\t\t\t\tarticleCount: 24,\n\t\t\t\t\turl: '#',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 'collection_2',\n\t\t\t\t\ttitle: 'Getting Started',\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Everything you need to know to get started with Product7.',\n\t\t\t\t\tarticleCount: 30,\n\t\t\t\t\turl: '#',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 'collection_3',\n\t\t\t\t\ttitle: 'AI Agent',\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Resolving customer questions instantly and accurately—from live chat to email.',\n\t\t\t\t\tarticleCount: 82,\n\t\t\t\t\turl: '#',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 'collection_4',\n\t\t\t\t\ttitle: 'Channels',\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Enabling the channels you use to communicate with customers, all from the Inbox.',\n\t\t\t\t\tarticleCount: 45,\n\t\t\t\t\turl: '#',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 'collection_5',\n\t\t\t\t\ttitle: 'Billing & Payments',\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Manage your subscription, invoices, and payment methods.',\n\t\t\t\t\tarticleCount: 12,\n\t\t\t\t\turl: '#',\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\n\t\t// TODO: Implement API call\n\t\treturn [];\n\t}\n\n\tasync _fetchChangelog() {\n\t\t// Mock data for now - simulating changelog API response\n\t\tif (this.apiService?.mock) {\n\t\t\treturn {\n\t\t\t\thomeItems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: 'changelog_5',\n\t\t\t\t\t\ttitle: 'New integrations available',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Connect with more tools you love and streamline your workflow.',\n\t\t\t\t\t\ttags: ['Integration'],\n\t\t\t\t\t\tcoverImage: 'https://feedback-sdk.product7.io/700x400__5_.png',\n\t\t\t\t\t\tcoverText: null,\n\t\t\t\t\t\tpublishedAt: new Date(\n\t\t\t\t\t\t\tDate.now() - 14 * 24 * 60 * 60 * 1000\n\t\t\t\t\t\t).toISOString(),\n\t\t\t\t\t\turl: '#',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: 'changelog_2',\n\t\t\t\t\t\ttitle: 'A new era of Insights has arrived',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'We announced Fin Insights, a groundbreaking, AI-powered product that gives you complete visibility into every customer conversation.',\n\t\t\t\t\t\ttags: ['New feature', 'AI'],\n\t\t\t\t\t\tcoverImage:\n\t\t\t\t\t\t\t'https://feedback-sdk.product7.io/Intercom_Messenger__1_.jpg',\n\t\t\t\t\t\tcoverText: 'Watch our major product launch on-demand',\n\t\t\t\t\t\tpublishedAt: new Date(\n\t\t\t\t\t\t\tDate.now() - 5 * 24 * 60 * 60 * 1000\n\t\t\t\t\t\t).toISOString(),\n\t\t\t\t\t\turl: '#',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: 'changelog_1',\n\t\t\t\t\t\ttitle: 'The 2025 Customer Service Transformation Report',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Learn how AI has transformed customer service from the ground up—rewriting its economics and reshaping expectations.',\n\t\t\t\t\t\ttags: ['Report'],\n\t\t\t\t\t\tcoverImage:\n\t\t\t\t\t\t\t'https://feedback-sdk.product7.io/Main_Report_Email_Header.png',\n\t\t\t\t\t\tcoverText: 'Customer service trends as we know them are dead.',\n\t\t\t\t\t\tpublishedAt: new Date(\n\t\t\t\t\t\t\tDate.now() - 2 * 24 * 60 * 60 * 1000\n\t\t\t\t\t\t).toISOString(),\n\t\t\t\t\t\turl: '#',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tchangelogItems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: 'changelog_4',\n\t\t\t\t\t\ttitle: 'Enhanced conversation analytics',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Get deeper insights into your customer conversations with our new analytics dashboard.',\n\t\t\t\t\t\ttags: ['Analytics'],\n\t\t\t\t\t\tcoverImage:\n\t\t\t\t\t\t\t'https://feedback-sdk.product7.io/cgangelog-Frame%202087334450.jpg',\n\t\t\t\t\t\tcoverText: null,\n\t\t\t\t\t\tpublishedAt: new Date(\n\t\t\t\t\t\t\tDate.now() - 10 * 24 * 60 * 60 * 1000\n\t\t\t\t\t\t).toISOString(),\n\t\t\t\t\t\turl: '#',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: 'changelog_3',\n\t\t\t\t\t\ttitle: 'Escalation guidance for complex issues',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'New AI-powered escalation guidance helps your team handle complex customer issues more effectively.',\n\t\t\t\t\t\ttags: ['New feature', 'AI'],\n\t\t\t\t\t\tcoverImage:\n\t\t\t\t\t\t\t'https://feedback-sdk.product7.io/cgangelog-image-escalation-guidance-event@2x.png',\n\t\t\t\t\t\tcoverText: null,\n\t\t\t\t\t\tpublishedAt: new Date(\n\t\t\t\t\t\t\tDate.now() - 7 * 24 * 60 * 60 * 1000\n\t\t\t\t\t\t).toISOString(),\n\t\t\t\t\t\turl: '#',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t};\n\t\t}\n\n\t\t// TODO: Implement API call for changelogs\n\t\treturn { homeItems: [], changelogItems: [] };\n\t}\n\n\tonMount() {\n\t\t// Load initial data after mounting\n\t\tthis.loadInitialData();\n\t}\n\n\tonDestroy() {\n\t\tif (this._stateUnsubscribe) {\n\t\t\tthis._stateUnsubscribe();\n\t\t}\n\t}\n\n\tdestroy() {\n\t\tif (this.launcher) {\n\t\t\tthis.launcher.destroy();\n\t\t}\n\t\tif (this.panel) {\n\t\t\tthis.panel.destroy();\n\t\t}\n\t\tsuper.destroy();\n\t}\n}\n","import { BaseWidget } from './BaseWidget.js';\n\nexport class SurveyWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'survey' });\n\n\t\tthis.surveyOptions = {\n\t\t\tsurveyId: options.surveyId || null, // Backend survey ID for API calls\n\t\t\tsurveyType: options.surveyType || 'nps', // 'nps', 'csat', 'ces', 'custom'\n\t\t\tposition: options.position || 'bottom-right', // 'bottom-right', 'bottom-left', 'center', 'bottom'\n\t\t\ttitle: options.title || null,\n\t\t\tdescription: options.description || null,\n\t\t\tlowLabel: options.lowLabel || null,\n\t\t\thighLabel: options.highLabel || null,\n\t\t\tcustomQuestions: options.customQuestions || [],\n\t\t\ttheme: options.theme || 'light',\n\t\t\tonSubmit: options.onSubmit || null,\n\t\t\tonDismiss: options.onDismiss || null,\n\t\t};\n\n\t\tthis.surveyState = {\n\t\t\tscore: null,\n\t\t\tfeedback: '',\n\t\t\tcustomAnswers: {},\n\t\t\tisVisible: false,\n\t\t};\n\t}\n\n\t_render() {\n\t\t// Survey widget doesn't render a trigger button, it's shown programmatically\n\t\tconst container = document.createElement('div');\n\t\tcontainer.className = 'feedback-survey-container';\n\t\tcontainer.style.display = 'none';\n\t\treturn container;\n\t}\n\n\t_attachEvents() {\n\t\t// Events are attached when survey is shown\n\t}\n\n\tshow() {\n\t\tthis._renderSurvey();\n\t\tthis.surveyState.isVisible = true;\n\t\tthis.sdk.eventBus.emit('survey:shown', {\n\t\t\twidget: this,\n\t\t\ttype: this.surveyOptions.surveyType,\n\t\t});\n\t\treturn this;\n\t}\n\n\thide() {\n\t\tthis._closeSurvey();\n\t\treturn this;\n\t}\n\n\t_renderSurvey() {\n\t\t// Remove any existing survey\n\t\tthis._closeSurvey();\n\n\t\tconst config = this._getSurveyConfig();\n\t\tconst positionStyles = this._getPositionStyles();\n\t\tconst themeStyles =\n\t\t\tthis.surveyOptions.theme === 'dark'\n\t\t\t\t? 'background: #1a1a1a; color: #fff;'\n\t\t\t\t: 'background: #fff; color: #1d1d1f;';\n\n\t\t// Create backdrop for center position\n\t\tif (this.surveyOptions.position === 'center') {\n\t\t\tthis.backdropElement = document.createElement('div');\n\t\t\tthis.backdropElement.className = 'feedback-survey-backdrop';\n\t\t\tdocument.body.appendChild(this.backdropElement);\n\t\t\tthis.backdropElement.addEventListener('click', () =>\n\t\t\t\tthis._handleDismiss()\n\t\t\t);\n\t\t}\n\n\t\tthis.surveyElement = document.createElement('div');\n\t\tthis.surveyElement.className = `feedback-survey feedback-survey-${this.surveyOptions.position} theme-${this.surveyOptions.theme}`;\n\t\tthis.surveyElement.style.cssText = `position: fixed; ${positionStyles} z-index: 10000; ${themeStyles} border-radius: 16px; box-shadow: 0 20px 60px rgba(0,0,0,0.3); padding: 24px; min-width: 320px; max-width: 400px; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;`;\n\n\t\tthis.surveyElement.innerHTML = `\n\t\t\t<button class=\"feedback-survey-close\" style=\"position: absolute; top: 12px; right: 12px; background: none; border: none; font-size: 20px; cursor: pointer; color: ${this.surveyOptions.theme === 'dark' ? '#888' : '#86868b'}; line-height: 1;\">&times;</button>\n\t\t\t<h3 class=\"feedback-survey-title\" style=\"margin: 0 0 8px 0; font-size: 18px; font-weight: 600; padding-right: 24px;\">${config.title}</h3>\n\t\t\t<p class=\"feedback-survey-description\" style=\"color: ${this.surveyOptions.theme === 'dark' ? '#aaa' : '#86868b'}; margin: 0 0 20px 0; font-size: 14px;\">${config.description}</p>\n\t\t\t<div class=\"feedback-survey-content\">${config.html}</div>\n\t\t\t<div class=\"feedback-survey-feedback\" style=\"margin-top: 16px;\">\n\t\t\t\t<textarea class=\"feedback-survey-textarea\" placeholder=\"Any additional feedback? (optional)\" style=\"width: 100%; padding: 12px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#333' : '#d2d2d7'}; border-radius: 8px; font-size: 14px; resize: none; height: 80px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#fff'}; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; font-family: inherit; box-sizing: border-box;\"></textarea>\n\t\t\t</div>\n\t\t\t<button class=\"feedback-survey-submit\" style=\"width: 100%; margin-top: 12px; padding: 12px; background: #007aff; color: white; border: none; border-radius: 8px; font-size: 14px; font-weight: 500; cursor: pointer; font-family: inherit;\">Submit</button>\n\t\t`;\n\n\t\tdocument.body.appendChild(this.surveyElement);\n\t\tthis._attachSurveyEvents();\n\n\t\t// Animate in\n\t\trequestAnimationFrame(() => {\n\t\t\tthis.surveyElement.style.opacity = '1';\n\t\t\tthis.surveyElement.style.transform =\n\t\t\t\tthis.surveyOptions.position === 'center'\n\t\t\t\t\t? 'translate(-50%, -50%) scale(1)'\n\t\t\t\t\t: 'translateY(0)';\n\t\t});\n\t}\n\n\t_getSurveyConfig() {\n\t\tconst configs = {\n\t\t\tnps: {\n\t\t\t\ttitle:\n\t\t\t\t\tthis.surveyOptions.title || 'How likely are you to recommend us?',\n\t\t\t\tdescription:\n\t\t\t\t\tthis.surveyOptions.description ||\n\t\t\t\t\t'On a scale of 0-10, how likely are you to recommend our product to a friend or colleague?',\n\t\t\t\thtml: `\n\t\t\t\t\t<div class=\"feedback-survey-nps\" style=\"display: flex; justify-content: space-between; gap: 4px;\">\n\t\t\t\t\t\t${[...Array(11).keys()]\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(n) => `\n\t\t\t\t\t\t\t<button class=\"feedback-survey-nps-btn\" data-score=\"${n}\" style=\"width: 28px; height: 36px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 6px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa'}; cursor: pointer; font-size: 12px; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; transition: all 0.15s;\">${n}</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style=\"display: flex; justify-content: space-between; margin-top: 8px; font-size: 11px; color: ${this.surveyOptions.theme === 'dark' ? '#888' : '#86868b'};\">\n\t\t\t\t\t\t<span>${this.surveyOptions.lowLabel || 'Not likely'}</span>\n\t\t\t\t\t\t<span>${this.surveyOptions.highLabel || 'Very likely'}</span>\n\t\t\t\t\t</div>\n\t\t\t\t`,\n\t\t\t},\n\t\t\tcsat: {\n\t\t\t\ttitle: this.surveyOptions.title || 'How satisfied are you?',\n\t\t\t\tdescription:\n\t\t\t\t\tthis.surveyOptions.description ||\n\t\t\t\t\t'How would you rate your overall satisfaction with our product?',\n\t\t\t\thtml: `\n\t\t\t\t\t<div class=\"feedback-survey-csat\" style=\"display: flex; justify-content: center; gap: 16px;\">\n\t\t\t\t\t\t${['😞', '😕', '😐', '🙂', '😄']\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(emoji, i) => `\n\t\t\t\t\t\t\t<button class=\"feedback-survey-csat-btn\" data-score=\"${i + 1}\" style=\"background: none; border: none; cursor: pointer; font-size: 36px; transition: transform 0.15s; padding: 8px;\">${emoji}</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div style=\"display: flex; justify-content: space-between; margin-top: 8px; font-size: 11px; color: ${this.surveyOptions.theme === 'dark' ? '#888' : '#86868b'};\">\n\t\t\t\t\t\t<span>${this.surveyOptions.lowLabel || 'Very dissatisfied'}</span>\n\t\t\t\t\t\t<span>${this.surveyOptions.highLabel || 'Very satisfied'}</span>\n\t\t\t\t\t</div>\n\t\t\t\t`,\n\t\t\t},\n\t\t\tces: {\n\t\t\t\ttitle: this.surveyOptions.title || 'How easy was it?',\n\t\t\t\tdescription:\n\t\t\t\t\tthis.surveyOptions.description ||\n\t\t\t\t\t'How easy was it to accomplish your task today?',\n\t\t\t\thtml: `\n\t\t\t\t\t<div class=\"feedback-survey-ces\" style=\"display: flex; justify-content: space-between; gap: 8px;\">\n\t\t\t\t\t\t${['Very Difficult', 'Difficult', 'Neutral', 'Easy', 'Very Easy']\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(label, i) => `\n\t\t\t\t\t\t\t<button class=\"feedback-survey-ces-btn\" data-score=\"${i + 1}\" style=\"flex: 1; padding: 12px 8px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa'}; cursor: pointer; font-size: 11px; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; transition: all 0.15s;\">${label}</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t</div>\n\t\t\t\t`,\n\t\t\t},\n\t\t\tcustom: {\n\t\t\t\ttitle: this.surveyOptions.title || 'Quick Feedback',\n\t\t\t\tdescription:\n\t\t\t\t\tthis.surveyOptions.description ||\n\t\t\t\t\t'Help us improve by answering a few questions.',\n\t\t\t\thtml: this._renderCustomQuestions(),\n\t\t\t},\n\t\t};\n\n\t\treturn configs[this.surveyOptions.surveyType] || configs.nps;\n\t}\n\n\t_renderCustomQuestions() {\n\t\tif (\n\t\t\t!this.surveyOptions.customQuestions ||\n\t\t\tthis.surveyOptions.customQuestions.length === 0\n\t\t) {\n\t\t\t// Default custom questions\n\t\t\treturn `\n\t\t\t\t<div style=\"margin-bottom: 16px;\">\n\t\t\t\t\t<label style=\"display: block; margin-bottom: 6px; font-size: 13px; font-weight: 500;\">What feature do you use most?</label>\n\t\t\t\t\t<select class=\"feedback-survey-select\" data-question=\"feature\" style=\"width: 100%; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; font-size: 14px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#fff'}; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'};\">\n\t\t\t\t\t\t<option value=\"\">Select a feature</option>\n\t\t\t\t\t\t<option value=\"feedback\">Feedback Collection</option>\n\t\t\t\t\t\t<option value=\"surveys\">Surveys</option>\n\t\t\t\t\t\t<option value=\"analytics\">Analytics</option>\n\t\t\t\t\t\t<option value=\"integrations\">Integrations</option>\n\t\t\t\t\t</select>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<label style=\"display: block; margin-bottom: 6px; font-size: 13px; font-weight: 500;\">How often do you use it?</label>\n\t\t\t\t\t<div class=\"feedback-survey-frequency\" style=\"display: flex; gap: 8px;\">\n\t\t\t\t\t\t${['Daily', 'Weekly', 'Monthly', 'Rarely']\n\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t(freq) => `\n\t\t\t\t\t\t\t<button class=\"feedback-survey-freq-btn\" data-freq=\"${freq}\" style=\"flex: 1; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa'}; cursor: pointer; font-size: 12px; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; transition: all 0.15s;\">${freq}</button>\n\t\t\t\t\t\t`\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.join('')}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t`;\n\t\t}\n\n\t\treturn this.surveyOptions.customQuestions\n\t\t\t.map(\n\t\t\t\t(q, index) => `\n\t\t\t<div style=\"margin-bottom: 16px;\">\n\t\t\t\t<label style=\"display: block; margin-bottom: 6px; font-size: 13px; font-weight: 500;\">${q.label}</label>\n\t\t\t\t${this._renderQuestionInput(q, index)}\n\t\t\t</div>\n\t\t`\n\t\t\t)\n\t\t\t.join('');\n\t}\n\n\t_renderQuestionInput(question, index) {\n\t\tswitch (question.type) {\n\t\t\tcase 'select':\n\t\t\t\treturn `\n\t\t\t\t\t<select class=\"feedback-survey-select\" data-question=\"${question.id || index}\" style=\"width: 100%; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; font-size: 14px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#fff'}; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'};\">\n\t\t\t\t\t\t<option value=\"\">${question.placeholder || 'Select an option'}</option>\n\t\t\t\t\t\t${question.options.map((opt) => `<option value=\"${opt.value}\">${opt.label}</option>`).join('')}\n\t\t\t\t\t</select>\n\t\t\t\t`;\n\t\t\tcase 'text':\n\t\t\t\treturn `\n\t\t\t\t\t<input type=\"text\" class=\"feedback-survey-input\" data-question=\"${question.id || index}\" placeholder=\"${question.placeholder || ''}\" style=\"width: 100%; padding: 10px; border: 1px solid ${this.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7'}; border-radius: 8px; font-size: 14px; background: ${this.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#fff'}; color: ${this.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f'}; box-sizing: border-box;\">\n\t\t\t\t`;\n\t\t\tdefault:\n\t\t\t\treturn '';\n\t\t}\n\t}\n\n\t_getPositionStyles() {\n\t\tconst positions = {\n\t\t\t'bottom-right':\n\t\t\t\t'bottom: 24px; right: 24px; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;',\n\t\t\t'bottom-left':\n\t\t\t\t'bottom: 24px; left: 24px; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;',\n\t\t\tcenter:\n\t\t\t\t'top: 50%; left: 50%; transform: translate(-50%, -50%) scale(0.95); opacity: 0; transition: all 0.3s ease;',\n\t\t\tbottom:\n\t\t\t\t'bottom: 0; left: 0; right: 0; border-radius: 16px 16px 0 0; max-width: none; opacity: 0; transform: translateY(20px); transition: all 0.3s ease;',\n\t\t};\n\t\treturn positions[this.surveyOptions.position] || positions['bottom-right'];\n\t}\n\n\t_attachSurveyEvents() {\n\t\tif (!this.surveyElement) return;\n\n\t\t// Close button\n\t\tconst closeBtn = this.surveyElement.querySelector('.feedback-survey-close');\n\t\tcloseBtn.addEventListener('click', () => this._handleDismiss());\n\n\t\t// Submit button\n\t\tconst submitBtn = this.surveyElement.querySelector(\n\t\t\t'.feedback-survey-submit'\n\t\t);\n\t\tsubmitBtn.addEventListener('click', () => this._handleSubmit());\n\n\t\t// Feedback textarea\n\t\tconst textarea = this.surveyElement.querySelector(\n\t\t\t'.feedback-survey-textarea'\n\t\t);\n\t\ttextarea.addEventListener('input', (e) => {\n\t\t\tthis.surveyState.feedback = e.target.value;\n\t\t});\n\n\t\t// Survey type specific events\n\t\tthis._attachTypeSpecificEvents();\n\n\t\t// Escape key\n\t\tthis._escapeHandler = (e) => {\n\t\t\tif (e.key === 'Escape') {\n\t\t\t\tthis._handleDismiss();\n\t\t\t}\n\t\t};\n\t\tdocument.addEventListener('keydown', this._escapeHandler);\n\t}\n\n\t_attachTypeSpecificEvents() {\n\t\tconst type = this.surveyOptions.surveyType;\n\n\t\tif (type === 'nps') {\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-nps-btn')\n\t\t\t\t.forEach((btn) => {\n\t\t\t\t\tbtn.addEventListener('click', () =>\n\t\t\t\t\t\tthis._selectNPS(parseInt(btn.dataset.score))\n\t\t\t\t\t);\n\t\t\t\t\tbtn.addEventListener('mouseenter', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tbtn.addEventListener('mouseleave', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t}\n\n\t\tif (type === 'csat') {\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-csat-btn')\n\t\t\t\t.forEach((btn) => {\n\t\t\t\t\tbtn.addEventListener('click', () =>\n\t\t\t\t\t\tthis._selectCSAT(parseInt(btn.dataset.score))\n\t\t\t\t\t);\n\t\t\t\t\tbtn.addEventListener('mouseenter', () => {\n\t\t\t\t\t\tbtn.style.transform = 'scale(1.1)';\n\t\t\t\t\t});\n\t\t\t\t\tbtn.addEventListener('mouseleave', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.transform = 'scale(1)';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t}\n\n\t\tif (type === 'ces') {\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-ces-btn')\n\t\t\t\t.forEach((btn) => {\n\t\t\t\t\tbtn.addEventListener('click', () =>\n\t\t\t\t\t\tthis._selectCES(parseInt(btn.dataset.score))\n\t\t\t\t\t);\n\t\t\t\t\tbtn.addEventListener('mouseenter', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tbtn.addEventListener('mouseleave', () => {\n\t\t\t\t\t\tif (this.surveyState.score !== parseInt(btn.dataset.score)) {\n\t\t\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t}\n\n\t\tif (type === 'custom') {\n\t\t\t// Frequency buttons\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-freq-btn')\n\t\t\t\t.forEach((btn) => {\n\t\t\t\t\tbtn.addEventListener('click', () =>\n\t\t\t\t\t\tthis._selectFrequency(btn.dataset.freq)\n\t\t\t\t\t);\n\t\t\t\t});\n\n\t\t\t// Select inputs\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-select')\n\t\t\t\t.forEach((select) => {\n\t\t\t\t\tselect.addEventListener('change', (e) => {\n\t\t\t\t\t\tthis.surveyState.customAnswers[select.dataset.question] =\n\t\t\t\t\t\t\te.target.value;\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t// Text inputs\n\t\t\tthis.surveyElement\n\t\t\t\t.querySelectorAll('.feedback-survey-input')\n\t\t\t\t.forEach((input) => {\n\t\t\t\t\tinput.addEventListener('input', (e) => {\n\t\t\t\t\t\tthis.surveyState.customAnswers[input.dataset.question] =\n\t\t\t\t\t\t\te.target.value;\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t}\n\t}\n\n\t_selectNPS(score) {\n\t\tthis.surveyState.score = score;\n\t\tthis.surveyElement\n\t\t\t.querySelectorAll('.feedback-survey-nps-btn')\n\t\t\t.forEach((btn) => {\n\t\t\t\tconst btnScore = parseInt(btn.dataset.score);\n\t\t\t\tif (btnScore === score) {\n\t\t\t\t\tbtn.style.background = '#007aff';\n\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\tbtn.style.color = '#fff';\n\t\t\t\t} else {\n\t\t\t\t\tbtn.style.background =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';\n\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\tbtn.style.color =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\t_selectCSAT(score) {\n\t\tthis.surveyState.score = score;\n\t\tthis.surveyElement\n\t\t\t.querySelectorAll('.feedback-survey-csat-btn')\n\t\t\t.forEach((btn) => {\n\t\t\t\tconst btnScore = parseInt(btn.dataset.score);\n\t\t\t\tbtn.style.transform = btnScore === score ? 'scale(1.2)' : 'scale(1)';\n\t\t\t});\n\t}\n\n\t_selectCES(score) {\n\t\tthis.surveyState.score = score;\n\t\tthis.surveyElement\n\t\t\t.querySelectorAll('.feedback-survey-ces-btn')\n\t\t\t.forEach((btn) => {\n\t\t\t\tconst btnScore = parseInt(btn.dataset.score);\n\t\t\t\tif (btnScore === score) {\n\t\t\t\t\tbtn.style.background = '#007aff';\n\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\tbtn.style.color = '#fff';\n\t\t\t\t} else {\n\t\t\t\t\tbtn.style.background =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';\n\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\tbtn.style.color =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\t_selectFrequency(freq) {\n\t\tthis.surveyState.customAnswers.frequency = freq;\n\t\tthis.surveyElement\n\t\t\t.querySelectorAll('.feedback-survey-freq-btn')\n\t\t\t.forEach((btn) => {\n\t\t\t\tif (btn.dataset.freq === freq) {\n\t\t\t\t\tbtn.style.background = '#007aff';\n\t\t\t\t\tbtn.style.borderColor = '#007aff';\n\t\t\t\t\tbtn.style.color = '#fff';\n\t\t\t\t} else {\n\t\t\t\t\tbtn.style.background =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#2a2a2a' : '#f8f9fa';\n\t\t\t\t\tbtn.style.borderColor =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#444' : '#d2d2d7';\n\t\t\t\t\tbtn.style.color =\n\t\t\t\t\t\tthis.surveyOptions.theme === 'dark' ? '#fff' : '#1d1d1f';\n\t\t\t\t}\n\t\t\t});\n\t}\n\n\tasync _handleSubmit() {\n\t\tconst type = this.surveyOptions.surveyType;\n\n\t\t// Validate\n\t\tif (\n\t\t\t(type === 'nps' || type === 'csat' || type === 'ces') &&\n\t\t\tthis.surveyState.score === null\n\t\t) {\n\t\t\tthis._showError('Please select a rating');\n\t\t\treturn;\n\t\t}\n\n\t\tconst responseData = {\n\t\t\trating: this.surveyState.score,\n\t\t\tfeedback: this.surveyState.feedback,\n\t\t\tanswers: this.surveyState.customAnswers,\n\t\t};\n\n\t\tconst response = {\n\t\t\ttype: type,\n\t\t\tscore: this.surveyState.score,\n\t\t\tfeedback: this.surveyState.feedback,\n\t\t\tcustomAnswers: this.surveyState.customAnswers,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t};\n\n\t\t// Call onSubmit callback if provided\n\t\tif (this.surveyOptions.onSubmit) {\n\t\t\tthis.surveyOptions.onSubmit(response);\n\t\t}\n\n\t\t// Submit to API\n\t\ttry {\n\t\t\tconst surveyId =\n\t\t\t\tthis.surveyOptions.surveyId || `local_${type}_${Date.now()}`;\n\t\t\tawait this.apiService.submitSurveyResponse(surveyId, responseData);\n\t\t} catch (error) {\n\t\t\tconsole.error('[SurveyWidget] Failed to submit survey:', error);\n\t\t}\n\n\t\tthis.sdk.eventBus.emit('survey:submitted', { widget: this, response });\n\n\t\tthis._closeSurvey();\n\t\tthis._showSuccessNotification();\n\t}\n\n\tasync _handleDismiss() {\n\t\t// Call dismiss API if survey has a backend ID\n\t\tif (this.surveyOptions.surveyId) {\n\t\t\ttry {\n\t\t\t\tawait this.apiService.dismissSurvey(this.surveyOptions.surveyId);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error('[SurveyWidget] Failed to dismiss survey:', error);\n\t\t\t}\n\t\t}\n\n\t\tif (this.surveyOptions.onDismiss) {\n\t\t\tthis.surveyOptions.onDismiss();\n\t\t}\n\t\tthis.sdk.eventBus.emit('survey:dismissed', { widget: this });\n\t\tthis._closeSurvey();\n\t}\n\n\t_showError(message) {\n\t\t// Simple error display - could be enhanced\n\t\tconst existing = this.surveyElement.querySelector('.feedback-survey-error');\n\t\tif (existing) existing.remove();\n\n\t\tconst error = document.createElement('div');\n\t\terror.className = 'feedback-survey-error';\n\t\terror.style.cssText =\n\t\t\t'color: #ef4444; font-size: 13px; margin-top: 8px; text-align: center;';\n\t\terror.textContent = message;\n\n\t\tconst submitBtn = this.surveyElement.querySelector(\n\t\t\t'.feedback-survey-submit'\n\t\t);\n\t\tsubmitBtn.parentNode.insertBefore(error, submitBtn);\n\n\t\tsetTimeout(() => error.remove(), 3000);\n\t}\n\n\t_showSuccessNotification() {\n\t\tconst notification = document.createElement('div');\n\t\tnotification.className = 'feedback-survey-success';\n\t\tnotification.style.cssText = `\n\t\t\tposition: fixed;\n\t\t\ttop: 24px;\n\t\t\tright: 24px;\n\t\t\tbackground: #10b981;\n\t\t\tcolor: white;\n\t\t\tpadding: 16px 24px;\n\t\t\tborder-radius: 12px;\n\t\t\tfont-size: 14px;\n\t\t\tfont-weight: 500;\n\t\t\tz-index: 10001;\n\t\t\tbox-shadow: 0 10px 40px rgba(0,0,0,0.2);\n\t\t\tfont-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n\t\t`;\n\t\tnotification.innerHTML = `\n\t\t\t<div style=\"display: flex; align-items: center; gap: 8px;\">\n\t\t\t\t<span style=\"font-size: 18px;\">✓</span>\n\t\t\t\t<span>Thank you for your feedback!</span>\n\t\t\t</div>\n\t\t`;\n\t\tdocument.body.appendChild(notification);\n\n\t\tsetTimeout(() => {\n\t\t\tnotification.style.opacity = '0';\n\t\t\tnotification.style.transition = 'opacity 0.3s ease';\n\t\t\tsetTimeout(() => notification.remove(), 300);\n\t\t}, 3000);\n\t}\n\n\t_closeSurvey() {\n\t\tif (this._escapeHandler) {\n\t\t\tdocument.removeEventListener('keydown', this._escapeHandler);\n\t\t\tthis._escapeHandler = null;\n\t\t}\n\n\t\t// Capture references to avoid race conditions with setTimeout\n\t\tconst surveyEl = this.surveyElement;\n\t\tconst backdropEl = this.backdropElement;\n\n\t\tif (surveyEl) {\n\t\t\tsurveyEl.style.opacity = '0';\n\t\t\tsurveyEl.style.transform =\n\t\t\t\tthis.surveyOptions.position === 'center'\n\t\t\t\t\t? 'translate(-50%, -50%) scale(0.95)'\n\t\t\t\t\t: 'translateY(20px)';\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (surveyEl && surveyEl.parentNode) {\n\t\t\t\t\tsurveyEl.parentNode.removeChild(surveyEl);\n\t\t\t\t}\n\t\t\t}, 300);\n\t\t\tthis.surveyElement = null;\n\t\t}\n\n\t\tif (backdropEl) {\n\t\t\tbackdropEl.style.opacity = '0';\n\t\t\tsetTimeout(() => {\n\t\t\t\tif (backdropEl && backdropEl.parentNode) {\n\t\t\t\t\tbackdropEl.parentNode.removeChild(backdropEl);\n\t\t\t\t}\n\t\t\t}, 300);\n\t\t\tthis.backdropElement = null;\n\t\t}\n\n\t\tthis.surveyState = {\n\t\t\tscore: null,\n\t\t\tfeedback: '',\n\t\t\tcustomAnswers: {},\n\t\t\tisVisible: false,\n\t\t};\n\t}\n\n\tdestroy() {\n\t\tthis._closeSurvey();\n\t\tsuper.destroy();\n\t}\n}\n","import { BaseWidget } from './BaseWidget.js';\n\nexport class TabWidget extends BaseWidget {\n\tconstructor(options) {\n\t\tsuper({ ...options, type: 'tab' });\n\t}\n\n\t_render() {\n\t\tconst tab = document.createElement('div');\n\t\ttab.className = `feedback-widget feedback-widget-tab theme-${this.options.theme} position-${this.options.position}`;\n\t\ttab.innerHTML = `\n <div class=\"feedback-tab-trigger\">\n <span class=\"feedback-tab-text\">Feedback</span>\n </div>\n `;\n\n\t\tif (this.options.customStyles) {\n\t\t\tObject.assign(tab.style, this.options.customStyles);\n\t\t}\n\n\t\treturn tab;\n\t}\n\n\t_attachEvents() {\n\t\tconst tab = this.element.querySelector('.feedback-tab-trigger');\n\t\ttab.addEventListener('click', this.openModal);\n\n\t\ttab.addEventListener('mouseenter', () => {\n\t\t\tif (!this.state.isSubmitting) {\n\t\t\t\ttab.style.transform = this._getHoverTransform();\n\t\t\t}\n\t\t});\n\n\t\ttab.addEventListener('mouseleave', () => {\n\t\t\ttab.style.transform = 'none';\n\t\t});\n\t}\n\n\t_getHoverTransform() {\n\t\tconst position = this.options.position;\n\t\tif (position.includes('right')) {\n\t\t\treturn 'translateX(-5px)';\n\t\t} else if (position.includes('left')) {\n\t\t\treturn 'translateX(5px)';\n\t\t}\n\t\treturn 'none';\n\t}\n\n\tupdateText(text) {\n\t\tconst textElement = this.element?.querySelector('.feedback-tab-text');\n\t\tif (textElement) {\n\t\t\ttextElement.textContent = text;\n\t\t}\n\t}\n\n\tupdatePosition(position) {\n\t\tthis.options.position = position;\n\t\tif (this.element) {\n\t\t\tthis.element.className = this.element.className.replace(\n\t\t\t\t/position-\\w+-\\w+/,\n\t\t\t\t`position-${position}`\n\t\t\t);\n\t\t}\n\t}\n}\n","import { SDKError } from '../utils/errors.js';\nimport { ButtonWidget } from './ButtonWidget.js';\nimport { InlineWidget } from './InlineWidget.js';\nimport { MessengerWidget } from './MessengerWidget.js';\nimport { SurveyWidget } from './SurveyWidget.js';\nimport { TabWidget } from './TabWidget.js';\n\nexport class WidgetFactory {\n\tstatic widgets = new Map([\n\t\t['button', ButtonWidget],\n\t\t['tab', TabWidget],\n\t\t['inline', InlineWidget],\n\t\t['survey', SurveyWidget],\n\t\t['messenger', MessengerWidget],\n\t]);\n\n\tstatic register(type, WidgetClass) {\n\t\tif (typeof type !== 'string' || !type.trim()) {\n\t\t\tthrow new SDKError('Widget type must be a non-empty string');\n\t\t}\n\n\t\tif (typeof WidgetClass !== 'function') {\n\t\t\tthrow new SDKError('Widget class must be a constructor function');\n\t\t}\n\n\t\tthis.widgets.set(type, WidgetClass);\n\t}\n\n\tstatic create(type, options = {}) {\n\t\tconst WidgetClass = this.widgets.get(type);\n\n\t\tif (!WidgetClass) {\n\t\t\tconst availableTypes = Array.from(this.widgets.keys()).join(', ');\n\t\t\tthrow new SDKError(\n\t\t\t\t`Unknown widget type: ${type}. Available types: ${availableTypes}`\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\treturn new WidgetClass(options);\n\t\t} catch (error) {\n\t\t\tthrow new SDKError(\n\t\t\t\t`Failed to create widget of type '${type}': ${error.message}`,\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t}\n\n\tstatic getAvailableTypes() {\n\t\treturn Array.from(this.widgets.keys());\n\t}\n\n\tstatic isTypeRegistered(type) {\n\t\treturn this.widgets.has(type);\n\t}\n\n\tstatic unregister(type) {\n\t\treturn this.widgets.delete(type);\n\t}\n\n\tstatic clear() {\n\t\tthis.widgets.clear();\n\t}\n\n\tstatic getWidgetClass(type) {\n\t\treturn this.widgets.get(type);\n\t}\n}\n","import { ConfigError, SDKError } from '../utils/errors.js';\nimport { deepMerge, generateId } from '../utils/helpers.js';\nimport { WidgetFactory } from '../widgets/WidgetFactory.js';\nimport { APIService } from './APIService.js';\nimport { EventBus } from './EventBus.js';\n\nexport class FeedbackSDK {\n\tconstructor(config = {}) {\n\t\tthis.config = this._validateAndMergeConfig(config);\n\t\tthis.initialized = false;\n\t\tthis.widgets = new Map();\n\t\tthis.eventBus = new EventBus();\n\n\t\tthis.apiService = new APIService({\n\t\t\tapiUrl: this.config.apiUrl,\n\t\t\tworkspace: this.config.workspace,\n\t\t\tuserContext: this.config.userContext,\n\t\t\tmock: this.config.mock,\n\t\t\tenv: this.config.env,\n\t\t});\n\n\t\tthis._bindMethods();\n\t}\n\n\tasync init() {\n\t\tif (this.initialized) {\n\t\t\treturn { alreadyInitialized: true };\n\t\t}\n\n\t\ttry {\n\t\t\tconst initData = await this.apiService.init(this.config.userContext);\n\n\t\t\t// Merge backend config as base, local config overrides\n\t\t\tif (initData.config) {\n\t\t\t\tthis.config = deepMerge(initData.config, this.config);\n\t\t\t}\n\n\t\t\tthis.initialized = true;\n\t\t\tthis.eventBus.emit('sdk:initialized', {\n\t\t\t\tconfig: this.config,\n\t\t\t\tsessionToken: initData.sessionToken,\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tinitialized: true,\n\t\t\t\tconfig: initData.config || {},\n\t\t\t\tsessionToken: initData.sessionToken,\n\t\t\t\texpiresIn: initData.expiresIn,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tthis.eventBus.emit('sdk:error', { error });\n\t\t\tthrow new SDKError(`Failed to initialize SDK: ${error.message}`, error);\n\t\t}\n\t}\n\n\tcreateWidget(type = 'button', options = {}) {\n\t\tif (!this.initialized) {\n\t\t\tthrow new SDKError(\n\t\t\t\t'SDK must be initialized before creating widgets. Call init() first.'\n\t\t\t);\n\t\t}\n\n\t\tconst widgetId = generateId('widget');\n\t\tconst widgetOptions = {\n\t\t\tid: widgetId,\n\t\t\tsdk: this,\n\t\t\tapiService: this.apiService,\n\t\t\t...this.config,\n\t\t\t...options,\n\t\t};\n\n\t\ttry {\n\t\t\tconst widget = WidgetFactory.create(type, widgetOptions);\n\t\t\tthis.widgets.set(widgetId, widget);\n\t\t\tthis.eventBus.emit('widget:created', { widget, type });\n\t\t\treturn widget;\n\t\t} catch (error) {\n\t\t\tthrow new SDKError(`Failed to create widget: ${error.message}`, error);\n\t\t}\n\t}\n\n\tgetWidget(id) {\n\t\treturn this.widgets.get(id);\n\t}\n\n\t/**\n\t * Fetch active surveys from the backend\n\t * @param {Object} context - Optional context for targeting\n\t * @param {string} context.page - Current page/route\n\t * @param {string} context.event - Event trigger name\n\t * @returns {Promise<Array>} Array of active survey configurations\n\t */\n\tasync getActiveSurveys(context = {}) {\n\t\tif (!this.initialized) {\n\t\t\tthrow new SDKError(\n\t\t\t\t'SDK must be initialized before fetching surveys. Call init() first.'\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await this.apiService.getActiveSurveys(context);\n\t\t\treturn result.data || [];\n\t\t} catch (error) {\n\t\t\tthis.eventBus.emit('sdk:error', { error });\n\t\t\tthrow new SDKError(\n\t\t\t\t`Failed to fetch active surveys: ${error.message}`,\n\t\t\t\terror\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Show a survey by its backend ID\n\t * Fetches survey configuration from the backend and displays it\n\t * @param {string} surveyId - The backend survey ID\n\t * @param {Object} options - Additional display options\n\t * @param {string} options.position - Position override\n\t * @param {string} options.theme - Theme override\n\t * @param {Function} options.onSubmit - Callback when survey is submitted\n\t * @param {Function} options.onDismiss - Callback when survey is dismissed\n\t * @returns {Promise<SurveyWidget>} The survey widget instance\n\t */\n\tasync showSurveyById(surveyId, options = {}) {\n\t\tif (!this.initialized) {\n\t\t\tthrow new SDKError(\n\t\t\t\t'SDK must be initialized before showing surveys. Call init() first.'\n\t\t\t);\n\t\t}\n\n\t\t// Fetch active surveys to find the one with matching ID\n\t\tconst surveys = await this.getActiveSurveys();\n\t\tconst surveyConfig = surveys.find((s) => s.id === surveyId);\n\n\t\tif (!surveyConfig) {\n\t\t\tthrow new SDKError(\n\t\t\t\t`Survey with ID '${surveyId}' not found or not active`\n\t\t\t);\n\t\t}\n\n\t\treturn this.showSurvey({\n\t\t\tsurveyId: surveyConfig.id,\n\t\t\tsurveyType: surveyConfig.type,\n\t\t\ttitle: surveyConfig.title,\n\t\t\tdescription: surveyConfig.description,\n\t\t\tlowLabel: surveyConfig.low_label,\n\t\t\thighLabel: surveyConfig.high_label,\n\t\t\tcustomQuestions: surveyConfig.questions,\n\t\t\t...options,\n\t\t});\n\t}\n\n\t/**\n\t * Show a survey widget (local/manual mode)\n\t * For backend-driven surveys, use showSurveyById() instead\n\t * @param {Object} options - Survey options\n\t * @param {string} options.surveyId - Backend survey ID (for API tracking)\n\t * @param {string} options.surveyType - Type of survey: 'nps', 'csat', 'ces', 'custom'\n\t * @param {string} options.position - Position: 'bottom-right', 'bottom-left', 'center', 'bottom'\n\t * @param {string} options.theme - Theme: 'light', 'dark'\n\t * @param {string} options.title - Custom title\n\t * @param {string} options.description - Custom description\n\t * @param {string} options.lowLabel - Low end label\n\t * @param {string} options.highLabel - High end label\n\t * @param {Function} options.onSubmit - Callback when survey is submitted\n\t * @param {Function} options.onDismiss - Callback when survey is dismissed\n\t * @returns {SurveyWidget} The survey widget instance\n\t */\n\tshowSurvey(options = {}) {\n\t\tif (!this.initialized) {\n\t\t\tthrow new SDKError(\n\t\t\t\t'SDK must be initialized before showing surveys. Call init() first.'\n\t\t\t);\n\t\t}\n\n\t\tconst surveyWidget = this.createWidget('survey', {\n\t\t\tsurveyId: options.surveyId,\n\t\t\tsurveyType: options.surveyType || options.type || 'nps',\n\t\t\tposition: options.position || 'bottom-right',\n\t\t\ttheme: options.theme || this.config.theme || 'light',\n\t\t\ttitle: options.title,\n\t\t\tdescription: options.description,\n\t\t\tlowLabel: options.lowLabel,\n\t\t\thighLabel: options.highLabel,\n\t\t\tcustomQuestions: options.customQuestions,\n\t\t\tonSubmit: options.onSubmit,\n\t\t\tonDismiss: options.onDismiss,\n\t\t});\n\n\t\tsurveyWidget.mount();\n\t\tsurveyWidget.show();\n\n\t\treturn surveyWidget;\n\t}\n\n\tgetAllWidgets() {\n\t\treturn Array.from(this.widgets.values());\n\t}\n\n\tdestroyWidget(id) {\n\t\tconst widget = this.widgets.get(id);\n\t\tif (widget) {\n\t\t\twidget.destroy();\n\t\t\tthis.widgets.delete(id);\n\t\t\tthis.eventBus.emit('widget:removed', { widgetId: id });\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tdestroyAllWidgets() {\n\t\tfor (const widget of this.widgets.values()) {\n\t\t\twidget.destroy();\n\t\t}\n\t\tthis.widgets.clear();\n\t\tthis.eventBus.emit('widgets:cleared');\n\t}\n\n\tupdateConfig(newConfig) {\n\t\tconst oldConfig = { ...this.config };\n\t\tthis.config = this._validateAndMergeConfig(newConfig, this.config);\n\n\t\tfor (const widget of this.widgets.values()) {\n\t\t\twidget.handleConfigUpdate(this.config);\n\t\t}\n\n\t\tthis.eventBus.emit('config:updated', {\n\t\t\toldConfig,\n\t\t\tnewConfig: this.config,\n\t\t});\n\t}\n\n\tsetUserContext(userContext) {\n\t\tthis.config.userContext = userContext;\n\t\tif (this.apiService) {\n\t\t\tthis.apiService.setUserContext(userContext);\n\t\t}\n\t\tthis.eventBus.emit('user:updated', { userContext });\n\t}\n\n\tgetUserContext() {\n\t\treturn (\n\t\t\tthis.config.userContext ||\n\t\t\t(this.apiService ? this.apiService.getUserContext() : null)\n\t\t);\n\t}\n\n\tasync reinitialize(newUserContext = null) {\n\t\tthis.apiService.clearSession();\n\t\tthis.initialized = false;\n\n\t\tif (newUserContext) {\n\t\t\tthis.setUserContext(newUserContext);\n\t\t}\n\n\t\treturn this.init();\n\t}\n\n\ton(event, callback) {\n\t\tthis.eventBus.on(event, callback);\n\t\treturn this;\n\t}\n\n\toff(event, callback) {\n\t\tthis.eventBus.off(event, callback);\n\t\treturn this;\n\t}\n\n\tonce(event, callback) {\n\t\tthis.eventBus.once(event, callback);\n\t\treturn this;\n\t}\n\n\temit(event, data) {\n\t\tthis.eventBus.emit(event, data);\n\t\treturn this;\n\t}\n\n\tdestroy() {\n\t\tthis.destroyAllWidgets();\n\t\tthis.eventBus.removeAllListeners();\n\t\tthis.apiService.clearSession();\n\t\tthis.initialized = false;\n\t\tthis.eventBus.emit('sdk:destroyed');\n\t}\n\n\t_validateAndMergeConfig(newConfig, existingConfig = {}) {\n\t\tconst defaultConfig = {\n\t\t\tapiUrl: null,\n\t\t\tworkspace: null,\n\t\t\tuserContext: null,\n\t\t\tposition: 'bottom-right',\n\t\t\ttheme: 'light',\n\t\t\tboardId: 'general',\n\t\t\tautoShow: true,\n\t\t\tdebug: false,\n\t\t\tmock: false,\n\t\t\tenv: 'production', // 'production' or 'staging'\n\t\t};\n\n\t\tconst mergedConfig = deepMerge(\n\t\t\tdeepMerge(defaultConfig, existingConfig),\n\t\t\tnewConfig\n\t\t);\n\n\t\tif (!mergedConfig.workspace) {\n\t\t\tthrow new ConfigError('Missing required configuration: workspace');\n\t\t}\n\n\t\tif (mergedConfig.userContext) {\n\t\t\tthis._validateUserContext(mergedConfig.userContext);\n\t\t}\n\n\t\treturn mergedConfig;\n\t}\n\n\t_validateUserContext(userContext) {\n\t\tif (!userContext.user_id && !userContext.email) {\n\t\t\tthrow new ConfigError(\n\t\t\t\t'User context must include at least user_id or email'\n\t\t\t);\n\t\t}\n\n\t\tconst validStructure = {\n\t\t\tuser_id: 'string',\n\t\t\temail: 'string',\n\t\t\tname: 'string',\n\t\t\tcustom_fields: 'object',\n\t\t\tcompany: 'object',\n\t\t};\n\n\t\tfor (const [key, expectedType] of Object.entries(validStructure)) {\n\t\t\tif (userContext[key] && typeof userContext[key] !== expectedType) {\n\t\t\t\tthrow new ConfigError(\n\t\t\t\t\t`User context field '${key}' must be of type '${expectedType}'`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t_bindMethods() {\n\t\tthis.createWidget = this.createWidget.bind(this);\n\t\tthis.destroyWidget = this.destroyWidget.bind(this);\n\t\tthis.updateConfig = this.updateConfig.bind(this);\n\t}\n\n\tstatic create(config) {\n\t\treturn new FeedbackSDK(config);\n\t}\n\n\tstatic async createAndInit(config) {\n\t\tconst sdk = new FeedbackSDK(config);\n\t\tawait sdk.init();\n\t\treturn sdk;\n\t}\n\n\tstatic extractUserContextFromAuth(authData) {\n\t\tif (!authData) return null;\n\n\t\treturn {\n\t\t\tuser_id: authData.sub || authData.id || authData.user_id,\n\t\t\temail: authData.email,\n\t\t\tname: authData.name || authData.display_name || authData.full_name,\n\t\t\tcustom_fields: {\n\t\t\t\trole: authData.role,\n\t\t\t\tplan: authData.plan || authData.subscription?.plan,\n\t\t\t\t...(authData.custom_fields || {}),\n\t\t\t},\n\t\t\tcompany:\n\t\t\t\tauthData.company || authData.organization\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tid: authData.company?.id || authData.organization?.id,\n\t\t\t\t\t\t\tname: authData.company?.name || authData.organization?.name,\n\t\t\t\t\t\t\tmonthly_spend: authData.company?.monthly_spend,\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t};\n\t}\n}\n","import { APIService } from './core/APIService.js';\nimport { EventBus } from './core/EventBus.js';\nimport { FeedbackSDK } from './core/FeedbackSDK.js';\nimport { MESSENGER_STYLES } from './styles/messengerStyles.js';\nimport { CSS_STYLES } from './styles/styles.js';\nimport {\n\tAPIError,\n\tConfigError,\n\tSDKError,\n\tValidationError,\n\tWidgetError,\n} from './utils/errors.js';\nimport * as helpers from './utils/helpers.js';\nimport { BaseWidget } from './widgets/BaseWidget.js';\nimport { ButtonWidget } from './widgets/ButtonWidget.js';\nimport { InlineWidget } from './widgets/InlineWidget.js';\nimport { MessengerWidget } from './widgets/MessengerWidget.js';\nimport { SurveyWidget } from './widgets/SurveyWidget.js';\nimport { TabWidget } from './widgets/TabWidget.js';\nimport { WidgetFactory } from './widgets/WidgetFactory.js';\n\nfunction injectStyles() {\n\tif (\n\t\ttypeof document !== 'undefined' &&\n\t\t!document.querySelector('#feedback-sdk-styles')\n\t) {\n\t\tconst style = document.createElement('style');\n\t\tstyle.id = 'feedback-sdk-styles';\n\t\tstyle.textContent = CSS_STYLES + MESSENGER_STYLES;\n\t\tdocument.head.appendChild(style);\n\t}\n}\n\nfunction autoInit() {\n\tif (typeof window !== 'undefined' && window.FeedbackSDKConfig) {\n\t\tinjectStyles();\n\n\t\tconst config = { ...window.FeedbackSDKConfig };\n\t\tconst sdk = new FeedbackSDK(config);\n\n\t\tsdk\n\t\t\t.init()\n\t\t\t.then((initData) => {\n\t\t\t\twindow.FeedbackSDK.instance = sdk;\n\n\t\t\t\tif (window.FeedbackSDKConfig.autoCreate) {\n\t\t\t\t\tconst widgets = Array.isArray(window.FeedbackSDKConfig.autoCreate)\n\t\t\t\t\t\t? window.FeedbackSDKConfig.autoCreate\n\t\t\t\t\t\t: [window.FeedbackSDKConfig.autoCreate];\n\n\t\t\t\t\twidgets.forEach((widgetConfig) => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst widget = sdk.createWidget(\n\t\t\t\t\t\t\t\twidgetConfig.type || 'button',\n\t\t\t\t\t\t\t\twidgetConfig\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\twidget.mount(widgetConfig.container);\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tconsole.error('[FeedbackSDK] Failed to create widget:', error);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif (typeof CustomEvent !== 'undefined') {\n\t\t\t\t\tconst event = new CustomEvent('FeedbackSDKReady', {\n\t\t\t\t\t\tdetail: { sdk, config, initData },\n\t\t\t\t\t});\n\t\t\t\t\twindow.dispatchEvent(event);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tconsole.error('[FeedbackSDK] Auto-initialization failed:', error);\n\n\t\t\t\tif (typeof CustomEvent !== 'undefined') {\n\t\t\t\t\tconst event = new CustomEvent('FeedbackSDKError', {\n\t\t\t\t\t\tdetail: { error, config, phase: 'initialization' },\n\t\t\t\t\t});\n\t\t\t\t\twindow.dispatchEvent(event);\n\t\t\t\t}\n\t\t\t});\n\t}\n}\n\nfunction handleDOMReady() {\n\tif (typeof document !== 'undefined') {\n\t\tif (document.readyState === 'loading') {\n\t\t\tdocument.addEventListener('DOMContentLoaded', autoInit);\n\t\t} else {\n\t\t\tsetTimeout(autoInit, 0);\n\t\t}\n\t}\n}\n\nconst FeedbackSDKExport = {\n\tFeedbackSDK,\n\tBaseWidget,\n\tButtonWidget,\n\tTabWidget,\n\tInlineWidget,\n\tSurveyWidget,\n\tMessengerWidget,\n\tWidgetFactory,\n\tEventBus,\n\tAPIService,\n\tSDKError,\n\tAPIError,\n\tWidgetError,\n\tConfigError,\n\tValidationError,\n\thelpers,\n\tcreate: (config) => {\n\t\tinjectStyles();\n\t\treturn new FeedbackSDK(config);\n\t},\n\tversion: '1.0.0',\n\tinstance: null,\n\n\tisReady: () => Boolean(FeedbackSDKExport.instance),\n\tgetInstance: () => FeedbackSDKExport.instance,\n\n\tsetUserContext: (userContext) => {\n\t\tif (FeedbackSDKExport.instance) {\n\t\t\tFeedbackSDKExport.instance.setUserContext(userContext);\n\t\t} else {\n\t\t\tif (typeof window !== 'undefined') {\n\t\t\t\twindow.FeedbackSDKUserContext = userContext;\n\t\t\t}\n\t\t}\n\t},\n\n\tinitWithUser: async (config, userContext) => {\n\t\tinjectStyles();\n\t\tconst fullConfig = { ...config, userContext };\n\t\tconst sdk = new FeedbackSDK(fullConfig);\n\t\tawait sdk.init();\n\n\t\tif (typeof window !== 'undefined') {\n\t\t\twindow.FeedbackSDK.instance = sdk;\n\t\t}\n\n\t\treturn sdk;\n\t},\n\n\tonReady: (callback) => {\n\t\tif (typeof window !== 'undefined') {\n\t\t\tif (FeedbackSDKExport.isReady()) {\n\t\t\t\tcallback(FeedbackSDKExport.instance);\n\t\t\t} else {\n\t\t\t\twindow.addEventListener(\n\t\t\t\t\t'FeedbackSDKReady',\n\t\t\t\t\t(event) => {\n\t\t\t\t\t\tcallback(event.detail.sdk, event.detail);\n\t\t\t\t\t},\n\t\t\t\t\t{ once: true }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t},\n\n\tonError: (callback) => {\n\t\tif (typeof window !== 'undefined') {\n\t\t\twindow.addEventListener('FeedbackSDKError', (event) => {\n\t\t\t\tcallback(event.detail.error, event.detail);\n\t\t\t});\n\t\t}\n\t},\n\n\textractUserContext: FeedbackSDK.extractUserContextFromAuth,\n};\n\nif (typeof window !== 'undefined') {\n\twindow.FeedbackSDK = FeedbackSDKExport;\n\thandleDOMReady();\n}\n\nexport default FeedbackSDKExport;\n\nexport {\n\tAPIError,\n\tAPIService,\n\tBaseWidget,\n\tButtonWidget,\n\tConfigError,\n\tEventBus,\n\tFeedbackSDK,\n\thelpers,\n\tInlineWidget,\n\tMessengerWidget,\n\tSDKError,\n\tSurveyWidget,\n\tTabWidget,\n\tValidationError,\n\tWidgetError,\n\tWidgetFactory,\n};\n"],"names":["SDKError","Error","constructor","message","cause","super","this","name","captureStackTrace","APIError","status","response","isNetworkError","isClientError","isServerError","WidgetError","widgetType","widgetId","ConfigError","configKey","ValidationError","field","value","MOCK_CONFIG","primaryColor","backgroundColor","textColor","boardId","size","displayMode","MOCK_SURVEYS","id","type","title","description","low_label","high_label","trigger","ENV_URLS","production","base","withWorkspace","workspace","staging","APIService","config","sessionToken","sessionExpiry","userContext","mock","env","apiUrl","baseURL","envConfig","_loadStoredSession","init","isSessionValid","error","Date","now","_storeSession","expiresIn","payload","user","_makeRequest","method","body","JSON","stringify","headers","session_token","expires_in","submitFeedback","feedbackData","Promise","resolve","setTimeout","success","data","content","board","board_id","attachments","Authorization","getActiveSurveys","context","queryParams","URLSearchParams","currentUrl","url","window","location","href","append","deviceInfo","_getDeviceInfo","device","browser","os","userProperties","endpoint","toString","navigator","ua","userAgent","test","includes","submitSurveyResponse","surveyId","responseData","survey_id","rating","feedback","answers","dismissSurvey","setUserContext","localStorage","setItem","getUserContext","clearSession","removeItem","sessionData","token","expiry","toISOString","stored","getItem","parse","options","fetch","ok","errorMessage","json","e","text","contentType","get","EventBus","events","Map","on","event","callback","has","set","push","off","callbacks","index","indexOf","splice","emit","forEach","console","once","unsubscribe","clear","getListenerCount","length","generateId","prefix","Math","random","substring","deepMerge","target","source","result","key","hasOwnProperty","Array","isArray","isBrowser","document","func","wait","timeout","args","clearTimeout","ms","string","replace","bytes","i","floor","log","parseFloat","pow","toFixed","platform","language","userLanguage","cookieEnabled","screenResolution","screen","width","height","windowSize","innerWidth","innerHeight","timezone","Intl","DateTimeFormat","resolvedOptions","timeZone","element","property","fallback","getComputedStyle","getPropertyValue","obj","path","defaultValue","undefined","keys","split","current","rect","getBoundingClientRect","top","left","bottom","documentElement","clientHeight","right","clientWidth","email","trim","str","div","createElement","textContent","innerHTML","scrollIntoView","behavior","block","inline","lastKey","pop","limit","lastFunc","lastRan","required","missing","join","BaseWidget","sdk","apiService","container","position","autoShow","showBackdrop","customStyles","panelElement","backdropElement","mounted","destroyed","state","isOpen","isLoading","isSubmitting","errors","_bindMethods","mount","querySelector","_render","appendChild","_attachEvents","onMount","show","eventBus","widget","style","display","hide","openPanel","_showLoadingModal","_hideLoadingModal","_renderPanel","requestAnimationFrame","classList","add","className","loadingElement","theme","remove","closePanel","parentNode","removeChild","_resetForm","_hideError","_updateSubmitButton","_showError","_showSuccessMessage","handleConfigUpdate","newConfig","_updateTheme","destroy","onDestroy","bind","addEventListener","modeClass","sizeClass","setProperty","_getPanelHTML","_attachPanelEvents","firstInput","focus","panel","preventDefault","handleEscape","removeEventListener","submitBtn","disabled","errorElement","notification","closeNotification","opacity","openModal","closeModal","ButtonWidget","isMinimized","button","Object","assign","closeBtn","stopPropagation","toggleMinimize","transform","updateText","textNode","childNodes","nodeType","Node","TEXT_NODE","updatePosition","InlineWidget","form","textarea","originalContent","updateTitle","titleElement","setPlaceholder","placeholder","input","MessengerState","currentView","unreadCount","activeConversationId","conversations","messages","helpArticles","helpSearchQuery","homeChangelogItems","changelogItems","teamName","teamAvatars","welcomeMessage","enableHelp","enableChangelog","_listeners","Set","subscribe","delete","_notify","changeType","cb","setView","view","previousView","setOpen","setActiveConversation","conversationId","setConversations","_updateUnreadCount","addConversation","conversation","unshift","setMessages","addMessage","conv","find","c","lastMessage","lastMessageTime","timestamp","isOwn","unread","markAsRead","reduce","sum","count","setHelpArticles","articles","setHelpSearchQuery","query","setHomeChangelogItems","items","setChangelogItems","getActiveConversation","getActiveMessages","getFilteredHelpArticles","toLowerCase","filter","article","reset","MessengerLauncher","_unsubscribe","render","_updateContent","_updateIcon","_updateBadge","badgeHtml","chatIcon","closeIcon","existingBadge","badge","NavigationTabs","_updateActiveTab","_getTabs","tabs","label","icon","_getHomeIcon","_getMessagesIcon","_getHelpIcon","_getChangelogIcon","tabsHtml","map","tab","isActive","closest","tabId","dataset","querySelectorAll","toggle","MessengerPanel","navigationTabs","currentViewComponent","viewRegistry","registerView","ViewClass","_renderCurrentView","viewsContainer","setHeader","headerContent","header","ChangelogView","_updateChangelogList","avatarsHtml","_renderTeamAvatars","changelogContainer","item","_renderChangelogCard","_attachChangelogEvents","_renderEmptyState","tagsHtml","tags","tag","dateStr","_formatDate","publishedAt","date","coverImage","_truncateText","avatars","colors","slice","avatar","startsWith","charAt","toUpperCase","dateString","toLocaleDateString","month","day","year","maxLength","card","changelogId","changelogItem","n","open","onChangelogClick","ChatView","_appendMessage","_scrollToBottom","messagesHtml","msg","_renderMessage","avatarHtml","_renderConversationAvatar","messageClass","timeStr","_formatMessageTime","_formatMessageContent","_renderSenderAvatar","sender","avatarUrl","participants","p","toLocaleTimeString","hour","minute","hour12","messagesContainer","emptyState","messageHtml","tempDiv","firstElementChild","scrollTop","scrollHeight","sendBtn","min","shiftKey","_sendMessage","onSendMessage","ConversationsView","_renderAvatarStack","conversationsHtml","_renderConversationItem","unreadClass","timeAgo","_formatTimeAgo","_renderConversationAvatars","_truncateMessage","_getAvatarColor","diffMs","diffMins","diffHours","diffDays","convId","newMsgBtn","_startNewConversation","newConv","HelpView","_updateCollectionsList","searchQuery","collectionCount","collectionsContainer","collections","filteredCollections","headerEl","collection","_renderCollectionItem","_attachCollectionEvents","articleCount","searchTimeout","collectionId","onArticleClick","HomeView","recentChangelogHtml","_renderRecentChangelog","logoUrl","_renderFeaturedCard","featuredContent","imageUrl","action","coverText","seeAllBtn","featuredBtn","MessengerWidget","messengerOptions","messengerState","launcher","_handleOpenChange","zIndex","_handleSendMessage","_stateUnsubscribe","close","navigateTo","setUnreadCount","getState","loadInitialData","_fetchConversations","_fetchHelpArticles","homeItems","_fetchChangelog","SurveyWidget","surveyOptions","surveyType","lowLabel","highLabel","customQuestions","onSubmit","onDismiss","surveyState","score","customAnswers","isVisible","_renderSurvey","_closeSurvey","_getSurveyConfig","positionStyles","_getPositionStyles","themeStyles","_handleDismiss","surveyElement","cssText","html","_attachSurveyEvents","configs","nps","csat","emoji","ces","custom","_renderCustomQuestions","q","_renderQuestionInput","freq","question","opt","positions","center","_handleSubmit","_attachTypeSpecificEvents","_escapeHandler","btn","_selectNPS","parseInt","borderColor","_selectCSAT","_selectCES","_selectFrequency","select","background","color","btnScore","frequency","_showSuccessNotification","existing","insertBefore","transition","surveyEl","backdropEl","TabWidget","_getHoverTransform","textElement","WidgetFactory","static","register","WidgetClass","widgets","create","availableTypes","from","getAvailableTypes","isTypeRegistered","unregister","getWidgetClass","FeedbackSDK","_validateAndMergeConfig","initialized","alreadyInitialized","initData","createWidget","widgetOptions","getWidget","showSurveyById","surveyConfig","s","showSurvey","questions","surveyWidget","getAllWidgets","values","destroyWidget","destroyAllWidgets","updateConfig","oldConfig","reinitialize","newUserContext","removeAllListeners","existingConfig","mergedConfig","debug","_validateUserContext","user_id","validStructure","custom_fields","company","expectedType","entries","createAndInit","extractUserContextFromAuth","authData","sub","display_name","full_name","role","plan","subscription","organization","monthly_spend","injectStyles","CSS_STYLES","head","autoInit","FeedbackSDKConfig","then","instance","autoCreate","widgetConfig","CustomEvent","detail","dispatchEvent","catch","phase","FeedbackSDKExport","helpers","version","isReady","Boolean","getInstance","FeedbackSDKUserContext","initWithUser","async","fullConfig","onReady","onError","extractUserContext","readyState"],"mappings":"kPAAO,MAAMA,UAAiBC,MAC7B,WAAAC,CAAYC,EAASC,GACpBC,MAAMF,GACNG,KAAKC,KAAO,WACZD,KAAKF,MAAQA,EAETH,MAAMO,mBACTP,MAAMO,kBAAkBF,KAAMN,EAEhC,EAGM,MAAMS,UAAiBR,MAC7B,WAAAC,CAAYQ,EAAQP,EAASQ,GAC5BN,MAAMF,GACNG,KAAKC,KAAO,WACZD,KAAKI,OAASA,EACdJ,KAAKK,SAAWA,EAEZV,MAAMO,mBACTP,MAAMO,kBAAkBF,KAAMG,EAEhC,CAEA,cAAAG,GACC,OAAuB,IAAhBN,KAAKI,MACb,CAEA,aAAAG,GACC,OAAOP,KAAKI,QAAU,KAAOJ,KAAKI,OAAS,GAC5C,CAEA,aAAAI,GACC,OAAOR,KAAKI,QAAU,KAAOJ,KAAKI,OAAS,GAC5C,EAGM,MAAMK,UAAoBd,MAChC,WAAAC,CAAYC,EAASa,EAAYC,GAChCZ,MAAMF,GACNG,KAAKC,KAAO,cACZD,KAAKU,WAAaA,EAClBV,KAAKW,SAAWA,EAEZhB,MAAMO,mBACTP,MAAMO,kBAAkBF,KAAMS,EAEhC,EAGM,MAAMG,UAAoBjB,MAChC,WAAAC,CAAYC,EAASgB,GACpBd,MAAMF,GACNG,KAAKC,KAAO,cACZD,KAAKa,UAAYA,EAEblB,MAAMO,mBACTP,MAAMO,kBAAkBF,KAAMY,EAEhC,EAGM,MAAME,UAAwBnB,MACpC,WAAAC,CAAYC,EAASkB,EAAOC,GAC3BjB,MAAMF,GACNG,KAAKC,KAAO,kBACZD,KAAKe,MAAQA,EACbf,KAAKgB,MAAQA,EAETrB,MAAMO,mBACTP,MAAMO,kBAAkBF,KAAMc,EAEhC,ECtED,MAAMG,EAAc,CACnBC,aAAc,UACdC,gBAAiB,UACjBC,UAAW,UACXC,QAAS,mBACTC,KAAM,SACNC,YAAa,SAIRC,EAAe,CACpB,CACCC,GAAI,kBACJC,KAAM,MACNC,MAAO,sCACPC,YAAa,iCACbC,UAAW,aACXC,WAAY,cACZC,QAAS,SACT3B,OAAQ,UAET,CACCqB,GAAI,mBACJC,KAAM,OACNC,MAAO,yBACPC,YAAa,wCACbG,QAAS,SACT3B,OAAQ,UAET,CACCqB,GAAI,kBACJC,KAAM,MACNC,MAAO,mBACPC,YAAa,wCACbC,UAAW,iBACXC,WAAY,YACZC,QAAS,SACT3B,OAAQ,WAKJ4B,EAAW,CAChBC,WAAY,CACXC,KAAM,iCACNC,cAAgBC,GAAc,WAAWA,4BAE1CC,QAAS,CACRH,KAAM,yCACNC,cAAgBC,GACf,WAAWA,qCAIP,MAAME,EACZ,WAAA1C,CAAY2C,EAAS,IAQpB,GAPAvC,KAAKoC,UAAYG,EAAOH,UACxBpC,KAAKwC,aAAe,KACpBxC,KAAKyC,cAAgB,KACrBzC,KAAK0C,YAAcH,EAAOG,aAAe,KACzC1C,KAAK2C,KAAOJ,EAAOI,OAAQ,EAC3B3C,KAAK4C,IAAML,EAAOK,KAAO,aAErBL,EAAOM,OACV7C,KAAK8C,QAAUP,EAAOM,WAChB,CACN,MAAME,EAAYf,EAAShC,KAAK4C,MAAQZ,EAASC,WACjDjC,KAAK8C,QAAU9C,KAAKoC,UACjBW,EAAUZ,cAAcnC,KAAKoC,WAC7BW,EAAUb,IACd,CAEAlC,KAAKgD,oBACN,CAEA,UAAMC,CAAKP,EAAc,MAKxB,GAJIA,IACH1C,KAAK0C,YAAcA,GAGhB1C,KAAKkD,iBACR,MAAO,CAAEV,aAAcxC,KAAKwC,cAG7B,IAAKxC,KAAK0C,cAAgB1C,KAAKoC,UAAW,CACzC,MAAMe,EAAQ,WAAYnD,KAAKoC,UAA0B,eAAd,iCAC3C,MAAM,IAAIjC,EAAS,IAAKgD,EACzB,CAGA,GAAInD,KAAK2C,KAIR,OAHA3C,KAAKwC,aAAe,gBAAkBY,KAAKC,MAC3CrD,KAAKyC,cAAgB,IAAIW,KAAKA,KAAKC,MAAQ,MAC3CrD,KAAKsD,gBACE,CACNd,aAAcxC,KAAKwC,aACnBD,OAAQtB,EACRsC,UAAW,MAIb,MAAMC,EAAU,CACfpB,UAAWpC,KAAKoC,UAChBqB,KAAMzD,KAAK0C,aAGZ,IACC,MAAMrC,QAAiBL,KAAK0D,aAAa,eAAgB,CACxDC,OAAQ,OACRC,KAAMC,KAAKC,UAAUN,GACrBO,QAAS,CACR,eAAgB,sBAQlB,OAJA/D,KAAKwC,aAAenC,EAAS2D,cAC7BhE,KAAKyC,cAAgB,IAAIW,KAAKA,KAAKC,MAA8B,IAAtBhD,EAAS4D,YACpDjE,KAAKsD,gBAEE,CACNd,aAAcxC,KAAKwC,aACnBD,OAAQlC,EAASkC,QAAU,CAAA,EAC3BgB,UAAWlD,EAAS4D,WAEtB,CAAE,MAAOd,GACR,MAAM,IAAIhD,EACTgD,EAAM/C,QAAU,IAChB,gCAAgC+C,EAAMtD,UACtCsD,EAAM9C,SAER,CACD,CAEA,oBAAM6D,CAAeC,GAKpB,GAJKnE,KAAKkD,wBACHlD,KAAKiD,QAGPjD,KAAKwC,aACT,MAAM,IAAIrC,EAAS,IAAK,oCAIzB,GAAIH,KAAK2C,KAER,aADM,IAAIyB,QAASC,GAAYC,WAAWD,EAAS,MAC5C,CACNE,SAAS,EACTC,KAAM,CACL/C,GAAI,aAAe2B,KAAKC,MACxB1B,MAAOwC,EAAaxC,MACpB8C,QAASN,EAAaM,SAEvB5E,QAAS,oCAIX,MAAM2D,EAAU,CACfkB,MACCP,EAAaQ,UAAYR,EAAaO,OAASP,EAAa9C,QAC7DM,MAAOwC,EAAaxC,MACpB8C,QAASN,EAAaM,QACtBG,YAAaT,EAAaS,aAAe,IAG1C,IAUC,aATuB5E,KAAK0D,aAAa,mBAAoB,CAC5DC,OAAQ,OACRC,KAAMC,KAAKC,UAAUN,GACrBO,QAAS,CACR,eAAgB,mBAChBc,cAAe,UAAU7E,KAAKwC,iBAKjC,CAAE,MAAOW,GACR,GAAqB,MAAjBA,EAAM/C,OAIT,OAHAJ,KAAKwC,aAAe,KACpBxC,KAAKyC,cAAgB,WACfzC,KAAKiD,OACJjD,KAAKkE,eAAeC,GAG5B,MAAM,IAAIhE,EACTgD,EAAM/C,QAAU,IAChB,8BAA8B+C,EAAMtD,UACpCsD,EAAM9C,SAER,CACD,CASA,sBAAMyE,CAAiBC,EAAU,IAKhC,GAJK/E,KAAKkD,wBACHlD,KAAKiD,QAGPjD,KAAKwC,aACT,MAAM,IAAIrC,EAAS,IAAK,oCAIzB,GAAIH,KAAK2C,KAER,aADM,IAAIyB,QAASC,GAAYC,WAAWD,EAAS,MAC5C,CACNE,SAAS,EACTC,KAAMhD,GAIR,IACC,MAAMwD,EAAc,IAAIC,gBAGlBC,EACLH,EAAQI,MACW,oBAAXC,OAAyBA,OAAOC,SAASC,KAAO,IACrDJ,GACHF,EAAYO,OAAO,MAAOL,GAI3B,MAAMM,EAAaxF,KAAKyF,iBACpBD,EAAWE,QAAQV,EAAYO,OAAO,SAAUC,EAAWE,QAC3DF,EAAWG,SAASX,EAAYO,OAAO,UAAWC,EAAWG,SAC7DH,EAAWI,IAAIZ,EAAYO,OAAO,KAAMC,EAAWI,IAGnDb,EAAQc,gBACXb,EAAYO,OACX,kBACA1B,KAAKC,UAAUiB,EAAQc,iBAIzB,MAAMC,EAAW,0BAAyBd,EAAYe,WAAa,IAAMf,EAAYe,WAAa,IASlG,aAPuB/F,KAAK0D,aAAaoC,EAAU,CAClDnC,OAAQ,MACRI,QAAS,CACRc,cAAe,UAAU7E,KAAKwC,iBAKjC,CAAE,MAAOW,GACR,GAAqB,MAAjBA,EAAM/C,OAIT,OAHAJ,KAAKwC,aAAe,KACpBxC,KAAKyC,cAAgB,WACfzC,KAAKiD,OACJjD,KAAK8E,iBAAiBC,GAG9B,MAAM,IAAI5E,EACTgD,EAAM/C,QAAU,IAChB,iCAAiC+C,EAAMtD,UACvCsD,EAAM9C,SAER,CACD,CAMA,cAAAoF,GACC,GAAyB,oBAAdO,UACV,MAAO,CAAEN,OAAQ,KAAMC,QAAS,KAAMC,GAAI,MAG3C,MAAMK,EAAKD,UAAUE,UAGrB,IAAIR,EAAS,UACT,gBAAgBS,KAAKF,KACxBP,EAAS,eAAeS,KAAKF,GAAM,SAAW,UAI/C,IAAIN,EAAU,UACVM,EAAGG,SAAS,WAAYT,EAAU,UAC7BM,EAAGG,SAAS,OAAQT,EAAU,OAC9BM,EAAGG,SAAS,UAAWT,EAAU,SACjCM,EAAGG,SAAS,UAAWT,EAAU,UACjCM,EAAGG,SAAS,UAAYH,EAAGG,SAAS,UAAQT,EAAU,SAG/D,IAAIC,EAAK,UAOT,OANIK,EAAGG,SAAS,WAAYR,EAAK,UACxBK,EAAGG,SAAS,OAAQR,EAAK,QACzBK,EAAGG,SAAS,SAAUR,EAAK,QAC3BK,EAAGG,SAAS,WAAYR,EAAK,WAC7BK,EAAGG,SAAS,WAAaH,EAAGG,SAAS,WAASR,EAAK,OAErD,CAAEF,SAAQC,UAASC,KAC3B,CAWA,0BAAMS,CAAqBC,EAAUC,GAKpC,GAJKvG,KAAKkD,wBACHlD,KAAKiD,QAGPjD,KAAKwC,aACT,MAAM,IAAIrC,EAAS,IAAK,oCAGzB,IAAKmG,EACJ,MAAM,IAAInG,EAAS,IAAK,yBAIzB,GAAIH,KAAK2C,KAER,aADM,IAAIyB,QAASC,GAAYC,WAAWD,EAAS,MAC5C,CACNE,SAAS,EACTC,KAAM,CACL/C,GAAI,iBAAmB2B,KAAKC,MAC5BmD,UAAWF,KACRC,GAEJ1G,QAAS,2CAIX,MAAM2D,EAAU,CACfiD,OAAQF,EAAaE,OACrBC,SAAUH,EAAaG,UAAY,GACnCC,QAASJ,EAAaI,SAAW,CAAA,GAGlC,IAaC,aAZuB3G,KAAK0D,aAC3B,mBAAmB4C,cACnB,CACC3C,OAAQ,OACRC,KAAMC,KAAKC,UAAUN,GACrBO,QAAS,CACR,eAAgB,mBAChBc,cAAe,UAAU7E,KAAKwC,iBAMlC,CAAE,MAAOW,GACR,GAAqB,MAAjBA,EAAM/C,OAIT,OAHAJ,KAAKwC,aAAe,KACpBxC,KAAKyC,cAAgB,WACfzC,KAAKiD,OACJjD,KAAKqG,qBAAqBC,EAAUC,GAG5C,MAAM,IAAIpG,EACTgD,EAAM/C,QAAU,IAChB,qCAAqC+C,EAAMtD,UAC3CsD,EAAM9C,SAER,CACD,CAOA,mBAAMuG,CAAcN,GAKnB,GAJKtG,KAAKkD,wBACHlD,KAAKiD,QAGPjD,KAAKwC,aACT,MAAM,IAAIrC,EAAS,IAAK,oCAGzB,IAAKmG,EACJ,MAAM,IAAInG,EAAS,IAAK,yBAIzB,GAAIH,KAAK2C,KAER,aADM,IAAIyB,QAASC,GAAYC,WAAWD,EAAS,MAC5C,CACNE,SAAS,EACT1E,QAAS,iCAIX,IAWC,aAVuBG,KAAK0D,aAC3B,mBAAmB4C,YACnB,CACC3C,OAAQ,OACRI,QAAS,CACRc,cAAe,UAAU7E,KAAKwC,iBAMlC,CAAE,MAAOW,GACR,GAAqB,MAAjBA,EAAM/C,OAIT,OAHAJ,KAAKwC,aAAe,KACpBxC,KAAKyC,cAAgB,WACfzC,KAAKiD,OACJjD,KAAK4G,cAAcN,GAG3B,MAAM,IAAInG,EACTgD,EAAM/C,QAAU,IAChB,6BAA6B+C,EAAMtD,UACnCsD,EAAM9C,SAER,CACD,CAEA,cAAA6C,GACC,OACClD,KAAKwC,cAAgBxC,KAAKyC,eAAiB,IAAIW,KAASpD,KAAKyC,aAE/D,CAEA,cAAAoE,CAAenE,GACd1C,KAAK0C,YAAcA,EACS,oBAAjBoE,cACVA,aAAaC,QACZ,0BACAlD,KAAKC,UAAUpB,GAGlB,CAEA,cAAAsE,GACC,OAAOhH,KAAK0C,WACb,CAEA,YAAAuE,GACCjH,KAAKwC,aAAe,KACpBxC,KAAKyC,cAAgB,KACO,oBAAjBqE,eACVA,aAAaI,WAAW,uBACxBJ,aAAaI,WAAW,2BAE1B,CAEA,aAAA5D,GACC,GAA4B,oBAAjBwD,aAEX,IACC,MAAMK,EAAc,CACnBC,MAAOpH,KAAKwC,aACZ6E,OAAQrH,KAAKyC,cAAc6E,cAC3BlF,UAAWpC,KAAKoC,WAEjB0E,aAAaC,QAAQ,sBAAuBlD,KAAKC,UAAUqD,GAC5D,CAAE,MAAOhE,GAET,CACD,CAEA,kBAAAH,GACC,GAA4B,oBAAjB8D,aAA8B,OAAO,EAEhD,IACC,MAAMS,EAAST,aAAaU,QAAQ,uBACpC,IAAKD,EAAQ,OAAO,EAEpB,MAAMJ,EAActD,KAAK4D,MAAMF,GAI/B,OAHAvH,KAAKwC,aAAe2E,EAAYC,MAChCpH,KAAKyC,cAAgB,IAAIW,KAAK+D,EAAYE,QAEnCrH,KAAKkD,gBACb,CAAE,MAAOC,GACR,OAAO,CACR,CACD,CAEA,kBAAMO,CAAaoC,EAAU4B,EAAU,IACtC,MAAMvC,EAAM,GAAGnF,KAAK8C,UAAUgD,IAE9B,IACC,MAAMzF,QAAiBsH,MAAMxC,EAAKuC,GAElC,IAAKrH,EAASuH,GAAI,CACjB,IAAIC,EAAe,QAAQxH,EAASD,SAChCmG,EAAe,KAEnB,IACCA,QAAqBlG,EAASyH,OAC9BD,EACCtB,EAAa1G,SAAW0G,EAAapD,OAAS0E,CAChD,CAAE,MAAOE,GACRF,QAAsBxH,EAAS2H,QAAWH,CAC3C,CAEA,MAAM,IAAI1H,EAASE,EAASD,OAAQyH,EAActB,EACnD,CAEA,MAAM0B,EAAc5H,EAAS0D,QAAQmE,IAAI,gBACzC,OAAID,GAAeA,EAAY7B,SAAS,0BAC1B/F,EAASyH,aAGVzH,EAAS2H,MACvB,CAAE,MAAO7E,GACR,GAAIA,aAAiBhD,EACpB,MAAMgD,EAEP,MAAM,IAAIhD,EAAS,EAAGgD,EAAMtD,QAAS,KACtC,CACD,EC9gBM,MAAMsI,EACZ,WAAAvI,GACCI,KAAKoI,OAAS,IAAIC,GACnB,CAEA,EAAAC,CAAGC,EAAOC,GAMT,OALKxI,KAAKoI,OAAOK,IAAIF,IACpBvI,KAAKoI,OAAOM,IAAIH,EAAO,IAExBvI,KAAKoI,OAAOF,IAAIK,GAAOI,KAAKH,GAErB,IAAMxI,KAAK4I,IAAIL,EAAOC,EAC9B,CAEA,GAAAI,CAAIL,EAAOC,GACV,MAAMK,EAAY7I,KAAKoI,OAAOF,IAAIK,GAClC,GAAIM,EAAW,CACd,MAAMC,EAAQD,EAAUE,QAAQP,GAC5BM,GAAQ,GACXD,EAAUG,OAAOF,EAAO,EAE1B,CACD,CAEA,IAAAG,CAAKV,EAAO/D,GACX,MAAMqE,EAAY7I,KAAKoI,OAAOF,IAAIK,GAC9BM,GACHA,EAAUK,QAASV,IAClB,IACCA,EAAShE,EACV,CAAE,MAAOrB,GACRgG,QAAQhG,MAAM,sCAAuCA,EACtD,GAGH,CAEA,IAAAiG,CAAKb,EAAOC,GACX,MAAMa,EAAcrJ,KAAKsI,GAAGC,EAAQ/D,IACnCgE,EAAShE,GACT6E,MAED,OAAOA,CACR,CAEA,KAAAC,GACCtJ,KAAKoI,OAAOkB,OACb,CAEA,gBAAAC,CAAiBhB,GAChB,MAAMM,EAAY7I,KAAKoI,OAAOF,IAAIK,GAClC,OAAOM,EAAYA,EAAUW,OAAS,CACvC,ECpDM,SAASC,EAAWC,EAAS,YAGnC,MAAO,GAAGA,KAFQtG,KAAKC,SACRsG,KAAKC,SAAS7D,SAAS,IAAI8D,UAAU,EAAG,IAExD,CAEO,SAASC,EAAUC,EAAQC,GACjC,MAAMC,EAAS,IAAKF,GAEpB,IAAK,MAAMG,KAAOF,EACbA,EAAOG,eAAeD,KAExBF,EAAOE,IACgB,iBAAhBF,EAAOE,KACbE,MAAMC,QAAQL,EAAOE,IAEtBD,EAAOC,GAAOJ,EAAUC,EAAOG,IAAQ,CAAA,EAAIF,EAAOE,IAElDD,EAAOC,GAAOF,EAAOE,IAKxB,OAAOD,CACR,CAkKO,SAASK,IACf,MAAyB,oBAAXlF,QAA8C,oBAAbmF,QAChD,8CAlKO,SAAkBC,EAAMC,GAC9B,IAAIC,EACJ,OAAO,YAA6BC,GAKnCC,aAAaF,GACbA,EAAUpG,WALI,KACbsG,aAAaF,GACbF,KAAQG,IAGmBF,EAC7B,CACD,oBAoGO,SAAeI,GACrB,OAAO,IAAIzG,QAASC,GAAYC,WAAWD,EAASwG,GACrD,cAUO,SAAqBC,GAC3B,OAAOA,EAAOC,QAAQ,sBAAuB,OAC9C,iBAxBO,SAAwBC,GAC9B,GAAc,IAAVA,EAAa,MAAO,UAExB,MAEMC,EAAItB,KAAKuB,MAAMvB,KAAKwB,IAAIH,GAASrB,KAAKwB,IAFlC,OAIV,OAAOC,YAAYJ,EAAQrB,KAAK0B,IAJtB,KAI6BJ,IAAIK,QAAQ,IAAM,IAH3C,CAAC,QAAS,KAAM,KAAM,MAGiCL,EACtE,8BAvBO,WAIN,MAAO,CACN/E,UAJiBF,UAAUE,UAK3BqF,SAJgBvF,UAAUuF,SAK1BC,SAAUxF,UAAUwF,UAAYxF,UAAUyF,aAC1CC,cAAe1F,UAAU0F,cACzBC,iBAAkB,GAAGC,OAAOC,SAASD,OAAOE,SAC5CC,WAAY,GAAG3G,OAAO4G,cAAc5G,OAAO6G,cAC3CC,SAAUC,KAAKC,iBAAiBC,kBAAkBC,SAEpD,iBAjDO,SAAwBC,EAASC,EAAUC,EAAW,IAC5D,IAAKF,IAAYC,EAAU,OAAOC,EAElC,IAEC,OADcrH,OAAOsH,iBAAiBH,GACzBI,iBAAiBH,IAAaC,CAC5C,CAAE,MAAOtJ,GACR,OAAOsJ,CACR,CACD,sBAoHO,WACN,OAAO,IAAIrJ,MAAOkE,aACnB,oBAlDO,SAA2BsF,EAAKC,EAAMC,OAAeC,GAC3D,IAAKH,IAAQC,EAAM,OAAOC,EAE1B,MAAME,EAAOH,EAAKI,MAAM,KACxB,IAAIC,EAAUN,EAEd,IAAK,MAAM1C,KAAO8C,EAAM,CACvB,GAAIE,WAA+ChD,KAAOgD,GACzD,OAAOJ,EAERI,EAAUA,EAAQhD,EACnB,CAEA,OAAOgD,CACR,2BAhFO,SAAsBX,GAC5B,IAAKA,EAAS,OAAO,EAErB,MAAMY,EAAOZ,EAAQa,wBACrB,OACCD,EAAKE,KAAO,GACZF,EAAKG,MAAQ,GACbH,EAAKI,SACHnI,OAAO6G,aAAe1B,SAASiD,gBAAgBC,eACjDN,EAAKO,QAAUtI,OAAO4G,YAAczB,SAASiD,gBAAgBG,YAE/D,WA6FO,WACN,QAAKrD,MAGJ,iEAAiEnE,KAChEH,UAAUE,YACNd,OAAO4G,YAAc,IAE5B,eA1IO,SAAsB4B,GAC5B,SAAKA,GAA0B,iBAAVA,IAEF,6BACDzH,KAAKyH,EAAMC,OAC9B,gBA2EO,SAAuBC,EAAKrB,EAAW,MAC7C,IACC,OAAO5I,KAAK4D,MAAMqG,EACnB,CAAE,MAAO3K,GACR,OAAOsJ,CACR,CACD,eA/EO,SAAsBqB,GAC5B,IAAKA,GAAsB,iBAARA,EAAkB,MAAO,GAE5C,MAAMC,EAAMxD,SAASyD,cAAc,OAEnC,OADAD,EAAIE,YAAcH,EACXC,EAAIG,SACZ,kBA0BO,SAAyB3B,EAAS7E,EAAU,IAClD,IAAK6E,EAAS,OAQdA,EAAQ4B,eAAe,CALtBC,SAAU,SACVC,MAAO,SACPC,OAAQ,aAGsC5G,GAChD,oBA2DO,SAA2BkF,EAAKC,EAAM7L,GAC5C,IAAK4L,IAAQC,EAAM,OAAOD,EAE1B,MAAMI,EAAOH,EAAKI,MAAM,KAClBsB,EAAUvB,EAAKwB,MACrB,IAAItB,EAAUN,EAEd,IAAK,MAAM1C,KAAO8C,EACX9C,KAAOgD,GAAoC,iBAAjBA,EAAQhD,KACvCgD,EAAQhD,GAAO,CAAA,GAEhBgD,EAAUA,EAAQhD,GAInB,OADAgD,EAAQqB,GAAWvN,EACZ4L,CACR,WAlJO,SAAkBpC,EAAMiE,GAC9B,IAAIC,EACAC,EACJ,OAAO,YAAahE,GACdgE,GAIJ/D,aAAa8D,GACbA,EAAWpK,WACV,KACKlB,KAAKC,MAAQsL,GAAWF,IAC3BjE,KAAQG,GACRgE,EAAUvL,KAAKC,QAGjBoL,GAASrL,KAAKC,MAAQsL,MAXvBnE,KAAQG,GACRgE,EAAUvL,KAAKC,MAajB,CACD,iBAkJO,SAAwBd,EAAQqM,EAAW,IACjD,MAAMC,EAAU,GAEhB,IAAK,MAAM3E,KAAO0E,EACZrM,EAAO2H,IACX2E,EAAQlG,KAAKuB,GAIf,GAAI2E,EAAQrF,OAAS,EACpB,MAAM,IAAI7J,MAAM,mCAAmCkP,EAAQC,KAAK,SAGjE,OAAO,CACR,IC1NO,MAAMC,EACZ,WAAAnP,CAAY8H,EAAU,IACrB1H,KAAKyB,GAAKiG,EAAQjG,GAClBzB,KAAKgP,IAAMtH,EAAQsH,IACnBhP,KAAKiP,WAAavH,EAAQuH,WAC1BjP,KAAK0B,KAAOgG,EAAQhG,MAAQ,OAE5B1B,KAAK0H,QAAU,CACdwH,UAAW,KACXC,SAAUnP,KAAKgP,IAAIzM,OAAO4M,SAC1B9N,QAASrB,KAAKgP,IAAIzM,OAAOlB,QACzBE,YAAamG,EAAQnG,aAAe,QACpCD,KAAMoG,EAAQpG,MAAQ,SACtBJ,aAAcwG,EAAQxG,cAAgB,UACtCC,gBAAiBuG,EAAQvG,iBAAmB,UAC5CC,UAAWsG,EAAQtG,WAAa,UAChCgO,UAAU,EACVC,cAAc,EACdC,aAAc,CAAA,KACX5H,GAGJ1H,KAAKuM,QAAU,KACfvM,KAAKuP,aAAe,KACpBvP,KAAKwP,gBAAkB,KACvBxP,KAAKyP,SAAU,EACfzP,KAAK0P,WAAY,EAEjB1P,KAAK2P,MAAQ,CACZC,QAAQ,EACRC,WAAW,EACXC,cAAc,EACdnO,MAAO,GACP8C,QAAS,GACTmJ,MAAO,GACPhJ,YAAa,GACbmL,OAAQ,CAAA,GAGT/P,KAAKgQ,cACN,CAEA,KAAAC,CAAMf,GACL,OAAIlP,KAAKyP,SAAWzP,KAAK0P,YAEA,iBAAdR,IACVA,EAAY3E,SAAS2F,cAAchB,IAG/BA,IACJA,EAAY3E,SAAS3G,MAGtB5D,KAAKkP,UAAYA,EACjBlP,KAAKuM,QAAUvM,KAAKmQ,UACpBnQ,KAAKkP,UAAUkB,YAAYpQ,KAAKuM,SAEhCvM,KAAKyP,SAAU,EACfzP,KAAKqQ,gBACLrQ,KAAKsQ,UAEDtQ,KAAK0H,QAAQ0H,UAChBpP,KAAKuQ,OAGNvQ,KAAKgP,IAAIwB,SAASvH,KAAK,iBAAkB,CAAEwH,OAAQzQ,QAtBRA,IAwB5C,CAEA,IAAAuQ,GAIC,OAHIvQ,KAAKuM,UACRvM,KAAKuM,QAAQmE,MAAMC,QAAU,SAEvB3Q,IACR,CAEA,IAAA4Q,GAIC,OAHI5Q,KAAKuM,UACRvM,KAAKuM,QAAQmE,MAAMC,QAAU,QAEvB3Q,IACR,CAEA,SAAA6Q,GACC7Q,KAAK2P,MAAMC,QAAS,EAEa,UAA7B5P,KAAK0H,QAAQnG,aAChBvB,KAAK8Q,oBAELxM,WAAW,KACVtE,KAAK+Q,oBACL/Q,KAAKgR,eACLC,sBAAsB,KACjBjR,KAAKuP,cACRvP,KAAKuP,aAAa2B,UAAUC,IAAI,QAE7BnR,KAAKwP,iBACRxP,KAAKwP,gBAAgB0B,UAAUC,IAAI,WAGnC,OAEHnR,KAAKgR,eACLC,sBAAsB,KACjBjR,KAAKuP,cACRvP,KAAKuP,aAAa2B,UAAUC,IAAI,QAE7BnR,KAAKwP,iBACRxP,KAAKwP,gBAAgB0B,UAAUC,IAAI,UAIvC,CAEA,iBAAAL,GACC9Q,KAAK2P,MAAME,WAAY,EAGvB7P,KAAKwP,gBAAkBjF,SAASyD,cAAc,OAC9ChO,KAAKwP,gBAAgB4B,UAAY,0BACjC7G,SAAS3G,KAAKwM,YAAYpQ,KAAKwP,iBAG/BxP,KAAKqR,eAAiB9G,SAASyD,cAAc,OAC7ChO,KAAKqR,eAAeD,UAAY,gCAAgCpR,KAAK0H,QAAQ4J,QAC7EtR,KAAKqR,eAAenD,UAAY,6DAGhC3D,SAAS3G,KAAKwM,YAAYpQ,KAAKqR,gBAE/BJ,sBAAsB,KACrBjR,KAAKwP,gBAAgB0B,UAAUC,IAAI,QACnCnR,KAAKqR,eAAeH,UAAUC,IAAI,SAEpC,CAEA,iBAAAJ,GACC/Q,KAAK2P,MAAME,WAAY,EACnB7P,KAAKqR,iBACRrR,KAAKqR,eAAeE,SACpBvR,KAAKqR,eAAiB,KAExB,CAEA,UAAAG,GACKxR,KAAKuP,cACRvP,KAAKuP,aAAa2B,UAAUK,OAAO,QAEhCvR,KAAKwP,iBACRxP,KAAKwP,gBAAgB0B,UAAUK,OAAO,QAGvCjN,WAAW,KACVtE,KAAK2P,MAAMC,QAAS,EAChB5P,KAAKuP,cAAgBvP,KAAKuP,aAAakC,aAC1CzR,KAAKuP,aAAakC,WAAWC,YAAY1R,KAAKuP,cAC9CvP,KAAKuP,aAAe,MAEjBvP,KAAKwP,iBAAmBxP,KAAKwP,gBAAgBiC,aAChDzR,KAAKwP,gBAAgBiC,WAAWC,YAAY1R,KAAKwP,iBACjDxP,KAAKwP,gBAAkB,MAExBxP,KAAK2R,cACH,IACJ,CAEA,oBAAMzN,GACL,IAAIlE,KAAK2P,MAAMG,aAAf,CAEA9P,KAAK4R,aAEL,IACC5R,KAAK2P,MAAMG,cAAe,EAC1B9P,KAAK6R,sBAEL,MAAMrO,EAAU,CACf7B,MAAO3B,KAAK2P,MAAMhO,OAAS,WAC3B8C,QAASzE,KAAK2P,MAAMlL,QACpBmJ,MAAO5N,KAAK2P,MAAM/B,MAClBjJ,SAAU3E,KAAK0H,QAAQrG,QACvBuD,YAAa5E,KAAK2P,MAAM/K,aAGzB,IAAK5E,KAAK2P,MAAMlL,QAAQoJ,OAEvB,YADA7N,KAAK8R,WAAW,uCAIjB,MAAMzR,QAAiBL,KAAKiP,WAAW/K,eAAeV,GAEtDxD,KAAK+R,sBACL/R,KAAKwR,aAELxR,KAAKgP,IAAIwB,SAASvH,KAAK,qBAAsB,CAC5CwH,OAAQzQ,KACR0G,SAAUrG,GAEZ,CAAE,MAAO8C,GACRnD,KAAK8R,WAAW,gDAChB9R,KAAKgP,IAAIwB,SAASvH,KAAK,iBAAkB,CAAEwH,OAAQzQ,KAAMmD,SAC1D,CAAC,QACAnD,KAAK2P,MAAMG,cAAe,EAC1B9P,KAAK6R,qBACN,CApC6B,CAqC9B,CAEA,kBAAAG,CAAmBC,GAClBjS,KAAK0H,QAAQ4J,MAAQW,EAAUX,MAC3BtR,KAAKuM,SACRvM,KAAKkS,cAEP,CAEA,OAAAC,GACKnS,KAAK0P,YAET1P,KAAKoS,YACLpS,KAAKwR,aAEDxR,KAAKuM,SAAWvM,KAAKuM,QAAQkF,YAChCzR,KAAKuM,QAAQkF,WAAWC,YAAY1R,KAAKuM,SAG1CvM,KAAK0P,WAAY,EACjB1P,KAAKyP,SAAU,EACfzP,KAAKgP,IAAIwB,SAASvH,KAAK,mBAAoB,CAAEwH,OAAQzQ,OACtD,CAEA,OAAAsQ,GAAW,CACX,SAAA8B,GAAa,CAEb,OAAAjC,GACC,MAAM,IAAIxQ,MAAM,mDACjB,CAEA,aAAA0Q,GAEA,CAEA,YAAAL,GACChQ,KAAK6Q,UAAY7Q,KAAK6Q,UAAUwB,KAAKrS,MACrCA,KAAKwR,WAAaxR,KAAKwR,WAAWa,KAAKrS,MACvCA,KAAKkE,eAAiBlE,KAAKkE,eAAemO,KAAKrS,KAChD,CAEA,YAAAgR,GACC,GAAIhR,KAAKuP,aAAc,OAEnBvP,KAAK0H,QAAQ2H,eAAiBrP,KAAKwP,kBACtCxP,KAAKwP,gBAAkBjF,SAASyD,cAAc,OAC9ChO,KAAKwP,gBAAgB4B,UAAY,0BACjC7G,SAAS3G,KAAKwM,YAAYpQ,KAAKwP,iBAE/BxP,KAAKwP,gBAAgB8C,iBAAiB,QAAStS,KAAKwR,aAGrD,MAAMe,EACwB,UAA7BvS,KAAK0H,QAAQnG,YACV,iBACA,iBACEiR,EAAY,QAAQxS,KAAK0H,QAAQpG,OACvCtB,KAAKuP,aAAehF,SAASyD,cAAc,OAC3ChO,KAAKuP,aAAa6B,UAAY,GAAGmB,KAAaC,IAC9CxS,KAAKuP,aAAamB,MAAM+B,YACvB,kBACAzS,KAAK0H,QAAQxG,cAEdlB,KAAKuP,aAAamB,MAAM+B,YACvB,aACAzS,KAAK0H,QAAQvG,iBAEdnB,KAAKuP,aAAamB,MAAM+B,YAAY,eAAgBzS,KAAK0H,QAAQtG,WACjEpB,KAAKuP,aAAarB,UAAYlO,KAAK0S,gBAEnCnI,SAAS3G,KAAKwM,YAAYpQ,KAAKuP,cAC/BvP,KAAK2S,qBAEL,MAAMC,EAAa5S,KAAKuP,aAAaW,cAAc,mBAC/C0C,GACHtO,WAAW,IAAMsO,EAAWC,QAAS,IAEvC,CAEA,aAAAH,GACC,MAAO,6ZASkC1S,KAAKyB,yHAGXzB,KAAKyB,iIAGjBzB,KAAK2P,MAAMhO,2IAIS3B,KAAKyB,yFAEXzB,KAAKyB,4IAI3BzB,KAAK2P,MAAMlL,wPAKVzE,KAAK2P,MAAMG,aAAe,aAAe,qHAO1D,CAEA,kBAAA6C,GACC,MAAMG,EAAQ9S,KAAKuP,aAEnBuD,EACE5C,cAAc,yBACdoC,iBAAiB,QAAStS,KAAKwR,YAEpBsB,EAAM5C,cAAc,kBAC5BoC,iBAAiB,SAAWvK,IAChCA,EAAEgL,iBACF/S,KAAKkE,mBAGN4O,EACE5C,cAAc,uBACdoC,iBAAiB,QAAUvK,IAC3B/H,KAAK2P,MAAMhO,MAAQoG,EAAEgC,OAAO/I,QAG9B8R,EACE5C,cAAc,4BACdoC,iBAAiB,QAAUvK,IAC3B/H,KAAK2P,MAAMlL,QAAUsD,EAAEgC,OAAO/I,QAGhC,MAAMgS,EAAgBjL,IACP,WAAVA,EAAEmC,MACLlK,KAAKwR,aACLjH,SAAS0I,oBAAoB,UAAWD,KAG1CzI,SAAS+H,iBAAiB,UAAWU,EACtC,CAEA,mBAAAnB,GACC,GAAI7R,KAAKuP,aAAc,CACtB,MAAM2D,EAAYlT,KAAKuP,aAAaW,cAAc,wBAC9CgD,IACHA,EAAUjF,YAAcjO,KAAK2P,MAAMG,aAChC,aACA,gBACHoD,EAAUC,SAAWnT,KAAK2P,MAAMG,aAElC,CACD,CAEA,UAAAgC,CAAWjS,GACV,GAAIG,KAAKuP,aAAc,CACtB,MAAM6D,EAAepT,KAAKuP,aAAaW,cAAc,mBACjDkD,IACHA,EAAanF,YAAcpO,EAC3BuT,EAAalC,UAAUC,IAAI,QAE7B,CACD,CAEA,UAAAS,GACC,GAAI5R,KAAKuP,aAAc,CACtB,MAAM6D,EAAepT,KAAKuP,aAAaW,cAAc,mBACjDkD,GACHA,EAAalC,UAAUK,OAAO,OAEhC,CACD,CAEA,mBAAAQ,GACC,MAAMsB,EAAe9I,SAASyD,cAAc,OAC5CqF,EAAajC,UAAY,gCACzBiC,EAAanF,UAAY,oQAQzB3D,SAAS3G,KAAKwM,YAAYiD,GAE1B,MACMC,EAAoB,KACrBD,EAAa5B,aAChB4B,EAAa3C,MAAM6C,QAAU,IAC7BjP,WAAW,KACN+O,EAAa5B,YAChB4B,EAAa5B,WAAWC,YAAY2B,IAEnC,OARYA,EAAanD,cAAc,2BAYnCoC,iBAAiB,QAASgB,GAEnChP,WAAWgP,EAAmB,IAC/B,CAEA,UAAA3B,GACC3R,KAAK2P,MAAMhO,MAAQ,GACnB3B,KAAK2P,MAAMlL,QAAU,GACrBzE,KAAK2P,MAAM/B,MAAQ,GACnB5N,KAAK2P,MAAMI,OAAS,CAAA,CACrB,CAEA,YAAAmC,GACKlS,KAAKuM,UACRvM,KAAKuM,QAAQ6E,UAAYpR,KAAKuM,QAAQ6E,UAAUrG,QAC/C,YACA,SAAS/K,KAAK0H,QAAQ4J,UAGpBtR,KAAKuP,eACRvP,KAAKuP,aAAa6B,UAAYpR,KAAKuP,aAAa6B,UAAUrG,QACzD,YACA,SAAS/K,KAAK0H,QAAQ4J,SAGzB,CAEA,SAAAkC,GACCxT,KAAK6Q,WACN,CAEA,UAAA4C,GACCzT,KAAKwR,YACN,EC5bM,MAAMkC,UAAqB3E,EAC9B,WAAAnP,CAAY8H,GACR3H,MAAM,IAAK2H,EAAShG,KAAM,WAC1B1B,KAAK2T,aAAc,CACvB,CAEA,OAAAxD,GACI,MAAMyD,EAASrJ,SAASyD,cAAc,OAqBtC,OApBA4F,EAAOxC,UAAY,gDAAgDpR,KAAK0H,QAAQ4J,kBAAkBtR,KAAK0H,QAAQyH,WAC/GyE,EAAO1F,UAAY,orBAeflO,KAAK0H,QAAQ4H,cACbuE,OAAOC,OAAOF,EAAOlD,MAAO1Q,KAAK0H,QAAQ4H,cAGtCsE,CACX,CAEA,aAAAvD,GACI,MAAMuD,EAAS5T,KAAKuM,QAAQ2D,cAAc,yBACpC6D,EAAW/T,KAAKuM,QAAQ2D,cAAc,uBAE5C0D,EAAOtB,iBAAiB,QAAStS,KAAK6Q,WAEtCkD,EAASzB,iBAAiB,QAAUvK,IAChCA,EAAEiM,kBACFhU,KAAKiU,mBAGTL,EAAOtB,iBAAiB,aAAc,KAC7BtS,KAAK2P,MAAMG,eACZ8D,EAAOlD,MAAMwD,UAAY,sBAIjCN,EAAOtB,iBAAiB,aAAc,KAClCsB,EAAOlD,MAAMwD,UAAY,iBAEjC,CAEA,cAAAD,GACIjU,KAAK2T,aAAe3T,KAAK2T,YAErB3T,KAAK2T,aACL3T,KAAKuM,QAAQ2E,UAAUC,IAAI,aAC3BrK,aAAaC,QAAQ,4BAA6B,UAElD/G,KAAKuM,QAAQ2E,UAAUK,OAAO,aAC9BzK,aAAaI,WAAW,6BAEhC,CAEA,KAAA+I,CAAMf,GACFnP,MAAMkQ,MAAMf,GAG8C,SAAtDpI,aAAaU,QAAQ,+BACrBxH,KAAK2T,aAAc,EACnB3T,KAAKuM,QAAQ2E,UAAUC,IAAI,aAEnC,CAEA,UAAAgD,CAAWnM,GACP,MAAM4L,EAAS5T,KAAKuM,SAAS2D,cAAc,yBAC3C,GAAI0D,EAAQ,CACR,MAAMQ,EAAWR,EAAOS,WAAWT,EAAOS,WAAW7K,OAAS,GAC1D4K,GAAYA,EAASE,WAAaC,KAAKC,YACvCJ,EAASnG,YAAcjG,EAE/B,CACJ,CAEA,cAAAyM,CAAetF,GACXnP,KAAK0H,QAAQyH,SAAWA,EACpBnP,KAAKuM,UACLvM,KAAKuM,QAAQ6E,UAAYpR,KAAKuM,QAAQ6E,UAAUrG,QAC5C,mBACA,YAAYoE,KAGxB,EC7FG,MAAMuF,UAAqB3F,EACjC,WAAAnP,CAAY8H,GACX3H,MAAM,IAAK2H,EAAShG,KAAM,UAC3B,CAEA,OAAAyO,GACC,MAAMM,EAASlG,SAASyD,cAAc,OAyCtC,OAxCAyC,EAAOW,UAAY,gDAAgDpR,KAAK0H,QAAQ4J,QAChFb,EAAOvC,UAAY,qUASElO,KAAK2P,MAAMhO,oOAQnB3B,KAAK2P,MAAMlL,wOAOHzE,KAAK2P,MAAM/B,gRAW5B5N,KAAK0H,QAAQ4H,cAChBuE,OAAOC,OAAOrD,EAAOC,MAAO1Q,KAAK0H,QAAQ4H,cAGnCmB,CACR,CAEA,aAAAJ,GACC,MAAMsE,EAAO3U,KAAKuM,QAAQ2D,cAAc,yBAExCyE,EAAKrC,iBAAiB,SAAWvK,IAChCA,EAAEgL,iBACF/S,KAAKkE,mBAGNyQ,EAAKzE,cAAc,uBAAuBoC,iBAAiB,QAAUvK,IACpE/H,KAAK2P,MAAMhO,MAAQoG,EAAEgC,OAAO/I,QAG7B2T,EACEzE,cAAc,4BACdoC,iBAAiB,QAAUvK,IAC3B/H,KAAK2P,MAAMlL,QAAUsD,EAAEgC,OAAO/I,QAGhC2T,EAAKzE,cAAc,uBAAuBoC,iBAAiB,QAAUvK,IACpE/H,KAAK2P,MAAM/B,MAAQ7F,EAAEgC,OAAO/I,OAE9B,CAEA,SAAAwS,GACC,MAAMoB,EAAW5U,KAAKuM,QAAQ2D,cAAc,4BACxC0E,GACHA,EAAS/B,OAEX,CAEA,UAAAY,GAEA,CAEA,mBAAA1B,GACC,MAAMtB,EAASzQ,KAAKuM,QAAQ2D,cAAc,4BACpC2E,EAAkBpE,EAAOvC,UAE/BuC,EAAOvC,UAAY,4RASFuC,EAAOP,cAAc,uBAC7BoC,iBAAiB,QAAS,KAClC7B,EAAOvC,UAAY2G,EACnB7U,KAAKqQ,gBACLrQ,KAAK2R,cAEP,CAEA,UAAAG,CAAWjS,GACV,MAAMuT,EAAepT,KAAKuM,QAAQ2D,cAAc,mBAC5CkD,IACHA,EAAanF,YAAcpO,EAC3BuT,EAAa1C,MAAMC,QAAU,QAE7BrM,WAAW,KACN8O,IACHA,EAAa1C,MAAMC,QAAU,SAE5B,KAEL,CAEA,mBAAAkB,GACC,MAAMqB,EAAYlT,KAAKuM,QAAQ2D,cAAc,wBACzCgD,IACHA,EAAUjF,YAAcjO,KAAK2P,MAAMG,aAChC,aACA,gBACHoD,EAAUC,SAAWnT,KAAK2P,MAAMG,aAElC,CAEA,WAAAgF,CAAYnT,GACX,MAAMoT,EAAe/U,KAAKuM,SAAS2D,cAAc,MAC7C6E,IACHA,EAAa9G,YAActM,EAE7B,CAEA,cAAAqT,CAAejU,EAAOkU,GACrB,MAAMC,EAAQlV,KAAKuM,SAAS2D,cAAc,UAAUnP,OAChDmU,IACHA,EAAMD,YAAcA,EAEtB,EC5IM,MAAME,EACZ,WAAAvV,CAAY8H,EAAU,IACrB1H,KAAKoV,YAAc,OACnBpV,KAAK4P,QAAS,EACd5P,KAAKqV,YAAc,EACnBrV,KAAKsV,qBAAuB,KAG5BtV,KAAKuV,cAAgB,GACrBvV,KAAKwV,SAAW,GAGhBxV,KAAKyV,aAAe,GACpBzV,KAAK0V,gBAAkB,GAGvB1V,KAAK2V,mBAAqB,GAC1B3V,KAAK4V,eAAiB,GAGtB5V,KAAK6V,SAAWnO,EAAQmO,UAAY,UACpC7V,KAAK8V,YAAcpO,EAAQoO,aAAe,GAC1C9V,KAAK+V,eAAiBrO,EAAQqO,gBAAkB,mBAGhD/V,KAAK0C,YAAcgF,EAAQhF,aAAe,KAG1C1C,KAAKgW,YAAoC,IAAvBtO,EAAQsO,WAC1BhW,KAAKiW,iBAA8C,IAA5BvO,EAAQuO,gBAG/BjW,KAAKkW,WAAa,IAAIC,GACvB,CAKA,SAAAC,CAAU5N,GAET,OADAxI,KAAKkW,WAAW/E,IAAI3I,GACb,IAAMxI,KAAKkW,WAAWG,OAAO7N,EACrC,CAKA,OAAA8N,CAAQC,EAAY/R,GACnBxE,KAAKkW,WAAWhN,QAASsN,GAAOA,EAAGD,EAAY/R,EAAMxE,MACtD,CAKA,OAAAyW,CAAQC,GACP,MAAMC,EAAe3W,KAAKoV,YAC1BpV,KAAKoV,YAAcsB,EACnB1W,KAAKsW,QAAQ,aAAc,CAAEK,eAAcvB,YAAasB,GACzD,CAKA,OAAAE,CAAQhH,GACP5P,KAAK4P,OAASA,EACd5P,KAAKsW,QAAQ,aAAc,CAAE1G,UAC9B,CAKA,qBAAAiH,CAAsBC,GACrB9W,KAAKsV,qBAAuBwB,EAC5B9W,KAAKsW,QAAQ,qBAAsB,CAAEQ,kBACtC,CAKA,gBAAAC,CAAiBxB,GAChBvV,KAAKuV,cAAgBA,EACrBvV,KAAKgX,qBACLhX,KAAKsW,QAAQ,sBAAuB,CAAEf,iBACvC,CAKA,eAAA0B,CAAgBC,GACflX,KAAKuV,cAAc4B,QAAQD,GAC3BlX,KAAKgX,qBACLhX,KAAKsW,QAAQ,oBAAqB,CAAEY,gBACrC,CAKA,WAAAE,CAAYN,EAAgBtB,GAC3BxV,KAAKwV,SAASsB,GAAkBtB,EAChCxV,KAAKsW,QAAQ,iBAAkB,CAAEQ,iBAAgBtB,YAClD,CAKA,UAAA6B,CAAWP,EAAgBjX,GACrBG,KAAKwV,SAASsB,KAClB9W,KAAKwV,SAASsB,GAAkB,IAEjC9W,KAAKwV,SAASsB,GAAgBnO,KAAK9I,GAGnC,MAAMyX,EAAOtX,KAAKuV,cAAcgC,KAAMC,GAAMA,EAAE/V,KAAOqV,GACjDQ,IACHA,EAAKG,YAAc5X,EAAQ4E,QAC3B6S,EAAKI,gBAAkB7X,EAAQ8X,UAC1B9X,EAAQ+X,QACZN,EAAKO,QAAUP,EAAKO,QAAU,GAAK,EACnC7X,KAAKgX,uBAIPhX,KAAKsW,QAAQ,eAAgB,CAAEQ,iBAAgBjX,WAChD,CAKA,UAAAiY,CAAWhB,GACV,MAAMQ,EAAOtX,KAAKuV,cAAcgC,KAAMC,GAAMA,EAAE/V,KAAOqV,GACjDQ,GAAQA,EAAKO,OAAS,IACzBP,EAAKO,OAAS,EACd7X,KAAKgX,qBACLhX,KAAKsW,QAAQ,mBAAoB,CAAEQ,mBAErC,CAKA,kBAAAE,GACChX,KAAKqV,YAAcrV,KAAKuV,cAAcwC,OACrC,CAACC,EAAKR,IAAMQ,GAAOR,EAAEK,QAAU,GAC/B,GAED7X,KAAKsW,QAAQ,oBAAqB,CAAE2B,MAAOjY,KAAKqV,aACjD,CAKA,eAAA6C,CAAgBC,GACfnY,KAAKyV,aAAe0C,EACpBnY,KAAKsW,QAAQ,qBAAsB,CAAE6B,YACtC,CAKA,kBAAAC,CAAmBC,GAClBrY,KAAK0V,gBAAkB2C,EACvBrY,KAAKsW,QAAQ,mBAAoB,CAAE+B,SACpC,CAKA,qBAAAC,CAAsBC,GACrBvY,KAAK2V,mBAAqB4C,EAC1BvY,KAAKsW,QAAQ,sBAAuB,CAAEiC,SACvC,CAKA,iBAAAC,CAAkBD,GACjBvY,KAAK4V,eAAiB2C,EACtBvY,KAAKsW,QAAQ,kBAAmB,CAAEiC,SACnC,CAKA,qBAAAE,GACC,OAAOzY,KAAKuV,cAAcgC,KAAMC,GAAMA,EAAE/V,KAAOzB,KAAKsV,qBACrD,CAKA,iBAAAoD,GACC,OAAO1Y,KAAKwV,SAASxV,KAAKsV,uBAAyB,EACpD,CAKA,uBAAAqD,GACC,IAAK3Y,KAAK0V,gBACT,OAAO1V,KAAKyV,aAEb,MAAM4C,EAAQrY,KAAK0V,gBAAgBkD,cACnC,OAAO5Y,KAAKyV,aAAaoD,OACvBC,GACAA,EAAQnX,MAAMiX,cAAcxS,SAASiS,IACpCS,EAAQlX,aACRkX,EAAQlX,YAAYgX,cAAcxS,SAASiS,GAE/C,CAKA,KAAAU,GACC/Y,KAAKoV,YAAc,OACnBpV,KAAKsV,qBAAuB,KAC5BtV,KAAK0V,gBAAkB,GACvB1V,KAAKsW,QAAQ,QAAS,GACvB,ECzNM,MAAM0C,EACZ,WAAApZ,CAAY+P,EAAOjI,EAAU,IAC5B1H,KAAK2P,MAAQA,EACb3P,KAAK0H,QAAU,CACdyH,SAAUzH,EAAQyH,UAAY,eAC9BjO,aAAcwG,EAAQxG,cAAgB,aACnCwG,GAEJ1H,KAAKuM,QAAU,KACfvM,KAAKiZ,aAAe,IACrB,CAEA,MAAAC,GAiBC,OAhBAlZ,KAAKuM,QAAUhC,SAASyD,cAAc,OACtChO,KAAKuM,QAAQ6E,UAAY,yCAAyCpR,KAAK0H,QAAQyH,WAE/EnP,KAAKmZ,iBACLnZ,KAAKqQ,gBAGLrQ,KAAKiZ,aAAejZ,KAAK2P,MAAMyG,UAAU,CAAC1U,EAAM8C,KAClC,eAAT9C,GACH1B,KAAKoZ,cAEO,sBAAT1X,GACH1B,KAAKqZ,iBAIArZ,KAAKuM,OACb,CAEA,cAAA4M,GACC,MAAMG,EACLtZ,KAAK2P,MAAM0F,YAAc,EACtB,0CAA0CrV,KAAK2P,MAAM0F,YAAc,EAAI,KAAOrV,KAAK2P,MAAM0F,qBACzF,GAEJrV,KAAKuM,QAAQ2B,UAAY,iGACgElO,KAAK0H,QAAQxG,uXAOlGoY,0BAGL,CAEA,aAAAjJ,GACCrQ,KAAKuM,QACH2D,cAAc,2BACdoC,iBAAiB,QAAS,KAC1BtS,KAAK2P,MAAMiH,SAAS5W,KAAK2P,MAAMC,SAElC,CAEA,WAAAwJ,GACC,MAAMG,EAAWvZ,KAAKuM,QAAQ2D,cAC7B,iCAEKsJ,EAAYxZ,KAAKuM,QAAQ2D,cAC9B,kCAGGlQ,KAAK2P,MAAMC,QACd2J,EAAS7I,MAAMC,QAAU,OACzB6I,EAAU9I,MAAMC,QAAU,OAC1B3Q,KAAKuM,QAAQ2E,UAAUC,IAAI,6BAE3BoI,EAAS7I,MAAMC,QAAU,OACzB6I,EAAU9I,MAAMC,QAAU,OAC1B3Q,KAAKuM,QAAQ2E,UAAUK,OAAO,2BAEhC,CAEA,YAAA8H,GACC,MAAMI,EAAgBzZ,KAAKuM,QAAQ2D,cAClC,6BAMD,GAJIuJ,GACHA,EAAclI,SAGXvR,KAAK2P,MAAM0F,YAAc,IAAMrV,KAAK2P,MAAMC,OAAQ,CACrD,MAAM8J,EAAQnP,SAASyD,cAAc,QACrC0L,EAAMtI,UAAY,2BAClBsI,EAAMzL,YACLjO,KAAK2P,MAAM0F,YAAc,EAAI,KAAOrV,KAAK2P,MAAM0F,YAChDrV,KAAKuM,QAAQ2D,cAAc,2BAA2BE,YAAYsJ,EACnE,CACD,CAEA,IAAAnJ,GACKvQ,KAAKuM,UACRvM,KAAKuM,QAAQmE,MAAMC,QAAU,QAE/B,CAEA,IAAAC,GACK5Q,KAAKuM,UACRvM,KAAKuM,QAAQmE,MAAMC,QAAU,OAE/B,CAEA,OAAAwB,GACKnS,KAAKiZ,cACRjZ,KAAKiZ,eAEFjZ,KAAKuM,SAAWvM,KAAKuM,QAAQkF,YAChCzR,KAAKuM,QAAQkF,WAAWC,YAAY1R,KAAKuM,QAE3C,EClHM,MAAMoN,EACZ,WAAA/Z,CAAY+P,EAAOjI,EAAU,IAC5B1H,KAAK2P,MAAQA,EACb3P,KAAK0H,QAAUA,EACf1H,KAAKuM,QAAU,KACfvM,KAAKiZ,aAAe,IACrB,CAEA,MAAAC,GAcC,OAbAlZ,KAAKuM,QAAUhC,SAASyD,cAAc,OACtChO,KAAKuM,QAAQ6E,UAAY,gBAEzBpR,KAAKmZ,iBACLnZ,KAAKqQ,gBAGLrQ,KAAKiZ,aAAejZ,KAAK2P,MAAMyG,UAAW1U,IAC5B,eAATA,GAAkC,sBAATA,GAC5B1B,KAAK4Z,qBAIA5Z,KAAKuM,OACb,CAEA,QAAAsN,GACC,MAAMC,EAAO,CACZ,CAAErY,GAAI,OAAQsY,MAAO,OAAQC,KAAMha,KAAKia,gBACxC,CACCxY,GAAI,WACJsY,MAAO,WACPC,KAAMha,KAAKka,mBACXR,MAAO1Z,KAAK2P,MAAM0F,cAgBpB,OAZIrV,KAAK2P,MAAMqG,YACd8D,EAAKnR,KAAK,CAAElH,GAAI,OAAQsY,MAAO,OAAQC,KAAMha,KAAKma,iBAG/Cna,KAAK2P,MAAMsG,iBACd6D,EAAKnR,KAAK,CACTlH,GAAI,YACJsY,MAAO,YACPC,KAAMha,KAAKoa,sBAINN,CACR,CAEA,cAAAX,GACC,MACMkB,EADOra,KAAK6Z,WAEhBS,IAAKC,IACL,MAAMC,EAAWxa,KAAK2P,MAAMyF,cAAgBmF,EAAI9Y,GAC1C6X,EACLiB,EAAIb,OAASa,EAAIb,MAAQ,EACtB,qCAAqCa,EAAIb,MAAQ,EAAI,KAAOa,EAAIb,eAChE,GAEJ,MAAO,8CAC4Bc,EAAW,SAAW,iBAAiBD,EAAI9Y,oDAC1C8Y,EAAIP,4DACHO,EAAIR,2BACtCT,iCAIHxK,KAAK,IAEP9O,KAAKuM,QAAQ2B,UAAYmM,CAC1B,CAEA,aAAAhK,GACCrQ,KAAKuM,QAAQ+F,iBAAiB,QAAUvK,IACvC,MAAMwS,EAAMxS,EAAEgC,OAAO0Q,QAAQ,sBAC7B,GAAIF,EAAK,CACR,MAAMG,EAAQH,EAAII,QAAQJ,IAC1Bva,KAAK2P,MAAM8G,QAAQiE,EACpB,GAEF,CAEA,gBAAAd,GACc5Z,KAAKuM,QAAQqO,iBAAiB,sBACtC1R,QAASqR,IACb,MAAMC,EAAWD,EAAII,QAAQJ,MAAQva,KAAK2P,MAAMyF,YAIhD,GAHAmF,EAAIrJ,UAAU2J,OAAO,SAAUL,GAGP,aAApBD,EAAII,QAAQJ,IAAoB,CACnC,MAAMd,EAAgBc,EAAIrK,cAAc,wBAGxC,GAFIuJ,GAAeA,EAAclI,SAE7BvR,KAAK2P,MAAM0F,YAAc,EAAG,CAC/B,MAAMqE,EAAQnP,SAASyD,cAAc,QACrC0L,EAAMtI,UAAY,sBAClBsI,EAAMzL,YACLjO,KAAK2P,MAAM0F,YAAc,EAAI,KAAOrV,KAAK2P,MAAM0F,YAChDkF,EAAInK,YAAYsJ,EACjB,CACD,GAEF,CAEA,YAAAO,GACC,MAAO,qEACR,CAEA,gBAAAC,GACC,MAAO,6DACR,CAEA,YAAAC,GACC,MAAO,iEACR,CAEA,iBAAAC,GACC,MAAO,kEACR,CAEA,OAAAjI,GACKnS,KAAKiZ,cACRjZ,KAAKiZ,eAEFjZ,KAAKuM,SAAWvM,KAAKuM,QAAQkF,YAChCzR,KAAKuM,QAAQkF,WAAWC,YAAY1R,KAAKuM,QAE3C,EC/HM,MAAMuO,EACZ,WAAAlb,CAAY+P,EAAOjI,EAAU,IAC5B1H,KAAK2P,MAAQA,EACb3P,KAAK0H,QAAU,CACdyH,SAAUzH,EAAQyH,UAAY,eAC9BmC,MAAO5J,EAAQ4J,OAAS,UACrB5J,GAEJ1H,KAAKuM,QAAU,KACfvM,KAAK+a,eAAiB,KACtB/a,KAAKgb,qBAAuB,KAC5Bhb,KAAKib,aAAe,CAAA,EACpBjb,KAAKiZ,aAAe,IACrB,CAKA,YAAAiC,CAAajb,EAAMkb,GAClBnb,KAAKib,aAAahb,GAAQkb,CAC3B,CAEA,MAAAjC,GACClZ,KAAKuM,QAAUhC,SAASyD,cAAc,OACtChO,KAAKuM,QAAQ6E,UAAY,mCAAmCpR,KAAK0H,QAAQyH,kBAAkBnP,KAAK0H,QAAQ4J,QAExGtR,KAAKuM,QAAQ2B,UAAY,wKAQzBlO,KAAK+a,eAAiB,IAAIpB,EAAe3Z,KAAK2P,MAAO3P,KAAK0H,SAc1D,OAbqB1H,KAAKuM,QAAQ2D,cAAc,wBACnCE,YAAYpQ,KAAK+a,eAAe7B,UAG7ClZ,KAAKob,qBAGLpb,KAAKiZ,aAAejZ,KAAK2P,MAAMyG,UAAW1U,IAC5B,eAATA,GACH1B,KAAKob,uBAIApb,KAAKuM,OACb,CAEA,kBAAA6O,GACC,MAAMC,EAAiBrb,KAAKuM,QAAQ2D,cAAc,0BAG9ClQ,KAAKgb,sBAAwBhb,KAAKgb,qBAAqB7I,SAC1DnS,KAAKgb,qBAAqB7I,UAI3BkJ,EAAenN,UAAY,GAG3B,MAAMiN,EAAYnb,KAAKib,aAAajb,KAAK2P,MAAMyF,aAC3C+F,GACHnb,KAAKgb,qBAAuB,IAAIG,EAAUnb,KAAK2P,MAAO3P,KAAK0H,SAC3D2T,EAAejL,YAAYpQ,KAAKgb,qBAAqB9B,WAErDmC,EAAenN,UAAY,2DAA2DlO,KAAK2P,MAAMyF,mBAEnG,CAKA,IAAA7E,GACKvQ,KAAKuM,UACRvM,KAAKuM,QAAQmE,MAAMC,QAAU,QAE7BM,sBAAsB,KACrBjR,KAAKuM,QAAQ2E,UAAUC,IAAI,UAG9B,CAKA,IAAAP,GACK5Q,KAAKuM,UACRvM,KAAKuM,QAAQ2E,UAAUK,OAAO,QAE9BjN,WAAW,KACNtE,KAAKuM,UACRvM,KAAKuM,QAAQmE,MAAMC,QAAU,SAE5B,KAEL,CAKA,SAAA2K,CAAUC,GACT,MAAMC,EAASxb,KAAKuM,QAAQ2D,cAAc,2BACtCsL,IACHA,EAAOtN,UAAYqN,EAErB,CAEA,OAAApJ,GACKnS,KAAKiZ,cACRjZ,KAAKiZ,eAEFjZ,KAAK+a,gBACR/a,KAAK+a,eAAe5I,UAEjBnS,KAAKgb,sBAAwBhb,KAAKgb,qBAAqB7I,SAC1DnS,KAAKgb,qBAAqB7I,UAEvBnS,KAAKuM,SAAWvM,KAAKuM,QAAQkF,YAChCzR,KAAKuM,QAAQkF,WAAWC,YAAY1R,KAAKuM,QAE3C,EC7HM,MAAMkP,EACZ,WAAA7b,CAAY+P,EAAOjI,EAAU,IAC5B1H,KAAK2P,MAAQA,EACb3P,KAAK0H,QAAUA,EACf1H,KAAKuM,QAAU,KACfvM,KAAKiZ,aAAe,IACrB,CAEA,MAAAC,GAaC,OAZAlZ,KAAKuM,QAAUhC,SAASyD,cAAc,OACtChO,KAAKuM,QAAQ6E,UAAY,0CAEzBpR,KAAKmZ,iBAGLnZ,KAAKiZ,aAAejZ,KAAK2P,MAAMyG,UAAW1U,IAC5B,oBAATA,GACH1B,KAAK0b,yBAIA1b,KAAKuM,OACb,CAEA,cAAA4M,GACC,MAAMwC,EAAc3b,KAAK4b,qBAEzB5b,KAAKuM,QAAQ2B,UAAY,yaAWTlO,KAAK2P,MAAMkG,8BACtB8F,4JASL3b,KAAK0b,uBACL1b,KAAKqQ,eACN,CAEA,oBAAAqL,GACC,MAAMG,EAAqB7b,KAAKuM,QAAQ2D,cACvC,6BAEK0F,EAAiB5V,KAAK2P,MAAMiG,eAEJ,IAA1BA,EAAepM,QAKnBqS,EAAmB3N,UAAY0H,EAC7B0E,IAAKwB,GAAS9b,KAAK+b,qBAAqBD,IACxChN,KAAK,IAGP9O,KAAKgc,0BATJH,EAAmB3N,UAAYlO,KAAKic,mBAUtC,CAEA,oBAAAF,CAAqBD,GACpB,MAAMI,EACLJ,EAAKK,MAAQL,EAAKK,KAAK3S,OAAS,EAC7B,mDACAsS,EAAKK,KAAK7B,IAAK8B,GAAQ,yCAAyCA,YAActN,KAAK,oBAEnF,GAEEuN,EAAUrc,KAAKsc,YAAYR,EAAKS,aAAeT,EAAKU,MAE1D,MAAO,oEACqDV,EAAKra,iBAE9Dqa,EAAKW,WACF,8EAEUX,EAAKW,oBAAoBX,EAAKna,6EAGxC,oEAGDua,sDACsCJ,EAAKna,yBAC3Cma,EAAKla,YAAc,8CAA8C5B,KAAK0c,cAAcZ,EAAKla,YAAa,WAAa,4GAE3Eya,kKAM9C,CAEA,kBAAAT,GACC,MAAMe,EAAU3c,KAAK2P,MAAMmG,YAC3B,IAAK6G,GAA8B,IAAnBA,EAAQnT,OACvB,MAAO,yMAOR,MAAMoT,EAAS,CAAC,UAAW,UAAW,WAWtC,MAAO,mEAVaD,EAClBE,MAAM,EAAG,GACTvC,IAAI,CAACwC,EAAQ7R,IACS,iBAAX6R,GAAuBA,EAAOC,WAAW,QAC5C,4DAA4DD,wCAA6C,EAAI7R,SAE9G,0EAA0E2R,EAAO3R,EAAI2R,EAAOpT,qBAAqB,EAAIyB,OAAO6R,EAAOE,OAAO,GAAGC,uBAEpJnO,KAAK,WAGR,CAEA,iBAAAmN,GACC,MAAO,+RASR,CAEA,WAAAK,CAAYY,GACX,IAAKA,EAAY,MAAO,GAExB,OADa,IAAI9Z,KAAK8Z,GACVC,mBAAmB,QAAS,CACvCC,MAAO,QACPC,IAAK,UACLC,KAAM,WAER,CAEA,aAAAZ,CAAc1U,EAAMuV,GACnB,OAAKvV,EACDA,EAAKwB,QAAU+T,EAAkBvV,EAC9BA,EAAK6B,UAAU,EAAG0T,GAAW1P,OAAS,MAF3B,EAGnB,CAEA,aAAAwC,GAECrQ,KAAKuM,QACH2D,cAAc,wBACdoC,iBAAiB,QAAS,KAC1BtS,KAAK2P,MAAMiH,SAAQ,KAGrB5W,KAAKgc,wBACN,CAEA,sBAAAA,GACChc,KAAKuM,QACHqO,iBAAiB,6BACjB1R,QAASsU,IACTA,EAAKlL,iBAAiB,QAAS,KAC9B,MAAMmL,EAAcD,EAAK7C,QAAQ8C,YAC3BC,EAAgB1d,KAAK2P,MAAMiG,eAAe2B,KAC9CoG,GAAMA,EAAElc,KAAOgc,GAEbC,GAAiBA,EAAcvY,IAClCC,OAAOwY,KAAKF,EAAcvY,IAAK,UACrBnF,KAAK0H,QAAQmW,kBACvB7d,KAAK0H,QAAQmW,iBAAiBH,MAInC,CAEA,OAAAvL,GACKnS,KAAKiZ,cACRjZ,KAAKiZ,eAEFjZ,KAAKuM,SAAWvM,KAAKuM,QAAQkF,YAChCzR,KAAKuM,QAAQkF,WAAWC,YAAY1R,KAAKuM,QAE3C,ECjMM,MAAMuR,EACZ,WAAAle,CAAY+P,EAAOjI,EAAU,IAC5B1H,KAAK2P,MAAQA,EACb3P,KAAK0H,QAAUA,EACf1H,KAAKuM,QAAU,KACfvM,KAAKiZ,aAAe,IACrB,CAEA,MAAAC,GAiBC,OAhBAlZ,KAAKuM,QAAUhC,SAASyD,cAAc,OACtChO,KAAKuM,QAAQ6E,UAAY,qCAEzBpR,KAAKmZ,iBAGLnZ,KAAKiZ,aAAejZ,KAAK2P,MAAMyG,UAAU,CAAC1U,EAAM8C,KAErC,iBAAT9C,GACA8C,EAAKsS,iBAAmB9W,KAAK2P,MAAM2F,uBAEnCtV,KAAK+d,eAAevZ,EAAK3E,SACzBG,KAAKge,qBAIAhe,KAAKuM,OACb,CAEA,cAAA4M,GACC,MAAMjC,EAAelX,KAAK2P,MAAM8I,wBAC1BjD,EAAWxV,KAAK2P,MAAM+I,oBAEtBuF,EACe,IAApBzI,EAAShM,OACNxJ,KAAKic,oBACLzG,EAAS8E,IAAK4D,GAAQle,KAAKme,eAAeD,IAAMpP,KAAK,IAEnDsP,EAAape,KAAKqe,0BAA0BnH,GAElDlX,KAAKuM,QAAQ2B,UAAY,mQAMpBkQ,mDACmClH,GAAcvV,OAAS,iQAQ3Dsc,gbAaJje,KAAKqQ,gBACLrQ,KAAKge,iBACN,CAEA,iBAAA/B,GAEC,MAAO,iGADYjc,KAAK4b,0KAQzB,CAEA,cAAAuC,CAAete,GACd,MAAM+X,EAAQ/X,EAAQ+X,MAChB0G,EAAe1G,EAClB,wBACA,6BACG2G,EAAUve,KAAKwe,mBAAmB3e,EAAQ8X,WAEhD,GAAIC,EACH,MAAO,2CAC0B0G,6GAEWte,KAAKye,sBAAsB5e,EAAQ4E,mFAEvC8Z,kCAMzC,MAAO,yCAC0BD,sDAFdte,KAAK0e,oBAAoB7e,EAAQ8e,mHAKT9e,EAAQ8e,QAAQ1e,MAAQ,yHAEtBD,KAAKye,sBAAsB5e,EAAQ4E,mFAEvC8Z,6CAI1C,CAEA,mBAAAG,CAAoBC,GACnB,GAAIA,GAAQC,UACX,MAAO,6DAA6DD,EAAOC,mBAAmBD,EAAO1e,WAGtG,MAAO,sFADU0e,GAAQ1e,MAAQ,KAAK+c,OAAO,GAAGC,qBAEjD,CAEA,yBAAAoB,CAA0BnH,GACzB,IAAKA,GAAc2H,cAAcrV,OAChC,MAAO,4FAER,MAAMsV,EAAI5H,EAAa2H,aAAa,GACpC,OAAIC,EAAEF,UACE,6DAA6DE,EAAEF,mBAAmBE,EAAE7e,WAErF,sFAAsF6e,EAAE7e,MAAQ,KAAK+c,OAAO,GAAGC,qBACvH,CAEA,kBAAArB,GACC,MAAMe,EAAU3c,KAAK2P,MAAMmG,YAC3B,IAAK6G,GAA8B,IAAnBA,EAAQnT,OACvB,MAAO,qOAQR,MAAMoT,EAAS,CAAC,UAAW,UAAW,UAAW,UAAW,WAW5D,MAAO,uCAVaD,EAClBE,MAAM,EAAG,GACTvC,IAAI,CAACwC,EAAQ7R,IACS,iBAAX6R,GAAuBA,EAAOC,WAAW,QAC5C,sCAAsCD,wCAA6C,EAAI7R,SAExF,oDAAoD2R,EAAO3R,EAAI2R,EAAOpT,qBAAqB,EAAIyB,OAAO6R,EAAOE,OAAO,GAAGC,uBAE9HnO,KAAK,WAGR,CAEA,kBAAA0P,CAAmB7G,GAClB,IAAKA,EAAW,MAAO,GAEvB,OADa,IAAIvU,KAAKuU,GACVoH,mBAAmB,QAAS,CACvCC,KAAM,UACNC,OAAQ,UACRC,QAAQ,GAEV,CAEA,qBAAAT,CAAsBha,GACrB,OAAKA,EAEEA,EACLsG,QAAQ,KAAM,SACdA,QAAQ,KAAM,QACdA,QAAQ,KAAM,QACdA,QAAQ,MAAO,QANI,EAOtB,CAEA,cAAAgT,CAAele,GACd,MAAMsf,EAAoBnf,KAAKuM,QAAQ2D,cACtC,4BAEKkP,EAAaD,EAAkBjP,cAAc,yBAC/CkP,GACHA,EAAW7N,SAGZ,MAAM8N,EAAcrf,KAAKme,eAAete,GAClCyf,EAAU/U,SAASyD,cAAc,OACvCsR,EAAQpR,UAAYmR,EACpBF,EAAkB/O,YAAYkP,EAAQC,kBACvC,CAEA,eAAAvB,GACC,MAAMmB,EAAoBnf,KAAKuM,QAAQ2D,cACtC,4BAEGiP,GACH7a,WAAW,KACV6a,EAAkBK,UAAYL,EAAkBM,cAC9C,GAEL,CAEA,aAAApP,GAECrQ,KAAKuM,QACH2D,cAAc,uBACdoC,iBAAiB,QAAS,KAC1BtS,KAAK2P,MAAM8G,QAAQ,cAIrBzW,KAAKuM,QACH2D,cAAc,wBACdoC,iBAAiB,QAAS,KAC1BtS,KAAK2P,MAAMiH,SAAQ,KAIrB,MAAM1B,EAAQlV,KAAKuM,QAAQ2D,cAAc,4BACnCwP,EAAU1f,KAAKuM,QAAQ2D,cAAc,2BAE3CgF,EAAM5C,iBAAiB,QAAS,KAE/B4C,EAAMxE,MAAM5E,OAAS,OACrBoJ,EAAMxE,MAAM5E,OAASnC,KAAKgW,IAAIzK,EAAMuK,aAAc,KAAO,KAGzDC,EAAQvM,UAAY+B,EAAMlU,MAAM6M,SAGjCqH,EAAM5C,iBAAiB,UAAYvK,IACpB,UAAVA,EAAEmC,KAAoBnC,EAAE6X,WAC3B7X,EAAEgL,iBACF/S,KAAK6f,kBAIPH,EAAQpN,iBAAiB,QAAS,KACjCtS,KAAK6f,gBAEP,CAEA,YAAAA,GACC,MAAM3K,EAAQlV,KAAKuM,QAAQ2D,cAAc,4BACnCzL,EAAUyQ,EAAMlU,MAAM6M,OAE5B,IAAKpJ,EAAS,OAGd,MAAM5E,EAAU,CACf4B,GAAI,OAAS2B,KAAKC,MAClBoB,QAASA,EACTmT,OAAO,EACPD,WAAW,IAAIvU,MAAOkE,eAGvBtH,KAAK2P,MAAM0H,WAAWrX,KAAK2P,MAAM2F,qBAAsBzV,GAGvDqV,EAAMlU,MAAQ,GACdkU,EAAMxE,MAAM5E,OAAS,OACrB9L,KAAKuM,QAAQ2D,cAAc,2BAA2BiD,UAAW,EAG7DnT,KAAK0H,QAAQoY,eAChB9f,KAAK0H,QAAQoY,cAAc9f,KAAK2P,MAAM2F,qBAAsBzV,EAE9D,CAEA,OAAAsS,GACKnS,KAAKiZ,cACRjZ,KAAKiZ,eAEFjZ,KAAKuM,SAAWvM,KAAKuM,QAAQkF,YAChCzR,KAAKuM,QAAQkF,WAAWC,YAAY1R,KAAKuM,QAE3C,ECvRM,MAAMwT,EACZ,WAAAngB,CAAY+P,EAAOjI,EAAU,IAC5B1H,KAAK2P,MAAQA,EACb3P,KAAK0H,QAAUA,EACf1H,KAAKuM,QAAU,KACfvM,KAAKiZ,aAAe,IACrB,CAEA,MAAAC,GAkBC,OAjBAlZ,KAAKuM,QAAUhC,SAASyD,cAAc,OACtChO,KAAKuM,QAAQ6E,UAAY,8CAEzBpR,KAAKmZ,iBACLnZ,KAAKqQ,gBAGLrQ,KAAKiZ,aAAejZ,KAAK2P,MAAMyG,UAAW1U,IAE/B,wBAATA,GACS,sBAATA,GACS,qBAATA,GAEA1B,KAAKmZ,mBAIAnZ,KAAKuM,OACb,CAEA,cAAA4M,GACC,MAAM5D,EAAgBvV,KAAK2P,MAAM4F,cAC3BoG,EAAc3b,KAAKggB,qBAEzB,IAAIC,EAEHA,EAD4B,IAAzB1K,EAAc/L,OACG,iUAUA,mEAEhB+L,EAAc+E,IAAKhD,GAAStX,KAAKkgB,wBAAwB5I,IAAOxI,KAAK,8BAK1E9O,KAAKuM,QAAQ2B,UAAY,8SASrB+R,mLAK4CtE,iKAOhD3b,KAAKqQ,eACN,CAEA,uBAAA6P,CAAwBhJ,GACvB,MAAMiJ,EAAcjJ,EAAaW,OAAS,EAAI,SAAW,GACnDuI,EAAUpgB,KAAKqgB,eAAenJ,EAAaQ,iBAC3CiE,EAAc3b,KAAKsgB,2BACxBpJ,EAAa2H,cAGd,MAAO,mDACoCsB,4BAAsCjJ,EAAazV,yEAEzFka,0LAI4CzE,EAAavV,OAAS,kFACvBye,mGAG1ClJ,EAAaW,OAAS,EAAI,6CAA+C,gEAC5B7X,KAAKugB,iBAAiBrJ,EAAaO,2EAKvF,CAEA,0BAAA6I,CAA2BzB,GAC1B,IAAKA,GAAwC,IAAxBA,EAAarV,OACjC,MAAO,6FAGR,MAAMsV,EAAID,EAAa,GACvB,OAAIC,EAAEF,UACE,8DAA8DE,EAAEF,mBAAmBE,EAAE7e,WAEtF,4EAA4ED,KAAKwgB,gBAAgB,SAAS1B,EAAE7e,MAAQ,KAAK+c,OAAO,GAAGC,qBAC3I,CAEA,kBAAA+C,GACC,MAAMrD,EAAU3c,KAAK2P,MAAMmG,YAC3B,IAAK6G,GAA8B,IAAnBA,EAAQnT,OACvB,MAAO,gTAkBR,MAAO,oEAVamT,EAClBE,MAAM,EAAG,GACTvC,IAAI,CAACwC,EAAQ7R,IACS,iBAAX6R,GAAuBA,EAAOC,WAAW,QAC5C,6DAA6DD,wCAA6C,EAAI7R,SAE/G,2EAA2EjL,KAAKwgB,gBAAgBvV,gBAAgB,EAAIA,OAAO6R,EAAOE,OAAO,GAAGC,uBAEnJnO,KAAK,WAGR,CAEA,eAAA0R,CAAgB1X,GACf,MAAM8T,EAAS,CAAC,UAAW,UAAW,UAAW,UAAW,WAC5D,OAAOA,EAAO9T,EAAQ8T,EAAOpT,OAC9B,CAEA,cAAA6W,CAAe1I,GACd,IAAKA,EAAW,MAAO,GACvB,MAAM6E,EAAO,IAAIpZ,KAAKuU,GAEhB8I,EADM,IAAIrd,KACKoZ,EACfkE,EAAW/W,KAAKuB,MAAMuV,EAAS,KAC/BE,EAAYhX,KAAKuB,MAAMuV,EAAS,MAChCG,EAAWjX,KAAKuB,MAAMuV,EAAS,OAErC,OAAIC,EAAW,EAAU,MACrBA,EAAW,GAAW,GAAGA,KACzBC,EAAY,GAAW,GAAGA,KAC1BC,EAAW,EAAU,GAAGA,KACrBpE,EAAKW,mBAAmB,QAAS,CAAEC,MAAO,QAASC,IAAK,WAChE,CAEA,gBAAAkD,CAAiB1gB,GAChB,IAAKA,EAAS,MAAO,kBAErB,OAAIA,EAAQ2J,QADM,GACsB3J,EACjCA,EAAQgK,UAAU,EAFP,IAEuB,KAC1C,CAEA,aAAAwG,GAEC,MAAM0D,EAAW/T,KAAKuM,QAAQ2D,cAAc,wBACxC6D,GACHA,EAASzB,iBAAiB,QAAS,KAClCtS,KAAK2P,MAAMiH,SAAQ,KAKrB5W,KAAKuM,QACHqO,iBAAiB,gCACjB1R,QAAS4S,IACTA,EAAKxJ,iBAAiB,QAAS,KAC9B,MAAMuO,EAAS/E,EAAKnB,QAAQ7D,eAC5B9W,KAAK2P,MAAMkH,sBAAsBgK,GACjC7gB,KAAK2P,MAAMmI,WAAW+I,GACtB7gB,KAAK2P,MAAM8G,QAAQ,YAKtB,MAAMqK,EAAY9gB,KAAKuM,QAAQ2D,cAAc,8BACzC4Q,GACHA,EAAUxO,iBAAiB,QAAS,KACnCtS,KAAK+gB,yBAGR,CAEA,qBAAAA,GAEC,MAAMC,EAAU,CACfvf,GAAI,QAAU2B,KAAKC,MACnB1B,MAAO,mBACPkd,aAAc,GACdpH,YAAa,KACbC,iBAAiB,IAAItU,MAAOkE,cAC5BuQ,OAAQ,GAET7X,KAAK2P,MAAMsH,gBAAgB+J,GAC3BhhB,KAAK2P,MAAMkH,sBAAsBmK,EAAQvf,IACzCzB,KAAK2P,MAAM8G,QAAQ,OACpB,CAEA,OAAAtE,GACKnS,KAAKiZ,cACRjZ,KAAKiZ,eAEFjZ,KAAKuM,SAAWvM,KAAKuM,QAAQkF,YAChCzR,KAAKuM,QAAQkF,WAAWC,YAAY1R,KAAKuM,QAE3C,EC1NM,MAAM0U,EACZ,WAAArhB,CAAY+P,EAAOjI,EAAU,IAC5B1H,KAAK2P,MAAQA,EACb3P,KAAK0H,QAAUA,EACf1H,KAAKuM,QAAU,KACfvM,KAAKiZ,aAAe,IACrB,CAEA,MAAAC,GAaC,OAZAlZ,KAAKuM,QAAUhC,SAASyD,cAAc,OACtChO,KAAKuM,QAAQ6E,UAAY,qCAEzBpR,KAAKmZ,iBAGLnZ,KAAKiZ,aAAejZ,KAAK2P,MAAMyG,UAAW1U,IAC5B,uBAATA,GAA0C,qBAATA,GACpC1B,KAAKkhB,2BAIAlhB,KAAKuM,OACb,CAEA,cAAA4M,GACC,MAAMgI,EAAcnhB,KAAK2P,MAAM+F,iBAAmB,GAE5C0L,GADcphB,KAAK2P,MAAM8F,cAAgB,IACXjM,OAEpCxJ,KAAKuM,QAAQ2B,UAAY,ieAcZiT,uQAQRC,4GAMLphB,KAAKkhB,yBACLlhB,KAAKqQ,eACN,CAEA,sBAAA6Q,GACC,MAAMG,EAAuBrhB,KAAKuM,QAAQ2D,cACzC,+BAEKoR,EAActhB,KAAK2P,MAAM8F,cAAgB,GACzC0L,GAAenhB,KAAK2P,MAAM+F,iBAAmB,IAAIkD,cAGjD2I,EAAsBJ,EACzBG,EAAYzI,OACXrB,GACAA,EAAE7V,MAAMiX,cAAcxS,SAAS+a,IAC9B3J,EAAE5V,aAAe4V,EAAE5V,YAAYgX,cAAcxS,SAAS+a,IAExDG,EAGGE,EAAWxhB,KAAKuM,QAAQ2D,cAC7B,sCAEGsR,IACHA,EAASvT,YAAc,GAAGsT,EAAoB/X,sBAGZ,IAA/B+X,EAAoB/X,QAKxB6X,EAAqBnT,UAAYqT,EAC/BjH,IAAKmH,GAAezhB,KAAK0hB,sBAAsBD,IAC/C3S,KAAK,IAGP9O,KAAK2hB,2BATJN,EAAqBnT,UAAYlO,KAAKic,mBAUxC,CAEA,qBAAAyF,CAAsBD,GACrB,MAAMG,EAAeH,EAAWG,cAAgB,EAChD,MAAO,sEACuDH,EAAWhgB,wHAExBggB,EAAW9f,mEACb8f,EAAW7f,aAAe,mEACtBggB,2JAKpD,CAEA,iBAAA3F,GAGC,OAFoBjc,KAAK2P,MAAM+F,gBAGvB,4SAWD,oRASR,CAEA,aAAArF,GAECrQ,KAAKuM,QACH2D,cAAc,wBACdoC,iBAAiB,QAAS,KAC1BtS,KAAK2P,MAAMiH,SAAQ,KAOrB,IAAIiL,EAHgB7hB,KAAKuM,QAAQ2D,cAChC,gCAGWoC,iBAAiB,QAAUvK,IACtC6C,aAAaiX,GACbA,EAAgBvd,WAAW,KAC1BtE,KAAK2P,MAAMyI,mBAAmBrQ,EAAEgC,OAAO/I,QACrC,OAGJhB,KAAK2hB,yBACN,CAEA,uBAAAA,GACC3hB,KAAKuM,QACHqO,iBAAiB,8BACjB1R,QAAS4S,IACTA,EAAKxJ,iBAAiB,QAAS,KAC9B,MAAMwP,EAAehG,EAAKnB,QAAQmH,aAC5BL,EAAazhB,KAAK2P,MAAM8F,aAAa8B,KACzCC,GAAMA,EAAE/V,KAAOqgB,GAEbL,GAAcA,EAAWtc,IAC5BC,OAAOwY,KAAK6D,EAAWtc,IAAK,UAClBnF,KAAK0H,QAAQqa,gBACvB/hB,KAAK0H,QAAQqa,eAAeN,MAIjC,CAEA,OAAAtP,GACKnS,KAAKiZ,cACRjZ,KAAKiZ,eAEFjZ,KAAKuM,SAAWvM,KAAKuM,QAAQkF,YAChCzR,KAAKuM,QAAQkF,WAAWC,YAAY1R,KAAKuM,QAE3C,EC1LM,MAAMyV,EACZ,WAAApiB,CAAY+P,EAAOjI,EAAU,IAC5B1H,KAAK2P,MAAQA,EACb3P,KAAK0H,QAAUA,EACf1H,KAAKuM,QAAU,KACfvM,KAAKiZ,aAAe,IACrB,CAEA,MAAAC,GAaC,OAZAlZ,KAAKuM,QAAUhC,SAASyD,cAAc,OACtChO,KAAKuM,QAAQ6E,UAAY,qCAEzBpR,KAAKmZ,iBAGLnZ,KAAKiZ,aAAejZ,KAAK2P,MAAMyG,UAAW1U,IAC5B,wBAATA,GAA2C,wBAATA,GACrC1B,KAAKmZ,mBAIAnZ,KAAKuM,OACb,CAEA,cAAA4M,GACC,MAAMwC,EAAc3b,KAAKggB,qBACnBiC,EAAsBjiB,KAAKkiB,yBAEjCliB,KAAKuM,QAAQ2B,UAAY,0JAInBlO,KAAK0H,QAAQya,QAAU,aAAaniB,KAAK0H,QAAQya,iBAAiBniB,KAAK2P,MAAMkG,eAAiB,uEAE3D8F,qVAOE3b,KAAK2P,MAAMoG,qSAUlD/V,KAAKoiB,oCAELH,wBAIJjiB,KAAKqQ,eACN,CAEA,kBAAA2P,GACC,MAAMrD,EAAU3c,KAAK2P,MAAMmG,YAC3B,IAAK6G,GAA8B,IAAnBA,EAAQnT,OAEvB,MAAO,qOAkBR,MAAO,uCAVamT,EAClBE,MAAM,EAAG,GACTvC,IAAI,CAACwC,EAAQ7R,IACS,iBAAX6R,GAAuBA,EAAOC,WAAW,QAC5C,sCAAsCD,wCAA6C,EAAI7R,SAExF,oDAAoDjL,KAAKwgB,gBAAgBvV,gBAAgB,EAAIA,OAAO6R,EAAOE,OAAO,GAAGC,uBAE5HnO,KAAK,WAGR,CAEA,eAAA0R,CAAgB1X,GACf,MAAM8T,EAAS,CAAC,UAAW,UAAW,UAAW,UAAW,WAC5D,OAAOA,EAAO9T,EAAQ8T,EAAOpT,OAC9B,CAEA,mBAAA4Y,GAEC,IAAKpiB,KAAK0H,QAAQ2a,gBACjB,MAAO,GAGR,MAAM1gB,MAAEA,EAAKC,YAAEA,EAAW0gB,SAAEA,EAAQC,OAAEA,GACrCviB,KAAK0H,QAAQ2a,gBAEd,MAAO,0DAEHC,EAAW,aAAaA,WAAkB3gB,mFAAyF,4EAE9HA,wBACDC,kCAEJ2gB,EAAS,4DAA4DA,EAAO7gB,qBAAqB6gB,EAAOvhB,UAAUuhB,EAAOxI,iBAAmB,wBAGjJ,CAEA,sBAAAmI,GAEC,MAAMtM,EAAiB5V,KAAK2P,MAAMgG,mBAClC,GAA8B,IAA1BC,EAAepM,OAClB,MAAO,GA0BR,MAAO,mEAvBeoM,EACpB0E,IACCwB,GAAS,yEACqDA,EAAKra,iBAEnEqa,EAAKW,WACF,mFAEUX,EAAKW,oBAAoBX,EAAKna,+DACxCma,EAAK0G,UAAY,qDAAqD1G,EAAK0G,mBAAqB,iCAGhG,8HAG+C1G,EAAKna,uEACPma,EAAKla,aAAe,8CAKrEkN,KAAK,yBAOR,CAEA,WAAAwN,CAAYY,GACX,IAAKA,EAAY,MAAO,GACxB,MAAMV,EAAO,IAAIpZ,KAAK8Z,GAChB7Z,EAAM,IAAID,KACVwd,EAAWjX,KAAKuB,OAAO7H,EAAMmZ,GAAI,OAEvC,OAAiB,IAAboE,EAAuB,QACV,IAAbA,EAAuB,YACvBA,EAAW,EAAU,GAAGA,SACrBpE,EAAKW,mBAAmB,QAAS,CAAEC,MAAO,QAASC,IAAK,WAChE,CAEA,aAAAhN,GAECrQ,KAAKuM,QACH2D,cAAc,wBACdoC,iBAAiB,QAAS,KAC1BtS,KAAK2P,MAAMiH,SAAQ,KAIrB5W,KAAKuM,QACH2D,cAAc,+BACdoC,iBAAiB,QAAS,KAC1BtS,KAAK2P,MAAM8G,QAAQ,cAIrBzW,KAAKuM,QACHqO,iBAAiB,kCACjB1R,QAAS4S,IACTA,EAAKxJ,iBAAiB,QAAS,KAE9BtS,KAAK2P,MAAM8G,QAAQ,iBAKtB,MAAMgM,EAAYziB,KAAKuM,QAAQ2D,cAC9B,iCAEGuS,GACHA,EAAUnQ,iBAAiB,QAAS,KACnCtS,KAAK2P,MAAM8G,QAAQ,eAKrB,MAAMiM,EAAc1iB,KAAKuM,QAAQ2D,cAChC,gCAEGwS,GACHA,EAAYpQ,iBAAiB,QAAS,KACrC,MAAMiQ,EAASG,EAAY/H,QAAQ4H,OAC7BvhB,EAAQ0hB,EAAY/H,QAAQ3Z,MACnB,QAAXuhB,EACHnd,OAAOwY,KAAK5c,EAAO,UACE,SAAXuhB,GACVviB,KAAK2P,MAAM8G,QAAQzV,IAIvB,CAEA,OAAAmR,GACKnS,KAAKiZ,cACRjZ,KAAKiZ,eAEFjZ,KAAKuM,SAAWvM,KAAKuM,QAAQkF,YAChCzR,KAAKuM,QAAQkF,WAAWC,YAAY1R,KAAKuM,QAE3C,ECjNM,MAAMoW,UAAwB5T,EACpC,WAAAnP,CAAY8H,GACX3H,MAAM,IAAK2H,EAAShG,KAAM,cAE1B1B,KAAK4iB,iBAAmB,CACvBzT,SAAUzH,EAAQyH,UAAY,eAC9BmC,MAAO5J,EAAQ4J,OAAS,QACxBuE,SAAUnO,EAAQmO,UAAY,UAC9BC,YAAapO,EAAQoO,aAAe,GACpCC,eAAgBrO,EAAQqO,gBAAkB,mBAC1CC,YAAmC,IAAvBtO,EAAQsO,WACpBC,iBAA6C,IAA5BvO,EAAQuO,gBACzBkM,QAASza,EAAQya,SAAW,0CAC5BE,gBAAiB3a,EAAQ2a,iBAAmB,KAC5CnhB,aAAcwG,EAAQxG,cAAgB,UAEtC4e,cAAepY,EAAQoY,eAAiB,KACxCiC,eAAgBra,EAAQqa,gBAAkB,KAC1ClE,iBAAkBnW,EAAQmW,kBAAoB,MAI/C7d,KAAK6iB,eAAiB,IAAI1N,EAAe,CACxCU,SAAU7V,KAAK4iB,iBAAiB/M,SAChCC,YAAa9V,KAAK4iB,iBAAiB9M,YACnCC,eAAgB/V,KAAK4iB,iBAAiB7M,eACtCC,WAAYhW,KAAK4iB,iBAAiB5M,WAClCC,gBAAiBjW,KAAK4iB,iBAAiB3M,gBACvCvT,YAAa1C,KAAKgP,KAAKC,YAAYjI,kBAAoB,OAGxDhH,KAAK8iB,SAAW,KAChB9iB,KAAK8S,MAAQ,KAGb9S,KAAK+iB,kBAAoB/iB,KAAK+iB,kBAAkB1Q,KAAKrS,KACtD,CAEA,OAAAmQ,GAEC,MAAMjB,EAAY3E,SAASyD,cAAc,OAmCzC,OAlCAkB,EAAUkC,UAAY,0BAA0BpR,KAAK4iB,iBAAiBtR,QACtEpC,EAAUwB,MAAMsS,OAAS,SAGzBhjB,KAAK8iB,SAAW,IAAI9J,EAAkBhZ,KAAK6iB,eAAgB,CAC1D1T,SAAUnP,KAAK4iB,iBAAiBzT,SAChCjO,aAAclB,KAAK4iB,iBAAiB1hB,eAErCgO,EAAUkB,YAAYpQ,KAAK8iB,SAAS5J,UAGpClZ,KAAK8S,MAAQ,IAAIgI,EAAe9a,KAAK6iB,eAAgB,CACpD1T,SAAUnP,KAAK4iB,iBAAiBzT,SAChCmC,MAAOtR,KAAK4iB,iBAAiBtR,MAC7BpQ,aAAclB,KAAK4iB,iBAAiB1hB,aACpCihB,QAASniB,KAAK4iB,iBAAiBT,QAC/BE,gBAAiBriB,KAAK4iB,iBAAiBP,gBACvCvC,cACC9f,KAAK4iB,iBAAiB9C,eACtB9f,KAAKijB,mBAAmB5Q,KAAKrS,MAC9B+hB,eAAgB/hB,KAAK4iB,iBAAiBb,eACtClE,iBAAkB7d,KAAK4iB,iBAAiB/E,mBAIzC7d,KAAK8S,MAAMoI,aAAa,OAAQ8G,GAChChiB,KAAK8S,MAAMoI,aAAa,WAAY6E,GACpC/f,KAAK8S,MAAMoI,aAAa,OAAQ4C,GAChC9d,KAAK8S,MAAMoI,aAAa,OAAQ+F,GAChCjhB,KAAK8S,MAAMoI,aAAa,YAAaO,GAErCvM,EAAUkB,YAAYpQ,KAAK8S,MAAMoG,UACjClZ,KAAK8S,MAAMlC,OAEJ1B,CACR,CAEA,aAAAmB,GAECrQ,KAAKkjB,kBAAoBljB,KAAK6iB,eAAezM,UAAU,CAAC1U,EAAM8C,KAChD,eAAT9C,GACH1B,KAAK+iB,kBAAkBve,EAAKoL,SAG/B,CAEA,iBAAAmT,CAAkBnT,GACbA,GACH5P,KAAK8S,MAAMvC,OACXvQ,KAAKgP,IAAIwB,SAASvH,KAAK,mBAAoB,CAAEwH,OAAQzQ,SAErDA,KAAK8S,MAAMlC,OACX5Q,KAAK6iB,eAAe9J,QACpB/Y,KAAKgP,IAAIwB,SAASvH,KAAK,mBAAoB,CAAEwH,OAAQzQ,OAEvD,CAEA,wBAAMijB,CAAmBnM,EAAgBjX,GAExCG,KAAKgP,IAAIwB,SAASvH,KAAK,wBAAyB,CAC/CwH,OAAQzQ,KACR8W,iBACAjX,YAIGG,KAAKiP,YAAYtM,MACpB2B,WAAW,KACV,MAAMjE,EAAW,CAChBoB,GAAI,OAAS2B,KAAKC,MAClBoB,QAAS,uDACTmT,OAAO,EACPD,WAAW,IAAIvU,MAAOkE,cACtBqX,OAAQ,CACP1e,KAAM,eACN2e,UAAW,OAGb5e,KAAK6iB,eAAexL,WAAWP,EAAgBzW,IAC7C,KAEL,CAKA,IAAAud,GACC5d,KAAK6iB,eAAejM,SAAQ,EAC7B,CAKA,KAAAuM,GACCnjB,KAAK6iB,eAAejM,SAAQ,EAC7B,CAKA,MAAAiE,GACC7a,KAAK6iB,eAAejM,SAAS5W,KAAK6iB,eAAejT,OAClD,CAKA,UAAAwT,CAAW1M,GACV1W,KAAK6iB,eAAepM,QAAQC,GACvB1W,KAAK6iB,eAAejT,QACxB5P,KAAK4d,MAEP,CAKA,gBAAA7G,CAAiBxB,GAChBvV,KAAK6iB,eAAe9L,iBAAiBxB,EACtC,CAKA,UAAA8B,CAAWP,EAAgBjX,GAC1BG,KAAK6iB,eAAexL,WAAWP,EAAgBjX,EAChD,CAKA,eAAAqY,CAAgBC,GACfnY,KAAK6iB,eAAe3K,gBAAgBC,EACrC,CAKA,qBAAAG,CAAsBC,GACrBvY,KAAK6iB,eAAevK,sBAAsBC,EAC3C,CAKA,iBAAAC,CAAkBD,GACjBvY,KAAK6iB,eAAerK,kBAAkBD,EACvC,CAKA,cAAA8K,CAAepL,GACdjY,KAAK6iB,eAAexN,YAAc4C,EAClCjY,KAAK6iB,eAAevM,QAAQ,oBAAqB,CAAE2B,SACpD,CAKA,QAAAqL,GACC,MAAO,CACN1T,OAAQ5P,KAAK6iB,eAAejT,OAC5BwF,YAAapV,KAAK6iB,eAAezN,YACjCC,YAAarV,KAAK6iB,eAAexN,YACjCE,cAAevV,KAAK6iB,eAAetN,cAErC,CAKA,qBAAMgO,GAEL,IACC,MAAMhO,QAAsBvV,KAAKwjB,sBACjCxjB,KAAK6iB,eAAe9L,iBAAiBxB,EACtC,CAAE,MAAOpS,GACRgG,QAAQhG,MAAM,kDAAmDA,EAClE,CAGA,GAAInD,KAAK4iB,iBAAiB5M,WACzB,IACC,MAAMmC,QAAiBnY,KAAKyjB,qBAC5BzjB,KAAK6iB,eAAe3K,gBAAgBC,EACrC,CAAE,MAAOhV,GACRgG,QAAQhG,MAAM,kDAAmDA,EAClE,CAID,GAAInD,KAAK4iB,iBAAiB3M,gBACzB,IACC,MAAMyN,UAAEA,EAAS9N,eAAEA,SAAyB5V,KAAK2jB,kBACjD3jB,KAAK6iB,eAAevK,sBAAsBoL,GAC1C1jB,KAAK6iB,eAAerK,kBAAkB5C,EACvC,CAAE,MAAOzS,GACRgG,QAAQhG,MAAM,8CAA+CA,EAC9D,CAEF,CAEA,yBAAMqgB,GAEL,OAAIxjB,KAAKiP,YAAYtM,KACb,CACN,CACClB,GAAI,SACJE,MAAO,kBACPkd,aAAc,CAAC,CAAE5e,KAAM,QAAS2e,UAAW,OAC3CnH,YAAa,gDACbC,gBAAiB,IAAItU,KAAKA,KAAKC,MAAQ,OAAgBiE,cACvDuQ,OAAQ,GAET,CACCpW,GAAI,SACJE,MAAO,gBACPkd,aAAc,CAAC,CAAE5e,KAAM,MAAO2e,UAAW,OACzCnH,YAAa,gDACbC,gBAAiB,IAAItU,KACpBA,KAAKC,MAAQ,QACZiE,cACFuQ,OAAQ,IAMJ,EACR,CAEA,wBAAM4L,GAEL,OAAIzjB,KAAKiP,YAAYtM,KACb,CACN,CACClB,GAAI,eACJE,MAAO,mBACPC,YAAa,yDACbggB,aAAc,GACdzc,IAAK,KAEN,CACC1D,GAAI,eACJE,MAAO,kBACPC,YACC,4DACDggB,aAAc,GACdzc,IAAK,KAEN,CACC1D,GAAI,eACJE,MAAO,WACPC,YACC,iFACDggB,aAAc,GACdzc,IAAK,KAEN,CACC1D,GAAI,eACJE,MAAO,WACPC,YACC,mFACDggB,aAAc,GACdzc,IAAK,KAEN,CACC1D,GAAI,eACJE,MAAO,qBACPC,YACC,2DACDggB,aAAc,GACdzc,IAAK,MAMD,EACR,CAEA,qBAAMwe,GAEL,OAAI3jB,KAAKiP,YAAYtM,KACb,CACN+gB,UAAW,CACV,CACCjiB,GAAI,cACJE,MAAO,6BACPC,YACC,iEACDua,KAAM,CAAC,eACPM,WAAY,mDACZ+F,UAAW,KACXjG,YAAa,IAAInZ,KAChBA,KAAKC,MAAQ,SACZiE,cACFnC,IAAK,KAEN,CACC1D,GAAI,cACJE,MAAO,oCACPC,YACC,uIACDua,KAAM,CAAC,cAAe,MACtBM,WACC,8DACD+F,UAAW,2CACXjG,YAAa,IAAInZ,KAChBA,KAAKC,MAAQ,OACZiE,cACFnC,IAAK,KAEN,CACC1D,GAAI,cACJE,MAAO,kDACPC,YACC,uHACDua,KAAM,CAAC,UACPM,WACC,gEACD+F,UAAW,oDACXjG,YAAa,IAAInZ,KAChBA,KAAKC,MAAQ,QACZiE,cACFnC,IAAK,MAGPyQ,eAAgB,CACf,CACCnU,GAAI,cACJE,MAAO,kCACPC,YACC,yFACDua,KAAM,CAAC,aACPM,WACC,oEACD+F,UAAW,KACXjG,YAAa,IAAInZ,KAChBA,KAAKC,MAAQ,OACZiE,cACFnC,IAAK,KAEN,CACC1D,GAAI,cACJE,MAAO,yCACPC,YACC,sGACDua,KAAM,CAAC,cAAe,MACtBM,WACC,oFACD+F,UAAW,KACXjG,YAAa,IAAInZ,KAChBA,KAAKC,MAAQ,QACZiE,cACFnC,IAAK,OAOF,CAAEue,UAAW,GAAI9N,eAAgB,GACzC,CAEA,OAAAtF,GAECtQ,KAAKujB,iBACN,CAEA,SAAAnR,GACKpS,KAAKkjB,mBACRljB,KAAKkjB,mBAEP,CAEA,OAAA/Q,GACKnS,KAAK8iB,UACR9iB,KAAK8iB,SAAS3Q,UAEXnS,KAAK8S,OACR9S,KAAK8S,MAAMX,UAEZpS,MAAMoS,SACP,ECrbM,MAAMyR,UAAqB7U,EACjC,WAAAnP,CAAY8H,GACX3H,MAAM,IAAK2H,EAAShG,KAAM,WAE1B1B,KAAK6jB,cAAgB,CACpBvd,SAAUoB,EAAQpB,UAAY,KAC9Bwd,WAAYpc,EAAQoc,YAAc,MAClC3U,SAAUzH,EAAQyH,UAAY,eAC9BxN,MAAO+F,EAAQ/F,OAAS,KACxBC,YAAa8F,EAAQ9F,aAAe,KACpCmiB,SAAUrc,EAAQqc,UAAY,KAC9BC,UAAWtc,EAAQsc,WAAa,KAChCC,gBAAiBvc,EAAQuc,iBAAmB,GAC5C3S,MAAO5J,EAAQ4J,OAAS,QACxB4S,SAAUxc,EAAQwc,UAAY,KAC9BC,UAAWzc,EAAQyc,WAAa,MAGjCnkB,KAAKokB,YAAc,CAClBC,MAAO,KACP3d,SAAU,GACV4d,cAAe,CAAA,EACfC,WAAW,EAEb,CAEA,OAAApU,GAEC,MAAMjB,EAAY3E,SAASyD,cAAc,OAGzC,OAFAkB,EAAUkC,UAAY,4BACtBlC,EAAUwB,MAAMC,QAAU,OACnBzB,CACR,CAEA,aAAAmB,GAEA,CAEA,IAAAE,GAOC,OANAvQ,KAAKwkB,gBACLxkB,KAAKokB,YAAYG,WAAY,EAC7BvkB,KAAKgP,IAAIwB,SAASvH,KAAK,eAAgB,CACtCwH,OAAQzQ,KACR0B,KAAM1B,KAAK6jB,cAAcC,aAEnB9jB,IACR,CAEA,IAAA4Q,GAEC,OADA5Q,KAAKykB,eACEzkB,IACR,CAEA,aAAAwkB,GAECxkB,KAAKykB,eAEL,MAAMliB,EAASvC,KAAK0kB,mBACdC,EAAiB3kB,KAAK4kB,qBACtBC,EACwB,SAA7B7kB,KAAK6jB,cAAcvS,MAChB,oCACA,oCAGgC,WAAhCtR,KAAK6jB,cAAc1U,WACtBnP,KAAKwP,gBAAkBjF,SAASyD,cAAc,OAC9ChO,KAAKwP,gBAAgB4B,UAAY,2BACjC7G,SAAS3G,KAAKwM,YAAYpQ,KAAKwP,iBAC/BxP,KAAKwP,gBAAgB8C,iBAAiB,QAAS,IAC9CtS,KAAK8kB,mBAIP9kB,KAAK+kB,cAAgBxa,SAASyD,cAAc,OAC5ChO,KAAK+kB,cAAc3T,UAAY,mCAAmCpR,KAAK6jB,cAAc1U,kBAAkBnP,KAAK6jB,cAAcvS,QAC1HtR,KAAK+kB,cAAcrU,MAAMsU,QAAU,oBAAoBL,qBAAkCE,0LAEzF7kB,KAAK+kB,cAAc7W,UAAY,6KACmK,SAA7BlO,KAAK6jB,cAAcvS,MAAmB,OAAS,4KAC5F/O,EAAOZ,0EAC1C,SAA7B3B,KAAK6jB,cAAcvS,MAAmB,OAAS,oDAAoD/O,EAAOX,+DAC1HW,EAAO0iB,iPAEoI,SAA7BjlB,KAAK6jB,cAAcvS,MAAmB,OAAS,2FAAwH,SAA7BtR,KAAK6jB,cAAcvS,MAAmB,UAAY,kBAA+C,SAA7BtR,KAAK6jB,cAAcvS,MAAmB,OAAS,+VAKnZ/G,SAAS3G,KAAKwM,YAAYpQ,KAAK+kB,eAC/B/kB,KAAKklB,sBAGLjU,sBAAsB,KACrBjR,KAAK+kB,cAAcrU,MAAM6C,QAAU,IACnCvT,KAAK+kB,cAAcrU,MAAMwD,UACQ,WAAhClU,KAAK6jB,cAAc1U,SAChB,iCACA,iBAEN,CAEA,gBAAAuV,GACC,MAAMS,EAAU,CACfC,IAAK,CACJzjB,MACC3B,KAAK6jB,cAAcliB,OAAS,sCAC7BC,YACC5B,KAAK6jB,cAAcjiB,aACnB,4FACDqjB,KAAM,+HAEF,IAAI7a,MAAM,IAAI4C,QACdsN,IACCqD,GAAM,uEAC8CA,0DAAuF,SAA7B3d,KAAK6jB,cAAcvS,MAAmB,OAAS,8CAA2E,SAA7BtR,KAAK6jB,cAAcvS,MAAmB,UAAY,uDAAoF,SAA7BtR,KAAK6jB,cAAcvS,MAAmB,OAAS,sCAAsCqM,4BAG1Y7O,KAAK,wIAE2H,SAA7B9O,KAAK6jB,cAAcvS,MAAmB,OAAS,mCAC5ItR,KAAK6jB,cAAcE,UAAY,0CAC/B/jB,KAAK6jB,cAAcG,WAAa,oDAI3CqB,KAAM,CACL1jB,MAAO3B,KAAK6jB,cAAcliB,OAAS,yBACnCC,YACC5B,KAAK6jB,cAAcjiB,aACnB,iEACDqjB,KAAM,0HAEF,CAAC,KAAM,KAAM,KAAM,KAAM,MACzB3K,IACA,CAACgL,EAAOra,IAAM,wEACwCA,EAAI,2HAA2Hqa,4BAGrLxW,KAAK,wIAE2H,SAA7B9O,KAAK6jB,cAAcvS,MAAmB,OAAS,mCAC5ItR,KAAK6jB,cAAcE,UAAY,iDAC/B/jB,KAAK6jB,cAAcG,WAAa,uDAI3CuB,IAAK,CACJ5jB,MAAO3B,KAAK6jB,cAAcliB,OAAS,mBACnCC,YACC5B,KAAK6jB,cAAcjiB,aACnB,iDACDqjB,KAAM,+HAEF,CAAC,iBAAkB,YAAa,UAAW,OAAQ,aACnD3K,IACA,CAACP,EAAO9O,IAAM,uEACuCA,EAAI,2DAAwF,SAA7BjL,KAAK6jB,cAAcvS,MAAmB,OAAS,8CAA2E,SAA7BtR,KAAK6jB,cAAcvS,MAAmB,UAAY,uDAAoF,SAA7BtR,KAAK6jB,cAAcvS,MAAmB,OAAS,sCAAsCyI,4BAG/YjL,KAAK,mCAIV0W,OAAQ,CACP7jB,MAAO3B,KAAK6jB,cAAcliB,OAAS,iBACnCC,YACC5B,KAAK6jB,cAAcjiB,aACnB,gDACDqjB,KAAMjlB,KAAKylB,2BAIb,OAAON,EAAQnlB,KAAK6jB,cAAcC,aAAeqB,EAAQC,GAC1D,CAEA,sBAAAK,GACC,OACEzlB,KAAK6jB,cAAcI,iBAC0B,IAA9CjkB,KAAK6jB,cAAcI,gBAAgBza,OA6B7BxJ,KAAK6jB,cAAcI,gBACxB3J,IACA,CAACoL,EAAG5c,IAAU,6IAE0E4c,EAAE3L,0BACxF/Z,KAAK2lB,qBAAqBD,EAAG5c,0BAI/BgG,KAAK,IAnCC,sTAG8I,SAA7B9O,KAAK6jB,cAAcvS,MAAmB,OAAS,+DAA4F,SAA7BtR,KAAK6jB,cAAcvS,MAAmB,UAAY,kBAA+C,SAA7BtR,KAAK6jB,cAAcvS,MAAmB,OAAS,klBAWpV,CAAC,QAAS,SAAU,UAAW,UAC/BgJ,IACCsL,GAAS,uEAC2CA,uDAAuF,SAA7B5lB,KAAK6jB,cAAcvS,MAAmB,OAAS,8CAA2E,SAA7BtR,KAAK6jB,cAAcvS,MAAmB,UAAY,uDAAoF,SAA7BtR,KAAK6jB,cAAcvS,MAAmB,OAAS,sCAAsCsU,4BAG1Y9W,KAAK,+CAgBZ,CAEA,oBAAA6W,CAAqBE,EAAU/c,GAC9B,OAAQ+c,EAASnkB,MAChB,IAAK,SACJ,MAAO,qEACkDmkB,EAASpkB,IAAMqH,2DAA4F,SAA7B9I,KAAK6jB,cAAcvS,MAAmB,OAAS,+DAA4F,SAA7BtR,KAAK6jB,cAAcvS,MAAmB,UAAY,kBAA+C,SAA7BtR,KAAK6jB,cAAcvS,MAAmB,OAAS,8CACnVuU,EAAS5Q,aAAe,4CACzC4Q,EAASne,QAAQ4S,IAAKwL,GAAQ,kBAAkBA,EAAI9kB,UAAU8kB,EAAI/L,kBAAkBjL,KAAK,qCAG9F,IAAK,OACJ,MAAO,+EAC4D+W,EAASpkB,IAAMqH,mBAAuB+c,EAAS5Q,aAAe,4DAAyF,SAA7BjV,KAAK6jB,cAAcvS,MAAmB,OAAS,+DAA4F,SAA7BtR,KAAK6jB,cAAcvS,MAAmB,UAAY,kBAA+C,SAA7BtR,KAAK6jB,cAAcvS,MAAmB,OAAS,iDAE/Z,QACC,MAAO,GAEV,CAEA,kBAAAsT,GACC,MAAMmB,EAAY,CACjB,eACC,iGACD,cACC,gGACDC,OACC,4GACDzY,OACC,oJAEF,OAAOwY,EAAU/lB,KAAK6jB,cAAc1U,WAAa4W,EAAU,eAC5D,CAEA,mBAAAb,GACC,IAAKllB,KAAK+kB,cAAe,OAGR/kB,KAAK+kB,cAAc7U,cAAc,0BACzCoC,iBAAiB,QAAS,IAAMtS,KAAK8kB,kBAG5B9kB,KAAK+kB,cAAc7U,cACpC,2BAESoC,iBAAiB,QAAS,IAAMtS,KAAKimB,iBAG9BjmB,KAAK+kB,cAAc7U,cACnC,6BAEQoC,iBAAiB,QAAUvK,IACnC/H,KAAKokB,YAAY1d,SAAWqB,EAAEgC,OAAO/I,QAItChB,KAAKkmB,4BAGLlmB,KAAKmmB,eAAkBpe,IACR,WAAVA,EAAEmC,KACLlK,KAAK8kB,kBAGPva,SAAS+H,iBAAiB,UAAWtS,KAAKmmB,eAC3C,CAEA,yBAAAD,GACC,MAAMxkB,EAAO1B,KAAK6jB,cAAcC,WAEnB,QAATpiB,GACH1B,KAAK+kB,cACHnK,iBAAiB,4BACjB1R,QAASkd,IACTA,EAAI9T,iBAAiB,QAAS,IAC7BtS,KAAKqmB,WAAWC,SAASF,EAAIzL,QAAQ0J,SAEtC+B,EAAI9T,iBAAiB,aAAc,KAC9BtS,KAAKokB,YAAYC,QAAUiC,SAASF,EAAIzL,QAAQ0J,SACnD+B,EAAI1V,MAAM6V,YAAc,aAG1BH,EAAI9T,iBAAiB,aAAc,KAC9BtS,KAAKokB,YAAYC,QAAUiC,SAASF,EAAIzL,QAAQ0J,SACnD+B,EAAI1V,MAAM6V,YACoB,SAA7BvmB,KAAK6jB,cAAcvS,MAAmB,OAAS,eAMxC,SAAT5P,GACH1B,KAAK+kB,cACHnK,iBAAiB,6BACjB1R,QAASkd,IACTA,EAAI9T,iBAAiB,QAAS,IAC7BtS,KAAKwmB,YAAYF,SAASF,EAAIzL,QAAQ0J,SAEvC+B,EAAI9T,iBAAiB,aAAc,KAClC8T,EAAI1V,MAAMwD,UAAY,eAEvBkS,EAAI9T,iBAAiB,aAAc,KAC9BtS,KAAKokB,YAAYC,QAAUiC,SAASF,EAAIzL,QAAQ0J,SACnD+B,EAAI1V,MAAMwD,UAAY,gBAMd,QAATxS,GACH1B,KAAK+kB,cACHnK,iBAAiB,4BACjB1R,QAASkd,IACTA,EAAI9T,iBAAiB,QAAS,IAC7BtS,KAAKymB,WAAWH,SAASF,EAAIzL,QAAQ0J,SAEtC+B,EAAI9T,iBAAiB,aAAc,KAC9BtS,KAAKokB,YAAYC,QAAUiC,SAASF,EAAIzL,QAAQ0J,SACnD+B,EAAI1V,MAAM6V,YAAc,aAG1BH,EAAI9T,iBAAiB,aAAc,KAC9BtS,KAAKokB,YAAYC,QAAUiC,SAASF,EAAIzL,QAAQ0J,SACnD+B,EAAI1V,MAAM6V,YACoB,SAA7BvmB,KAAK6jB,cAAcvS,MAAmB,OAAS,eAMxC,WAAT5P,IAEH1B,KAAK+kB,cACHnK,iBAAiB,6BACjB1R,QAASkd,IACTA,EAAI9T,iBAAiB,QAAS,IAC7BtS,KAAK0mB,iBAAiBN,EAAIzL,QAAQiL,SAKrC5lB,KAAK+kB,cACHnK,iBAAiB,2BACjB1R,QAASyd,IACTA,EAAOrU,iBAAiB,SAAWvK,IAClC/H,KAAKokB,YAAYE,cAAcqC,EAAOhM,QAAQkL,UAC7C9d,EAAEgC,OAAO/I,UAKbhB,KAAK+kB,cACHnK,iBAAiB,0BACjB1R,QAASgM,IACTA,EAAM5C,iBAAiB,QAAUvK,IAChC/H,KAAKokB,YAAYE,cAAcpP,EAAMyF,QAAQkL,UAC5C9d,EAAEgC,OAAO/I,UAIf,CAEA,UAAAqlB,CAAWhC,GACVrkB,KAAKokB,YAAYC,MAAQA,EACzBrkB,KAAK+kB,cACHnK,iBAAiB,4BACjB1R,QAASkd,IACQE,SAASF,EAAIzL,QAAQ0J,SACrBA,GAChB+B,EAAI1V,MAAMkW,WAAa,UACvBR,EAAI1V,MAAM6V,YAAc,UACxBH,EAAI1V,MAAMmW,MAAQ,SAElBT,EAAI1V,MAAMkW,WACoB,SAA7B5mB,KAAK6jB,cAAcvS,MAAmB,UAAY,UACnD8U,EAAI1V,MAAM6V,YACoB,SAA7BvmB,KAAK6jB,cAAcvS,MAAmB,OAAS,UAChD8U,EAAI1V,MAAMmW,MACoB,SAA7B7mB,KAAK6jB,cAAcvS,MAAmB,OAAS,YAGpD,CAEA,WAAAkV,CAAYnC,GACXrkB,KAAKokB,YAAYC,MAAQA,EACzBrkB,KAAK+kB,cACHnK,iBAAiB,6BACjB1R,QAASkd,IACT,MAAMU,EAAWR,SAASF,EAAIzL,QAAQ0J,OACtC+B,EAAI1V,MAAMwD,UAAY4S,IAAazC,EAAQ,aAAe,YAE7D,CAEA,UAAAoC,CAAWpC,GACVrkB,KAAKokB,YAAYC,MAAQA,EACzBrkB,KAAK+kB,cACHnK,iBAAiB,4BACjB1R,QAASkd,IACQE,SAASF,EAAIzL,QAAQ0J,SACrBA,GAChB+B,EAAI1V,MAAMkW,WAAa,UACvBR,EAAI1V,MAAM6V,YAAc,UACxBH,EAAI1V,MAAMmW,MAAQ,SAElBT,EAAI1V,MAAMkW,WACoB,SAA7B5mB,KAAK6jB,cAAcvS,MAAmB,UAAY,UACnD8U,EAAI1V,MAAM6V,YACoB,SAA7BvmB,KAAK6jB,cAAcvS,MAAmB,OAAS,UAChD8U,EAAI1V,MAAMmW,MACoB,SAA7B7mB,KAAK6jB,cAAcvS,MAAmB,OAAS,YAGpD,CAEA,gBAAAoV,CAAiBd,GAChB5lB,KAAKokB,YAAYE,cAAcyC,UAAYnB,EAC3C5lB,KAAK+kB,cACHnK,iBAAiB,6BACjB1R,QAASkd,IACLA,EAAIzL,QAAQiL,OAASA,GACxBQ,EAAI1V,MAAMkW,WAAa,UACvBR,EAAI1V,MAAM6V,YAAc,UACxBH,EAAI1V,MAAMmW,MAAQ,SAElBT,EAAI1V,MAAMkW,WACoB,SAA7B5mB,KAAK6jB,cAAcvS,MAAmB,UAAY,UACnD8U,EAAI1V,MAAM6V,YACoB,SAA7BvmB,KAAK6jB,cAAcvS,MAAmB,OAAS,UAChD8U,EAAI1V,MAAMmW,MACoB,SAA7B7mB,KAAK6jB,cAAcvS,MAAmB,OAAS,YAGpD,CAEA,mBAAM2U,GACL,MAAMvkB,EAAO1B,KAAK6jB,cAAcC,WAGhC,IACW,QAATpiB,GAA2B,SAATA,GAA4B,QAATA,IACX,OAA3B1B,KAAKokB,YAAYC,MAGjB,YADArkB,KAAK8R,WAAW,0BAIjB,MAAMvL,EAAe,CACpBE,OAAQzG,KAAKokB,YAAYC,MACzB3d,SAAU1G,KAAKokB,YAAY1d,SAC3BC,QAAS3G,KAAKokB,YAAYE,eAGrBjkB,EAAW,CAChBqB,KAAMA,EACN2iB,MAAOrkB,KAAKokB,YAAYC,MACxB3d,SAAU1G,KAAKokB,YAAY1d,SAC3B4d,cAAetkB,KAAKokB,YAAYE,cAChC3M,WAAW,IAAIvU,MAAOkE,eAInBtH,KAAK6jB,cAAcK,UACtBlkB,KAAK6jB,cAAcK,SAAS7jB,GAI7B,IACC,MAAMiG,EACLtG,KAAK6jB,cAAcvd,UAAY,SAAS5E,KAAQ0B,KAAKC,cAChDrD,KAAKiP,WAAW5I,qBAAqBC,EAAUC,EACtD,CAAE,MAAOpD,GACRgG,QAAQhG,MAAM,0CAA2CA,EAC1D,CAEAnD,KAAKgP,IAAIwB,SAASvH,KAAK,mBAAoB,CAAEwH,OAAQzQ,KAAMK,aAE3DL,KAAKykB,eACLzkB,KAAKgnB,0BACN,CAEA,oBAAMlC,GAEL,GAAI9kB,KAAK6jB,cAAcvd,SACtB,UACOtG,KAAKiP,WAAWrI,cAAc5G,KAAK6jB,cAAcvd,SACxD,CAAE,MAAOnD,GACRgG,QAAQhG,MAAM,2CAA4CA,EAC3D,CAGGnD,KAAK6jB,cAAcM,WACtBnkB,KAAK6jB,cAAcM,YAEpBnkB,KAAKgP,IAAIwB,SAASvH,KAAK,mBAAoB,CAAEwH,OAAQzQ,OACrDA,KAAKykB,cACN,CAEA,UAAA3S,CAAWjS,GAEV,MAAMonB,EAAWjnB,KAAK+kB,cAAc7U,cAAc,0BAC9C+W,GAAUA,EAAS1V,SAEvB,MAAMpO,EAAQoH,SAASyD,cAAc,OACrC7K,EAAMiO,UAAY,wBAClBjO,EAAMuN,MAAMsU,QACX,wEACD7hB,EAAM8K,YAAcpO,EAEpB,MAAMqT,EAAYlT,KAAK+kB,cAAc7U,cACpC,2BAEDgD,EAAUzB,WAAWyV,aAAa/jB,EAAO+P,GAEzC5O,WAAW,IAAMnB,EAAMoO,SAAU,IAClC,CAEA,wBAAAyV,GACC,MAAM3T,EAAe9I,SAASyD,cAAc,OAC5CqF,EAAajC,UAAY,0BACzBiC,EAAa3C,MAAMsU,QAAU,mXAc7B3R,EAAanF,UAAY,8LAMzB3D,SAAS3G,KAAKwM,YAAYiD,GAE1B/O,WAAW,KACV+O,EAAa3C,MAAM6C,QAAU,IAC7BF,EAAa3C,MAAMyW,WAAa,oBAChC7iB,WAAW,IAAM+O,EAAa9B,SAAU,MACtC,IACJ,CAEA,YAAAkT,GACKzkB,KAAKmmB,iBACR5b,SAAS0I,oBAAoB,UAAWjT,KAAKmmB,gBAC7CnmB,KAAKmmB,eAAiB,MAIvB,MAAMiB,EAAWpnB,KAAK+kB,cAChBsC,EAAarnB,KAAKwP,gBAEpB4X,IACHA,EAAS1W,MAAM6C,QAAU,IACzB6T,EAAS1W,MAAMwD,UACkB,WAAhClU,KAAK6jB,cAAc1U,SAChB,oCACA,mBACJ7K,WAAW,KACN8iB,GAAYA,EAAS3V,YACxB2V,EAAS3V,WAAWC,YAAY0V,IAE/B,KACHpnB,KAAK+kB,cAAgB,MAGlBsC,IACHA,EAAW3W,MAAM6C,QAAU,IAC3BjP,WAAW,KACN+iB,GAAcA,EAAW5V,YAC5B4V,EAAW5V,WAAWC,YAAY2V,IAEjC,KACHrnB,KAAKwP,gBAAkB,MAGxBxP,KAAKokB,YAAc,CAClBC,MAAO,KACP3d,SAAU,GACV4d,cAAe,CAAA,EACfC,WAAW,EAEb,CAEA,OAAApS,GACCnS,KAAKykB,eACL1kB,MAAMoS,SACP,ECnmBM,MAAMmV,UAAkBvY,EAC9B,WAAAnP,CAAY8H,GACX3H,MAAM,IAAK2H,EAAShG,KAAM,OAC3B,CAEA,OAAAyO,GACC,MAAMoK,EAAMhQ,SAASyD,cAAc,OAYnC,OAXAuM,EAAInJ,UAAY,6CAA6CpR,KAAK0H,QAAQ4J,kBAAkBtR,KAAK0H,QAAQyH,WACzGoL,EAAIrM,UAAY,0HAMZlO,KAAK0H,QAAQ4H,cAChBuE,OAAOC,OAAOyG,EAAI7J,MAAO1Q,KAAK0H,QAAQ4H,cAGhCiL,CACR,CAEA,aAAAlK,GACC,MAAMkK,EAAMva,KAAKuM,QAAQ2D,cAAc,yBACvCqK,EAAIjI,iBAAiB,QAAStS,KAAKwT,WAEnC+G,EAAIjI,iBAAiB,aAAc,KAC7BtS,KAAK2P,MAAMG,eACfyK,EAAI7J,MAAMwD,UAAYlU,KAAKunB,wBAI7BhN,EAAIjI,iBAAiB,aAAc,KAClCiI,EAAI7J,MAAMwD,UAAY,QAExB,CAEA,kBAAAqT,GACC,MAAMpY,EAAWnP,KAAK0H,QAAQyH,SAC9B,OAAIA,EAAS/I,SAAS,SACd,mBACG+I,EAAS/I,SAAS,QACrB,kBAED,MACR,CAEA,UAAA+N,CAAWnM,GACV,MAAMwf,EAAcxnB,KAAKuM,SAAS2D,cAAc,sBAC5CsX,IACHA,EAAYvZ,YAAcjG,EAE5B,CAEA,cAAAyM,CAAetF,GACdnP,KAAK0H,QAAQyH,SAAWA,EACpBnP,KAAKuM,UACRvM,KAAKuM,QAAQ6E,UAAYpR,KAAKuM,QAAQ6E,UAAUrG,QAC/C,mBACA,YAAYoE,KAGf,ECxDM,MAAMsY,EACZC,eAAiB,IAAIrf,IAAI,CACxB,CAAC,SAAUqL,GACX,CAAC,MAAO4T,GACR,CAAC,SAAU5S,GACX,CAAC,SAAUkP,GACX,CAAC,YAAajB,KAGf,eAAOgF,CAASjmB,EAAMkmB,GACrB,GAAoB,iBAATlmB,IAAsBA,EAAKmM,OACrC,MAAM,IAAInO,EAAS,0CAGpB,GAA2B,mBAAhBkoB,EACV,MAAM,IAAIloB,EAAS,+CAGpBM,KAAK6nB,QAAQnf,IAAIhH,EAAMkmB,EACxB,CAEA,aAAOE,CAAOpmB,EAAMgG,EAAU,IAC7B,MAAMkgB,EAAc5nB,KAAK6nB,QAAQ3f,IAAIxG,GAErC,IAAKkmB,EAAa,CACjB,MAAMG,EAAiB3d,MAAM4d,KAAKhoB,KAAK6nB,QAAQ7a,QAAQ8B,KAAK,MAC5D,MAAM,IAAIpP,EACT,wBAAwBgC,uBAA0BqmB,IAEpD,CAEA,IACC,OAAO,IAAIH,EAAYlgB,EACxB,CAAE,MAAOvE,GACR,MAAM,IAAIzD,EACT,oCAAoCgC,OAAUyB,EAAMtD,UACpDsD,EAEF,CACD,CAEA,wBAAO8kB,GACN,OAAO7d,MAAM4d,KAAKhoB,KAAK6nB,QAAQ7a,OAChC,CAEA,uBAAOkb,CAAiBxmB,GACvB,OAAO1B,KAAK6nB,QAAQpf,IAAI/G,EACzB,CAEA,iBAAOymB,CAAWzmB,GACjB,OAAO1B,KAAK6nB,QAAQxR,OAAO3U,EAC5B,CAEA,YAAO4H,GACNtJ,KAAK6nB,QAAQve,OACd,CAEA,qBAAO8e,CAAe1mB,GACrB,OAAO1B,KAAK6nB,QAAQ3f,IAAIxG,EACzB,EC5DM,MAAM2mB,EACZ,WAAAzoB,CAAY2C,EAAS,IACpBvC,KAAKuC,OAASvC,KAAKsoB,wBAAwB/lB,GAC3CvC,KAAKuoB,aAAc,EACnBvoB,KAAK6nB,QAAU,IAAIxf,IACnBrI,KAAKwQ,SAAW,IAAIrI,EAEpBnI,KAAKiP,WAAa,IAAI3M,EAAW,CAChCO,OAAQ7C,KAAKuC,OAAOM,OACpBT,UAAWpC,KAAKuC,OAAOH,UACvBM,YAAa1C,KAAKuC,OAAOG,YACzBC,KAAM3C,KAAKuC,OAAOI,KAClBC,IAAK5C,KAAKuC,OAAOK,MAGlB5C,KAAKgQ,cACN,CAEA,UAAM/M,GACL,GAAIjD,KAAKuoB,YACR,MAAO,CAAEC,oBAAoB,GAG9B,IACC,MAAMC,QAAiBzoB,KAAKiP,WAAWhM,KAAKjD,KAAKuC,OAAOG,aAaxD,OAVI+lB,EAASlmB,SACZvC,KAAKuC,OAASuH,EAAU2e,EAASlmB,OAAQvC,KAAKuC,SAG/CvC,KAAKuoB,aAAc,EACnBvoB,KAAKwQ,SAASvH,KAAK,kBAAmB,CACrC1G,OAAQvC,KAAKuC,OACbC,aAAcimB,EAASjmB,eAGjB,CACN+lB,aAAa,EACbhmB,OAAQkmB,EAASlmB,QAAU,CAAA,EAC3BC,aAAcimB,EAASjmB,aACvBe,UAAWklB,EAASllB,UAEtB,CAAE,MAAOJ,GAER,MADAnD,KAAKwQ,SAASvH,KAAK,YAAa,CAAE9F,UAC5B,IAAIzD,EAAS,6BAA6ByD,EAAMtD,UAAWsD,EAClE,CACD,CAEA,YAAAulB,CAAahnB,EAAO,SAAUgG,EAAU,CAAA,GACvC,IAAK1H,KAAKuoB,YACT,MAAM,IAAI7oB,EACT,uEAIF,MAAMiB,EAAW8I,EAAW,UACtBkf,EAAgB,CACrBlnB,GAAId,EACJqO,IAAKhP,KACLiP,WAAYjP,KAAKiP,cACdjP,KAAKuC,UACLmF,GAGJ,IACC,MAAM+I,EAASgX,EAAcK,OAAOpmB,EAAMinB,GAG1C,OAFA3oB,KAAK6nB,QAAQnf,IAAI/H,EAAU8P,GAC3BzQ,KAAKwQ,SAASvH,KAAK,iBAAkB,CAAEwH,SAAQ/O,SACxC+O,CACR,CAAE,MAAOtN,GACR,MAAM,IAAIzD,EAAS,4BAA4ByD,EAAMtD,UAAWsD,EACjE,CACD,CAEA,SAAAylB,CAAUnnB,GACT,OAAOzB,KAAK6nB,QAAQ3f,IAAIzG,EACzB,CASA,sBAAMqD,CAAiBC,EAAU,IAChC,IAAK/E,KAAKuoB,YACT,MAAM,IAAI7oB,EACT,uEAIF,IAEC,aADqBM,KAAKiP,WAAWnK,iBAAiBC,IACxCP,MAAQ,EACvB,CAAE,MAAOrB,GAER,MADAnD,KAAKwQ,SAASvH,KAAK,YAAa,CAAE9F,UAC5B,IAAIzD,EACT,mCAAmCyD,EAAMtD,UACzCsD,EAEF,CACD,CAaA,oBAAM0lB,CAAeviB,EAAUoB,EAAU,IACxC,IAAK1H,KAAKuoB,YACT,MAAM,IAAI7oB,EACT,sEAKF,MACMopB,SADgB9oB,KAAK8E,oBACEyS,KAAMwR,GAAMA,EAAEtnB,KAAO6E,GAElD,IAAKwiB,EACJ,MAAM,IAAIppB,EACT,mBAAmB4G,8BAIrB,OAAOtG,KAAKgpB,WAAW,CACtB1iB,SAAUwiB,EAAarnB,GACvBqiB,WAAYgF,EAAapnB,KACzBC,MAAOmnB,EAAannB,MACpBC,YAAaknB,EAAalnB,YAC1BmiB,SAAU+E,EAAajnB,UACvBmiB,UAAW8E,EAAahnB,WACxBmiB,gBAAiB6E,EAAaG,aAC3BvhB,GAEL,CAkBA,UAAAshB,CAAWthB,EAAU,IACpB,IAAK1H,KAAKuoB,YACT,MAAM,IAAI7oB,EACT,sEAIF,MAAMwpB,EAAelpB,KAAK0oB,aAAa,SAAU,CAChDpiB,SAAUoB,EAAQpB,SAClBwd,WAAYpc,EAAQoc,YAAcpc,EAAQhG,MAAQ,MAClDyN,SAAUzH,EAAQyH,UAAY,eAC9BmC,MAAO5J,EAAQ4J,OAAStR,KAAKuC,OAAO+O,OAAS,QAC7C3P,MAAO+F,EAAQ/F,MACfC,YAAa8F,EAAQ9F,YACrBmiB,SAAUrc,EAAQqc,SAClBC,UAAWtc,EAAQsc,UACnBC,gBAAiBvc,EAAQuc,gBACzBC,SAAUxc,EAAQwc,SAClBC,UAAWzc,EAAQyc,YAMpB,OAHA+E,EAAajZ,QACbiZ,EAAa3Y,OAEN2Y,CACR,CAEA,aAAAC,GACC,OAAO/e,MAAM4d,KAAKhoB,KAAK6nB,QAAQuB,SAChC,CAEA,aAAAC,CAAc5nB,GACb,MAAMgP,EAASzQ,KAAK6nB,QAAQ3f,IAAIzG,GAChC,QAAIgP,IACHA,EAAO0B,UACPnS,KAAK6nB,QAAQxR,OAAO5U,GACpBzB,KAAKwQ,SAASvH,KAAK,iBAAkB,CAAEtI,SAAUc,KAC1C,EAGT,CAEA,iBAAA6nB,GACC,IAAK,MAAM7Y,KAAUzQ,KAAK6nB,QAAQuB,SACjC3Y,EAAO0B,UAERnS,KAAK6nB,QAAQve,QACbtJ,KAAKwQ,SAASvH,KAAK,kBACpB,CAEA,YAAAsgB,CAAatX,GACZ,MAAMuX,EAAY,IAAKxpB,KAAKuC,QAC5BvC,KAAKuC,OAASvC,KAAKsoB,wBAAwBrW,EAAWjS,KAAKuC,QAE3D,IAAK,MAAMkO,KAAUzQ,KAAK6nB,QAAQuB,SACjC3Y,EAAOuB,mBAAmBhS,KAAKuC,QAGhCvC,KAAKwQ,SAASvH,KAAK,iBAAkB,CACpCugB,YACAvX,UAAWjS,KAAKuC,QAElB,CAEA,cAAAsE,CAAenE,GACd1C,KAAKuC,OAAOG,YAAcA,EACtB1C,KAAKiP,YACRjP,KAAKiP,WAAWpI,eAAenE,GAEhC1C,KAAKwQ,SAASvH,KAAK,eAAgB,CAAEvG,eACtC,CAEA,cAAAsE,GACC,OACChH,KAAKuC,OAAOG,cACX1C,KAAKiP,WAAajP,KAAKiP,WAAWjI,iBAAmB,KAExD,CAEA,kBAAMyiB,CAAaC,EAAiB,MAQnC,OAPA1pB,KAAKiP,WAAWhI,eAChBjH,KAAKuoB,aAAc,EAEfmB,GACH1pB,KAAK6G,eAAe6iB,GAGd1pB,KAAKiD,MACb,CAEA,EAAAqF,CAAGC,EAAOC,GAET,OADAxI,KAAKwQ,SAASlI,GAAGC,EAAOC,GACjBxI,IACR,CAEA,GAAA4I,CAAIL,EAAOC,GAEV,OADAxI,KAAKwQ,SAAS5H,IAAIL,EAAOC,GAClBxI,IACR,CAEA,IAAAoJ,CAAKb,EAAOC,GAEX,OADAxI,KAAKwQ,SAASpH,KAAKb,EAAOC,GACnBxI,IACR,CAEA,IAAAiJ,CAAKV,EAAO/D,GAEX,OADAxE,KAAKwQ,SAASvH,KAAKV,EAAO/D,GACnBxE,IACR,CAEA,OAAAmS,GACCnS,KAAKspB,oBACLtpB,KAAKwQ,SAASmZ,qBACd3pB,KAAKiP,WAAWhI,eAChBjH,KAAKuoB,aAAc,EACnBvoB,KAAKwQ,SAASvH,KAAK,gBACpB,CAEA,uBAAAqf,CAAwBrW,EAAW2X,EAAiB,IACnD,MAaMC,EAAe/f,EACpBA,EAdqB,CACrBjH,OAAQ,KACRT,UAAW,KACXM,YAAa,KACbyM,SAAU,eACVmC,MAAO,QACPjQ,QAAS,UACT+N,UAAU,EACV0a,OAAO,EACPnnB,MAAM,EACNC,IAAK,cAIoBgnB,GACzB3X,GAGD,IAAK4X,EAAaznB,UACjB,MAAM,IAAIxB,EAAY,6CAOvB,OAJIipB,EAAannB,aAChB1C,KAAK+pB,qBAAqBF,EAAannB,aAGjCmnB,CACR,CAEA,oBAAAE,CAAqBrnB,GACpB,IAAKA,EAAYsnB,UAAYtnB,EAAYkL,MACxC,MAAM,IAAIhN,EACT,uDAIF,MAAMqpB,EAAiB,CACtBD,QAAS,SACTpc,MAAO,SACP3N,KAAM,SACNiqB,cAAe,SACfC,QAAS,UAGV,IAAK,MAAOjgB,EAAKkgB,KAAiBvW,OAAOwW,QAAQJ,GAChD,GAAIvnB,EAAYwH,WAAexH,EAAYwH,KAASkgB,EACnD,MAAM,IAAIxpB,EACT,uBAAuBsJ,uBAAyBkgB,KAIpD,CAEA,YAAApa,GACChQ,KAAK0oB,aAAe1oB,KAAK0oB,aAAarW,KAAKrS,MAC3CA,KAAKqpB,cAAgBrpB,KAAKqpB,cAAchX,KAAKrS,MAC7CA,KAAKupB,aAAevpB,KAAKupB,aAAalX,KAAKrS,KAC5C,CAEA,aAAO8nB,CAAOvlB,GACb,OAAO,IAAI8lB,EAAY9lB,EACxB,CAEA,0BAAa+nB,CAAc/nB,GAC1B,MAAMyM,EAAM,IAAIqZ,EAAY9lB,GAE5B,aADMyM,EAAI/L,OACH+L,CACR,CAEA,iCAAOub,CAA2BC,GACjC,OAAKA,EAEE,CACNR,QAASQ,EAASC,KAAOD,EAAS/oB,IAAM+oB,EAASR,QACjDpc,MAAO4c,EAAS5c,MAChB3N,KAAMuqB,EAASvqB,MAAQuqB,EAASE,cAAgBF,EAASG,UACzDT,cAAe,CACdU,KAAMJ,EAASI,KACfC,KAAML,EAASK,MAAQL,EAASM,cAAcD,QAC1CL,EAASN,eAAiB,IAE/BC,QACCK,EAASL,SAAWK,EAASO,aAC1B,CACAtpB,GAAI+oB,EAASL,SAAS1oB,IAAM+oB,EAASO,cAActpB,GACnDxB,KAAMuqB,EAASL,SAASlqB,MAAQuqB,EAASO,cAAc9qB,KACvD+qB,cAAeR,EAASL,SAASa,oBAEjCje,GAlBiB,IAoBvB,ECnWD,SAASke,IACR,GACqB,oBAAb1gB,WACNA,SAAS2F,cAAc,wBACvB,CACD,MAAMQ,EAAQnG,SAASyD,cAAc,SACrC0C,EAAMjP,GAAK,sBACXiP,EAAMzC,YAAcid,g92CACpB3gB,SAAS4gB,KAAK/a,YAAYM,EAC3B,CACD,CAEA,SAAS0a,IACR,GAAsB,oBAAXhmB,QAA0BA,OAAOimB,kBAAmB,CAC9DJ,IAEA,MAAM1oB,EAAS,IAAK6C,OAAOimB,mBACrBrc,EAAM,IAAIqZ,EAAY9lB,GAE5ByM,EACE/L,OACAqoB,KAAM7C,IAGN,GAFArjB,OAAOijB,YAAYkD,SAAWvc,EAE1B5J,OAAOimB,kBAAkBG,WAAY,EACxBphB,MAAMC,QAAQjF,OAAOimB,kBAAkBG,YACpDpmB,OAAOimB,kBAAkBG,WACzB,CAACpmB,OAAOimB,kBAAkBG,aAErBtiB,QAASuiB,IAChB,IACgBzc,EAAI0Z,aAClB+C,EAAa/pB,MAAQ,SACrB+pB,GAEMxb,MAAMwb,EAAavc,UAC3B,CAAE,MAAO/L,GACRgG,QAAQhG,MAAM,yCAA0CA,EACzD,GAEF,CAEA,GAA2B,oBAAhBuoB,YAA6B,CACvC,MAAMnjB,EAAQ,IAAImjB,YAAY,mBAAoB,CACjDC,OAAQ,CAAE3c,MAAKzM,SAAQkmB,cAExBrjB,OAAOwmB,cAAcrjB,EACtB,IAEAsjB,MAAO1oB,IAGP,GAFAgG,QAAQhG,MAAM,4CAA6CA,GAEhC,oBAAhBuoB,YAA6B,CACvC,MAAMnjB,EAAQ,IAAImjB,YAAY,mBAAoB,CACjDC,OAAQ,CAAExoB,QAAOZ,SAAQupB,MAAO,oBAEjC1mB,OAAOwmB,cAAcrjB,EACtB,GAEH,CACD,CAYK,MAACwjB,EAAoB,CACzB1D,cACAtZ,aACA2E,eACA4T,YACA5S,eACAkP,eACAjB,kBACA8E,gBACAtf,WACA7F,aACA5C,WACAS,WACAM,cACAG,cACAE,kBACAkrB,UACAlE,OAASvlB,IACR0oB,IACO,IAAI5C,EAAY9lB,IAExB0pB,QAAS,QACTV,SAAU,KAEVW,QAAS,IAAMC,QAAQJ,EAAkBR,UACzCa,YAAa,IAAML,EAAkBR,SAErC1kB,eAAiBnE,IACZqpB,EAAkBR,SACrBQ,EAAkBR,SAAS1kB,eAAenE,GAEpB,oBAAX0C,SACVA,OAAOinB,uBAAyB3pB,IAKnC4pB,aAAcC,MAAOhqB,EAAQG,KAC5BuoB,IACA,MAAMuB,EAAa,IAAKjqB,EAAQG,eAC1BsM,EAAM,IAAIqZ,EAAYmE,GAO5B,aANMxd,EAAI/L,OAEY,oBAAXmC,SACVA,OAAOijB,YAAYkD,SAAWvc,GAGxBA,GAGRyd,QAAUjkB,IACa,oBAAXpD,SACN2mB,EAAkBG,UACrB1jB,EAASujB,EAAkBR,UAE3BnmB,OAAOkN,iBACN,mBACC/J,IACAC,EAASD,EAAMojB,OAAO3c,IAAKzG,EAAMojB,SAElC,CAAEviB,MAAM,MAMZsjB,QAAUlkB,IACa,oBAAXpD,QACVA,OAAOkN,iBAAiB,mBAAqB/J,IAC5CC,EAASD,EAAMojB,OAAOxoB,MAAOoF,EAAMojB,WAKtCgB,mBAAoBtE,EAAYkC,4BAGX,oBAAXnlB,SACVA,OAAOijB,YAAc0D,EAvFG,oBAAbxhB,WACkB,YAAxBA,SAASqiB,WACZriB,SAAS+H,iBAAiB,mBAAoB8Y,GAE9C9mB,WAAW8mB,EAAU"}