From 597480cd841214c4aebe46a2af7fc2992611f0bb Mon Sep 17 00:00:00 2001 From: rockwellll Date: Sun, 6 Sep 2026 18:38:53 -0300 Subject: [PATCH 1/4] Add Smart Alert runtime and interaction tracking --- __tests__/alert_initialization_test.js | 180 +++++++ __tests__/api/push/alerts_test.js | 58 +++ .../controllers/alert_controller_test.js | 440 ++++++++++++++++++ __tests__/models/alert_test.js | 187 ++++++++ dist/hellotext.js | 2 +- docs/push.md | 64 +++ index.d.ts | 18 + lib/api/index.cjs | 4 + lib/api/index.js | 4 + lib/api/push/alerts.cjs | 45 ++ lib/api/push/alerts.js | 38 ++ lib/controllers/alert_controller.cjs | 265 +++++++++++ lib/controllers/alert_controller.js | 257 ++++++++++ lib/core/event.cjs | 2 +- lib/core/event.js | 2 +- lib/hellotext.cjs | 12 +- lib/hellotext.js | 14 +- lib/index.cjs | 2 + lib/index.js | 2 + lib/models/alert.cjs | 100 ++++ lib/models/alert.js | 94 ++++ lib/models/business.cjs | 3 +- lib/models/business.js | 3 +- lib/models/index.cjs | 7 + lib/models/index.js | 1 + src/api/index.js | 5 + src/api/push/alerts.js | 33 ++ src/controllers/alert_controller.js | 258 ++++++++++ src/core/event.js | 3 + src/hellotext.js | 14 +- src/index.js | 2 + src/models/alert.js | 109 +++++ src/models/business.js | 3 +- src/models/index.js | 1 + 34 files changed, 2219 insertions(+), 13 deletions(-) create mode 100644 __tests__/alert_initialization_test.js create mode 100644 __tests__/api/push/alerts_test.js create mode 100644 __tests__/controllers/alert_controller_test.js create mode 100644 __tests__/models/alert_test.js create mode 100644 lib/api/push/alerts.cjs create mode 100644 lib/api/push/alerts.js create mode 100644 lib/controllers/alert_controller.cjs create mode 100644 lib/controllers/alert_controller.js create mode 100644 lib/models/alert.cjs create mode 100644 lib/models/alert.js create mode 100644 src/api/push/alerts.js create mode 100644 src/controllers/alert_controller.js create mode 100644 src/models/alert.js diff --git a/__tests__/alert_initialization_test.js b/__tests__/alert_initialization_test.js new file mode 100644 index 00000000..981a8784 --- /dev/null +++ b/__tests__/alert_initialization_test.js @@ -0,0 +1,180 @@ +import { Application } from '@hotwired/stimulus' +import Hellotext from '../src/hellotext' +import API from '../src/api' +import { Business, Push } from '../src/models' +import AlertController from '../src/controllers/alert_controller' + +const html = ` + +` + +const businessData = (overrides = {}) => ({ + id: 'alert-initialization-business', + locale: 'en', + style_url: 'https://example.com/hellotext.css', + webchat: null, + whatsapp: null, + push: { public_key: 'business-public-key' }, + alert: { html }, + ...overrides, +}) + +const deferred = () => { + let resolve + const promise = new Promise(done => { resolve = done }) + return { promise, resolve } +} + +describe('Smart Alert initialization', () => { + let application + let supported + let stylesheetLoaded + let notificationDescriptor + let forms + + const hydrate = data => { + API.businesses.get.mockResolvedValue({ ok: true, json: async () => data }) + } + + const initialize = async (id = 'alert-initialization-business', config = {}) => { + await Hellotext.initialize(id, config) + forms.push(Hellotext.forms) + } + + beforeEach(async () => { + document.body.innerHTML = '' + localStorage.clear() + forms = [] + notificationDescriptor = Object.getOwnPropertyDescriptor(window, 'Notification') + Object.defineProperty(window, 'Notification', { + configurable: true, + value: { permission: 'default' }, + }) + supported = jest.spyOn(Push, 'supported', 'get').mockReturnValue(true) + jest.spyOn(Push.prototype, 'initialize').mockImplementation(function () { + this.ready = Promise.resolve() + return this.ready + }) + stylesheetLoaded = jest.spyOn(Business, 'waitForStylesheet').mockResolvedValue(true) + jest.spyOn(API.businesses, 'get') + jest.spyOn(API.pushAlerts, 'create').mockResolvedValue({ succeeded: true }) + hydrate(businessData()) + application = new Application(document.documentElement) + application.register('hellotext--alert', AlertController) + await application.start() + }) + + afterEach(() => { + Hellotext.alert?.dispose() + Hellotext.alert = null + Hellotext.push?.dispose() + Hellotext.push = null + forms.forEach(collection => collection.mutationObserver?.disconnect()) + application.stop() + document.body.innerHTML = '' + document.querySelectorAll('link[data-hellotext-stylesheet]').forEach(link => link.remove()) + jest.restoreAllMocks() + if (notificationDescriptor) { + Object.defineProperty(window, 'Notification', notificationDescriptor) + } else { + delete window.Notification + } + }) + + it('exposes a hidden alert that can show server-provided sections', async () => { + await initialize() + await Hellotext.alert.ready + + expect(document.querySelector('article').hidden).toBe(true) + await expect(Hellotext.alert.show('homepage')).resolves.toBe(true) + expect(document.querySelector('h4').textContent).toBe('Store updates') + expect(document.querySelector('article').hidden).toBe(false) + }) + + it.each([ + ['the alert payload is missing', { alert: undefined }], + ['the playbook is disabled', { alert: null }], + ['the public key is missing', { push: {} }], + ])('does not create an alert when %s', async (_reason, overrides) => { + hydrate(businessData(overrides)) + + await initialize() + + expect(Hellotext.alert).toBeNull() + expect(document.querySelector('article')).toBeNull() + }) + + it('does not create an alert when Push is disabled in page configuration', async () => { + await initialize('alert-initialization-business', { push: false }) + + expect(Hellotext.alert).toBeNull() + expect(Hellotext.push).toBeNull() + expect(document.querySelector('article')).toBeNull() + }) + + it('does not create an alert when the browser lacks Push support', async () => { + supported.mockReturnValue(false) + + await initialize() + + expect(Hellotext.alert).toBeNull() + expect(document.querySelector('article')).toBeNull() + }) + + it('removes the old alert when reinitialized with Push disabled', async () => { + await initialize() + const previous = Hellotext.alert + await previous.show('homepage') + + await initialize('alert-initialization-business', { push: false }) + + expect(previous.disposed).toBe(true) + expect(previous.push.disposed).toBe(true) + expect(Hellotext.alert).toBeNull() + expect(document.querySelector('article')).toBeNull() + }) + + it('prevents a pending old alert from mounting after another business initializes', async () => { + const previousStylesheet = deferred() + stylesheetLoaded.mockReturnValue(previousStylesheet.promise) + await initialize('business-a') + const previous = Hellotext.alert + const previousShown = previous.show('homepage') + + stylesheetLoaded.mockResolvedValue(true) + hydrate(businessData({ id: 'business-b', style_url: 'https://example.com/business-b.css' })) + await initialize('business-b') + await expect(Hellotext.alert.show('homepage')).resolves.toBe(true) + previousStylesheet.resolve(true) + + await expect(previousShown).resolves.toBe(false) + expect(previous.disposed).toBe(true) + expect(document.querySelectorAll('article')).toHaveLength(1) + expect(document.querySelector('article')).toBe(Hellotext.alert.element) + expect(Hellotext.alert.business.id).toBe('business-b') + }) + + it('ignores an earlier hydration that finishes after Push was disabled for another business', async () => { + const previousResponse = deferred() + API.businesses.get.mockReturnValueOnce(previousResponse.promise) + const previousInitialization = initialize('business-a') + + hydrate(businessData({ id: 'business-b' })) + await initialize('business-b', { push: false }) + previousResponse.resolve({ ok: true, json: async () => businessData({ id: 'business-a' }) }) + await previousInitialization + + expect(Hellotext.business.id).toBe('business-b') + expect(Hellotext.push).toBeNull() + expect(Hellotext.alert).toBeNull() + expect(document.querySelector('article')).toBeNull() + }) +}) diff --git a/__tests__/api/push/alerts_test.js b/__tests__/api/push/alerts_test.js new file mode 100644 index 00000000..4ca62690 --- /dev/null +++ b/__tests__/api/push/alerts_test.js @@ -0,0 +1,58 @@ +import API from '../../../src/api' +import Hellotext from '../../../src/hellotext' +import { Configuration } from '../../../src/core' + +describe('PushAlertsAPI', () => { + const defaultApiRoot = Configuration.apiRoot + let previousBusiness + + beforeEach(() => { + previousBusiness = Hellotext.business + Configuration.apiRoot = 'https://api.hellotext.test/v1' + Hellotext.business = { id: 'business-id' } + jest.spyOn(Hellotext, 'session', 'get').mockReturnValue('session-id') + global.fetch = jest.fn().mockResolvedValue({ ok: true, status: 204 }) + }) + + afterEach(() => { + jest.restoreAllMocks() + Configuration.apiRoot = defaultApiRoot + Hellotext.business = previousBusiness + }) + + it.each(['shown', 'dismissed', 'accepted'])('posts %s with the current session and section', async kind => { + const response = await API.pushAlerts.create({ section: 'homepage', kind }) + + expect(global.fetch).toHaveBeenCalledWith('https://api.hellotext.test/v1/public/push/alerts', { + method: 'POST', + keepalive: true, + headers: { + Authorization: 'Bearer business-id', + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ session: 'session-id', section: 'homepage', kind }), + }) + expect(response.succeeded).toBe(true) + }) + + it('uses the latest SDK session for each request', async () => { + await API.pushAlerts.create({ section: 'homepage', kind: 'shown' }) + jest.spyOn(Hellotext, 'session', 'get').mockReturnValue('next-session-id') + await API.pushAlerts.create({ section: 'product_details', kind: 'accepted' }) + + expect(JSON.parse(global.fetch.mock.calls[1][1].body)).toEqual({ + session: 'next-session-id', + section: 'product_details', + kind: 'accepted', + }) + }) + + it('returns a failed response when the endpoint rejects the interaction', async () => { + global.fetch.mockResolvedValue({ ok: false, status: 422 }) + + const response = await API.pushAlerts.create({ section: 'homepage', kind: 'shown' }) + + expect(response.failed).toBe(true) + }) +}) diff --git a/__tests__/controllers/alert_controller_test.js b/__tests__/controllers/alert_controller_test.js new file mode 100644 index 00000000..0cba4124 --- /dev/null +++ b/__tests__/controllers/alert_controller_test.js @@ -0,0 +1,440 @@ +import { Application } from '@hotwired/stimulus' +import AlertController from '../../src/controllers/alert_controller' +import Hellotext from '../../src/hellotext' +import API from '../../src/api' +import { Alert } from '../../src/models/alert' + +const DAY = 24 * 60 * 60 * 1000 +const sections = ['homepage', 'product_collection', 'product_details'].map(kind => ({ + kind, + title: `${kind} title`, + description: `${kind} description`, + primary_action: `${kind} subscribe`, + secondary_action: `${kind} dismiss`, +})) + +const alertHTML = (content = sections) => { + const element = document.createElement('article') + element.setAttribute('hidden', '') + element.dataset.controller = 'hellotext--alert' + element.setAttribute('data-hellotext--alert-sections-value', JSON.stringify(content)) + element.innerHTML = ` +

+

+ + + ` + return element.outerHTML +} + +describe('Smart Alert interactions', () => { + let application + let alert + let business + let push + let now + let originalNotification + let events + let businessNumber = 0 + + const primary = () => alert.element.querySelector('[data-hellotext--alert-target="primaryAction"]') + const secondary = () => alert.element.querySelector('[data-hellotext--alert-target="secondaryAction"]') + const saved = () => JSON.parse(localStorage.getItem(`hellotext:alert:${business.id}`)) + + beforeEach(async () => { + jest.spyOn(API.pushAlerts, 'create').mockResolvedValue({ succeeded: true }) + localStorage.clear() + document.body.innerHTML = '' + originalNotification = global.Notification + global.Notification = { permission: 'default', requestPermission: jest.fn() } + now = Date.UTC(2026, 8, 6) + jest.spyOn(Date, 'now').mockImplementation(() => now) + business = { id: `alert-business-${++businessNumber}`, stylesheetLoaded: Promise.resolve(true) } + push = { + ready: Promise.resolve(), + subscribed: false, + disposed: false, + subscribe: jest.fn().mockImplementation(async () => { + push.subscribed = true + return { succeeded: true } + }), + } + application = Application.start() + application.register('hellotext--alert', AlertController) + alert = new Alert({ html: alertHTML() }, business, push) + await alert.ready + + events = { shown: jest.fn(), dismissed: jest.fn(), accepted: jest.fn() } + Object.entries(events).forEach(([name, callback]) => Hellotext.on(`alert:${name}`, callback)) + }) + + afterEach(async () => { + alert.dispose() + await Promise.resolve() + application.stop() + jest.restoreAllMocks() + global.Notification = originalNotification + document.body.innerHTML = '' + Object.entries(events).forEach(([name, callback]) => Hellotext.removeEventListener(`alert:${name}`, callback)) + }) + + it('starts hidden and switches all four fields without requesting permission', async () => { + expect(alert.element.hidden).toBe(true) + + for (const section of sections) { + await expect(alert.show(section.kind)).resolves.toBe(true) + expect(alert.element.hidden).toBe(false) + expect(alert.element.querySelector('h4').textContent).toBe(section.title) + expect(alert.element.querySelector('p').textContent).toBe(section.description) + expect(primary().textContent).toBe(section.primary_action) + expect(secondary().textContent).toBe(section.secondary_action) + } + + expect(push.subscribe).not.toHaveBeenCalled() + expect(Notification.requestPermission).not.toHaveBeenCalled() + expect(events.shown.mock.calls).toEqual(sections.map(({ kind }) => [{ kind }])) + expect(API.pushAlerts.create.mock.calls).toEqual(sections.map(({ kind }) => [{ section: kind, kind: 'shown' }])) + expect(events.dismissed).not.toHaveBeenCalled() + expect(events.accepted).not.toHaveBeenCalled() + }) + + it('renders merchant copy as text and hides the previous section for an unknown kind', async () => { + alert.controller.sectionsValue = [{ ...sections[0], title: '' }] + await alert.show('homepage') + expect(alert.element.querySelector('h4').textContent).toBe('') + expect(alert.element.querySelector('img')).toBeNull() + + await expect(alert.show('product_details')).resolves.toBe(false) + expect(alert.element.hidden).toBe(true) + expect(events.shown).toHaveBeenCalledTimes(1) + expect(events.shown).toHaveBeenCalledWith({ kind: 'homepage' }) + }) + + it('renders overrides as text for one call without changing section defaults', async () => { + const defaults = alert.controller.sectionsValue + const options = { + title: 'New title', + description: 'New description', + primaryAction: 'Notify me', + secondaryAction: 'Maybe later', + } + + await expect(alert.show('homepage', options)).resolves.toBe(true) + expect(alert.element.querySelector('h4').textContent).toBe(options.title) + expect(alert.element.querySelector('p').textContent).toBe(options.description) + expect(primary().textContent).toBe(options.primaryAction) + expect(secondary().textContent).toBe(options.secondaryAction) + expect(alert.element.querySelector('[data-untrusted]')).toBeNull() + expect(alert.controller.sectionsValue).toEqual(defaults) + + await alert.show('homepage') + expect(alert.element.querySelector('h4').textContent).toBe(sections[0].title) + expect(alert.element.querySelector('p').textContent).toBe(sections[0].description) + expect(primary().textContent).toBe(sections[0].primary_action) + expect(secondary().textContent).toBe(sections[0].secondary_action) + }) + + it('permits empty overrides and falls back to defaults for null or undefined', async () => { + await alert.show('homepage', { + title: '', + description: null, + primaryAction: '', + secondaryAction: undefined, + }) + + expect(alert.element.querySelector('h4').textContent).toBe('') + expect(alert.element.querySelector('p').textContent).toBe(sections[0].description) + expect(primary().textContent).toBe('') + expect(secondary().textContent).toBe(sections[0].secondary_action) + }) + + it('shares a seven-day first dismissal across sections and later visits', async () => { + await alert.show('homepage') + secondary().click() + expect(saved()).toEqual({ dismissals: 1, dismissedUntil: now + 7 * DAY }) + expect(alert.element.hidden).toBe(true) + expect(events.dismissed).toHaveBeenCalledTimes(1) + expect(events.dismissed).toHaveBeenCalledWith({ kind: 'homepage' }) + expect(API.pushAlerts.create).toHaveBeenLastCalledWith({ section: 'homepage', kind: 'dismissed' }) + + alert.dispose() + alert = new Alert({ html: alertHTML() }, business, push) + now += 7 * DAY - 1 + await expect(alert.show('product_collection')).resolves.toBe(false) + expect(events.shown).toHaveBeenCalledTimes(1) + now += 1 + await expect(alert.show('product_details')).resolves.toBe(true) + expect(events.dismissed).toHaveBeenCalledTimes(1) + }) + + it('forces one display during cooldown without resetting dismissal history', async () => { + await alert.show('homepage') + secondary().click() + const firstDismissal = saved() + + await expect(alert.show('product_details', { force: true })).resolves.toBe(true) + expect(alert.element.hidden).toBe(false) + expect(saved()).toEqual(firstDismissal) + await expect(alert.show('product_collection')).resolves.toBe(false) + expect(events.shown.mock.calls).toEqual([[{ kind: 'homepage' }], [{ kind: 'product_details' }]]) + + await alert.show('product_details', { force: true, secondaryAction: 'Maybe later' }) + expect(secondary().textContent).toBe('Maybe later') + secondary().click() + expect(alert.element.hidden).toBe(true) + expect(saved()).toEqual({ dismissals: 2, dismissedUntil: now + 30 * DAY }) + expect(events.shown).toHaveBeenCalledTimes(3) + expect(events.dismissed.mock.calls).toEqual([[{ kind: 'homepage' }], [{ kind: 'product_details' }]]) + }) + + it.each(['missing section', 'existing subscription', 'denied permission'])( + 'does not bypass %s when forced', + async reason => { + await alert.show('product_details') + if (reason === 'missing section') alert.controller.sectionsValue = [sections[0]] + if (reason === 'existing subscription') push.subscribed = true + if (reason === 'denied permission') Notification.permission = 'denied' + + await expect(alert.show('product_details', { force: true })).resolves.toBe(false) + expect(alert.element.hidden).toBe(true) + expect(saved()).toBeNull() + expect(push.subscribe).not.toHaveBeenCalled() + expect(events.shown).toHaveBeenCalledTimes(1) + }, + ) + + it('uses thirty-day cycles for the second and every subsequent dismissal', async () => { + await alert.show('homepage') + secondary().click() + now += 7 * DAY + + for (let count = 2; count <= 4; count += 1) { + await expect(alert.show('homepage')).resolves.toBe(true) + secondary().click() + expect(saved()).toEqual({ dismissals: count, dismissedUntil: now + 30 * DAY }) + now += 30 * DAY - 1 + await expect(alert.show('product_details')).resolves.toBe(false) + now += 1 + } + }) + + it('does not share cooldowns between businesses', async () => { + await alert.show('homepage') + secondary().click() + alert.dispose() + alert = new Alert({ html: alertHTML() }, { ...business, id: 'another-business' }, push) + await expect(alert.show('homepage')).resolves.toBe(true) + }) + + it('counts a dismissal only once when an already-hidden button is clicked', async () => { + await alert.show('homepage') + secondary().click() + secondary().click() + expect(saved().dismissals).toBe(1) + expect(events.dismissed).toHaveBeenCalledTimes(1) + expect(events.dismissed).toHaveBeenCalledWith({ kind: 'homepage' }) + }) + + it('does not announce visitor dismissals when hidden or removed programmatically', async () => { + await alert.show('homepage') + alert.hide() + + await alert.show('product_collection') + alert.controller.close() + + await alert.show('product_details') + alert.dispose() + + expect(events.dismissed).not.toHaveBeenCalled() + expect(events.accepted).not.toHaveBeenCalled() + expect(saved()).toBeNull() + expect(API.pushAlerts.create.mock.calls.map(([data]) => data.kind)).toEqual(['shown', 'shown', 'shown']) + }) + + it('keeps a page-local cooldown when browser storage is blocked', async () => { + jest.spyOn(Storage.prototype, 'getItem').mockImplementation(() => { + throw new Error('Storage blocked') + }) + jest.spyOn(Storage.prototype, 'setItem').mockImplementation(() => { + throw new Error('Storage blocked') + }) + + await alert.show('homepage') + secondary().click() + alert.dispose() + alert = new Alert({ html: alertHTML() }, business, push) + await expect(alert.show('product_details')).resolves.toBe(false) + now += 7 * DAY + await expect(alert.show('homepage')).resolves.toBe(true) + secondary().click() + now += 7 * DAY + await expect(alert.show('homepage')).resolves.toBe(false) + }) + + it.each(['invalid JSON', '{"dismissals":-1,"dismissedUntil":99999999999999}', 'null'])( + 'ignores malformed dismissal history: %s', + async value => { + localStorage.setItem(`hellotext:alert:${business.id}`, value) + await expect(alert.show('homepage')).resolves.toBe(true) + secondary().click() + expect(saved().dismissals).toBe(1) + }, + ) + + it('hides a visible section after dismissal in another tab', async () => { + await alert.show('homepage') + const key = `hellotext:alert:${business.id}` + const value = JSON.stringify({ dismissals: 1, dismissedUntil: now + 7 * DAY }) + localStorage.setItem(key, value) + window.dispatchEvent(new StorageEvent('storage', { key, newValue: value })) + expect(alert.element.hidden).toBe(true) + expect(events.dismissed).not.toHaveBeenCalled() + }) + + it('waits for restoration before showing an already-subscribed visitor', async () => { + let resolveReady + push.ready = new Promise(resolve => { resolveReady = resolve }) + const showing = alert.show('homepage') + await Promise.resolve() + expect(alert.element.hidden).toBe(true) + push.subscribed = true + resolveReady() + await expect(showing).resolves.toBe(false) + }) + + it('suppresses a restored subscription even when its server sync failed', async () => { + push.subscribed = true + push.ready = Promise.reject(new Error('Sync failed')) + await expect(alert.show('homepage')).resolves.toBe(false) + }) + + it('allows retry when initialization failed before a subscription was restored', async () => { + push.ready = Promise.reject(new Error('Worker unavailable')) + await expect(alert.show('homepage')).resolves.toBe(true) + }) + + it('does not confuse granted permission with an existing subscription', async () => { + Notification.permission = 'granted' + await expect(alert.show('homepage')).resolves.toBe(true) + }) + + it.each(['denied', undefined])('suppresses alerts when permission is %s', async permission => { + if (permission) Notification.permission = permission + else global.Notification = undefined + await expect(alert.show('homepage')).resolves.toBe(false) + expect(events.shown).not.toHaveBeenCalled() + expect(API.pushAlerts.create).not.toHaveBeenCalled() + }) + + it('calls subscribe within the click, disables both actions, and prevents duplicate requests', async () => { + let complete + push.subscribe.mockImplementation(() => new Promise(resolve => { complete = resolve })) + await alert.show('homepage', { primaryAction: 'Notify me', secondaryAction: 'Maybe later' }) + expect(primary().textContent).toBe('Notify me') + expect(secondary().textContent).toBe('Maybe later') + primary().click() + expect(push.subscribe).toHaveBeenCalledTimes(1) + expect(events.accepted).toHaveBeenCalledTimes(1) + expect(events.accepted).toHaveBeenCalledWith({ kind: 'homepage' }) + expect(API.pushAlerts.create).toHaveBeenLastCalledWith({ section: 'homepage', kind: 'accepted' }) + expect(primary().disabled).toBe(true) + expect(secondary().disabled).toBe(true) + expect(alert.element.getAttribute('aria-busy')).toBe('true') + primary().click() + secondary().click() + expect(push.subscribe).toHaveBeenCalledTimes(1) + expect(events.accepted).toHaveBeenCalledTimes(1) + expect(events.dismissed).not.toHaveBeenCalled() + expect(saved()).toBeNull() + + push.subscribed = true + complete({ succeeded: true }) + await Promise.resolve() + expect(alert.element.hidden).toBe(true) + expect(primary().disabled).toBe(false) + expect(secondary().disabled).toBe(false) + expect(saved()).toBeNull() + expect(events.accepted).toHaveBeenCalledTimes(1) + expect(events.dismissed).not.toHaveBeenCalled() + }) + + it('does not wait for recording before display, dismissal, or requesting permission', async () => { + API.pushAlerts.create.mockImplementation(() => new Promise(() => {})) + + await expect(alert.show('homepage')).resolves.toBe(true) + secondary().click() + expect(alert.element.hidden).toBe(true) + + await alert.show('product_details', { force: true }) + primary().click() + expect(push.subscribe).toHaveBeenCalledTimes(1) + expect(API.pushAlerts.create.mock.calls).toEqual([ + [{ section: 'homepage', kind: 'shown' }], + [{ section: 'homepage', kind: 'dismissed' }], + [{ section: 'product_details', kind: 'shown' }], + [{ section: 'product_details', kind: 'accepted' }], + ]) + await Promise.resolve() + }) + + it.each(['rejection', 'failed response'])('keeps alert actions working after a recording %s', async failure => { + const warn = jest.spyOn(console, 'warn').mockImplementation(() => {}) + if (failure === 'rejection') API.pushAlerts.create.mockRejectedValue(new Error('Offline')) + else API.pushAlerts.create.mockResolvedValue({ failed: true }) + + await expect(alert.show('homepage')).resolves.toBe(true) + secondary().click() + expect(saved().dismissals).toBe(1) + + await alert.show('product_details', { force: true }) + primary().click() + expect(push.subscribe).toHaveBeenCalledTimes(1) + await Promise.resolve() + expect(warn).toHaveBeenCalled() + }) + + it('suppresses after native denial without adding a dismissal', async () => { + push.subscribe.mockImplementation(async () => { + Notification.permission = 'denied' + throw new Error('Permission denied') + }) + await alert.show('homepage') + await alert.controller.subscribe() + expect(alert.element.hidden).toBe(true) + expect(saved()).toBeNull() + await expect(alert.show('homepage')).resolves.toBe(false) + expect(events.accepted).toHaveBeenCalledTimes(1) + expect(events.accepted).toHaveBeenCalledWith({ kind: 'homepage' }) + expect(events.dismissed).not.toHaveBeenCalled() + }) + + it('keeps actions available after a subscription failure and emits the error', async () => { + const error = new Error('Subscription failed') + const onError = jest.fn() + push.subscribe.mockRejectedValue(error) + alert.element.addEventListener('hellotext--alert:error', onError) + await alert.show('homepage') + await alert.controller.subscribe() + expect(alert.element.hidden).toBe(false) + expect(primary().disabled).toBe(false) + expect(onError.mock.calls[0][0].detail.error).toBe(error) + expect(saved()).toBeNull() + expect(events.accepted).toHaveBeenCalledTimes(1) + expect(events.accepted).toHaveBeenCalledWith({ kind: 'homepage' }) + expect(events.dismissed).not.toHaveBeenCalled() + }) + + it.each(['response', 'rejection'])('hides when subscribed despite a server sync %s', async failure => { + push.subscribe.mockImplementation(async () => { + push.subscribed = true + if (failure === 'rejection') throw new Error('Sync failed') + return { failed: true } + }) + await alert.show('homepage') + await alert.controller.subscribe() + expect(alert.element.hidden).toBe(true) + expect(saved()).toBeNull() + }) +}) diff --git a/__tests__/models/alert_test.js b/__tests__/models/alert_test.js new file mode 100644 index 00000000..39568640 --- /dev/null +++ b/__tests__/models/alert_test.js @@ -0,0 +1,187 @@ +import { Application } from '@hotwired/stimulus' +import AlertController from '../../src/controllers/alert_controller' +import { Alert } from '../../src/models/alert' +import API from '../../src/api' + +const sections = [ + { + kind: 'homepage', + title: 'Homepage updates', + description: 'Hear about new arrivals.', + primary_action: 'Activate alerts', + secondary_action: 'Not now', + }, + { + kind: 'product_details', + title: 'Product updates', + description: 'Hear when this product returns.', + primary_action: 'Notify me', + secondary_action: 'Later', + }, +] + +const html = ` + +` + +const deferred = () => { + let resolve + const promise = new Promise(done => { resolve = done }) + return { promise, resolve } +} + +describe('Alert', () => { + let application + let alert + let business + let push + let notificationDescriptor + + beforeEach(async () => { + document.body.innerHTML = '' + localStorage.clear() + jest.spyOn(API.pushAlerts, 'create').mockResolvedValue({ succeeded: true }) + notificationDescriptor = Object.getOwnPropertyDescriptor(window, 'Notification') + Object.defineProperty(window, 'Notification', { + configurable: true, + value: { permission: 'default' }, + }) + business = { id: 'alert-model-business', stylesheetLoaded: Promise.resolve(true) } + push = { ready: Promise.resolve(), subscribed: false, disposed: false } + application = new Application(document.documentElement) + application.register('hellotext--alert', AlertController) + await application.start() + }) + + afterEach(() => { + alert?.dispose() + application.stop() + jest.restoreAllMocks() + document.body.innerHTML = '' + if (notificationDescriptor) { + Object.defineProperty(window, 'Notification', notificationDescriptor) + } else { + delete window.Notification + } + }) + + it('waits for the stylesheet and controller before showing a requested section', async () => { + const stylesheet = deferred() + business.stylesheetLoaded = stylesheet.promise + alert = new Alert({ html }, business, push) + + const shown = alert.show('product_details', { title: 'This product is coming back', primaryAction: 'Notify me about this product' }) + + expect(document.querySelector('article')).toBeNull() + stylesheet.resolve(true) + + await expect(shown).resolves.toBe(true) + expect(document.querySelector('article')).toBe(alert.element) + expect(alert.element.hidden).toBe(false) + expect(alert.element.querySelector('h4').textContent).toBe('This product is coming back') + expect(alert.element.querySelector('p').textContent).toBe('Hear when this product returns.') + expect(alert.element.querySelector('button').textContent).toBe('Notify me about this product') + }) + + it('keeps the mounted alert hidden until a section is requested', async () => { + alert = new Alert({ html }, business, push) + + await expect(alert.ready).resolves.toBe(true) + + expect(document.querySelector('article')).toBe(alert.element) + expect(alert.element.hidden).toBe(true) + }) + + it('does not mount or show when the stylesheet fails', async () => { + business.stylesheetLoaded = Promise.resolve(false) + alert = new Alert({ html }, business, push) + + await expect(alert.ready).resolves.toBe(false) + await expect(alert.show('homepage')).resolves.toBe(false) + expect(document.querySelector('article')).toBeNull() + }) + + it('ignores payloads without an alert controller element', async () => { + alert = new Alert({ html: '

No alert configured

' }, business, push) + + await expect(alert.ready).resolves.toBe(false) + await expect(alert.show('homepage')).resolves.toBe(false) + expect(document.body.innerHTML).toBe('') + }) + + it('uses the latest section requested before mounting finishes', async () => { + const stylesheet = deferred() + business.stylesheetLoaded = stylesheet.promise + alert = new Alert({ html }, business, push) + const homepage = alert.show('homepage') + const product = alert.show('product_details') + + stylesheet.resolve(true) + + await expect(homepage).resolves.toBe(false) + await expect(product).resolves.toBe(true) + expect(alert.element.querySelector('h4').textContent).toBe('Product updates') + }) + + it('cancels a queued show when hidden before mounting', async () => { + const stylesheet = deferred() + business.stylesheetLoaded = stylesheet.promise + alert = new Alert({ html }, business, push) + const shown = alert.show('homepage') + + alert.hide() + stylesheet.resolve(true) + + await expect(shown).resolves.toBe(false) + expect(alert.element.hidden).toBe(true) + expect(localStorage.length).toBe(0) + }) + + it('does not mount an alert disposed while waiting for its stylesheet', async () => { + const stylesheet = deferred() + business.stylesheetLoaded = stylesheet.promise + alert = new Alert({ html }, business, push) + const shown = alert.show('homepage') + + alert.dispose() + stylesheet.resolve(true) + + await expect(shown).resolves.toBe(false) + expect(document.querySelector('article')).toBeNull() + }) + + it('removes a mounted alert and cancels showing while Push restores', async () => { + const restored = deferred() + push.ready = restored.promise + alert = new Alert({ html }, business, push) + await alert.ready + const shown = alert.show('homepage') + await Promise.resolve() + + alert.dispose() + restored.resolve() + + await expect(shown).resolves.toBe(false) + expect(document.querySelector('article')).toBeNull() + expect(alert.element.hidden).toBe(true) + }) + + it('hides without recording a dismissal and can be shown again', async () => { + alert = new Alert({ html }, business, push) + await alert.show('homepage') + + alert.hide() + + expect(alert.element.hidden).toBe(true) + expect(localStorage.length).toBe(0) + await expect(alert.show('product_details')).resolves.toBe(true) + }) +}) diff --git a/dist/hellotext.js b/dist/hellotext.js index eed7d8d6..943a0c26 100644 --- a/dist/hellotext.js +++ b/dist/hellotext.js @@ -1,2 +1,2 @@ /*! For license information please see hellotext.js.LICENSE.txt */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Hellotext=t():e.Hellotext=t()}(Object("undefined"!=typeof self?self:this),()=>(()=>{"use strict";var e={891(e,t,s){s.d(t,{lg:()=>G,xI:()=>ie});class n{constructor(e,t,s){this.eventTarget=e,this.eventName=t,this.eventOptions=s,this.unorderedBindings=new Set}connect(){this.eventTarget.addEventListener(this.eventName,this,this.eventOptions)}disconnect(){this.eventTarget.removeEventListener(this.eventName,this,this.eventOptions)}bindingConnected(e){this.unorderedBindings.add(e)}bindingDisconnected(e){this.unorderedBindings.delete(e)}handleEvent(e){const t=function(e){if("immediatePropagationStopped"in e)return e;{const{stopImmediatePropagation:t}=e;return Object.assign(e,{immediatePropagationStopped:!1,stopImmediatePropagation(){this.immediatePropagationStopped=!0,t.call(this)}})}}(e);for(const e of this.bindings){if(t.immediatePropagationStopped)break;e.handleEvent(t)}}hasBindings(){return this.unorderedBindings.size>0}get bindings(){return Array.from(this.unorderedBindings).sort((e,t)=>{const s=e.index,n=t.index;return sn?1:0})}}class i{constructor(e){this.application=e,this.eventListenerMaps=new Map,this.started=!1}start(){this.started||(this.started=!0,this.eventListeners.forEach(e=>e.connect()))}stop(){this.started&&(this.started=!1,this.eventListeners.forEach(e=>e.disconnect()))}get eventListeners(){return Array.from(this.eventListenerMaps.values()).reduce((e,t)=>e.concat(Array.from(t.values())),[])}bindingConnected(e){this.fetchEventListenerForBinding(e).bindingConnected(e)}bindingDisconnected(e,t=!1){this.fetchEventListenerForBinding(e).bindingDisconnected(e),t&&this.clearEventListenersForBinding(e)}handleError(e,t,s={}){this.application.handleError(e,`Error ${t}`,s)}clearEventListenersForBinding(e){const t=this.fetchEventListenerForBinding(e);t.hasBindings()||(t.disconnect(),this.removeMappedEventListenerFor(e))}removeMappedEventListenerFor(e){const{eventTarget:t,eventName:s,eventOptions:n}=e,i=this.fetchEventListenerMapForEventTarget(t),r=this.cacheKey(s,n);i.delete(r),0==i.size&&this.eventListenerMaps.delete(t)}fetchEventListenerForBinding(e){const{eventTarget:t,eventName:s,eventOptions:n}=e;return this.fetchEventListener(t,s,n)}fetchEventListener(e,t,s){const n=this.fetchEventListenerMapForEventTarget(e),i=this.cacheKey(t,s);let r=n.get(i);return r||(r=this.createEventListener(e,t,s),n.set(i,r)),r}createEventListener(e,t,s){const i=new n(e,t,s);return this.started&&i.connect(),i}fetchEventListenerMapForEventTarget(e){let t=this.eventListenerMaps.get(e);return t||(t=new Map,this.eventListenerMaps.set(e,t)),t}cacheKey(e,t){const s=[e];return Object.keys(t).sort().forEach(e=>{s.push(`${t[e]?"":"!"}${e}`)}),s.join(":")}}const r={stop:({event:e,value:t})=>(t&&e.stopPropagation(),!0),prevent:({event:e,value:t})=>(t&&e.preventDefault(),!0),self:({event:e,value:t,element:s})=>!t||s===e.target},a=/^(?:(?:([^.]+?)\+)?(.+?)(?:\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;function o(e){return e.replace(/(?:[_-])([a-z0-9])/g,(e,t)=>t.toUpperCase())}function c(e){return o(e.replace(/--/g,"-").replace(/__/g,"_"))}function l(e){return e.charAt(0).toUpperCase()+e.slice(1)}function h(e){return e.replace(/([A-Z])/g,(e,t)=>`-${t.toLowerCase()}`)}function u(e){return null!=e}function d(e,t){return Object.prototype.hasOwnProperty.call(e,t)}const p=["meta","ctrl","alt","shift"];class m{constructor(e,t,s,n){this.element=e,this.index=t,this.eventTarget=s.eventTarget||e,this.eventName=s.eventName||function(e){const t=e.tagName.toLowerCase();if(t in g)return g[t](e)}(e)||f("missing event name"),this.eventOptions=s.eventOptions||{},this.identifier=s.identifier||f("missing identifier"),this.methodName=s.methodName||f("missing method name"),this.keyFilter=s.keyFilter||"",this.schema=n}static forToken(e,t){return new this(e.element,e.index,function(e){const t=e.trim().match(a)||[];let s=t[2],n=t[3];return n&&!["keydown","keyup","keypress"].includes(s)&&(s+=`.${n}`,n=""),{eventTarget:(i=t[4],"window"==i?window:"document"==i?document:void 0),eventName:s,eventOptions:t[7]?(r=t[7],r.split(":").reduce((e,t)=>Object.assign(e,{[t.replace(/^!/,"")]:!/^!/.test(t)}),{})):{},identifier:t[5],methodName:t[6],keyFilter:t[1]||n};var i,r}(e.content),t)}toString(){const e=this.keyFilter?`.${this.keyFilter}`:"",t=this.eventTargetName?`@${this.eventTargetName}`:"";return`${this.eventName}${e}${t}->${this.identifier}#${this.methodName}`}shouldIgnoreKeyboardEvent(e){if(!this.keyFilter)return!1;const t=this.keyFilter.split("+");if(this.keyFilterDissatisfied(e,t))return!0;const s=t.filter(e=>!p.includes(e))[0];return!!s&&(d(this.keyMappings,s)||f(`contains unknown key filter: ${this.keyFilter}`),this.keyMappings[s].toLowerCase()!==e.key.toLowerCase())}shouldIgnoreMouseEvent(e){if(!this.keyFilter)return!1;const t=[this.keyFilter];return!!this.keyFilterDissatisfied(e,t)}get params(){const e={},t=new RegExp(`^data-${this.identifier}-(.+)-param$`,"i");for(const{name:s,value:n}of Array.from(this.element.attributes)){const i=s.match(t),r=i&&i[1];r&&(e[o(r)]=b(n))}return e}get eventTargetName(){return(e=this.eventTarget)==window?"window":e==document?"document":void 0;var e}get keyMappings(){return this.schema.keyMappings}keyFilterDissatisfied(e,t){const[s,n,i,r]=p.map(e=>t.includes(e));return e.metaKey!==s||e.ctrlKey!==n||e.altKey!==i||e.shiftKey!==r}}const g={a:()=>"click",button:()=>"click",form:()=>"submit",details:()=>"toggle",input:e=>"submit"==e.getAttribute("type")?"click":"input",select:()=>"change",textarea:()=>"input"};function f(e){throw new Error(e)}function b(e){try{return JSON.parse(e)}catch(t){return e}}class y{constructor(e,t){this.context=e,this.action=t}get index(){return this.action.index}get eventTarget(){return this.action.eventTarget}get eventOptions(){return this.action.eventOptions}get identifier(){return this.context.identifier}handleEvent(e){const t=this.prepareActionEvent(e);this.willBeInvokedByEvent(e)&&this.applyEventModifiers(t)&&this.invokeWithEvent(t)}get eventName(){return this.action.eventName}get method(){const e=this.controller[this.methodName];if("function"==typeof e)return e;throw new Error(`Action "${this.action}" references undefined method "${this.methodName}"`)}applyEventModifiers(e){const{element:t}=this.action,{actionDescriptorFilters:s}=this.context.application,{controller:n}=this.context;let i=!0;for(const[r,a]of Object.entries(this.eventOptions))if(r in s){const o=s[r];i=i&&o({name:r,value:a,event:e,element:t,controller:n})}return i}prepareActionEvent(e){return Object.assign(e,{params:this.action.params})}invokeWithEvent(e){const{target:t,currentTarget:s}=e;try{this.method.call(this.controller,e),this.context.logDebugActivity(this.methodName,{event:e,target:t,currentTarget:s,action:this.methodName})}catch(t){const{identifier:s,controller:n,element:i,index:r}=this,a={identifier:s,controller:n,element:i,index:r,event:e};this.context.handleError(t,`invoking action "${this.action}"`,a)}}willBeInvokedByEvent(e){const t=e.target;return!(e instanceof KeyboardEvent&&this.action.shouldIgnoreKeyboardEvent(e))&&!(e instanceof MouseEvent&&this.action.shouldIgnoreMouseEvent(e))&&(this.element===t||(t instanceof Element&&this.element.contains(t)?this.scope.containsElement(t):this.scope.containsElement(this.action.element)))}get controller(){return this.context.controller}get methodName(){return this.action.methodName}get element(){return this.scope.element}get scope(){return this.context.scope}}class v{constructor(e,t){this.mutationObserverInit={attributes:!0,childList:!0,subtree:!0},this.element=e,this.started=!1,this.delegate=t,this.elements=new Set,this.mutationObserver=new MutationObserver(e=>this.processMutations(e))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,this.mutationObserverInit),this.refresh())}pause(e){this.started&&(this.mutationObserver.disconnect(),this.started=!1),e(),this.started||(this.mutationObserver.observe(this.element,this.mutationObserverInit),this.started=!0)}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started){const e=new Set(this.matchElementsInTree());for(const t of Array.from(this.elements))e.has(t)||this.removeElement(t);for(const t of Array.from(e))this.addElement(t)}}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){"attributes"==e.type?this.processAttributeChange(e.target,e.attributeName):"childList"==e.type&&(this.processRemovedNodes(e.removedNodes),this.processAddedNodes(e.addedNodes))}processAttributeChange(e,t){this.elements.has(e)?this.delegate.elementAttributeChanged&&this.matchElement(e)?this.delegate.elementAttributeChanged(e,t):this.removeElement(e):this.matchElement(e)&&this.addElement(e)}processRemovedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.processTree(e,this.removeElement)}}processAddedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.elementIsActive(e)&&this.processTree(e,this.addElement)}}matchElement(e){return this.delegate.matchElement(e)}matchElementsInTree(e=this.element){return this.delegate.matchElementsInTree(e)}processTree(e,t){for(const s of this.matchElementsInTree(e))t.call(this,s)}elementFromNode(e){if(e.nodeType==Node.ELEMENT_NODE)return e}elementIsActive(e){return e.isConnected==this.element.isConnected&&this.element.contains(e)}addElement(e){this.elements.has(e)||this.elementIsActive(e)&&(this.elements.add(e),this.delegate.elementMatched&&this.delegate.elementMatched(e))}removeElement(e){this.elements.has(e)&&(this.elements.delete(e),this.delegate.elementUnmatched&&this.delegate.elementUnmatched(e))}}class w{constructor(e,t,s){this.attributeName=t,this.delegate=s,this.elementObserver=new v(e,this)}get element(){return this.elementObserver.element}get selector(){return`[${this.attributeName}]`}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get started(){return this.elementObserver.started}matchElement(e){return e.hasAttribute(this.attributeName)}matchElementsInTree(e){const t=this.matchElement(e)?[e]:[],s=Array.from(e.querySelectorAll(this.selector));return t.concat(s)}elementMatched(e){this.delegate.elementMatchedAttribute&&this.delegate.elementMatchedAttribute(e,this.attributeName)}elementUnmatched(e){this.delegate.elementUnmatchedAttribute&&this.delegate.elementUnmatchedAttribute(e,this.attributeName)}elementAttributeChanged(e,t){this.delegate.elementAttributeValueChanged&&this.attributeName==t&&this.delegate.elementAttributeValueChanged(e,t)}}function T(e,t){let s=e.get(t);return s||(s=new Set,e.set(t,s)),s}class S{constructor(){this.valuesByKey=new Map}get keys(){return Array.from(this.valuesByKey.keys())}get values(){return Array.from(this.valuesByKey.values()).reduce((e,t)=>e.concat(Array.from(t)),[])}get size(){return Array.from(this.valuesByKey.values()).reduce((e,t)=>e+t.size,0)}add(e,t){!function(e,t,s){T(e,t).add(s)}(this.valuesByKey,e,t)}delete(e,t){!function(e,t,s){T(e,t).delete(s),function(e,t){const s=e.get(t);null!=s&&0==s.size&&e.delete(t)}(e,t)}(this.valuesByKey,e,t)}has(e,t){const s=this.valuesByKey.get(e);return null!=s&&s.has(t)}hasKey(e){return this.valuesByKey.has(e)}hasValue(e){return Array.from(this.valuesByKey.values()).some(t=>t.has(e))}getValuesForKey(e){const t=this.valuesByKey.get(e);return t?Array.from(t):[]}getKeysForValue(e){return Array.from(this.valuesByKey).filter(([t,s])=>s.has(e)).map(([e,t])=>e)}}class C{constructor(e,t,s,n){this._selector=t,this.details=n,this.elementObserver=new v(e,this),this.delegate=s,this.matchesByElement=new S}get started(){return this.elementObserver.started}get selector(){return this._selector}set selector(e){this._selector=e,this.refresh()}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get element(){return this.elementObserver.element}matchElement(e){const{selector:t}=this;if(t){const s=e.matches(t);return this.delegate.selectorMatchElement?s&&this.delegate.selectorMatchElement(e,this.details):s}return!1}matchElementsInTree(e){const{selector:t}=this;if(t){const s=this.matchElement(e)?[e]:[],n=Array.from(e.querySelectorAll(t)).filter(e=>this.matchElement(e));return s.concat(n)}return[]}elementMatched(e){const{selector:t}=this;t&&this.selectorMatched(e,t)}elementUnmatched(e){const t=this.matchesByElement.getKeysForValue(e);for(const s of t)this.selectorUnmatched(e,s)}elementAttributeChanged(e,t){const{selector:s}=this;if(s){const t=this.matchElement(e),n=this.matchesByElement.has(s,e);t&&!n?this.selectorMatched(e,s):!t&&n&&this.selectorUnmatched(e,s)}}selectorMatched(e,t){this.delegate.selectorMatched(e,t,this.details),this.matchesByElement.add(t,e)}selectorUnmatched(e,t){this.delegate.selectorUnmatched(e,t,this.details),this.matchesByElement.delete(t,e)}}class O{constructor(e,t){this.element=e,this.delegate=t,this.started=!1,this.stringMap=new Map,this.mutationObserver=new MutationObserver(e=>this.processMutations(e))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,{attributes:!0,attributeOldValue:!0}),this.refresh())}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started)for(const e of this.knownAttributeNames)this.refreshAttribute(e,null)}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){const t=e.attributeName;t&&this.refreshAttribute(t,e.oldValue)}refreshAttribute(e,t){const s=this.delegate.getStringMapKeyForAttribute(e);if(null!=s){this.stringMap.has(e)||this.stringMapKeyAdded(s,e);const n=this.element.getAttribute(e);if(this.stringMap.get(e)!=n&&this.stringMapValueChanged(n,s,t),null==n){const t=this.stringMap.get(e);this.stringMap.delete(e),t&&this.stringMapKeyRemoved(s,e,t)}else this.stringMap.set(e,n)}}stringMapKeyAdded(e,t){this.delegate.stringMapKeyAdded&&this.delegate.stringMapKeyAdded(e,t)}stringMapValueChanged(e,t,s){this.delegate.stringMapValueChanged&&this.delegate.stringMapValueChanged(e,t,s)}stringMapKeyRemoved(e,t,s){this.delegate.stringMapKeyRemoved&&this.delegate.stringMapKeyRemoved(e,t,s)}get knownAttributeNames(){return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)))}get currentAttributeNames(){return Array.from(this.element.attributes).map(e=>e.name)}get recordedAttributeNames(){return Array.from(this.stringMap.keys())}}class A{constructor(e,t,s){this.attributeObserver=new w(e,t,this),this.delegate=s,this.tokensByElement=new S}get started(){return this.attributeObserver.started}start(){this.attributeObserver.start()}pause(e){this.attributeObserver.pause(e)}stop(){this.attributeObserver.stop()}refresh(){this.attributeObserver.refresh()}get element(){return this.attributeObserver.element}get attributeName(){return this.attributeObserver.attributeName}elementMatchedAttribute(e){this.tokensMatched(this.readTokensForElement(e))}elementAttributeValueChanged(e){const[t,s]=this.refreshTokensForElement(e);this.tokensUnmatched(t),this.tokensMatched(s)}elementUnmatchedAttribute(e){this.tokensUnmatched(this.tokensByElement.getValuesForKey(e))}tokensMatched(e){e.forEach(e=>this.tokenMatched(e))}tokensUnmatched(e){e.forEach(e=>this.tokenUnmatched(e))}tokenMatched(e){this.delegate.tokenMatched(e),this.tokensByElement.add(e.element,e)}tokenUnmatched(e){this.delegate.tokenUnmatched(e),this.tokensByElement.delete(e.element,e)}refreshTokensForElement(e){const t=this.tokensByElement.getValuesForKey(e),s=this.readTokensForElement(e),n=function(e,t){const s=Math.max(e.length,t.length);return Array.from({length:s},(s,n)=>[e[n],t[n]])}(t,s).findIndex(([e,t])=>{return n=t,!((s=e)&&n&&s.index==n.index&&s.content==n.content);var s,n});return-1==n?[[],[]]:[t.slice(n),s.slice(n)]}readTokensForElement(e){const t=this.attributeName;return function(e,t,s){return e.trim().split(/\s+/).filter(e=>e.length).map((e,n)=>({element:t,attributeName:s,content:e,index:n}))}(e.getAttribute(t)||"",e,t)}}class E{constructor(e,t,s){this.tokenListObserver=new A(e,t,this),this.delegate=s,this.parseResultsByToken=new WeakMap,this.valuesByTokenByElement=new WeakMap}get started(){return this.tokenListObserver.started}start(){this.tokenListObserver.start()}stop(){this.tokenListObserver.stop()}refresh(){this.tokenListObserver.refresh()}get element(){return this.tokenListObserver.element}get attributeName(){return this.tokenListObserver.attributeName}tokenMatched(e){const{element:t}=e,{value:s}=this.fetchParseResultForToken(e);s&&(this.fetchValuesByTokenForElement(t).set(e,s),this.delegate.elementMatchedValue(t,s))}tokenUnmatched(e){const{element:t}=e,{value:s}=this.fetchParseResultForToken(e);s&&(this.fetchValuesByTokenForElement(t).delete(e),this.delegate.elementUnmatchedValue(t,s))}fetchParseResultForToken(e){let t=this.parseResultsByToken.get(e);return t||(t=this.parseToken(e),this.parseResultsByToken.set(e,t)),t}fetchValuesByTokenForElement(e){let t=this.valuesByTokenByElement.get(e);return t||(t=new Map,this.valuesByTokenByElement.set(e,t)),t}parseToken(e){try{return{value:this.delegate.parseValueForToken(e)}}catch(e){return{error:e}}}}class x{constructor(e,t){this.context=e,this.delegate=t,this.bindingsByAction=new Map}start(){this.valueListObserver||(this.valueListObserver=new E(this.element,this.actionAttribute,this),this.valueListObserver.start())}stop(){this.valueListObserver&&(this.valueListObserver.stop(),delete this.valueListObserver,this.disconnectAllActions())}get element(){return this.context.element}get identifier(){return this.context.identifier}get actionAttribute(){return this.schema.actionAttribute}get schema(){return this.context.schema}get bindings(){return Array.from(this.bindingsByAction.values())}connectAction(e){const t=new y(this.context,e);this.bindingsByAction.set(e,t),this.delegate.bindingConnected(t)}disconnectAction(e){const t=this.bindingsByAction.get(e);t&&(this.bindingsByAction.delete(e),this.delegate.bindingDisconnected(t))}disconnectAllActions(){this.bindings.forEach(e=>this.delegate.bindingDisconnected(e,!0)),this.bindingsByAction.clear()}parseValueForToken(e){const t=m.forToken(e,this.schema);if(t.identifier==this.identifier)return t}elementMatchedValue(e,t){this.connectAction(t)}elementUnmatchedValue(e,t){this.disconnectAction(t)}}class M{constructor(e,t){this.context=e,this.receiver=t,this.stringMapObserver=new O(this.element,this),this.valueDescriptorMap=this.controller.valueDescriptorMap}start(){this.stringMapObserver.start(),this.invokeChangedCallbacksForDefaultValues()}stop(){this.stringMapObserver.stop()}get element(){return this.context.element}get controller(){return this.context.controller}getStringMapKeyForAttribute(e){if(e in this.valueDescriptorMap)return this.valueDescriptorMap[e].name}stringMapKeyAdded(e,t){const s=this.valueDescriptorMap[t];this.hasValue(e)||this.invokeChangedCallback(e,s.writer(this.receiver[e]),s.writer(s.defaultValue))}stringMapValueChanged(e,t,s){const n=this.valueDescriptorNameMap[t];null!==e&&(null===s&&(s=n.writer(n.defaultValue)),this.invokeChangedCallback(t,e,s))}stringMapKeyRemoved(e,t,s){const n=this.valueDescriptorNameMap[e];this.hasValue(e)?this.invokeChangedCallback(e,n.writer(this.receiver[e]),s):this.invokeChangedCallback(e,n.writer(n.defaultValue),s)}invokeChangedCallbacksForDefaultValues(){for(const{key:e,name:t,defaultValue:s,writer:n}of this.valueDescriptors)null==s||this.controller.data.has(e)||this.invokeChangedCallback(t,n(s),void 0)}invokeChangedCallback(e,t,s){const n=`${e}Changed`,i=this.receiver[n];if("function"==typeof i){const n=this.valueDescriptorNameMap[e];try{const e=n.reader(t);let r=s;s&&(r=n.reader(s)),i.call(this.receiver,e,r)}catch(e){throw e instanceof TypeError&&(e.message=`Stimulus Value "${this.context.identifier}.${n.name}" - ${e.message}`),e}}}get valueDescriptors(){const{valueDescriptorMap:e}=this;return Object.keys(e).map(t=>e[t])}get valueDescriptorNameMap(){const e={};return Object.keys(this.valueDescriptorMap).forEach(t=>{const s=this.valueDescriptorMap[t];e[s.name]=s}),e}hasValue(e){const t=`has${l(this.valueDescriptorNameMap[e].name)}`;return this.receiver[t]}}class k{constructor(e,t){this.context=e,this.delegate=t,this.targetsByName=new S}start(){this.tokenListObserver||(this.tokenListObserver=new A(this.element,this.attributeName,this),this.tokenListObserver.start())}stop(){this.tokenListObserver&&(this.disconnectAllTargets(),this.tokenListObserver.stop(),delete this.tokenListObserver)}tokenMatched({element:e,content:t}){this.scope.containsElement(e)&&this.connectTarget(e,t)}tokenUnmatched({element:e,content:t}){this.disconnectTarget(e,t)}connectTarget(e,t){var s;this.targetsByName.has(t,e)||(this.targetsByName.add(t,e),null===(s=this.tokenListObserver)||void 0===s||s.pause(()=>this.delegate.targetConnected(e,t)))}disconnectTarget(e,t){var s;this.targetsByName.has(t,e)&&(this.targetsByName.delete(t,e),null===(s=this.tokenListObserver)||void 0===s||s.pause(()=>this.delegate.targetDisconnected(e,t)))}disconnectAllTargets(){for(const e of this.targetsByName.keys)for(const t of this.targetsByName.getValuesForKey(e))this.disconnectTarget(t,e)}get attributeName(){return`data-${this.context.identifier}-target`}get element(){return this.context.element}get scope(){return this.context.scope}}function I(e,t){const s=L(e);return Array.from(s.reduce((e,s)=>(function(e,t){const s=e[t];return Array.isArray(s)?s:[]}(s,t).forEach(t=>e.add(t)),e),new Set))}function L(e){const t=[];for(;e;)t.push(e),e=Object.getPrototypeOf(e);return t.reverse()}class _{constructor(e,t){this.started=!1,this.context=e,this.delegate=t,this.outletsByName=new S,this.outletElementsByName=new S,this.selectorObserverMap=new Map,this.attributeObserverMap=new Map}start(){this.started||(this.outletDefinitions.forEach(e=>{this.setupSelectorObserverForOutlet(e),this.setupAttributeObserverForOutlet(e)}),this.started=!0,this.dependentContexts.forEach(e=>e.refresh()))}refresh(){this.selectorObserverMap.forEach(e=>e.refresh()),this.attributeObserverMap.forEach(e=>e.refresh())}stop(){this.started&&(this.started=!1,this.disconnectAllOutlets(),this.stopSelectorObservers(),this.stopAttributeObservers())}stopSelectorObservers(){this.selectorObserverMap.size>0&&(this.selectorObserverMap.forEach(e=>e.stop()),this.selectorObserverMap.clear())}stopAttributeObservers(){this.attributeObserverMap.size>0&&(this.attributeObserverMap.forEach(e=>e.stop()),this.attributeObserverMap.clear())}selectorMatched(e,t,{outletName:s}){const n=this.getOutlet(e,s);n&&this.connectOutlet(n,e,s)}selectorUnmatched(e,t,{outletName:s}){const n=this.getOutletFromMap(e,s);n&&this.disconnectOutlet(n,e,s)}selectorMatchElement(e,{outletName:t}){const s=this.selector(t),n=this.hasOutlet(e,t),i=e.matches(`[${this.schema.controllerAttribute}~=${t}]`);return!!s&&n&&i&&e.matches(s)}elementMatchedAttribute(e,t){const s=this.getOutletNameFromOutletAttributeName(t);s&&this.updateSelectorObserverForOutlet(s)}elementAttributeValueChanged(e,t){const s=this.getOutletNameFromOutletAttributeName(t);s&&this.updateSelectorObserverForOutlet(s)}elementUnmatchedAttribute(e,t){const s=this.getOutletNameFromOutletAttributeName(t);s&&this.updateSelectorObserverForOutlet(s)}connectOutlet(e,t,s){var n;this.outletElementsByName.has(s,t)||(this.outletsByName.add(s,e),this.outletElementsByName.add(s,t),null===(n=this.selectorObserverMap.get(s))||void 0===n||n.pause(()=>this.delegate.outletConnected(e,t,s)))}disconnectOutlet(e,t,s){var n;this.outletElementsByName.has(s,t)&&(this.outletsByName.delete(s,e),this.outletElementsByName.delete(s,t),null===(n=this.selectorObserverMap.get(s))||void 0===n||n.pause(()=>this.delegate.outletDisconnected(e,t,s)))}disconnectAllOutlets(){for(const e of this.outletElementsByName.keys)for(const t of this.outletElementsByName.getValuesForKey(e))for(const s of this.outletsByName.getValuesForKey(e))this.disconnectOutlet(s,t,e)}updateSelectorObserverForOutlet(e){const t=this.selectorObserverMap.get(e);t&&(t.selector=this.selector(e))}setupSelectorObserverForOutlet(e){const t=this.selector(e),s=new C(document.body,t,this,{outletName:e});this.selectorObserverMap.set(e,s),s.start()}setupAttributeObserverForOutlet(e){const t=this.attributeNameForOutletName(e),s=new w(this.scope.element,t,this);this.attributeObserverMap.set(e,s),s.start()}selector(e){return this.scope.outlets.getSelectorForOutletName(e)}attributeNameForOutletName(e){return this.scope.schema.outletAttributeForScope(this.identifier,e)}getOutletNameFromOutletAttributeName(e){return this.outletDefinitions.find(t=>this.attributeNameForOutletName(t)===e)}get outletDependencies(){const e=new S;return this.router.modules.forEach(t=>{I(t.definition.controllerConstructor,"outlets").forEach(s=>e.add(s,t.identifier))}),e}get outletDefinitions(){return this.outletDependencies.getKeysForValue(this.identifier)}get dependentControllerIdentifiers(){return this.outletDependencies.getValuesForKey(this.identifier)}get dependentContexts(){const e=this.dependentControllerIdentifiers;return this.router.contexts.filter(t=>e.includes(t.identifier))}hasOutlet(e,t){return!!this.getOutlet(e,t)||!!this.getOutletFromMap(e,t)}getOutlet(e,t){return this.application.getControllerForElementAndIdentifier(e,t)}getOutletFromMap(e,t){return this.outletsByName.getValuesForKey(t).find(t=>t.element===e)}get scope(){return this.context.scope}get schema(){return this.context.schema}get identifier(){return this.context.identifier}get application(){return this.context.application}get router(){return this.application.router}}class P{constructor(e,t){this.logDebugActivity=(e,t={})=>{const{identifier:s,controller:n,element:i}=this;t=Object.assign({identifier:s,controller:n,element:i},t),this.application.logDebugActivity(this.identifier,e,t)},this.module=e,this.scope=t,this.controller=new e.controllerConstructor(this),this.bindingObserver=new x(this,this.dispatcher),this.valueObserver=new M(this,this.controller),this.targetObserver=new k(this,this),this.outletObserver=new _(this,this);try{this.controller.initialize(),this.logDebugActivity("initialize")}catch(e){this.handleError(e,"initializing controller")}}connect(){this.bindingObserver.start(),this.valueObserver.start(),this.targetObserver.start(),this.outletObserver.start();try{this.controller.connect(),this.logDebugActivity("connect")}catch(e){this.handleError(e,"connecting controller")}}refresh(){this.outletObserver.refresh()}disconnect(){try{this.controller.disconnect(),this.logDebugActivity("disconnect")}catch(e){this.handleError(e,"disconnecting controller")}this.outletObserver.stop(),this.targetObserver.stop(),this.valueObserver.stop(),this.bindingObserver.stop()}get application(){return this.module.application}get identifier(){return this.module.identifier}get schema(){return this.application.schema}get dispatcher(){return this.application.dispatcher}get element(){return this.scope.element}get parentElement(){return this.element.parentElement}handleError(e,t,s={}){const{identifier:n,controller:i,element:r}=this;s=Object.assign({identifier:n,controller:i,element:r},s),this.application.handleError(e,`Error ${t}`,s)}targetConnected(e,t){this.invokeControllerMethod(`${t}TargetConnected`,e)}targetDisconnected(e,t){this.invokeControllerMethod(`${t}TargetDisconnected`,e)}outletConnected(e,t,s){this.invokeControllerMethod(`${c(s)}OutletConnected`,e,t)}outletDisconnected(e,t,s){this.invokeControllerMethod(`${c(s)}OutletDisconnected`,e,t)}invokeControllerMethod(e,...t){const s=this.controller;"function"==typeof s[e]&&s[e](...t)}}const N="function"==typeof Object.getOwnPropertySymbols?e=>[...Object.getOwnPropertyNames(e),...Object.getOwnPropertySymbols(e)]:Object.getOwnPropertyNames,F=(()=>{function e(e){function t(){return Reflect.construct(e,arguments,new.target)}return t.prototype=Object.create(e.prototype,{constructor:{value:t}}),Reflect.setPrototypeOf(t,e),t}try{return function(){const t=e(function(){this.a.call(this)});t.prototype.a=function(){},new t}(),e}catch(e){return e=>class extends e{}}})();class D{constructor(e,t){this.application=e,this.definition=function(e){return{identifier:e.identifier,controllerConstructor:(t=e.controllerConstructor,function(e,t){const s=F(e),n=function(e,t){return N(t).reduce((s,n)=>{const i=function(e,t,s){const n=Object.getOwnPropertyDescriptor(e,s);if(!n||!("value"in n)){const e=Object.getOwnPropertyDescriptor(t,s).value;return n&&(e.get=n.get||e.get,e.set=n.set||e.set),e}}(e,t,n);return i&&Object.assign(s,{[n]:i}),s},{})}(e.prototype,t);return Object.defineProperties(s.prototype,n),s}(t,function(e){return I(e,"blessings").reduce((t,s)=>{const n=s(e);for(const e in n){const s=t[e]||{};t[e]=Object.assign(s,n[e])}return t},{})}(t)))};var t}(t),this.contextsByScope=new WeakMap,this.connectedContexts=new Set}get identifier(){return this.definition.identifier}get controllerConstructor(){return this.definition.controllerConstructor}get contexts(){return Array.from(this.connectedContexts)}connectContextForScope(e){const t=this.fetchContextForScope(e);this.connectedContexts.add(t),t.connect()}disconnectContextForScope(e){const t=this.contextsByScope.get(e);t&&(this.connectedContexts.delete(t),t.disconnect())}fetchContextForScope(e){let t=this.contextsByScope.get(e);return t||(t=new P(this,e),this.contextsByScope.set(e,t)),t}}class R{constructor(e){this.scope=e}has(e){return this.data.has(this.getDataKey(e))}get(e){return this.getAll(e)[0]}getAll(e){return(this.data.get(this.getDataKey(e))||"").match(/[^\s]+/g)||[]}getAttributeName(e){return this.data.getAttributeNameForKey(this.getDataKey(e))}getDataKey(e){return`${e}-class`}get data(){return this.scope.data}}class j{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get(e){const t=this.getAttributeNameForKey(e);return this.element.getAttribute(t)}set(e,t){const s=this.getAttributeNameForKey(e);return this.element.setAttribute(s,t),this.get(e)}has(e){const t=this.getAttributeNameForKey(e);return this.element.hasAttribute(t)}delete(e){if(this.has(e)){const t=this.getAttributeNameForKey(e);return this.element.removeAttribute(t),!0}return!1}getAttributeNameForKey(e){return`data-${this.identifier}-${h(e)}`}}class B{constructor(e){this.warnedKeysByObject=new WeakMap,this.logger=e}warn(e,t,s){let n=this.warnedKeysByObject.get(e);n||(n=new Set,this.warnedKeysByObject.set(e,n)),n.has(t)||(n.add(t),this.logger.warn(s,e))}}function $(e,t){return`[${e}~="${t}"]`}class V{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce((e,t)=>e||this.findTarget(t)||this.findLegacyTarget(t),void 0)}findAll(...e){return e.reduce((e,t)=>[...e,...this.findAllTargets(t),...this.findAllLegacyTargets(t)],[])}findTarget(e){const t=this.getSelectorForTargetName(e);return this.scope.findElement(t)}findAllTargets(e){const t=this.getSelectorForTargetName(e);return this.scope.findAllElements(t)}getSelectorForTargetName(e){return $(this.schema.targetAttributeForScope(this.identifier),e)}findLegacyTarget(e){const t=this.getLegacySelectorForTargetName(e);return this.deprecate(this.scope.findElement(t),e)}findAllLegacyTargets(e){const t=this.getLegacySelectorForTargetName(e);return this.scope.findAllElements(t).map(t=>this.deprecate(t,e))}getLegacySelectorForTargetName(e){const t=`${this.identifier}.${e}`;return $(this.schema.targetAttribute,t)}deprecate(e,t){if(e){const{identifier:s}=this,n=this.schema.targetAttribute,i=this.schema.targetAttributeForScope(s);this.guide.warn(e,`target:${t}`,`Please replace ${n}="${s}.${t}" with ${i}="${t}". The ${n} attribute is deprecated and will be removed in a future version of Stimulus.`)}return e}get guide(){return this.scope.guide}}class q{constructor(e,t){this.scope=e,this.controllerElement=t}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce((e,t)=>e||this.findOutlet(t),void 0)}findAll(...e){return e.reduce((e,t)=>[...e,...this.findAllOutlets(t)],[])}getSelectorForOutletName(e){const t=this.schema.outletAttributeForScope(this.identifier,e);return this.controllerElement.getAttribute(t)}findOutlet(e){const t=this.getSelectorForOutletName(e);if(t)return this.findElement(t,e)}findAllOutlets(e){const t=this.getSelectorForOutletName(e);return t?this.findAllElements(t,e):[]}findElement(e,t){return this.scope.queryElements(e).filter(s=>this.matchesElement(s,e,t))[0]}findAllElements(e,t){return this.scope.queryElements(e).filter(s=>this.matchesElement(s,e,t))}matchesElement(e,t,s){const n=e.getAttribute(this.scope.schema.controllerAttribute)||"";return e.matches(t)&&n.split(" ").includes(s)}}class U{constructor(e,t,s,n){this.targets=new V(this),this.classes=new R(this),this.data=new j(this),this.containsElement=e=>e.closest(this.controllerSelector)===this.element,this.schema=e,this.element=t,this.identifier=s,this.guide=new B(n),this.outlets=new q(this.documentScope,t)}findElement(e){return this.element.matches(e)?this.element:this.queryElements(e).find(this.containsElement)}findAllElements(e){return[...this.element.matches(e)?[this.element]:[],...this.queryElements(e).filter(this.containsElement)]}queryElements(e){return Array.from(this.element.querySelectorAll(e))}get controllerSelector(){return $(this.schema.controllerAttribute,this.identifier)}get isDocumentScope(){return this.element===document.documentElement}get documentScope(){return this.isDocumentScope?this:new U(this.schema,document.documentElement,this.identifier,this.guide.logger)}}class z{constructor(e,t,s){this.element=e,this.schema=t,this.delegate=s,this.valueListObserver=new E(this.element,this.controllerAttribute,this),this.scopesByIdentifierByElement=new WeakMap,this.scopeReferenceCounts=new WeakMap}start(){this.valueListObserver.start()}stop(){this.valueListObserver.stop()}get controllerAttribute(){return this.schema.controllerAttribute}parseValueForToken(e){const{element:t,content:s}=e;return this.parseValueForElementAndIdentifier(t,s)}parseValueForElementAndIdentifier(e,t){const s=this.fetchScopesByIdentifierForElement(e);let n=s.get(t);return n||(n=this.delegate.createScopeForElementAndIdentifier(e,t),s.set(t,n)),n}elementMatchedValue(e,t){const s=(this.scopeReferenceCounts.get(t)||0)+1;this.scopeReferenceCounts.set(t,s),1==s&&this.delegate.scopeConnected(t)}elementUnmatchedValue(e,t){const s=this.scopeReferenceCounts.get(t);s&&(this.scopeReferenceCounts.set(t,s-1),1==s&&this.delegate.scopeDisconnected(t))}fetchScopesByIdentifierForElement(e){let t=this.scopesByIdentifierByElement.get(e);return t||(t=new Map,this.scopesByIdentifierByElement.set(e,t)),t}}class W{constructor(e){this.application=e,this.scopeObserver=new z(this.element,this.schema,this),this.scopesByIdentifier=new S,this.modulesByIdentifier=new Map}get element(){return this.application.element}get schema(){return this.application.schema}get logger(){return this.application.logger}get controllerAttribute(){return this.schema.controllerAttribute}get modules(){return Array.from(this.modulesByIdentifier.values())}get contexts(){return this.modules.reduce((e,t)=>e.concat(t.contexts),[])}start(){this.scopeObserver.start()}stop(){this.scopeObserver.stop()}loadDefinition(e){this.unloadIdentifier(e.identifier);const t=new D(this.application,e);this.connectModule(t);const s=e.controllerConstructor.afterLoad;s&&s.call(e.controllerConstructor,e.identifier,this.application)}unloadIdentifier(e){const t=this.modulesByIdentifier.get(e);t&&this.disconnectModule(t)}getContextForElementAndIdentifier(e,t){const s=this.modulesByIdentifier.get(t);if(s)return s.contexts.find(t=>t.element==e)}proposeToConnectScopeForElementAndIdentifier(e,t){const s=this.scopeObserver.parseValueForElementAndIdentifier(e,t);s?this.scopeObserver.elementMatchedValue(s.element,s):console.error(`Couldn't find or create scope for identifier: "${t}" and element:`,e)}handleError(e,t,s){this.application.handleError(e,t,s)}createScopeForElementAndIdentifier(e,t){return new U(this.schema,e,t,this.logger)}scopeConnected(e){this.scopesByIdentifier.add(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.connectContextForScope(e)}scopeDisconnected(e){this.scopesByIdentifier.delete(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.disconnectContextForScope(e)}connectModule(e){this.modulesByIdentifier.set(e.identifier,e),this.scopesByIdentifier.getValuesForKey(e.identifier).forEach(t=>e.connectContextForScope(t))}disconnectModule(e){this.modulesByIdentifier.delete(e.identifier),this.scopesByIdentifier.getValuesForKey(e.identifier).forEach(t=>e.disconnectContextForScope(t))}}const H={controllerAttribute:"data-controller",actionAttribute:"data-action",targetAttribute:"data-target",targetAttributeForScope:e=>`data-${e}-target`,outletAttributeForScope:(e,t)=>`data-${e}-${t}-outlet`,keyMappings:Object.assign(Object.assign({enter:"Enter",tab:"Tab",esc:"Escape",space:" ",up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",home:"Home",end:"End",page_up:"PageUp",page_down:"PageDown"},K("abcdefghijklmnopqrstuvwxyz".split("").map(e=>[e,e]))),K("0123456789".split("").map(e=>[e,e])))};function K(e){return e.reduce((e,[t,s])=>Object.assign(Object.assign({},e),{[t]:s}),{})}class G{constructor(e=document.documentElement,t=H){this.logger=console,this.debug=!1,this.logDebugActivity=(e,t,s={})=>{this.debug&&this.logFormattedMessage(e,t,s)},this.element=e,this.schema=t,this.dispatcher=new i(this),this.router=new W(this),this.actionDescriptorFilters=Object.assign({},r)}static start(e,t){const s=new this(e,t);return s.start(),s}async start(){await new Promise(e=>{"loading"==document.readyState?document.addEventListener("DOMContentLoaded",()=>e()):e()}),this.logDebugActivity("application","starting"),this.dispatcher.start(),this.router.start(),this.logDebugActivity("application","start")}stop(){this.logDebugActivity("application","stopping"),this.dispatcher.stop(),this.router.stop(),this.logDebugActivity("application","stop")}register(e,t){this.load({identifier:e,controllerConstructor:t})}registerActionOption(e,t){this.actionDescriptorFilters[e]=t}load(e,...t){(Array.isArray(e)?e:[e,...t]).forEach(e=>{e.controllerConstructor.shouldLoad&&this.router.loadDefinition(e)})}unload(e,...t){(Array.isArray(e)?e:[e,...t]).forEach(e=>this.router.unloadIdentifier(e))}get controllers(){return this.router.contexts.map(e=>e.controller)}getControllerForElementAndIdentifier(e,t){const s=this.router.getContextForElementAndIdentifier(e,t);return s?s.controller:null}handleError(e,t,s){var n;this.logger.error("%s\n\n%o\n\n%o",t,e,s),null===(n=window.onerror)||void 0===n||n.call(window,t,"",0,0,e)}logFormattedMessage(e,t,s={}){s=Object.assign({application:this},s),this.logger.groupCollapsed(`${e} #${t}`),this.logger.log("details:",Object.assign({},s)),this.logger.groupEnd()}}function J(e,t,s){return e.application.getControllerForElementAndIdentifier(t,s)}function Y(e,t,s){let n=J(e,t,s);return n||(e.application.router.proposeToConnectScopeForElementAndIdentifier(t,s),n=J(e,t,s),n||void 0)}function Z([e,t],s){return function(e){const{token:t,typeDefinition:s}=e,n=`${h(t)}-value`,i=function(e){const{controller:t,token:s,typeDefinition:n}=e,i=function(e){const{controller:t,token:s,typeObject:n}=e,i=u(n.type),r=u(n.default),a=i&&r,o=i&&!r,c=!i&&r,l=X(n.type),h=Q(e.typeObject.default);if(o)return l;if(c)return h;if(l!==h)throw new Error(`The specified default value for the Stimulus Value "${t?`${t}.${s}`:s}" must match the defined type "${l}". The provided default value of "${n.default}" is of type "${h}".`);return a?l:void 0}({controller:t,token:s,typeObject:n}),r=Q(n),a=X(n),o=i||r||a;if(o)return o;throw new Error(`Unknown value type "${t?`${t}.${n}`:s}" for "${s}" value`)}(e);return{type:i,key:n,name:o(n),get defaultValue(){return function(e){const t=X(e);if(t)return ee[t];const s=d(e,"default"),n=d(e,"type"),i=e;if(s)return i.default;if(n){const{type:e}=i,t=X(e);if(t)return ee[t]}return e}(s)},get hasCustomDefaultValue(){return void 0!==Q(s)},reader:te[i],writer:se[i]||se.default}}({controller:s,token:e,typeDefinition:t})}function X(e){switch(e){case Array:return"array";case Boolean:return"boolean";case Number:return"number";case Object:return"object";case String:return"string"}}function Q(e){switch(typeof e){case"boolean":return"boolean";case"number":return"number";case"string":return"string"}return Array.isArray(e)?"array":"[object Object]"===Object.prototype.toString.call(e)?"object":void 0}const ee={get array(){return[]},boolean:!1,number:0,get object(){return{}},string:""},te={array(e){const t=JSON.parse(e);if(!Array.isArray(t))throw new TypeError(`expected value of type "array" but instead got value "${e}" of type "${Q(t)}"`);return t},boolean:e=>!("0"==e||"false"==String(e).toLowerCase()),number:e=>Number(e.replace(/_/g,"")),object(e){const t=JSON.parse(e);if(null===t||"object"!=typeof t||Array.isArray(t))throw new TypeError(`expected value of type "object" but instead got value "${e}" of type "${Q(t)}"`);return t},string:e=>e},se={default:function(e){return`${e}`},array:ne,object:ne};function ne(e){return JSON.stringify(e)}class ie{constructor(e){this.context=e}static get shouldLoad(){return!0}static afterLoad(e,t){}get application(){return this.context.application}get scope(){return this.context.scope}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get targets(){return this.scope.targets}get outlets(){return this.scope.outlets}get classes(){return this.scope.classes}get data(){return this.scope.data}initialize(){}connect(){}disconnect(){}dispatch(e,{target:t=this.element,detail:s={},prefix:n=this.identifier,bubbles:i=!0,cancelable:r=!0}={}){const a=new CustomEvent(n?`${n}:${e}`:e,{detail:s,bubbles:i,cancelable:r});return t.dispatchEvent(a),a}}ie.blessings=[function(e){return I(e,"classes").reduce((e,t)=>{return Object.assign(e,(s=t,{[`${s}Class`]:{get(){const{classes:e}=this;if(e.has(s))return e.get(s);{const t=e.getAttributeName(s);throw new Error(`Missing attribute "${t}"`)}}},[`${s}Classes`]:{get(){return this.classes.getAll(s)}},[`has${l(s)}Class`]:{get(){return this.classes.has(s)}}}));var s},{})},function(e){return I(e,"targets").reduce((e,t)=>{return Object.assign(e,(s=t,{[`${s}Target`]:{get(){const e=this.targets.find(s);if(e)return e;throw new Error(`Missing target element "${s}" for "${this.identifier}" controller`)}},[`${s}Targets`]:{get(){return this.targets.findAll(s)}},[`has${l(s)}Target`]:{get(){return this.targets.has(s)}}}));var s},{})},function(e){const t=function(e,t){return L(e).reduce((e,s)=>(e.push(...function(e,t){const s=e[t];return s?Object.keys(s).map(e=>[e,s[e]]):[]}(s,t)),e),[])}(e,"values"),s={valueDescriptorMap:{get(){return t.reduce((e,t)=>{const s=Z(t,this.identifier),n=this.data.getAttributeNameForKey(s.key);return Object.assign(e,{[n]:s})},{})}}};return t.reduce((e,t)=>Object.assign(e,function(e){const t=Z(e,void 0),{key:s,name:n,reader:i,writer:r}=t;return{[n]:{get(){const e=this.data.get(s);return null!==e?i(e):t.defaultValue},set(e){void 0===e?this.data.delete(s):this.data.set(s,r(e))}},[`has${l(n)}`]:{get(){return this.data.has(s)||t.hasCustomDefaultValue}}}}(t)),s)},function(e){return I(e,"outlets").reduce((e,t)=>Object.assign(e,function(e){const t=c(e);return{[`${t}Outlet`]:{get(){const t=this.outlets.find(e),s=this.outlets.getSelectorForOutletName(e);if(t){const s=Y(this,t,e);if(s)return s;throw new Error(`The provided outlet element is missing an outlet controller "${e}" instance for host controller "${this.identifier}"`)}throw new Error(`Missing outlet element "${e}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${s}".`)}},[`${t}Outlets`]:{get(){const t=this.outlets.findAll(e);return t.length>0?t.map(t=>{const s=Y(this,t,e);if(s)return s;console.warn(`The provided outlet element is missing an outlet controller "${e}" instance for host controller "${this.identifier}"`,t)}).filter(e=>e):[]}},[`${t}OutletElement`]:{get(){const t=this.outlets.find(e),s=this.outlets.getSelectorForOutletName(e);if(t)return t;throw new Error(`Missing outlet element "${e}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${s}".`)}},[`${t}OutletElements`]:{get(){return this.outlets.findAll(e)}},[`has${l(t)}Outlet`]:{get(){return this.outlets.has(e)}}}}(t)),{})}],ie.targets=[],ie.outlets=[],ie.values={}},623(e,t,s){s.d(t,{default:()=>tn});var n=s(891);class i extends Error{constructor(e){super(`${e} is not valid. Please provide a valid event name`),this.name="InvalidEvent"}}class r{static events=["session-set","utm-set","forms:collected","form:completed","webchat:mounted","webchat:opened","webchat:closed","webchat:message:sent","webchat:message:received","cart.added"];static valid(e){return r.exists(e)}static invalid(e){return!this.valid(e)}static exists(e){return void 0!==this.events.find(t=>t===e)}constructor(){this.subscribers={}}addSubscriber(e,t){if(r.invalid(e))throw new i(e);this.subscribers={...this.subscribers,[e]:this.subscribers[e]?[...this.subscribers[e],t]:[t]}}removeSubscriber(e,t){if(r.invalid(e))throw new i(e);this.subscribers[e]&&(this.subscribers[e]=this.subscribers[e].filter(e=>e!==t))}dispatch(e,t){this.subscribers[e]?.forEach(e=>{e(t)})}get listeners(){return 0!==Object.keys(this.subscribers).length}}class a{static autoMount=!0;static successMessage=!0;static assign(e){return e&&Object.entries(e).forEach(([e,t])=>{this[e]=t}),this}static get shouldShowSuccessMessage(){return this.successMessage}}class o{static _identifier;static set identifier(e){this._identifier=e}static get identifier(){return this._identifier?this._identifier:this.#e||this.#t||this.#s||"en"}static toString(){return this.identifier}static get#e(){return document?.documentElement?.lang}static get#t(){return document?.querySelector('meta[name="locale"]')?.content}static get#s(){return navigator?.language?.split("-")[0]}}const c={TOP_LEFT:"top-left",TOP_RIGHT:"top-right",BOTTOM_LEFT:"bottom-left",BOTTOM_RIGHT:"bottom-right"},l={ABSOLUTE:"absolute",FIXED:"fixed"},h={MODAL:"modal",POPOVER:"popover"};class u{static _id;static _container="body";static _placement="bottom-right";static _style={};static _appearance={};static _whatsapp={};static _mode=h.POPOVER;static _behaviour=null;static _hasBehaviourOverride=!1;static _strategy=null;static set container(e){this._container=e}static get container(){return this._container}static set placement(e){if(!Object.values(c).includes(e))throw new Error(`Invalid placement value: ${e}`);this._placement=e}static get placement(){return this._placement}static set id(e){this._id=e}static get id(){return this._id}static get isSet(){return!!this._id}static get style(){return this._style}static set style(e){if("object"!=typeof e)throw new Error("Style must be an object");Object.entries(e).forEach(([e,t])=>{if(!["primaryColor","secondaryColor","typography"].includes(e))throw new Error(`Invalid style property: ${e}`);if("typography"!==e&&!this.isHexOrRgba(t))throw new Error(`Invalid color value: ${t} for ${e}. Colors must be hex or rgb/a.`)}),this._style=e}static get appearance(){return this._appearance}static set appearance(e){if(!this.isPlainObject(e))throw new Error("Appearance must be an object");Object.entries(e).forEach(([e,t])=>{if(!["header","launcher"].includes(e))throw new Error(`Invalid appearance property: ${e}`);if(!this.isPlainObject(t))throw new Error(`Appearance ${e} must be an object`);Object.entries(t).forEach(([t,s])=>{if("header"===e&&"name"!==t)throw new Error(`Invalid appearance header property: ${t}`);if("launcher"===e&&"iconUrl"!==t)throw new Error(`Invalid appearance launcher property: ${t}`);if(null!=s&&"string"!=typeof s)throw new Error(`Invalid appearance ${e}.${t} value: ${s}`)})}),this._appearance=e}static get whatsapp(){return this._whatsapp}static set whatsapp(e){if(!this.isPlainObject(e))throw new Error("WhatsApp must be an object");Object.entries(e).forEach(([e,t])=>{if(!["number","restrictToChannel"].includes(e))throw new Error(`Invalid WhatsApp property: ${e}`);if(null!=t){if("number"===e&&"string"!=typeof t)throw new Error(`Invalid WhatsApp number value: ${t}`);if("restrictToChannel"===e&&"boolean"!=typeof t)throw new Error(`Invalid WhatsApp restrictToChannel value: ${t}`)}}),this._whatsapp=e}static get mode(){return this._mode}static set mode(e){if(!Object.values(h).includes(e))throw new Error(`Invalid mode value: ${e}`);this._mode=e}static get behaviour(){return this._behaviour}static set behaviour(e){if(null!=e){if("object"!=typeof e||Array.isArray(e))throw new Error(`Invalid behaviour value: ${e}`);this._behaviour=e}else this._behaviour=e}static get hasBehaviourOverride(){return this._hasBehaviourOverride}static set behaviourOverride(e){this._hasBehaviourOverride=!!e}static get strategy(){return this._strategy?this._strategy:"body"==this.container?l.FIXED:l.ABSOLUTE}static set strategy(e){if(e&&!Object.values(l).includes(e))throw new Error(`Invalid strategy value: ${e}`);this._strategy=e}static assign(e){return e&&Object.entries(e).forEach(([e,t])=>{this[e]=t}),this}static isHexOrRgba(e){return/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(e)||/^rgba?\(\s*\d{1,3},\s*\d{1,3},\s*\d{1,3},?\s*(0|1|0?\.\d+)?\s*\)$/.test(e)}static isPlainObject(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}}const d={TOP_LEFT:"top-left",TOP_RIGHT:"top-right",BOTTOM_LEFT:"bottom-left",BOTTOM_RIGHT:"bottom-right"};class p{static _id;static _container="body";static _placement="bottom-right";static _appearance={};static _number=null;static _body=null;static set id(e){this._id=e}static get id(){return this._id}static set container(e){this._container=e}static get container(){return this._container}static set placement(e){if(!Object.values(d).includes(e))throw new Error(`Invalid placement value: ${e}`);this._placement=e}static get placement(){return this._placement}static get appearance(){return this._appearance}static set appearance(e){if(!this.isPlainObject(e))throw new Error("Appearance must be an object");Object.entries(e).forEach(([e,t])=>{if("launcher"!==e)throw new Error(`Invalid appearance property: ${e}`);if(!this.isPlainObject(t))throw new Error(`Appearance ${e} must be an object`);Object.entries(t).forEach(([t,s])=>{if("iconUrl"!==t)throw new Error(`Invalid appearance launcher property: ${t}`);if(null!=s&&"string"!=typeof s)throw new Error(`Invalid appearance ${e}.${t} value: ${s}`)})}),this._appearance=e}static get number(){return this._number}static set number(e){if(null!=e&&"string"!=typeof e)throw new Error(`Invalid number value: ${e}`);this._number=e}static get body(){return this._body}static set body(e){if(null!=e&&"string"!=typeof e)throw new Error(`Invalid body value: ${e}`);this._body=e}static assign(e){return e&&Object.entries(e).forEach(([e,t])=>{this[e]=t}),this}static isPlainObject(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}}class m{static serviceWorkerUrl=null;static channelId=null;static assign(e){return this.serviceWorkerUrl=e?.serviceWorkerUrl||null,this.channelId=e?.channelId||null,this}}class g{static apiRoot="https://api.hellotext.com/v1";static actionCableUrl="wss://www.hellotext.com/cable";static autoGenerateSession=!0;static session=null;static forms=a;static webchat=u;static whatsapp=p;static push=m;static assign(e){if(e){const t=Object.prototype.hasOwnProperty.call(e,"apiRoot")&&!Object.prototype.hasOwnProperty.call(e,"actionCableUrl");Object.entries(e).forEach(([e,t])=>{"forms"===e?this.forms=a.assign(t):"webchat"===e?this.webchat=u.assign(t):"whatsappWidget"===e?this.whatsapp=p.assign(t):"push"===e?this.push=m.assign(t):this[e]=t}),t&&(this.actionCableUrl=this.actionCableUrlForApiRoot(this.apiRoot))}return this}static set locale(e){o.identifier=e}static get locale(){return o.toString()}static endpoint(e){return`${this.apiRoot}/${e}`}static actionCableUrlForApiRoot(e){try{const t=new URL(e),s="https:"===t.protocol?"wss:":"ws:";return t.protocol=s,t.pathname="/cable",t.search="",t.hash="",t.toString()}catch(e){return this.actionCableUrl}}}const f=class{static get endpoint(){return g.endpoint("public/businesses")}static async get(e){return fetch(`${this.endpoint}/${e}`,{method:"GET",headers:{Authorization:`Bearer ${e}`,Accept:"application/json","Content-Type":"application/json"}})}};class b{static get inPreviewMode(){return(new this).inPreviewMode}constructor(){this.urlSearchParams=new URLSearchParams(window.location.search)}get(e){return this.urlSearchParams.get(this.toHellotextParam(e))}has(e){return this.urlSearchParams.has(this.toHellotextParam(e))}get inPreviewMode(){return this.has("preview")}get session(){return this.get("session")}toHellotextParam(e){return`hello_${e}`}}class y{#n;constructor(e,t){this.response=t,this.#n=e}get data(){return this.response}async json(){return await this.response.json()}get failed(){return!1===this.#n}get succeeded(){return!0===this.#n}}class v{static get endpoint(){return g.endpoint("track/events")}static async create({headers:e,body:t,keepalive:s=!1}){if(b.inPreviewMode)return new y(!0,{received:!0});const n={method:"POST",headers:e,body:JSON.stringify(t)};s&&(n.keepalive=!0);const i=await fetch(this.endpoint,n);return new y(200===i.status,await i.json())}}class w{static get endpoint(){return g.endpoint("public/forms")}static async get(e){const t=new URL(`${this.endpoint}/${e}`);return t.searchParams.append("session",gt.session),t.searchParams.append("locale",o.toString()),fetch(t,{method:"GET",headers:gt.headers})}static async submit(e,t){const s=await fetch(`${this.endpoint}/${e}/submissions`,{method:"POST",headers:gt.headers,body:JSON.stringify({session:gt.session,...t})});return new y(s.ok,s)}}const T=class{static get endpoint(){return g.endpoint("public/identifications")}static async create(e={}){const t=await fetch(this.endpoint,{method:"POST",headers:gt.headers,body:JSON.stringify({session:gt.session,...e})});return new y(t.ok,t)}},S=class{static get endpoint(){return g.endpoint("public/webchats")}static async get(e){const t=new URL(`${this.endpoint}/${e}`);t.searchParams.append("session",gt.session),t.searchParams.append("locale",o.toString()),Object.entries(g.webchat.style).forEach(([e,s])=>{t.searchParams.append(`style[${e}]`,s)}),this.appendWebchatOverrides(t),t.searchParams.append("placement",g.webchat.placement);const s=await fetch(t,{method:"GET",headers:gt.headers}),n=await s.json();return gt.business.data||(gt.business.setData(n.business),gt.business.setLocale(n.locale)),(new DOMParser).parseFromString(n.html,"text/html").querySelector("article")}static appendWebchatOverrides(e){const{appearance:t,whatsapp:s}=g.webchat;this.appendIfSupplied(e,"webchat[appearance][header][name]",t.header?.name),this.appendIfSupplied(e,"webchat[appearance][launcher][icon_url]",t.launcher?.iconUrl),this.appendIfSupplied(e,"webchat[handoff][identifier]",s.number),this.appendIfSupplied(e,"webchat[handoff][restrict_to_channel]",s.restrictToChannel)}static appendIfSupplied(e,t,s){null!=s&&e.searchParams.append(t,String(s))}},C=class{static get endpoint(){return g.endpoint("public/widgets/whatsapp")}static async get(e){const t=new URL(`${this.endpoint}/${e}`);t.searchParams.append("locale",o.toString()),t.searchParams.append("placement",g.whatsapp.placement),this.appendWhatsAppOverrides(t);const s=await this.fetchWidget(t);if(!s.ok)return null;const n=await this.parseWidgetResponse(s);return n?(gt.business.data||(gt.business.setData(n.business),gt.business.setLocale(n.locale)),(new DOMParser).parseFromString(n.html,"text/html").querySelector("article")):null}static appendWhatsAppOverrides(e){const{appearance:t,body:s,number:n}=g.whatsapp;this.appendIfSupplied(e,"whatsapp[appearance][launcher][icon_url]",t.launcher?.iconUrl),this.appendIfSupplied(e,"whatsapp[number]",n),this.appendIfSupplied(e,"whatsapp[body]",s)}static appendIfSupplied(e,t,s){null!=s&&e.searchParams.append(t,String(s))}static async fetchWidget(e){try{return await fetch(e,{method:"GET",headers:gt.headers})}catch(e){return{ok:!1}}}static async parseWidgetResponse(e){try{return await e.json()}catch(e){return null}}},O=class{static get endpoint(){return g.endpoint("public/acks")}static async send(e={}){const t={...e,session:gt.session,at:(new Date).toISOString()};fetch(this.endpoint,{method:"POST",headers:gt.headers,body:JSON.stringify(t),keepalive:!0})}},A=class{static get endpoint(){return g.endpoint("public/push/identities")}static async create(e={}){const t=await fetch(this.endpoint,{method:"POST",keepalive:!0,headers:gt.headers,body:JSON.stringify({...e,session:gt.session,origin:window.location.origin})});return new y(t.ok,t)}static async destroy(e={}){const t=await fetch(this.endpoint,{method:"DELETE",keepalive:!0,headers:gt.headers,body:JSON.stringify({...e,session:gt.session,origin:window.location.origin})});return new y(t.ok,t)}};function E(e){const t=JSON.stringify(e);return"undefined"==typeof Blob?t.length<6e4:new Blob([t]).size<6e4}class x{static get businesses(){return f}static get events(){return v}static get forms(){return w}static get webchats(){return S}static get whatsappWidgets(){return C}static get identifications(){return T}static get acks(){return O}static get pushIdentities(){return A}}const M={en:{white_label:{powered_by:"By"},errors:{parameter_not_unique:"This value is taken.",blank:"This field is required."},forms:{phone:"Click the link sent via SMS to verify your submission.",email:"Click the link sent via email to verify your submission.",phone_and_email:"Click the links sent via SMS and email to verify your submission.",none:"Your submission has been received."}},es:{white_label:{powered_by:"Por"},errors:{parameter_not_unique:"Este valor ya está en uso.",blank:"Este campo es obligatorio."},forms:{phone:"Haga clic en el enlace enviado por SMS para verificar su envío.",email:"Haga clic en el enlace enviado por e-mail para verificar su envío.",phone_and_email:"Haga clic en los enlaces enviados por SMS y e-mail para verificar su envío.",none:"Su envío ha sido recibido."}}},k="data-hellotext-stylesheet";class I{constructor(e){this.id=e,this.data=null,this.stylesheet=null,this.stylesheetLoaded=Promise.resolve(!1)}async hydrate(){try{const e=await f.get(this.id);if(!1===e.ok)return null;const t=await e.json();return t?(this.setData(t),t.locale&&this.setLocale(t.locale),t):null}catch(e){return null}}setData(e){this.data=e,"undefined"!=typeof document&&e.style_url?(this.stylesheet=this.constructor.ensureStylesheet(e.style_url),this.stylesheetLoaded=this.constructor.waitForStylesheet(this.stylesheet)):(this.stylesheet=null,this.stylesheetLoaded=Promise.resolve(!1))}static get stylesheetSelector(){return`link[rel="stylesheet"][${k}]`}static ensureStylesheet(e){const t=this.normalizedStylesheetUrl(e),s=this.stylesheetLinks.find(e=>e.href===t);if(s)return s.setAttribute(k,"true"),s;const n=document.createElement("link");return n.rel="stylesheet",n.href=e,n.setAttribute(k,"true"),this.waitForStylesheet(n),document.head.append(n),n}static get stylesheetLinks(){return"undefined"==typeof document?[]:Array.from(document.querySelectorAll(this.stylesheetSelector))}static get latestStylesheet(){return this.stylesheetLinks[this.stylesheetLinks.length-1]}static normalizedStylesheetUrl(e){try{return new URL(e,document.baseURI).href}catch(t){return e}}static waitForStylesheet(e){return e?this.stylesheetIsLoaded(e)?Promise.resolve(!0):"false"===e.dataset.hellotextStylesheetLoaded?Promise.resolve(!1):(e._hellotextStylesheetLoaded||(e._hellotextStylesheetLoaded=new Promise(t=>{let s;const n=n=>{clearTimeout(s),e.removeEventListener("load",i),e.removeEventListener("error",r),e.dataset.hellotextStylesheetLoaded=n?"true":"false",t(n)},i=()=>n(this.stylesheetIsLoaded(e)),r=()=>n(!1);e.addEventListener("load",i),e.addEventListener("error",r),s=setTimeout(()=>n(this.stylesheetIsLoaded(e)),1e4),s.unref&&s.unref()})),e._hellotextStylesheetLoaded):Promise.resolve(!1)}static stylesheetIsLoaded(e){return"true"===e.dataset.hellotextStylesheetLoaded||!!e.sheet}get subscription(){return this.data.subscription}get country(){return this.data.country}get enabledWhitelist(){return"disabled"!==this.data.whitelist}setLocale(e){if(!M[e])return console.warn(`Locale ${e} not found`);this.data||(this.data={}),this.data.locale=e}get locale(){return M[this.data.locale]}get features(){return this.data.features}}class L{static set(e,t){if("undefined"!=typeof document){const s="https:"===window.location.protocol?"; Secure":"",n=P.getRootDomain(),i=31536e4;document.cookie=n?`${e}=${t}; path=/${s}; domain=${n}; max-age=${i}; SameSite=Lax`:`${e}=${t}; path=/${s}; max-age=${i}; SameSite=Lax`}return"hello_session"===e&>.eventEmitter.dispatch("session-set",t),"hello_utm"===e&>.eventEmitter.dispatch("utm-set",t),t}static get(e){return"undefined"!=typeof document?document.cookie.match("(^|;)\\s*"+e+"\\s*=\\s*([^;]+)")?.pop():void 0}static delete(e){if("undefined"!=typeof document){const t=P.getRootDomain(),s="https:"===window.location.protocol?"; Secure":"";document.cookie=t?`${e}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT${s}; domain=${t}; SameSite=Lax`:`${e}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT${s}; SameSite=Lax`}}}class _{constructor(){const e=new URLSearchParams(window.location.search),t={source:e.get("utm_source"),medium:e.get("utm_medium"),campaign:e.get("utm_campaign"),term:e.get("utm_term"),content:e.get("utm_content")};this.save(t)}save(e){if(!e.source||!e.medium)return;const t=Object.fromEntries(Object.entries(e).filter(([e,t])=>t));t.observed_at=(new Date).toISOString(),L.set("hello_utm",JSON.stringify(t))}get current(){try{return JSON.parse(L.get("hello_utm"))||{}}catch(e){return{}}}}class P{constructor(e=null){this.utm=new _,this._url=e}get url(){return null!==this._url&&void 0!==this._url?this._url:window.location.href}get title(){return document.title}get path(){if(this._url)try{return new URL(this._url).pathname}catch(e){return"/"}return window.location.pathname}get utmParams(){return this.utm.current}get trackingData(){return{page:{url:this.url,title:this.title,path:this.path},utm_params:this.utmParams}}get domain(){try{const e=this.url;if(!e)return null;const t=new URL(e).hostname;return P.getRootDomain(t)}catch(e){return null}}static getRootDomain(e=null){try{if(!e){if("undefined"==typeof window||!window.location?.hostname)return null;e=window.location.hostname}const t=e.split(".");if(t.length<=1)return e;const s=["myshopify.com","vtexcommercestable.com.br","myvtex.com","wixsite.com"];for(const e of s){const s=e.split(".");if(t.slice(-s.length).join(".")===e&&t.length>s.length)return`.${t.slice(-(s.length+1)).join(".")}`}const n=t[t.length-1],i=t[t.length-2];return t.length>2&&2===n.length&&i.length<=3?`.${t.slice(-3).join(".")}`:`.${t.slice(-2).join(".")}`}catch(e){return null}}}class N{static#i;static#r;static#a;static get session(){return this.#i}static get ackPayload(){return{utm_params:this.#a?.utmParams||{}}}static set session(e){const t=L.get("hello_session");return this.#i=e,L.set("hello_session",e),t!==e&&L.delete("hello_session_ack_at"),L.get("hello_session_ack_at")||(x.acks.send(this.ackPayload),L.set("hello_session_ack_at",(new Date).toISOString())),this.#i}static initialize(e=new P){this.#a=e,this.#r=new b,this.session=this.#r.session||g.session||L.get("hello_session"),!this.session&&g.autoGenerateSession&&(this.session=crypto.randomUUID())}}class F{static build(e){const t=document.createElement("article"),s=document.createElement("label"),n=document.createElement("input");s.innerText=e.label,n.type=e.type,n.required=e.required,n.placeholder=e.placeholder,["first_name","last_name"].includes(e.kind)?(n.type="text",n.id=n.name=e.kind,s.setAttribute("for",e.kind)):(n.type=e.type,"email"===e.type?(n.id=n.name="email",s.setAttribute("for","email")):"tel"===n.type?(n.id=n.name="phone",s.setAttribute("for","phone"),n.value=`+${gt.business.country.prefix}`,n.setAttribute("data-default-value",`+${gt.business.country.prefix}`)):(n.name=n.id=`property_by_id[${e.property}]`,s.setAttribute("for",`property_by_id[${e.property}]`)));const i=document.createElement("main");i.appendChild(s),i.appendChild(n),t.appendChild(i),t.setAttribute("data-hellotext--form-target","inputContainer"),n.setAttribute("data-hellotext--form-target","input");const r=document.createElement("div");return r.setAttribute("data-error-container",""),t.appendChild(r),t}}class D{static build(){const e=document.createElement("div");return e.innerHTML=this.#o(),e.firstElementChild}static#o(){const e=`https://www.hellotext.com?hello_session=${gt.session}`;return`\n
\n ${gt.business.locale.white_label.powered_by}\n\n \n \n Hellotext\n \n \n \n
\n `}}function R(e,t){(null==t||t>e.length)&&(t=e.length);for(var s=0,n=Array(t);s2?s-2:0),i=2;i1?t-1:0),n=1;n1?s-1:0),i=1;i2&&void 0!==arguments[2]?arguments[2]:se;if($&&$(e,null),!te(t))return e;let n=t.length;for(;n--;){let i=t[n];if("string"==typeof i){const e=s(i);e!==i&&(V(t)||(t[n]=e),i=e)}e[i]=!0}return e}function ve(e){for(let t=0;t/g),Fe=W(/\${[\w\W]*/g),De=W(/^data-[\-\w.\u00B7-\uFFFF]+$/),Re=W(/^aria-[\-\w]+$/),je=W(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),Be=W(/^(?:\w+script|data):/i),$e=W(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),Ve=W(/^html$/i),qe=W(/^[a-z][.\w]*(-[.\w]+)+$/i),Ue=W(/<[/\w!]/g),ze=W(/<[/\w]/g),We=W(/<\/no(script|embed|frames)/i),He=W(/\/>/i),Ke=["style","script","xmp","iframe","noembed","noframes","plaintext","noscript"],Ge=z(ye({},Ke)),Je=function(){const e={};return Y(Ke,t=>{e[t]=W(new RegExp("])","i"))}),z(e)}(),Ye=function(){return"undefined"==typeof window?null:window},Ze=function(e,t,s,n){return de(e,t)&&te(e[t])?ye(n.base?we(n.base):{},e[t],n.transform):s},Xe=function(e,t,s){const n=de(e,t)?e[t]:void 0;return n&&"object"==typeof n?we(n):s()};var Qe=function e(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Ye();const s=t=>e(t);if(s.version="3.4.14",s.removed=[],!t||!t.document||9!==t.document.nodeType||!t.Element)return s.isSupported=!1,s;let n=t.document;const i=n,r=i.currentScript;t.DocumentFragment;const a=t.HTMLTemplateElement,o=t.Node,c=t.Element,l=t.NodeFilter;void 0===t.NamedNodeMap&&(t.NamedNodeMap||t.MozNamedAttrMap),t.HTMLFormElement;const h=t.DOMParser,u=t.trustedTypes,d=c.prototype,p=Te(d,"cloneNode"),m=Te(d,"remove"),g=Te(d,"nextSibling"),f=Te(d,"childNodes"),b=Te(d,"parentNode"),y=Te(d,"shadowRoot"),v=Te(d,"attributes"),w=o&&o.prototype?Te(o.prototype,"nodeType"):null,T=o&&o.prototype?Te(o.prototype,"nodeName"):null,S=o&&o.prototype?Te(o.prototype,"ownerDocument"):null,C=function(e){return w?w(e):e.nodeType},O=function(e){return T?T(e):e.nodeName};if("function"==typeof a){const e=n.createElement("template");e.content&&e.content.ownerDocument&&(n=e.content.ownerDocument)}let A,E,x="",M=!1,k=0;const I=function(){if(k>0)throw ge('A configured TRUSTED_TYPES_POLICY callback (createHTML or createScriptURL) must not call DOMPurify.sanitize, as that causes infinite recursion. Do not pass a policy whose callbacks wrap DOMPurify as TRUSTED_TYPES_POLICY; see the "DOMPurify and Trusted Types" section of the README.')},L=function(e){I(),k++;try{return A.createHTML(e)}finally{k--}},_=n,P=_.implementation,N=_.createNodeIterator,F=_.createDocumentFragment,D=_.getElementsByTagName,R=i.importNode;let j={afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]};s.isSupported="function"==typeof B&&"function"==typeof b&&P&&void 0!==P.createHTMLDocument;const $=Pe,V=Ne,q=Fe,U=De,K=Re,G=Be,J=$e,fe=qe;let be=je,ve=null;const Ke=ye({},[...Se,...Ce,...Oe,...Ee,...Me]);let Qe=null;const et=ye({},[...ke,...Ie,...Le,..._e]);let tt=Object.seal(H(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),st=null,nt=null;const it=Object.seal(H(null,{tagCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeCheck:{writable:!0,configurable:!1,enumerable:!0,value:null}}));let rt=!0,at=!0,ot=!1,ct=!0,lt=!1,ht=!0,ut=!1,dt=!1,pt=null,mt=null,gt=!1,ft=!1,bt=!1,yt=!1,vt=!0,wt=!1;const Tt="user-content-";let St=!0,Ct=!1,Ot={},At=null;const Et=ye({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","selectedcontent","style","svg","template","thead","title","video","xmp"]);let xt=null;const Mt=ye({},["audio","video","img","source","image","track"]);let kt=null;const It=ye({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Lt="http://www.w3.org/1998/Math/MathML",_t="http://www.w3.org/2000/svg",Pt="http://www.w3.org/1999/xhtml";let Nt=Pt,Ft=!1,Dt=null;const Rt=ye({},[Lt,_t,Pt],ne),jt=z(["mi","mo","mn","ms","mtext"]);let Bt=ye({},jt);const $t=z(["annotation-xml"]);let Vt=ye({},$t);const qt=ye({},["title","style","font","a","script"]);let Ut=null;const zt=["application/xhtml+xml","text/html"];let Wt=null,Ht=null;const Kt=n.createElement("form"),Gt=function(e){return e instanceof RegExp||e instanceof Function},Jt=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(Ht&&Ht===e)return;e&&"object"==typeof e||(e={}),e=we(e),Ut=-1===zt.indexOf(e.PARSER_MEDIA_TYPE)?"text/html":e.PARSER_MEDIA_TYPE,Wt="application/xhtml+xml"===Ut?ne:se,ve=Ze(e,"ALLOWED_TAGS",Ke,{transform:Wt}),Qe=Ze(e,"ALLOWED_ATTR",et,{transform:Wt}),Dt=Ze(e,"ALLOWED_NAMESPACES",Rt,{transform:ne}),kt=Ze(e,"ADD_URI_SAFE_ATTR",It,{transform:Wt,base:It}),xt=Ze(e,"ADD_DATA_URI_TAGS",Mt,{transform:Wt,base:Mt}),At=Ze(e,"FORBID_CONTENTS",Et,{transform:Wt}),st=Ze(e,"FORBID_TAGS",we({}),{transform:Wt}),nt=Ze(e,"FORBID_ATTR",we({}),{transform:Wt}),Ot=!!de(e,"USE_PROFILES")&&(e.USE_PROFILES&&"object"==typeof e.USE_PROFILES?we(e.USE_PROFILES):e.USE_PROFILES),rt=!1!==e.ALLOW_ARIA_ATTR,at=!1!==e.ALLOW_DATA_ATTR,ot=e.ALLOW_UNKNOWN_PROTOCOLS||!1,ct=!1!==e.ALLOW_SELF_CLOSE_IN_ATTR,lt=e.SAFE_FOR_TEMPLATES||!1,ht=!1!==e.SAFE_FOR_XML,ut=e.WHOLE_DOCUMENT||!1,ft=e.RETURN_DOM||!1,bt=e.RETURN_DOM_FRAGMENT||!1,yt=e.RETURN_TRUSTED_TYPE||!1,gt=e.FORCE_BODY||!1,vt=!1!==e.SANITIZE_DOM,wt=e.SANITIZE_NAMED_PROPS||!1,St=!1!==e.KEEP_CONTENT,Ct=e.IN_PLACE||!1,be=function(e){try{return me(e,""),!0}catch(e){return!1}}(e.ALLOWED_URI_REGEXP)?e.ALLOWED_URI_REGEXP:je,Nt="string"==typeof e.NAMESPACE?e.NAMESPACE:Pt,Bt=Xe(e,"MATHML_TEXT_INTEGRATION_POINTS",()=>ye({},jt)),Vt=Xe(e,"HTML_INTEGRATION_POINTS",()=>ye({},$t));const t=Xe(e,"CUSTOM_ELEMENT_HANDLING",()=>H(null));if(tt=H(null),de(t,"tagNameCheck")&&Gt(t.tagNameCheck)&&(tt.tagNameCheck=t.tagNameCheck),de(t,"attributeNameCheck")&&Gt(t.attributeNameCheck)&&(tt.attributeNameCheck=t.attributeNameCheck),de(t,"allowCustomizedBuiltInElements")&&"boolean"==typeof t.allowCustomizedBuiltInElements&&(tt.allowCustomizedBuiltInElements=t.allowCustomizedBuiltInElements),W(tt),lt&&(at=!1),bt&&(ft=!0),Ot&&(ve=ye({},Me),Qe=H(null),!0===Ot.html&&(ye(ve,Se),ye(Qe,ke)),!0===Ot.svg&&(ye(ve,Ce),ye(Qe,Ie),ye(Qe,_e)),!0===Ot.svgFilters&&(ye(ve,Oe),ye(Qe,Ie),ye(Qe,_e)),!0===Ot.mathMl&&(ye(ve,Ee),ye(Qe,Le),ye(Qe,_e))),it.tagCheck=null,it.attributeCheck=null,de(e,"ADD_TAGS")&&("function"==typeof e.ADD_TAGS?it.tagCheck=e.ADD_TAGS:te(e.ADD_TAGS)&&(ve===Ke&&(ve=we(ve)),ye(ve,e.ADD_TAGS,Wt))),de(e,"ADD_ATTR")&&("function"==typeof e.ADD_ATTR?it.attributeCheck=e.ADD_ATTR:te(e.ADD_ATTR)&&(Qe===et&&(Qe=we(Qe)),ye(Qe,e.ADD_ATTR,Wt))),de(e,"ADD_FORBID_CONTENTS")&&te(e.ADD_FORBID_CONTENTS)&&(At===Et&&(At=we(At)),ye(At,e.ADD_FORBID_CONTENTS,Wt)),St&&(ve["#text"]=!0),ut&&ye(ve,["html","head","body"]),ve.table&&(ye(ve,["tbody"]),delete st.tbody),e.TRUSTED_TYPES_POLICY){if("function"!=typeof e.TRUSTED_TYPES_POLICY.createHTML)throw ge('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof e.TRUSTED_TYPES_POLICY.createScriptURL)throw ge('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');const t=A;A=e.TRUSTED_TYPES_POLICY;try{x=L("")}catch(e){throw A=t,e}}else null===e.TRUSTED_TYPES_POLICY?(A=void 0,x=""):(void 0===A&&(M||(E=function(e,t){if("object"!=typeof e||"function"!=typeof e.createPolicy)return null;let s=null;const n="data-tt-policy-suffix";t&&t.hasAttribute(n)&&(s=t.getAttribute(n));const i="dompurify"+(s?"#"+s:"");try{return e.createPolicy(i,{createHTML:e=>e,createScriptURL:e=>e})}catch(e){return console.warn("TrustedTypes policy "+i+" could not be created."),null}}(u,r),M=!0),A=E),A&&"string"==typeof x&&(x=L("")));z&&z(e),Ht=e},Yt=ye({},[...Ce,...Oe,...Ae]),Zt=ye({},[...Ee,...xe]),Xt=function(e){Q(s.removed,{element:e});try{b(e).removeChild(e)}catch(t){if(m(e),!b(e))throw ge("a node selected for removal could not be detached from its tree and cannot be safely returned; refusing to sanitize in place")}},Qt=function(e,t,s){try{e.removeAttributeNode(t)}catch(t){try{e.removeAttribute(s)}catch(e){}}},es=function(e){ns(e);const t=f(e);if(t){const e=[];Y(t,t=>{Q(e,t)}),Y(e,e=>{try{m(e)}catch(e){}})}const s=v(e);if(s)for(let t=s.length-1;t>=0;--t){const n=s[t],i=n&&n.name;"string"==typeof i&&Qt(e,n,i)}},ts=function(e,t,n){if(!n)try{n=t.getAttributeNode(e)}catch(e){n=null}Q(s.removed,{attribute:n||null,from:t});try{n?t.removeAttributeNode(n):t.removeAttribute(e)}catch(s){try{t.removeAttribute(e)}catch(e){}}if("is"===e)if(ft||bt)try{Xt(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},ss=function(e){const t=v(e);if(t)for(let s=t.length-1;s>=0;--s){const n=t[s],i=n&&n.name;"string"!=typeof i||Qe[Wt(i)]||Qt(e,n,i)}},ns=function(e){const t=[e];for(;t.length>0;){const e=t.pop();1===C(e)&&ss(e);const s=f(e);if(s)for(let e=s.length-1;e>=0;--e)t.push(s[e])}},is=function(e,t){return!!ht&&("patchsrc"===e||"for"===e&&"label"!==t&&"output"!==t)},rs=function(e){let t=null,s=null;if(gt)e=""+e;else{const t=ie(e,/^[\r\n\t ]+/);s=t&&t[0]}"application/xhtml+xml"===Ut&&Nt===Pt&&(e=''+e+"");const i=A?L(e):e;if(Nt===Pt)try{t=(new h).parseFromString(i,Ut)}catch(e){}if(!t||!t.documentElement){t=P.createDocument(Nt,"template",null);try{t.documentElement.innerHTML=Ft?x:i}catch(e){}}const r=t.body||t.documentElement;return e&&s&&r.insertBefore(n.createTextNode(s),r.childNodes[0]||null),Nt===Pt?D.call(t,ut?"html":"body")[0]:ut?t.documentElement:r},as=function(e){const t=S?S(e):e.ownerDocument;return N.call(t||e,e,l.SHOW_ELEMENT|l.SHOW_COMMENT|l.SHOW_TEXT|l.SHOW_PROCESSING_INSTRUCTION|l.SHOW_CDATA_SECTION,null)},os=function(e){return e=re(e,$," "),e=re(e,V," "),re(e,q," ")},cs=function(e){var t;e.normalize();const s=S?S(e):e.ownerDocument,n=N.call(s||e,e,l.SHOW_TEXT|l.SHOW_COMMENT|l.SHOW_CDATA_SECTION|l.SHOW_PROCESSING_INSTRUCTION,null);let i=n.nextNode();for(;i;)i.data=os(i.data),i=n.nextNode();const r=null===(t=e.querySelectorAll)||void 0===t?void 0:t.call(e,"template");r&&Y(r,e=>{hs(e.content)&&cs(e.content)})},ls=function(e){const t=T?T(e):null;return"string"==typeof t&&"form"===Wt(t)&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||e.attributes!==v(e)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore||"function"!=typeof e.hasChildNodes||e.nodeType!==w(e)||e.childNodes!==f(e))},hs=function(e){if(!w||"object"!=typeof e||null===e)return!1;try{return 11===w(e)}catch(e){return!1}},us=function(e){if(!w||"object"!=typeof e||null===e)return!1;try{return"number"==typeof w(e)}catch(e){return!1}};function ds(e,t,n){0!==e.length&&Y(e,e=>{e.call(s,t,n,Ht)})}const ps=function(e,t){if(e instanceof RegExp)return me(e,t);if(e instanceof Function){for(var s=arguments.length,n=new Array(s>2?s-2:0),i=2;i=0;--i){const r=e===s?p(n[i],!0):n[i];t.insertBefore(r,g(e))}}return Xt(e),!0}(e,n,t);return!1===s&&ds(j.afterSanitizeElements,e,null),s}if(1===C(e)&&!function(e){let t=b(e);t&&t.tagName||(t={namespaceURI:Nt,tagName:"template"});const s=se(e.tagName),n=se(t.tagName);return!!Dt[e.namespaceURI]&&(e.namespaceURI===_t?function(e,t,s){return t.namespaceURI===Pt?"svg"===e:t.namespaceURI===Lt?"svg"===e&&("annotation-xml"===s||Bt[s]):Boolean(Yt[e])}(s,t,n):e.namespaceURI===Lt?function(e,t,s){return t.namespaceURI===Pt?"math"===e:t.namespaceURI===_t?"math"===e&&Vt[s]:Boolean(Zt[e])}(s,t,n):e.namespaceURI===Pt?function(e,t,s){return!(t.namespaceURI===_t&&!Vt[s])&&!(t.namespaceURI===Lt&&!Bt[s])&&!Zt[e]&&(qt[e]||!Yt[e])}(s,t,n):!("application/xhtml+xml"!==Ut||!Dt[e.namespaceURI]))}(e))return Xt(e),!0;if(("noscript"===n||"noembed"===n||"noframes"===n)&&me(We,e.innerHTML))return Xt(e),!0;if(lt&&3===e.nodeType){const t=os(e.textContent);e.textContent!==t&&(Q(s.removed,{element:e.cloneNode()}),e.textContent=t)}return ds(j.afterSanitizeElements,e,null),!1},bs=function(e,t,s){if(nt[t])return!1;if(is(t,e))return!1;if(vt&&("id"===t||"name"===t)&&(s in n||s in Kt))return!1;const i=Qe[t]||it.attributeCheck instanceof Function&&it.attributeCheck(t,e);return!(!at||!me(U,t))||!(!rt||!me(K,t))||(i?!(!kt[t]&&!me(be,re(s,J,""))&&("src"!==t&&"xlink:href"!==t&&"href"!==t||"script"===e||0!==ae(s,"data:")||!xt[e])&&(!ot||me(G,re(s,J,"")))&&s):vs(e)&&ps(tt.tagNameCheck,e)&&ps(tt.attributeNameCheck,t,e)||"is"===t&&tt.allowCustomizedBuiltInElements&&ps(tt.tagNameCheck,s))},ys=ye({},["annotation-xml","color-profile","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","missing-glyph"]),vs=function(e){return!ys[se(e)]&&me(fe,e)},ws=function(e,t,s,n){if(A&&"object"==typeof u&&"function"==typeof u.getAttributeType&&!s)switch(u.getAttributeType(e,t)){case"TrustedHTML":return L(n);case"TrustedScriptURL":return function(e){I(),k++;try{return A.createScriptURL(e)}finally{k--}}(n)}return n},Ts=function(e,t,n,i){try{n?e.setAttributeNS(n,t,i):e.setAttribute(t,i),ls(e)?Xt(e):X(s.removed)}catch(s){ts(t,e)}},Ss=function(e){ds(j.beforeSanitizeAttributes,e,null);const t=e.attributes;if(!t||ls(e))return;Qe=ms(j.uponSanitizeAttribute,Qe,et,mt);const s={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:Qe,forceKeepAttr:void 0};let n=t.length;const i=Wt(e.nodeName);for(;n--;){const r=t[n],a=r.name,o=r.namespaceURI,c=r.value,l=Wt(a),h=c;let u="value"===a?h:oe(h);s.attrName=l,s.attrValue=u,s.keepAttr=!0,s.forceKeepAttr=void 0,ds(j.uponSanitizeAttribute,e,s),u=s.attrValue,!wt||"id"!==l&&"name"!==l||0===ae(u,Tt)||(ts(a,e,r),u=Tt+u),ht&&me(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i,u)||"attributename"===l&&ie(u,"href")?ts(a,e,r):s.forceKeepAttr||(!s.keepAttr||!ct&&me(He,u)?ts(a,e,r):(lt&&(u=os(u)),bs(i,l,u)?(u=ws(i,l,o,u),u!==h&&Ts(e,a,o,u)):ts(a,e,r)))}ds(j.afterSanitizeAttributes,e,null)},Cs=function(e){let t=null;const s=as(e);for(ds(j.beforeSanitizeShadowDOM,e,null);t=s.nextNode();)if(ds(j.uponSanitizeShadowNode,t,null),fs(t,e),Ss(t),hs(t.content)&&Cs(t.content),1===C(t)){const e=y(t);hs(e)&&(Os(e),Cs(e))}ds(j.afterSanitizeShadowDOM,e,null)},Os=function(e){const t=[{node:e,shadow:null}];for(;t.length>0;){const e=t.pop();if(e.shadow){Cs(e.shadow);continue}const s=e.node,n=1===C(s),i=f(s);if(i)for(let e=i.length-1;e>=0;--e)t.push({node:i[e],shadow:null});if(n){const e=T?T(s):null;if("string"==typeof e&&"template"===Wt(e)){const e=s.content;hs(e)&&t.push({node:e,shadow:null})}}if(n){const e=y(s);hs(e)&&t.push({node:null,shadow:e},{node:e,shadow:null})}}};return s.sanitize=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=null,r=null,a=null,o=null;if(Ft=!e,Ft&&(e="\x3c!--\x3e"),"string"!=typeof e&&!us(e)&&"string"!=typeof(e=function(e){switch(typeof e){case"string":return e;case"number":return ce(e);case"boolean":return le(e);case"bigint":return he?he(e):"0";case"symbol":return ue?ue(e):"Symbol()";case"undefined":default:return pe(e);case"function":case"object":{if(null===e)return pe(e);const t=e,s=Te(t,"toString");if("function"==typeof s){const e=s(t);return"string"==typeof e?e:pe(e)}return pe(e)}}}(e)))throw ge("dirty is not a string, aborting");if(!s.isSupported)return e;dt?(ve=pt,Qe=mt):Jt(t),(j.uponSanitizeElement.length>0||j.uponSanitizeAttribute.length>0)&&(ve=we(ve)),j.uponSanitizeAttribute.length>0&&(Qe=we(Qe)),s.removed=[];const c=Ct&&"string"!=typeof e&&us(e);if(c){!function(e){if(!ht)return;const t=[e];for(;t.length>0;){const e=t.pop(),s=C(e);if(7===s||8===s&&me(ze,e.data)){try{m(e)}catch(e){}continue}if(1===s){const t=e,s=Wt(O(e));try{t.hasAttribute&&t.hasAttribute("patchsrc")&&t.removeAttribute("patchsrc"),t.hasAttribute&&t.hasAttribute("for")&&is("for",s)&&t.removeAttribute("for")}catch(e){}}const n=f(e);if(n)for(let e=n.length-1;e>=0;--e)t.push(n[e])}}(e);const t=O(e);if("string"==typeof t){const s=Wt(t);if(!ve[s]||st[s])throw es(e),ge("root node is forbidden and cannot be sanitized in-place")}if(ls(e))throw es(e),ge("root node is clobbered and cannot be sanitized in-place");try{Os(e)}catch(t){throw es(e),t}}else if(us(e))n=rs("\x3c!----\x3e"),r=n.ownerDocument.importNode(e,!0),1===r.nodeType&&"BODY"===r.nodeName||"HTML"===r.nodeName?n=r:n.appendChild(r),Os(r);else{if(!ft&&!lt&&!ut&&-1===e.indexOf("<"))return A&&yt?L(e):e;if(n=rs(e),!n)return ft?null:yt?x:""}n&>&&Xt(n.firstChild);const l=c?e:n;try{const e=as(l);for(;a=e.nextNode();)fs(a,l),Ss(a),hs(a.content)&&Cs(a.content)}catch(t){throw c&&(es(e),Y(s.removed,e=>{e.element&&ns(e.element)})),t}if(c)return Y(s.removed,e=>{e.element&&ns(e.element)}),lt&&cs(e),e;if(ft){if(lt&&cs(n),bt)for(o=F.call(n.ownerDocument);n.firstChild;)o.appendChild(n.firstChild);else o=n;return(Qe.shadowroot||Qe.shadowrootmode)&&(o=R.call(i,o,!0)),o}let h=ut?n.outerHTML:n.innerHTML;return ut&&ve["!doctype"]&&n.ownerDocument&&n.ownerDocument.doctype&&n.ownerDocument.doctype.name&&me(Ve,n.ownerDocument.doctype.name)&&(h="\n"+h),lt&&(h=os(h)),A&&yt?L(h):h},s.setConfig=function(){Jt(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),dt=!0,pt=ve,mt=Qe},s.clearConfig=function(){Ht=null,dt=!1,pt=null,mt=null,A=E,x=""},s.isValidAttribute=function(e,t,s){Ht||Jt({});const n=Wt(e),i=Wt(t);return bs(n,i,s)},s.addHook=function(e,t){"function"==typeof t&&de(j,e)&&Q(j[e],t)},s.removeHook=function(e,t){if(de(j,e)){if(void 0!==t){const s=Z(j[e],t);return-1===s?void 0:ee(j[e],s,1)[0]}return X(j[e])}},s.removeHooks=function(e){de(j,e)&&(j[e]=[])},s.removeAllHooks=function(){j={afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}},s}();const et={ADD_ATTR:["target"],ALLOW_DATA_ATTR:!1,RETURN_DOM_FRAGMENT:!0,USE_PROFILES:{html:!0}},tt={ADD_ATTR:["target"],ADD_TAGS:["hellotext-icon"],RETURN_DOM_FRAGMENT:!0,USE_PROFILES:{html:!0,svg:!0}};function st(e,t){const s=Qe.sanitize(e,t);return s.querySelectorAll('a[target="_blank"]').forEach(e=>{const t=new Set(e.rel.split(/\s+/).filter(Boolean));t.add("noopener"),t.add("noreferrer"),e.rel=Array.from(t).join(" ")}),s}function nt(e,t){e.replaceChildren(function(e){return st(e,et)}(t))}class it{constructor(e,t=null){this.data=e,this.element=t||document.querySelector(`[data-hello-form="${this.id}"]`)||document.createElement("form")}async mount({ifCompleted:e=!0}={}){if(e&&this.hasBeenCompleted)return this.element?.remove(),gt.eventEmitter.dispatch("form:completed",{id:this.id,...JSON.parse(localStorage.getItem(`hello-form-${this.id}`))});const t=this.data.steps[0];this.buildHeader(t.header),this.buildInputs(t.inputs),this.buildButton(t.button),this.buildFooter(t.footer),this.elementAttributes.forEach(e=>{this.element.setAttribute(e.name,e.value)}),document.contains(this.element)||document.body.appendChild(this.element),gt.business.features.white_label||this.element.prepend(D.build())}buildHeader(e){const t=this.#c("[data-form-header]","header");nt(t,e.content),this.element.querySelector("[data-form-header]")?this.element.querySelector("[data-form-header]").replaceWith(t):this.element.prepend(t)}buildInputs(e){const t=this.#c("[data-form-inputs]","main");e.map(e=>F.build(e)).forEach(e=>t.appendChild(e)),this.element.querySelector("[data-form-inputs]")?this.element.querySelector("[data-form-inputs]").replaceWith(t):this.element.querySelector("[data-form-header]").insertAdjacentHTML("afterend",t.outerHTML)}buildButton(e){const t=this.#c("[data-form-button]","button");t.innerText=e.text,t.setAttribute("data-action","click->hellotext--form#submit"),t.setAttribute("data-hellotext--form-target","button"),this.element.querySelector("[data-form-button]")?this.element.querySelector("[data-form-button]").replaceWith(t):this.element.querySelector("[data-form-inputs]").insertAdjacentHTML("afterend",t.outerHTML)}buildFooter(e){const t=this.#c("[data-form-footer]","footer");nt(t,e.content),this.element.querySelector("[data-form-footer]")?this.element.querySelector("[data-form-footer]").replaceWith(t):this.element.appendChild(t)}markAsCompleted(e){const t={state:"completed",id:this.id,data:e,completedAt:(new Date).getTime()};localStorage.setItem(`hello-form-${this.id}`,JSON.stringify(t)),gt.eventEmitter.dispatch("form:completed",t)}get hasBeenCompleted(){return null!==localStorage.getItem(`hello-form-${this.id}`)}get id(){return this.data.id}get localeAuthKey(){const e=this.data.steps[0];return e.inputs.some(e=>"email"===e.kind)&&e.inputs.some(e=>"phone"===e.kind)?"phone_and_email":e.inputs.some(e=>"email"===e.kind)?"email":e.inputs.some(e=>"phone"===e.kind)?"phone":"none"}get elementAttributes(){return[{name:"data-controller",value:"hellotext--form"},{name:"data-hello-form",value:this.id},{name:"data-hellotext--form-data-value",value:JSON.stringify(this.data)}]}#c(e,t){const s=this.element.querySelector(e);if(s)return s.cloneNode(!0);const n=document.createElement(t);return n.setAttribute(e.replace("[","").replace("]",""),""),n}}class rt extends Error{constructor(){super("You need to initialize before tracking events. Call Hellotext.initialize and pass your public business id"),this.name="NotInitializedError"}}class at{constructor(){this.forms=[],this.includes=this.includes.bind(this),this.excludes=this.excludes.bind(this),this.add=this.add.bind(this),"undefined"!=typeof MutationObserver&&(this.mutationObserver=new MutationObserver(this.formMutationObserver.bind(this)),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0}))}collectExistingFormsOnPage(){Array.from(document.querySelectorAll("[data-hello-form]")).length>0&&this.collect()}formMutationObserver(e){e.find(e=>"childList"===e.type&&e.addedNodes.length>0)&&Array.from(document.querySelectorAll("[data-hello-form]")).length>0&&this.collect()}async collect(){if(gt.notInitialized)throw new rt;if(this.fetching)return;if("undefined"==typeof document||!("querySelectorAll"in document))return console.warn("Document is not defined, collection is not possible. Please make sure to initialize the library after the document is loaded.");const e=this.#l;if(0===e.length)return;const t=e.map(e=>w.get(e).then(e=>e.json()));this.fetching=!0,await Promise.all(t).then(e=>e.forEach(this.add)).then(()=>gt.eventEmitter.dispatch("forms:collected",this)).then(()=>this.fetching=!1),g.forms.autoMount&&this.forms.forEach(e=>e.mount())}forEach(e){this.forms.forEach(e)}map(e){return this.forms.map(e)}add(e){this.includes(e.id)||(gt.business.data||(gt.business.setData(e.business),gt.business.setLocale(o.toString())),gt.business.enabledWhitelist||console.warn("No whitelist has been configured. It is advised to whitelist the domain to avoid bots from submitting forms."),this.forms.push(new it(e)))}getById(e){return this.forms.find(t=>t.id===e)}getByIndex(e){return this.forms[e]}includes(e){return this.forms.some(t=>t.id===e)}excludes(e){return!this.includes(e)}get length(){return this.forms.length}get#l(){return Array.from(document.querySelectorAll("[data-hello-form]")).map(e=>e.dataset.helloForm).filter(this.excludes)}}class ot{constructor(e){this.publicKey=e.public_key,this.serviceWorkerUrl=g.push.serviceWorkerUrl,this.channelId=g.push.channelId,this.ready=null,this.registrationPromise=null,this.subscribePromise=null,this.unsubscribePromise=null,this.syncPromise=null,this.subscription=null,this.retryTimeout=null,this.retryAttempts=0,this.disposed=!1}initialize(){return this.ready=this.restoreSubscription(),this.ready}async restoreSubscription(){const e=await this.getRegistration(),t=await e.pushManager.getSubscription();!this.disposed&&!this.unsubscribePromise&&t&&this.owns(t)&&(this.subscription=t,await this.sync())}subscribe(){if(this.disposed)return Promise.resolve();if(this.unsubscribePromise)return Promise.reject(new Error("Push unsubscribe is in progress"));if(this.subscribePromise)return this.subscribePromise;const e="default"===Notification.permission?Notification.requestPermission():Promise.resolve(Notification.permission);return this.subscribePromise=this.createSubscription(e).finally(()=>{this.subscribePromise=null}),this.subscribePromise}async createSubscription(e){if("granted"!==await e)throw new Error("Push permission was not granted");const t=await this.getRegistration();if(this.disposed)return;let s=await t.pushManager.getSubscription();if(!this.disposed){if(s&&!this.owns(s))throw new Error("The existing Push subscription belongs to a different application");if(s||=await t.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:this.applicationServerKey}),!this.disposed)return this.subscription=s,this.sync()}}unsubscribe(){return this.disposed?Promise.resolve():(this.unsubscribePromise||(this.clearRetryTimeout(),this.unsubscribePromise=this.removeSubscription().finally(()=>{this.unsubscribePromise=null})),this.unsubscribePromise)}async removeSubscription(){await(this.ready?.catch(()=>{})),await(this.subscribePromise?.catch(()=>{})),await(this.syncPromise?.catch(()=>{}));const e=await this.getRegistration(),t=await e.pushManager.getSubscription()||this.subscription;if(this.disposed)return;if(!t)return null;if(!this.owns(t))throw new Error("The existing Push subscription belongs to a different application");this.subscription=t;const s=await x.pushIdentities.destroy({subscription:t.toJSON()});return s.failed?s:this.disposed?void 0:(await t.unsubscribe(),this.subscription=null,this.clearRetryTimeout(),s)}sync(){return this.disposed?Promise.resolve():(this.syncPromise||(this.clearRetryTimeout(),this.syncPromise=this.registerIdentity().finally(()=>{this.syncPromise=null})),this.syncPromise)}async registerIdentity(){try{const e=await x.pushIdentities.create({subscription:this.subscription.toJSON(),...this.channelId?{channel_id:this.channelId}:{}});return e.succeeded?this.retryAttempts=0:this.scheduleRetry(),e}catch(e){throw this.scheduleRetry(),e}}scheduleRetry(){this.disposed||this.unsubscribePromise||this.retryTimeout||this.retryAttempts>=3||(this.retryTimeout=setTimeout(()=>{this.retryTimeout=null,this.sync().catch(()=>{})},1e3*2**this.retryAttempts),this.retryAttempts+=1)}clearRetryTimeout(){clearTimeout(this.retryTimeout),this.retryTimeout=null}dispose(){this.disposed=!0,this.clearRetryTimeout()}get subscribed(){return!!this.subscription}get applicationServerKey(){const e=this.publicKey.replace(/-/g,"+").replace(/_/g,"/");return Uint8Array.from(atob(e.padEnd(4*Math.ceil(e.length/4),"=")),e=>e.charCodeAt(0))}owns(e){const t=e.options?.applicationServerKey;if(!t)return!1;const s=new Uint8Array(t),n=this.applicationServerKey;return s.length===n.length&&s.every((e,t)=>e===n[t])}getRegistration(){return this.registrationPromise||(this.registrationPromise=this.loadRegistration().catch(e=>{throw this.registrationPromise=null,e})),this.registrationPromise}async loadRegistration(){if(this.serviceWorkerUrl){const e=await navigator.serviceWorker.register(this.serviceWorkerUrl);!e.active||e.installing||e.waiting||await e.update();const t=e.installing||e.waiting||e.active;return"activated"===t?.state?e:new Promise((s,n)=>{const i=setTimeout(()=>r(new Error("Push service worker did not become active")),1e4),r=r=>{clearTimeout(i),t?.removeEventListener("statechange",a),r?n(r):s(e)},a=()=>{"activated"===t?.state&&r(),"redundant"===t?.state&&r(new Error("Push service worker installation failed"))};t?.addEventListener("statechange",a),a()})}return new Promise((e,t)=>{const s=setTimeout(()=>t(new Error("Push service worker is not available")),1e4);navigator.serviceWorker.ready.then(t=>{clearTimeout(s),e(t)},e=>{clearTimeout(s),t(e)})})}static get supported(){return"undefined"!=typeof window&&!0===window.isSecureContext&&"undefined"!=typeof navigator&&"serviceWorker"in navigator&&"undefined"!=typeof PushManager&&"undefined"!=typeof Notification}}class ct{static async load(e){const t=new ct({id:e,html:await x.webchats.get(e)});return t.rendered=t.render(),t}constructor(e){this.data=e,this.mounted=!1,this.rendered=Promise.resolve(!1)}async render(){return this.applyBehaviourOverride(),await this.stylesheetLoaded?(this.containerToAppendTo.appendChild(this.data.html),this.markCoexistingWidgets(),this.mounted=!0,!0):(console.warn("Hellotext webchat was not mounted because its stylesheet failed to load."),!1)}applyBehaviourOverride(){g.webchat.hasBehaviourOverride&&g.webchat.behaviour&&this.data.html.setAttribute("data-hellotext--webchat-behaviour-value",JSON.stringify(this.serializedBehaviour))}get serializedBehaviour(){const e=g.webchat.behaviour;return{trigger:this.serializeTrigger(e.trigger),delay_seconds:e.delaySeconds,first_visit_only:e.firstVisitOnly,once_per_session:e.oncePerSession}}serializeTrigger(e){return"onLoad"===e?"on_load":"onClick"===e?"on_click":e}get containerToAppendTo(){return document.querySelector(g.webchat.container)}get stylesheetLoaded(){return I.waitForStylesheet(I.latestStylesheet)}markCoexistingWidgets(){const e=this.data.html,t=document.querySelector(".hellotext--whatsapp-widget");e&&t&&(e.classList.add("hellotext--with-whatsapp-widget"),t.classList.add("hellotext--with-webchat"))}}class lt{static async load(e){const t=new lt({id:e,html:await x.whatsappWidgets.get(e)});return t.rendered=t.render(),t}constructor(e){this.data=e,this.mounted=!1,this.rendered=Promise.resolve(!1)}async render(){if(!this.data.html)return!1;const e=this.containerToAppendTo;return e?await this.stylesheetLoaded?(e.appendChild(this.data.html),this.markCoexistingWidgets(),this.mounted=!0,!0):(console.warn("Hellotext WhatsApp widget was not mounted because its stylesheet failed to load."),!1):(console.warn(`Hellotext WhatsApp widget was not mounted because the container ${g.whatsapp.container} was not found.`),!1)}get containerToAppendTo(){try{return document.querySelector(g.whatsapp.container)}catch(e){return null}}get stylesheetLoaded(){return I.waitForStylesheet(I.latestStylesheet)}markCoexistingWidgets(){const e=document.querySelector(".hellotext--webchat:not(.hellotext--whatsapp-widget)"),t=this.data.html;e&&t&&(e.classList.add("hellotext--with-whatsapp-widget"),t.classList.add("hellotext--with-webchat"))}}class ht{static get id(){return L.get("hello_user_id")}static get source(){return L.get("hello_user_source")}static get fingerprint(){return L.get("hello_user_identification_hash")}static remember(e,t,s){t&&L.set("hello_user_source",t),s&&L.set("hello_user_identification_hash",s),L.set("hello_user_id",e)}static forget(){L.delete("hello_user_id"),L.delete("hello_user_source"),L.delete("hello_user_identification_hash")}static get identificationData(){return this.id?{id:this.id,source:this.source}:{}}}function ut(e){if(null!=e){if("string"==typeof e){const t=e.trim();return""===t?void 0:t}if(Array.isArray(e))return e.map(e=>ut(e)).filter(e=>void 0!==e);if(e instanceof Date)return e.toISOString();if("object"==typeof e){const t=Object.keys(e).sort((e,t)=>e.localeCompare(t)).reduce((t,s)=>{const n=ut(e[s]);return void 0!==n&&(t[s]=n),t},{});return Object.keys(t).length>0?t:void 0}return"number"==typeof e||"boolean"==typeof e?e:void 0}}function dt(e,t,s={}){const n=ut({session:e,user_id:t,...s})||{};return JSON.stringify(n)}class pt{static matches(e,t){return!!e&&e===t}static async generate(e,t,s={}){return await async function(e){if(!globalThis.crypto?.subtle||"undefined"==typeof TextEncoder)return function(e){let t=5381;for(let s=0;s>>0).toString(16)}`}(e);const t=await globalThis.crypto.subtle.digest("SHA-256",(new TextEncoder).encode(e));return`v1:${Array.from(new Uint8Array(t)).map(e=>e.toString(16).padStart(2,"0")).join("")}`}(dt(e,t,s))}}class mt{static eventEmitter=new r;static forms;static business;static webchat;static whatsapp;static push;static async initialize(e,t={}){this.push?.dispose(),this.push=null,this.business=new I(e),this.page=new P,g.assign({push:{},...t}),N.initialize(this.page),this.forms=new at,this.query=new b;const s=await this.business.hydrate();!1!==t.push&&s?.push?.public_key&&ot.supported&&(this.push=new ot(s.push),this.push.initialize().catch(e=>{console.warn("Hellotext Push initialization failed:",e)}));const n=!1!==t.webchat&&this.mergeWebchatConfig(s&&s.webchat||{},t.webchat||{}),i=!1!==t.whatsappWidget&&this.mergeWhatsAppConfig(s&&s.whatsapp||{},t.whatsappWidget||{}),r=t.webchat&&!1!==t.webchat&&Object.prototype.hasOwnProperty.call(t.webchat,"behaviour");g.webchat.behaviourOverride=r,n&&n.id&&(g.webchat.assign(n),this.webchat=await ct.load(n.id)),i&&i.id&&(g.whatsapp.assign(i),this.whatsapp=await lt.load(i.id)),"undefined"!=typeof MutationObserver&&this.forms.collectExistingFormsOnPage()}static mergeWebchatConfig(e,t){return this.deepMergePlainObjects(e,t)}static mergeWhatsAppConfig(e,t){return this.deepMergePlainObjects(e,t)}static deepMergePlainObjects(e,t){const s={...e};return Object.entries(t).forEach(([e,t])=>{this.isPlainObject(t)&&this.isPlainObject(s[e])?s[e]=this.deepMergePlainObjects(s[e],t):s[e]=t}),s}static isPlainObject(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}static async track(e,t={}){if(this.notInitialized)throw new rt;const s={...t&&t.headers||{},...this.headers},n={...ht.identificationData,...t.user_parameters||{}},i=t&&t.url?new P(t.url):this.page,r={session:this.session,user_parameters:n,action:e,...t,...i.trackingData};return delete r.headers,await x.events.create({headers:s,body:r,keepalive:E(r)})}static async identify(e,t={}){const s=await pt.generate(this.session,e,t);if(pt.matches(ht.fingerprint,s))return new y(!0,{json:async()=>({already_identified:!0})});const n=await x.identifications.create({user_id:e,...t});return n.succeeded&&ht.remember(e,t.source,s),n}static forget(){ht.forget()}static on(e,t){this.eventEmitter.addSubscriber(e,t)}static removeEventListener(e,t){this.eventEmitter.removeSubscriber(e,t)}static get session(){return N.session}static get isInitialized(){return void 0!==N.session}static get notInitialized(){return!this.business||void 0===this.business.id}static get headers(){if(this.notInitialized)throw new rt;return{Authorization:`Bearer ${this.business.id}`,Accept:"application/json","Content-Type":"application/json"}}}const gt=mt,ft=class extends n.xI{static values={data:Object,step:{type:Number,default:1}};static targets=["inputContainer","input","button","otpContainer"];initialize(){this.form=new it(this.dataValue,this.element)}connect(){super.connect(),this.element.addEventListener("submit",this.submit.bind(this)),"INPUT"!==document.activeElement.tagName&&this.inputTargets[0].focus()}async submit(e){if(e.preventDefault(),this.invalid)return this.showErrorMessages();this.clearErrorMessages(),this.formData=Object.fromEntries(new FormData(this.element)),this.buttonTarget.disabled=!0;const t=await w.submit(this.form.id,this.formData);this.buttonTarget.disabled=!1;const s=await t.json();if(t.failed)return s.errors.forEach(e=>{const{type:t,parameter:s}=e,n=this.inputTargets.find(e=>e.name===s);n.setCustomValidity(gt.business.locale.errors[t]),n.reportValidity(),n.addEventListener("input",()=>{n.setCustomValidity(""),n.reportValidity()})}),this.showErrorMessages();this.buttonTarget.style.display="none",this.element.querySelectorAll("input").forEach(e=>e.disabled=!0),this.completed()}completed(){if(this.form.markAsCompleted(this.formData),!g.forms.shouldShowSuccessMessage)return this.element.remove();"string"==typeof g.forms.successMessage?this.element.innerHTML=g.forms.successMessage:this.element.innerHTML=gt.business.locale.forms[this.form.localeAuthKey]}showErrorMessages(){this.inputTargets.forEach(e=>{const t=e.closest("article").querySelector("[data-error-container]");e.validity.valid?t.innerText="":t.innerText=e.validationMessage})}clearErrorMessages(){this.inputTargets.forEach(e=>{e.setCustomValidity(""),e.closest("article").querySelector("[data-error-container]").innerText=""})}inputTargetConnected(e){e.getAttribute("data-default-value")&&(e.value=e.getAttribute("data-default-value"))}get requiredInputs(){return this.inputTargets.filter(e=>e.required)}get invalid(){return!this.element.checkValidity()}},bt=class extends n.xI{static values={fadeDistance:{type:Number,default:64},id:String,kind:String,pageStartOffset:{type:Number,default:0},utm:Object};static targets=["carouselContainer","leftFade","rightFade","carouselCard"];connect(){this.updateFades(),this.observeContainerSize()}disconnect(){this.resizeObserver?.disconnect()}setId({detail:e}){this.idValue=e,this.element.id=e}onScroll(){this.updateFades()}quickReply({currentTarget:e}){const t=e.closest('[data-hellotext--message-target="carouselCard"]'),s=e.closest('[data-controller~="hellotext--message"]'),n=e.dataset.text||e.textContent.trim();this.dispatch("quickReply",{detail:{id:this.idValue,product:t?.dataset.id,buttonId:e.dataset.id,body:n,cardElement:t||s||e}})}addToCart({currentTarget:e}){const t=e.closest('[data-hellotext--message-target="carouselCard"]'),{id:s,reference:n,source:i}=t.dataset,r={product:s,quantity:1};this.hasUtmValue&>.page.utm.save(this.utmValue),gt.eventEmitter.dispatch("cart.added",{object_parameters:{items:[{...r,...n&&{reference:n},...i&&{source:i}}]},source:{kind:this.kindValue,message_id:this.idValue,button_id:e.dataset.id}})}moveToLeft(){if(!this.hasCarouselContainerTarget)return;const e=this.getPreviousPageScrollLeft(),t=this.carouselContainerTarget.scrollLeft-e;t<1||this.carouselContainerTarget.scrollBy({left:-t,behavior:"smooth"})}moveToRight(){if(!this.hasCarouselContainerTarget)return;const e=this.getNextPageScrollLeft()-this.carouselContainerTarget.scrollLeft;e<1||this.carouselContainerTarget.scrollBy({left:e,behavior:"smooth"})}getScrollAmount(){return this.getCardScrollAmount()}getCardScrollAmount(){const e=this.carouselContainerTarget.querySelector(".message__carousel_card");return e?e.offsetWidth+this.getGap():280}getPageScrollAmount(){const e=this.carouselContainerTarget.clientWidth-this.getGap();return e>0?e:this.getCardScrollAmount()}getNextPageScrollLeft(){const e=this.getCurrentScrollLeft(),t=e+this.carouselContainerTarget.clientWidth,s=this.getCardMetrics().find(e=>e.end>t+1),n=s?this.getPageAlignedScrollLeft(s.start):e+this.getPageScrollAmount(),i=e+this.getPageScrollAmount();return this.clampScrollLeft(n>e+1?n:i)}getPreviousPageScrollLeft(){const e=this.getCurrentScrollLeft();if(e<=1)return 0;const t=Math.max(e-this.getPageScrollAmount(),0);if(t<=1)return 0;const s=this.getCardMetrics(),n=s.find(s=>s.start>=t-1&&s.startt.start{const t=this.getCardScrollLeft(e);return{start:t,end:t+e.offsetWidth}})}getCardScrollLeft(e){const t=e.getBoundingClientRect(),s=this.carouselContainerTarget.getBoundingClientRect();return t.left||t.width||s.left||s.width?t.left-s.left+this.carouselContainerTarget.scrollLeft:e.offsetLeft||0}getCurrentScrollLeft(){return this.clampScrollLeft(this.carouselContainerTarget.scrollLeft)}clampScrollLeft(e){const t=Math.max(this.carouselContainerTarget.scrollWidth-this.carouselContainerTarget.clientWidth,0);return Math.min(Math.max(e,0),t)}getGap(){const e=window.getComputedStyle(this.carouselContainerTarget),t=Number.parseFloat(e.columnGap||e.gap);return Number.isFinite(t)?t:16}getFadeDistance(){return Number.isFinite(this.fadeDistanceValue)?this.fadeDistanceValue:64}getPageStartOffset(){return Number.isFinite(this.pageStartOffsetValue)?this.pageStartOffsetValue:0}observeContainerSize(){this.hasCarouselContainerTarget&&window.ResizeObserver&&(this.resizeObserver=new ResizeObserver(()=>this.updateFades()),this.resizeObserver.observe(this.carouselContainerTarget))}updateFades(){if(!this.hasCarouselContainerTarget)return;const e=Math.max(this.carouselContainerTarget.scrollWidth-this.carouselContainerTarget.clientWidth,0);if(e<=1)return this.hideFade(this.leftFadeTarget),void this.hideFade(this.rightFadeTarget);const t=Math.min(Math.max(this.carouselContainerTarget.scrollLeft,0),e),s=this.getFadeDistance();this.setFadeOpacity(this.leftFadeTarget,t/s),this.setFadeOpacity(this.rightFadeTarget,(e-t)/s)}setFadeOpacity(e,t){const s=Math.min(Math.max(t,0),1);s<=.05?this.hideFade(e):(e.classList.remove("hidden"),e.removeAttribute("disabled"),e.removeAttribute("tabindex"),e.setAttribute("aria-hidden","false"),e.style.opacity=s.toFixed(3),e.style.pointerEvents="auto")}hideFade(e){e.style.opacity="0",e.style.pointerEvents="none",e.setAttribute("aria-hidden","true"),e.setAttribute("tabindex","-1"),"disabled"in e&&(e.disabled=!0),e.classList.add("hidden")}},yt=["start","end"],vt=["top","right","bottom","left"].reduce((e,t)=>e.concat(t,t+"-"+yt[0],t+"-"+yt[1]),[]),wt=Math.min,Tt=Math.max,St=Math.round,Ct=Math.floor,Ot=e=>({x:e,y:e}),At={left:"right",right:"left",bottom:"top",top:"bottom"},Et={start:"end",end:"start"};function xt(e,t,s){return Tt(e,wt(t,s))}function Mt(e,t){return"function"==typeof e?e(t):e}function kt(e){return e.split("-")[0]}function It(e){return e.split("-")[1]}function Lt(e){return"x"===e?"y":"x"}function _t(e){return"y"===e?"height":"width"}const Pt=new Set(["top","bottom"]);function Nt(e){return Pt.has(kt(e))?"y":"x"}function Ft(e){return Lt(Nt(e))}function Dt(e,t,s){void 0===s&&(s=!1);const n=It(e),i=Ft(e),r=_t(i);let a="x"===i?n===(s?"end":"start")?"right":"left":"start"===n?"bottom":"top";return t.reference[r]>t.floating[r]&&(a=qt(a)),[a,qt(a)]}function Rt(e){return e.replace(/start|end/g,e=>Et[e])}const jt=["left","right"],Bt=["right","left"],$t=["top","bottom"],Vt=["bottom","top"];function qt(e){return e.replace(/left|right|bottom|top/g,e=>At[e])}function Ut(e){const{x:t,y:s,width:n,height:i}=e;return{width:n,height:i,top:s,left:t,right:t+n,bottom:s+i,x:t,y:s}}function zt(e,t,s){let{reference:n,floating:i}=e;const r=Nt(t),a=Ft(t),o=_t(a),c=kt(t),l="y"===r,h=n.x+n.width/2-i.width/2,u=n.y+n.height/2-i.height/2,d=n[o]/2-i[o]/2;let p;switch(c){case"top":p={x:h,y:n.y-i.height};break;case"bottom":p={x:h,y:n.y+n.height};break;case"right":p={x:n.x+n.width,y:u};break;case"left":p={x:n.x-i.width,y:u};break;default:p={x:n.x,y:n.y}}switch(It(t)){case"start":p[a]-=d*(s&&l?-1:1);break;case"end":p[a]+=d*(s&&l?-1:1)}return p}async function Wt(e,t){var s;void 0===t&&(t={});const{x:n,y:i,platform:r,rects:a,elements:o,strategy:c}=e,{boundary:l="clippingAncestors",rootBoundary:h="viewport",elementContext:u="floating",altBoundary:d=!1,padding:p=0}=Mt(t,e),m=function(e){return"number"!=typeof e?function(e){return{top:0,right:0,bottom:0,left:0,...e}}(e):{top:e,right:e,bottom:e,left:e}}(p),g=o[d?"floating"===u?"reference":"floating":u],f=Ut(await r.getClippingRect({element:null==(s=await(null==r.isElement?void 0:r.isElement(g)))||s?g:g.contextElement||await(null==r.getDocumentElement?void 0:r.getDocumentElement(o.floating)),boundary:l,rootBoundary:h,strategy:c})),b="floating"===u?{x:n,y:i,width:a.floating.width,height:a.floating.height}:a.reference,y=await(null==r.getOffsetParent?void 0:r.getOffsetParent(o.floating)),v=await(null==r.isElement?void 0:r.isElement(y))&&await(null==r.getScale?void 0:r.getScale(y))||{x:1,y:1},w=Ut(r.convertOffsetParentRelativeRectToViewportRelativeRect?await r.convertOffsetParentRelativeRectToViewportRelativeRect({elements:o,rect:b,offsetParent:y,strategy:c}):b);return{top:(f.top-w.top+m.top)/v.y,bottom:(w.bottom-f.bottom+m.bottom)/v.y,left:(f.left-w.left+m.left)/v.x,right:(w.right-f.right+m.right)/v.x}}const Ht=new Set(["left","top"]);function Kt(){return"undefined"!=typeof window}function Gt(e){return Zt(e)?(e.nodeName||"").toLowerCase():"#document"}function Jt(e){var t;return(null==e||null==(t=e.ownerDocument)?void 0:t.defaultView)||window}function Yt(e){var t;return null==(t=(Zt(e)?e.ownerDocument:e.document)||window.document)?void 0:t.documentElement}function Zt(e){return!!Kt()&&(e instanceof Node||e instanceof Jt(e).Node)}function Xt(e){return!!Kt()&&(e instanceof Element||e instanceof Jt(e).Element)}function Qt(e){return!!Kt()&&(e instanceof HTMLElement||e instanceof Jt(e).HTMLElement)}function es(e){return!(!Kt()||"undefined"==typeof ShadowRoot)&&(e instanceof ShadowRoot||e instanceof Jt(e).ShadowRoot)}const ts=new Set(["inline","contents"]);function ss(e){const{overflow:t,overflowX:s,overflowY:n,display:i}=ms(e);return/auto|scroll|overlay|hidden|clip/.test(t+n+s)&&!ts.has(i)}const ns=new Set(["table","td","th"]);function is(e){return ns.has(Gt(e))}const rs=[":popover-open",":modal"];function as(e){return rs.some(t=>{try{return e.matches(t)}catch(e){return!1}})}const os=["transform","translate","scale","rotate","perspective"],cs=["transform","translate","scale","rotate","perspective","filter"],ls=["paint","layout","strict","content"];function hs(e){const t=us(),s=Xt(e)?ms(e):e;return os.some(e=>!!s[e]&&"none"!==s[e])||!!s.containerType&&"normal"!==s.containerType||!t&&!!s.backdropFilter&&"none"!==s.backdropFilter||!t&&!!s.filter&&"none"!==s.filter||cs.some(e=>(s.willChange||"").includes(e))||ls.some(e=>(s.contain||"").includes(e))}function us(){return!("undefined"==typeof CSS||!CSS.supports)&&CSS.supports("-webkit-backdrop-filter","none")}const ds=new Set(["html","body","#document"]);function ps(e){return ds.has(Gt(e))}function ms(e){return Jt(e).getComputedStyle(e)}function gs(e){return Xt(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function fs(e){if("html"===Gt(e))return e;const t=e.assignedSlot||e.parentNode||es(e)&&e.host||Yt(e);return es(t)?t.host:t}function bs(e){const t=fs(e);return ps(t)?e.ownerDocument?e.ownerDocument.body:e.body:Qt(t)&&ss(t)?t:bs(t)}function ys(e,t,s){var n;void 0===t&&(t=[]),void 0===s&&(s=!0);const i=bs(e),r=i===(null==(n=e.ownerDocument)?void 0:n.body),a=Jt(i);if(r){const e=vs(a);return t.concat(a,a.visualViewport||[],ss(i)?i:[],e&&s?ys(e):[])}return t.concat(i,ys(i,[],s))}function vs(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}function ws(e){const t=ms(e);let s=parseFloat(t.width)||0,n=parseFloat(t.height)||0;const i=Qt(e),r=i?e.offsetWidth:s,a=i?e.offsetHeight:n,o=St(s)!==r||St(n)!==a;return o&&(s=r,n=a),{width:s,height:n,$:o}}function Ts(e){return Xt(e)?e:e.contextElement}function Ss(e){const t=Ts(e);if(!Qt(t))return Ot(1);const s=t.getBoundingClientRect(),{width:n,height:i,$:r}=ws(t);let a=(r?St(s.width):s.width)/n,o=(r?St(s.height):s.height)/i;return a&&Number.isFinite(a)||(a=1),o&&Number.isFinite(o)||(o=1),{x:a,y:o}}const Cs=Ot(0);function Os(e){const t=Jt(e);return us()&&t.visualViewport?{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}:Cs}function As(e,t,s,n){void 0===t&&(t=!1),void 0===s&&(s=!1);const i=e.getBoundingClientRect(),r=Ts(e);let a=Ot(1);t&&(n?Xt(n)&&(a=Ss(n)):a=Ss(e));const o=function(e,t,s){return void 0===t&&(t=!1),!(!s||t&&s!==Jt(e))&&t}(r,s,n)?Os(r):Ot(0);let c=(i.left+o.x)/a.x,l=(i.top+o.y)/a.y,h=i.width/a.x,u=i.height/a.y;if(r){const e=Jt(r),t=n&&Xt(n)?Jt(n):n;let s=e,i=vs(s);for(;i&&n&&t!==s;){const e=Ss(i),t=i.getBoundingClientRect(),n=ms(i),r=t.left+(i.clientLeft+parseFloat(n.paddingLeft))*e.x,a=t.top+(i.clientTop+parseFloat(n.paddingTop))*e.y;c*=e.x,l*=e.y,h*=e.x,u*=e.y,c+=r,l+=a,s=Jt(i),i=vs(s)}}return Ut({width:h,height:u,x:c,y:l})}function Es(e,t){const s=gs(e).scrollLeft;return t?t.left+s:As(Yt(e)).left+s}function xs(e,t,s){void 0===s&&(s=!1);const n=e.getBoundingClientRect();return{x:n.left+t.scrollLeft-(s?0:Es(e,n)),y:n.top+t.scrollTop}}const Ms=new Set(["absolute","fixed"]);function ks(e,t,s){let n;if("viewport"===t)n=function(e,t){const s=Jt(e),n=Yt(e),i=s.visualViewport;let r=n.clientWidth,a=n.clientHeight,o=0,c=0;if(i){r=i.width,a=i.height;const e=us();(!e||e&&"fixed"===t)&&(o=i.offsetLeft,c=i.offsetTop)}return{width:r,height:a,x:o,y:c}}(e,s);else if("document"===t)n=function(e){const t=Yt(e),s=gs(e),n=e.ownerDocument.body,i=Tt(t.scrollWidth,t.clientWidth,n.scrollWidth,n.clientWidth),r=Tt(t.scrollHeight,t.clientHeight,n.scrollHeight,n.clientHeight);let a=-s.scrollLeft+Es(e);const o=-s.scrollTop;return"rtl"===ms(n).direction&&(a+=Tt(t.clientWidth,n.clientWidth)-i),{width:i,height:r,x:a,y:o}}(Yt(e));else if(Xt(t))n=function(e,t){const s=As(e,!0,"fixed"===t),n=s.top+e.clientTop,i=s.left+e.clientLeft,r=Qt(e)?Ss(e):Ot(1);return{width:e.clientWidth*r.x,height:e.clientHeight*r.y,x:i*r.x,y:n*r.y}}(t,s);else{const s=Os(e);n={x:t.x-s.x,y:t.y-s.y,width:t.width,height:t.height}}return Ut(n)}function Is(e,t){const s=fs(e);return!(s===t||!Xt(s)||ps(s))&&("fixed"===ms(s).position||Is(s,t))}function Ls(e,t,s){const n=Qt(t),i=Yt(t),r="fixed"===s,a=As(e,!0,r,t);let o={scrollLeft:0,scrollTop:0};const c=Ot(0);function l(){c.x=Es(i)}if(n||!n&&!r)if(("body"!==Gt(t)||ss(i))&&(o=gs(t)),n){const e=As(t,!0,r,t);c.x=e.x+t.clientLeft,c.y=e.y+t.clientTop}else i&&l();r&&!n&&i&&l();const h=!i||n||r?Ot(0):xs(i,o);return{x:a.left+o.scrollLeft-c.x-h.x,y:a.top+o.scrollTop-c.y-h.y,width:a.width,height:a.height}}function _s(e){return"static"===ms(e).position}function Ps(e,t){if(!Qt(e)||"fixed"===ms(e).position)return null;if(t)return t(e);let s=e.offsetParent;return Yt(e)===s&&(s=s.ownerDocument.body),s}function Ns(e,t){const s=Jt(e);if(as(e))return s;if(!Qt(e)){let t=fs(e);for(;t&&!ps(t);){if(Xt(t)&&!_s(t))return t;t=fs(t)}return s}let n=Ps(e,t);for(;n&&is(n)&&_s(n);)n=Ps(n,t);return n&&ps(n)&&_s(n)&&!hs(n)?s:n||function(e){let t=fs(e);for(;Qt(t)&&!ps(t);){if(hs(t))return t;if(as(t))return null;t=fs(t)}return null}(e)||s}const Fs={convertOffsetParentRelativeRectToViewportRelativeRect:function(e){let{elements:t,rect:s,offsetParent:n,strategy:i}=e;const r="fixed"===i,a=Yt(n),o=!!t&&as(t.floating);if(n===a||o&&r)return s;let c={scrollLeft:0,scrollTop:0},l=Ot(1);const h=Ot(0),u=Qt(n);if((u||!u&&!r)&&(("body"!==Gt(n)||ss(a))&&(c=gs(n)),Qt(n))){const e=As(n);l=Ss(n),h.x=e.x+n.clientLeft,h.y=e.y+n.clientTop}const d=!a||u||r?Ot(0):xs(a,c,!0);return{width:s.width*l.x,height:s.height*l.y,x:s.x*l.x-c.scrollLeft*l.x+h.x+d.x,y:s.y*l.y-c.scrollTop*l.y+h.y+d.y}},getDocumentElement:Yt,getClippingRect:function(e){let{element:t,boundary:s,rootBoundary:n,strategy:i}=e;const r=[..."clippingAncestors"===s?as(t)?[]:function(e,t){const s=t.get(e);if(s)return s;let n=ys(e,[],!1).filter(e=>Xt(e)&&"body"!==Gt(e)),i=null;const r="fixed"===ms(e).position;let a=r?fs(e):e;for(;Xt(a)&&!ps(a);){const t=ms(a),s=hs(a);s||"fixed"!==t.position||(i=null),(r?!s&&!i:!s&&"static"===t.position&&i&&Ms.has(i.position)||ss(a)&&!s&&Is(e,a))?n=n.filter(e=>e!==a):i=t,a=fs(a)}return t.set(e,n),n}(t,this._c):[].concat(s),n],a=r[0],o=r.reduce((e,s)=>{const n=ks(t,s,i);return e.top=Tt(n.top,e.top),e.right=wt(n.right,e.right),e.bottom=wt(n.bottom,e.bottom),e.left=Tt(n.left,e.left),e},ks(t,a,i));return{width:o.right-o.left,height:o.bottom-o.top,x:o.left,y:o.top}},getOffsetParent:Ns,getElementRects:async function(e){const t=this.getOffsetParent||Ns,s=this.getDimensions,n=await s(e.floating);return{reference:Ls(e.reference,await t(e.floating),e.strategy),floating:{x:0,y:0,width:n.width,height:n.height}}},getClientRects:function(e){return Array.from(e.getClientRects())},getDimensions:function(e){const{width:t,height:s}=ws(e);return{width:t,height:s}},getScale:Ss,isElement:Xt,isRTL:function(e){return"rtl"===ms(e).direction}};function Ds(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}const Rs=function(e){return void 0===e&&(e=0),{name:"offset",options:e,async fn(t){var s,n;const{x:i,y:r,placement:a,middlewareData:o}=t,c=await async function(e,t){const{placement:s,platform:n,elements:i}=e,r=await(null==n.isRTL?void 0:n.isRTL(i.floating)),a=kt(s),o=It(s),c="y"===Nt(s),l=Ht.has(a)?-1:1,h=r&&c?-1:1,u=Mt(t,e);let{mainAxis:d,crossAxis:p,alignmentAxis:m}="number"==typeof u?{mainAxis:u,crossAxis:0,alignmentAxis:null}:{mainAxis:u.mainAxis||0,crossAxis:u.crossAxis||0,alignmentAxis:u.alignmentAxis};return o&&"number"==typeof m&&(p="end"===o?-1*m:m),c?{x:p*h,y:d*l}:{x:d*l,y:p*h}}(t,e);return a===(null==(s=o.offset)?void 0:s.placement)&&null!=(n=o.arrow)&&n.alignmentOffset?{}:{x:i+c.x,y:r+c.y,data:{...c,placement:a}}}}},js=function(e){return void 0===e&&(e={}),{name:"shift",options:e,async fn(t){const{x:s,y:n,placement:i}=t,{mainAxis:r=!0,crossAxis:a=!1,limiter:o={fn:e=>{let{x:t,y:s}=e;return{x:t,y:s}}},...c}=Mt(e,t),l={x:s,y:n},h=await Wt(t,c),u=Nt(kt(i)),d=Lt(u);let p=l[d],m=l[u];if(r){const e="y"===d?"bottom":"right";p=xt(p+h["y"===d?"top":"left"],p,p-h[e])}if(a){const e="y"===u?"bottom":"right";m=xt(m+h["y"===u?"top":"left"],m,m-h[e])}const g=o.fn({...t,[d]:p,[u]:m});return{...g,data:{x:g.x-s,y:g.y-n,enabled:{[d]:r,[u]:a}}}}}},Bs=function(e){return void 0===e&&(e={}),{name:"flip",options:e,async fn(t){var s,n;const{placement:i,middlewareData:r,rects:a,initialPlacement:o,platform:c,elements:l}=t,{mainAxis:h=!0,crossAxis:u=!0,fallbackPlacements:d,fallbackStrategy:p="bestFit",fallbackAxisSideDirection:m="none",flipAlignment:g=!0,...f}=Mt(e,t);if(null!=(s=r.arrow)&&s.alignmentOffset)return{};const b=kt(i),y=Nt(o),v=kt(o)===o,w=await(null==c.isRTL?void 0:c.isRTL(l.floating)),T=d||(v||!g?[qt(o)]:function(e){const t=qt(e);return[Rt(e),t,Rt(t)]}(o)),S="none"!==m;!d&&S&&T.push(...function(e,t,s,n){const i=It(e);let r=function(e,t,s){switch(e){case"top":case"bottom":return s?t?Bt:jt:t?jt:Bt;case"left":case"right":return t?$t:Vt;default:return[]}}(kt(e),"start"===s,n);return i&&(r=r.map(e=>e+"-"+i),t&&(r=r.concat(r.map(Rt)))),r}(o,g,m,w));const C=[o,...T],O=await Wt(t,f),A=[];let E=(null==(n=r.flip)?void 0:n.overflows)||[];if(h&&A.push(O[b]),u){const e=Dt(i,a,w);A.push(O[e[0]],O[e[1]])}if(E=[...E,{placement:i,overflows:A}],!A.every(e=>e<=0)){var x,M;const e=((null==(x=r.flip)?void 0:x.index)||0)+1,t=C[e];if(t&&("alignment"!==u||y===Nt(t)||E.every(e=>Nt(e.placement)!==y||e.overflows[0]>0)))return{data:{index:e,overflows:E},reset:{placement:t}};let s=null==(M=E.filter(e=>e.overflows[0]<=0).sort((e,t)=>e.overflows[1]-t.overflows[1])[0])?void 0:M.placement;if(!s)switch(p){case"bestFit":{var k;const e=null==(k=E.filter(e=>{if(S){const t=Nt(e.placement);return t===y||"y"===t}return!0}).map(e=>[e.placement,e.overflows.filter(e=>e>0).reduce((e,t)=>e+t,0)]).sort((e,t)=>e[1]-t[1])[0])?void 0:k[0];e&&(s=e);break}case"initialPlacement":s=o}if(i!==s)return{reset:{placement:s}}}return{}}}},$s=e=>{Object.assign(e,{show(){this.cancelBehaviourOpen?.(),this.openValue=!0},hide(){this.openValue=!1},toggle(){this.cancelBehaviourOpen?.(),this.openValue=!this.openValue},setupFloatingUI({trigger:e,popover:t,strategy:s}){this.floatingUICleanup=function(e,t,s,n){void 0===n&&(n={});const{ancestorScroll:i=!0,ancestorResize:r=!0,elementResize:a="function"==typeof ResizeObserver,layoutShift:o="function"==typeof IntersectionObserver,animationFrame:c=!1}=n,l=Ts(e),h=i||r?[...l?ys(l):[],...ys(t)]:[];h.forEach(e=>{i&&e.addEventListener("scroll",s,{passive:!0}),r&&e.addEventListener("resize",s)});const u=l&&o?function(e,t){let s,n=null;const i=Yt(e);function r(){var e;clearTimeout(s),null==(e=n)||e.disconnect(),n=null}return function a(o,c){void 0===o&&(o=!1),void 0===c&&(c=1),r();const l=e.getBoundingClientRect(),{left:h,top:u,width:d,height:p}=l;if(o||t(),!d||!p)return;const m={rootMargin:-Ct(u)+"px "+-Ct(i.clientWidth-(h+d))+"px "+-Ct(i.clientHeight-(u+p))+"px "+-Ct(h)+"px",threshold:Tt(0,wt(1,c))||1};let g=!0;function f(t){const n=t[0].intersectionRatio;if(n!==c){if(!g)return a();n?a(!1,n):s=setTimeout(()=>{a(!1,1e-7)},1e3)}1!==n||Ds(l,e.getBoundingClientRect())||a(),g=!1}try{n=new IntersectionObserver(f,{...m,root:i.ownerDocument})}catch(e){n=new IntersectionObserver(f,m)}n.observe(e)}(!0),r}(l,s):null;let d,p=-1,m=null;a&&(m=new ResizeObserver(e=>{let[n]=e;n&&n.target===l&&m&&(m.unobserve(t),cancelAnimationFrame(p),p=requestAnimationFrame(()=>{var e;null==(e=m)||e.observe(t)})),s()}),l&&!c&&m.observe(l),m.observe(t));let g=c?As(e):null;return c&&function t(){const n=As(e);g&&!Ds(g,n)&&s(),g=n,d=requestAnimationFrame(t)}(),s(),()=>{var e;h.forEach(e=>{i&&e.removeEventListener("scroll",s),r&&e.removeEventListener("resize",s)}),null==u||u(),null==(e=m)||e.disconnect(),m=null,c&&cancelAnimationFrame(d)}}(e,t,()=>{((e,t,s)=>{const n=new Map,i={platform:Fs,...s},r={...i.platform,_c:n};return(async(e,t,s)=>{const{placement:n="bottom",strategy:i="absolute",middleware:r=[],platform:a}=s,o=r.filter(Boolean),c=await(null==a.isRTL?void 0:a.isRTL(t));let l=await a.getElementRects({reference:e,floating:t,strategy:i}),{x:h,y:u}=zt(l,n,c),d=n,p={},m=0;for(let s=0;s{const i={left:`${e}px`,top:`${s}px`,position:n};Object.assign(t.style,i)})})},openValueChanged(){this.disabledValue||(this.openValue?(this.preparePopoverOpenAnimation?.(),this.popoverTarget.showPopover(),this.popoverTarget.setAttribute("aria-expanded","true"),this.onPopoverOpened&&this.onPopoverOpened()):(this.popoverTarget.hidePopover(),this.popoverTarget.removeAttribute("aria-expanded"),this.onPopoverClosed&&this.onPopoverClosed()))}})},Vs=class extends n.xI{static targets=["button","popover"];static values={placement:{type:String,default:"bottom-end"},open:{type:Boolean,default:!1},autoPlacement:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},size:{type:Number,default:24},perLine:{type:Number,default:9}};initialize(){this.onEmojiSelect=this.onEmojiSelect.bind(this),this.pickerLoaded=!1,this.pickerLoadPromise=null,this.connected=!1,super.initialize()}connect(){this.connected=!0,$s(this),this.setupFloatingUI({trigger:this.buttonTarget,popover:this.popoverTarget,strategy:"absolute"}),super.connect()}disconnect(){this.connected=!1,this.pickerLoadPromise=null,this.floatingUICleanup(),super.disconnect()}onEmojiSelect(e){this.dispatch("selected",{detail:e.native}),this.hide()}onClickOutside(e){this.openValue&&e.target.nodeType&&!1===this.element.contains(e.target)&&(this.openValue=!1)}async onPopoverOpened(){await this.loadPicker()}async loadPicker(){if(this.pickerLoaded)return;this.pickerLoadPromise||=this.loadPickerDependencies();const{Picker:e,i18n:t}=await this.pickerLoadPromise;this.connected&&!this.pickerLoaded&&(this.popoverTarget.appendChild(this.buildPicker(e,t)),this.pickerLoaded=!0)}async loadPickerDependencies(){const[e,t]=await Promise.all([s.e(160).then(s.bind(s,405)),this.loadI18n()]);return{Picker:e.Picker,i18n:t.default||t}}loadI18n(){return"es"===Hellotext.business.locale?s.e(437).then(s.t.bind(s,9,19)):s.e(200).then(s.t.bind(s,714,19))}buildPicker(e,t){return new e({onEmojiSelect:this.onEmojiSelect,theme:"light",dynamicWidth:!0,previewPosition:"none",skinTonePosition:"none",emojiSize:this.sizeValue,perLine:this.perLineValue,i18n:t})}get middlewares(){return[Rs(5),js({padding:24}),(e={allowedPlacements:["top","bottom"]},void 0===e&&(e={}),{name:"autoPlacement",options:e,async fn(t){var s,n,i;const{rects:r,middlewareData:a,placement:o,platform:c,elements:l}=t,{crossAxis:h=!1,alignment:u,allowedPlacements:d=vt,autoAlignment:p=!0,...m}=Mt(e,t),g=void 0!==u||d===vt?function(e,t,s){return(e?[...s.filter(t=>It(t)===e),...s.filter(t=>It(t)!==e)]:s.filter(e=>kt(e)===e)).filter(s=>!e||It(s)===e||!!t&&Rt(s)!==s)}(u||null,p,d):d,f=await Wt(t,m),b=(null==(s=a.autoPlacement)?void 0:s.index)||0,y=g[b];if(null==y)return{};const v=Dt(y,r,await(null==c.isRTL?void 0:c.isRTL(l.floating)));if(o!==y)return{reset:{placement:g[0]}};const w=[f[kt(y)],f[v[0]],f[v[1]]],T=[...(null==(n=a.autoPlacement)?void 0:n.overflows)||[],{placement:y,overflows:w}],S=g[b+1];if(S)return{data:{index:b+1,overflows:T},reset:{placement:S}};const C=T.map(e=>{const t=It(e.placement);return[e.placement,t&&h?e.overflows.slice(0,2).reduce((e,t)=>e+t,0):e.overflows[0],e.overflows]}).sort((e,t)=>e[1]-t[1]),O=(null==(i=C.filter(e=>e[2].slice(0,It(e[0])?2:3).every(e=>e<=0))[0])?void 0:i[0])||C[0][0];return O!==o?{data:{index:b+1,overflows:T},reset:{placement:O}}:{}}})];var e}};class qs{static get endpoint(){return g.endpoint("public/webchats/:id/messages")}constructor(e){this.webchatId=e}async index(e){const t=new URL(this.url);return Object.entries(e).forEach(([e,s])=>{t.searchParams.append(e,s)}),await fetch(t,{method:"GET",headers:gt.headers})}catchUp(e){return this.index({after_id:e,session:gt.session})}async create(e){const t=await fetch(this.url,{method:"POST",headers:{Authorization:`Bearer ${gt.business.id}`},body:e});return new y(t.ok,t)}markAsSeen(e=null){const t=e?this.url+`/${e}`:this.url+"/seen";fetch(t,{method:"PATCH",headers:gt.headers,body:JSON.stringify({session:gt.session})})}get url(){return qs.endpoint.replace(":id",this.webchatId)}}const Us=qs;class zs{static webSocket;static channels=new Set;static messageHandlers=new Set;static disconnectHandlers=new Set;static subscriptionConfirmHandlers=new Set;static reconnectTimeout=null;static reconnectAttempts=0;static reconnectBaseDelay=500;static reconnectMaxDelay=1e4;static reconnectJitter=.3;static needsResubscribe=!1;constructor(){zs.channels.add(this)}send({command:e,identifier:t,data:s}){const n={command:e,identifier:JSON.stringify(t),data:JSON.stringify(s||{})},i=zs.ensureWebSocket(),r=JSON.stringify(n);i.readyState===WebSocket.OPEN?i.send(r):i.addEventListener("open",()=>{i.send(r)})}onMessage(e){const t=t=>{const s=JSON.parse(t.data),{type:n,message:i}=s;this.ignoredEvents.includes(n)||e(i)};zs.messageHandlers.add(t),zs.ensureWebSocket().addEventListener("message",t)}onDisconnect(e){zs.disconnectHandlers.add(e)}onSubscriptionConfirmed(e){zs.subscriptionConfirmHandlers.add(e)}get webSocket(){return zs.ensureWebSocket()}static ensureWebSocket(){return this.webSocket&&!this.closedWebSocket(this.webSocket)?this.webSocket:(this.webSocket&&(this.needsResubscribe=!0),this.openWebSocket())}static openWebSocket(){this.clearReconnectTimeout();const e=new WebSocket(g.actionCableUrl);return this.webSocket=e,this.installWebSocketHandlers(e),e}static installWebSocketHandlers(e){e.addEventListener("open",()=>this.handleOpen(e)),e.addEventListener("close",()=>this.handleDisconnect(e)),e.addEventListener("error",()=>this.handleDisconnect(e)),e.addEventListener("message",e=>this.handleControlMessage(e)),this.messageHandlers.forEach(t=>{e.addEventListener("message",t)})}static handleOpen(e){e===this.webSocket&&(this.reconnectAttempts=0,this.needsResubscribe&&(this.needsResubscribe=!1,this.resubscribeChannels()))}static handleControlMessage(e){let t;try{t=JSON.parse(e.data)}catch{return}"confirm_subscription"===t.type&&this.subscriptionConfirmHandlers.forEach(e=>e(t.identifier))}static handleDisconnect(e){e===this.webSocket&&(this.disconnectHandlers.forEach(e=>e()),this.webSocket=null,this.needsResubscribe=!0,this.scheduleReconnect())}static scheduleReconnect(){this.reconnectTimeout||(this.reconnectTimeout=setTimeout(()=>{this.reconnectTimeout=null,this.reconnectAttempts+=1,this.openWebSocket()},this.reconnectDelay))}static clearReconnectTimeout(){this.reconnectTimeout&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=null)}static resubscribeChannels(){this.channels.forEach(e=>{const t=e.resubscribe||e.subscribe;"function"==typeof t&&t.call(e)})}static closedWebSocket(e){return e.readyState===WebSocket.CLOSED||e.readyState===WebSocket.CLOSING}static get reconnectDelay(){const e=Math.min(this.reconnectMaxDelay,this.reconnectBaseDelay*2**this.reconnectAttempts);return e+Math.round(e*this.reconnectJitter*Math.random())}get ignoredEvents(){return["ping","confirm_subscription","welcome"]}}const Ws=zs,Hs=class extends Ws{constructor(e,t,s){super(),this.id=e,this.session=t,this.conversation=s,this.subscribed=!1,this.awaitingReconnectConfirmation=!1,this.reconnectCallbacks=new Set,this.onSubscriptionConfirmed(e=>this.handleSubscriptionConfirmed(e)),this.subscribe()}subscribe(){this.subscribed=!0;const e={channel:"WebchatChannel",id:this.id,session:this.session,conversation:this.conversation};this.send({command:"subscribe",identifier:e})}unsubscribe(){this.subscribed=!1;const e={channel:"WebchatChannel",id:this.id,session:this.session,conversation:this.conversation};this.send({command:"unsubscribe",identifier:e})}resubscribe(){!1!==this.subscribed&&(this.awaitingReconnectConfirmation=!0,this.subscribe())}onReconnect(e){this.reconnectCallbacks.add(e)}handleSubscriptionConfirmed(e){this.awaitingReconnectConfirmation&&this.matchesIdentifier(e)&&(this.awaitingReconnectConfirmation=!1,this.reconnectCallbacks.forEach(e=>e()))}matchesIdentifier(e){let t;try{t="string"==typeof e?JSON.parse(e):e}catch{return!1}return"WebchatChannel"===t.channel&&t.id===this.id&&t.session===this.session&&t.conversation===this.conversation}startTypingIndicator(){const e={channel:"WebchatChannel",id:this.id,session:this.session,conversation:this.conversation};this.send({command:"message",identifier:e,data:{action:"started_typing"}})}stopTypingIndicator(){const e={channel:"WebchatChannel",id:this.id,session:this.session,conversation:this.conversation};this.send({command:"typing:stop",identifier:e,data:{action:"stopped_typing"}})}onMessage(e){super.onMessage(t=>{"message"===t.type&&e(t)})}onReaction(e){super.onMessage(t=>{"reaction.create"!==t.type&&"reaction.destroy"!==t.type||e(t)})}onTypingStart(e){super.onMessage(t=>{"started_typing"===t.type&&e(t)})}updateSubscriptionWith(e){this.unsubscribe(),setTimeout(()=>{this.conversation=e,this.subscribe()},1e3)}},Ks=e=>{Object.assign(e,{scheduleBehaviourOpen(){if(!this.shouldAutoOpenFromBehaviour())return;const e=1e3*Number(this.behaviourValue.delay_seconds||0);this.behaviourOpenTimeout=window.setTimeout(()=>{this.behaviourOpenTimeout=null,this.openValue||(this.openValue=!0,this.markBehaviourAutoOpened())},e)},cancelBehaviourOpen(){window.clearTimeout(this.behaviourOpenTimeout),this.behaviourOpenTimeout=null},shouldAutoOpenFromBehaviour(){const e=this.behaviourValue;return!(!e||"on_load"!==e.trigger||e.first_visit_only&&localStorage.getItem(this.firstVisitKey())||e.once_per_session&&sessionStorage.getItem(this.sessionKey()))},markBehaviourAutoOpened(){this.behaviourValue.first_visit_only&&localStorage.setItem(this.firstVisitKey(),"1"),this.behaviourValue.once_per_session&&sessionStorage.setItem(this.sessionKey(),"1")},firstVisitKey(){return`hellotext--webchat--${this.idValue}--auto-opened`},sessionKey(){return`hellotext--webchat--${this.idValue}--auto-opened-session`}})},Gs=e=>{Object.assign(e,{setupOpeningSequence(){this.openingSequenceStarted=!1,this.openingSequenceCancelled=!1,this.openingSequenceTimeout=null,this.openingSequenceMessages=[],this.revealedOpeningSequenceMessageIds=[]},teardownOpeningSequence(){this.cancelOpeningSequence()},startOpeningSequence(){this.openingSequenceMessages=Array.from(this.openingSequenceMessageTargets||[]),this.openingSequenceCanStart()&&(this.openingSequenceStarted=!0,this.openingSequenceCancelled=!1,this.revealedOpeningSequenceMessageIds=[],this.playOpeningSequenceMessageAt(0))},openingSequenceCanStart(){return!this.conversationIdValue&&this.hasOpeningSequenceTarget&&this.openingSequenceMessages.length>0&&!this.openingSequenceStarted},playOpeningSequenceMessageAt(e){const t=this.openingSequenceMessages[e];if(!t)return;const s=1e3*this.openingSequenceMessageDelay(t);this.openingSequenceTimeout=window.setTimeout(()=>{this.openingSequenceTimeout=null,this.openingSequenceCancelled||(this.revealOpeningSequenceMessage(t),this.playOpeningSequenceMessageAt(e+1))},s)},revealOpeningSequenceMessage(e){this.messagesContainerTarget.insertBefore(e,this.messageTemplateTarget),e.hidden=!1,this.recordOpeningSequenceMessage(e),this.scrollOpeningSequenceToBottom()},recordOpeningSequenceMessage(e){const t=e.dataset.openingSequenceMessageId;t&&!this.revealedOpeningSequenceMessageIds.includes(t)&&this.revealedOpeningSequenceMessageIds.push(t)},openingSequenceMessageDelay(e){const t=Number(e.dataset.delaySeconds||0);return Number.isFinite(t)?t:0},scrollOpeningSequenceToBottom(){this.messagesContainerTarget.scroll&&this.messagesContainerTarget.scroll({top:this.messagesContainerTarget.scrollHeight,behavior:"smooth"})},cancelOpeningSequence(){this.openingSequenceCancelled=!0,null!==this.openingSequenceTimeout&&void 0!==this.openingSequenceTimeout&&(window.clearTimeout(this.openingSequenceTimeout),this.openingSequenceTimeout=null)},appendOpeningSequenceMessageIds(e){this.cancelOpeningSequence(),(this.revealedOpeningSequenceMessageIds||[]).forEach(t=>{e.append("message[opening_sequence_message_ids][]",t)})},clearRevealedOpeningSequenceMessageIds(){this.revealedOpeningSequenceMessageIds=[]}})},Js=e=>{Object.assign(e,{setupTeaser(){this.teaserCycleTimeout=null,this.teaserMessages=[],this.boundOnTeaserClick=this.boundOnTeaserClick||this.onTeaserClick.bind(this),this.hasTeaserTarget&&(this.teaserTarget.addEventListener("click",this.boundOnTeaserClick),this.startTeaserPresentation())},teardownTeaser(){this.stopTeaserCycle(),this.hasTeaserTarget&&this.boundOnTeaserClick&&this.teaserTarget.removeEventListener("click",this.boundOnTeaserClick)},collectTeaserMessages(){return this.hasTeaserTarget?Array.from(this.teaserTarget.querySelectorAll("[data-teaser-message]")):[]},startTeaserPresentation(){this.stopTeaserCycle(),this.teaserMessages=this.collectTeaserMessages(),this.hasTeaserTarget&&(0!==this.teaserMessages.length?this.openValue||this.conversationIdValue||this.hasRenderedConversationMessages()?this.dismissTeaserForSession():this.teaserSeenForSession()?this.hideTeaser():(this.teaserTarget.classList.remove("invisible"),this.showTeaserMessage(0),this.teaserMessages.length<2||this.scheduleNextTeaserMessage(0)):this.hideTeaser())},scheduleNextTeaserMessage(e){const t=e+1;if(t>=this.teaserMessages.length)return;const s=this.teaserMessages[e],n=this.teaserPresentationDelay(s);this.teaserCycleTimeout=window.setTimeout(()=>{this.teaserCycleTimeout=null,this.showTeaserMessage(t),this.scheduleNextTeaserMessage(t)},n)},showTeaserMessage(e){this.teaserMessages.forEach((t,s)=>{t.classList.toggle("hidden",s!==e)})},stopTeaserCycle(){null!==this.teaserCycleTimeout&&void 0!==this.teaserCycleTimeout&&(window.clearTimeout(this.teaserCycleTimeout),this.teaserCycleTimeout=null)},teaserMessageDelay(e){const t=Number(e.dataset.delaySeconds||0);return Number.isFinite(t)?t:0},teaserPresentationDelay(e){return Math.max(1e3*this.teaserMessageDelay(e),250)},hasRenderedConversationMessages(){let e=[];try{e=Array.from(this.messageTargets||[])}catch(t){e=[]}return e.some(e=>e!==this.messageTemplateTarget)},teaserSeenKey(){const e=this.hasTeaserTarget?this.teaserTarget.dataset.teaserVersion:"",t=e?`:${e}`:"";return`hellotext:webchat:${this.idValue||this.element.id}:teaser-seen${t}`},teaserSeenForSession(){try{return"true"===window.sessionStorage.getItem(this.teaserSeenKey())}catch(e){return!1}},markTeaserSeenForSession(){try{window.sessionStorage.setItem(this.teaserSeenKey(),"true")}catch(e){}},dismissTeaserForSession(){this.markTeaserSeenForSession(),this.hideTeaser()},hideTeaser(){this.stopTeaserCycle(),this.hasTeaserTarget&&this.teaserTarget.classList.add("invisible")},onTeaserClick(e){e.target.closest("a")||(this.dismissTeaserForSession(),this.show())}})},Ys={hour:"numeric",minute:"2-digit"},Zs=/Android|iPhone|iPad|iPod/i,Xs={capture:!0,passive:!0},Qs=class extends n.xI{static messageTimestampFormatters={};static values={id:String,conversationId:String,media:Object,fileSizeErrorMessage:String,placement:{type:String,default:"bottom-end"},open:{type:Boolean,default:!1},autoPlacement:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},nextPage:{type:Number,default:void 0},fullScreenThreshold:{type:Number,default:1024},typingIndicatorKeepAlive:{type:Number,default:3e4},offset:{type:Number,default:24},padding:{type:Number,default:24},optimisticTypingIndicatorWait:{type:Number,default:1e3},teaser:Object,messageTeaser:String,behaviour:Object};static classes=["fadeOut"];static targets=["trigger","popover","input","attachmentInput","attachmentButton","errorMessageContainer","attachmentTemplate","attachmentContainer","attachment","messageTemplate","messagesContainer","title","attachmentImage","footer","toolbar","message","unreadCounter","typingIndicator","typingIndicatorTemplate","teaser","teaserMessage","inboundMessageTeaser","inboundMessageTeaserBody","openingSequence","openingSequenceMessage"];initialize(){this.messagesAPI=new Us(this.idValue),this.webChatChannel=new Hs(this.idValue,gt.session,this.conversationIdValue),this.files=[],this.messageIds=new Set,this.catchUpAfterMessageId=null,this.fetchingCatchUpMessages=!1,this.onMessageReceived=this.onMessageReceived.bind(this),this.onMessageReaction=this.onMessageReaction.bind(this),this.onTypingStart=this.onTypingStart.bind(this),this.captureCatchUpCursor=this.captureCatchUpCursor.bind(this),this.catchUpMessages=this.catchUpMessages.bind(this),this.onScroll=this.onScroll.bind(this),this.onOutboundMessageSent=this.onOutboundMessageSent.bind(this),this.closePopoverOnEscape=this.closePopoverOnEscape.bind(this),this.broadcastChannel=new BroadcastChannel(`hellotext--webchat--${this.idValue}`),this.webChatChannel.onDisconnect(this.captureCatchUpCursor),this.webChatChannel.onReconnect(this.catchUpMessages),super.initialize()}connect(){Ks(this),$s(this),Gs(this),Js(this),this.setupFloatingUI({trigger:this.triggerTarget,popover:this.popoverTarget}),this.hasTeaserTarget&&this.setupFloatingUI({trigger:this.triggerTarget,popover:this.teaserTarget,strategy:"absolute"}),this.setupTeaser(),this.setupOpeningSequence(),this.localizeMessageTimestamps(),this.webChatChannel.onMessage(this.onMessageReceived),this.webChatChannel.onTypingStart(this.onTypingStart),this.webChatChannel.onReaction(this.onMessageReaction),this.setupMessagesContainerScrollIsolation(),this.messagesContainerTarget.addEventListener("scroll",this.onScroll),this.messagesContainerTarget.addEventListener("wheel",this.stopHostScrollPropagation,Xs),this.messagesContainerTarget.addEventListener("touchmove",this.stopHostScrollPropagation,Xs),this.shouldOpenOnMount&&(this.openValue=!0),gt.eventEmitter.dispatch("webchat:mounted"),this.broadcastChannel.addEventListener("message",this.onOutboundMessageSent),window.addEventListener("keydown",this.closePopoverOnEscape,!0),this.scheduleBehaviourOpen(),super.connect()}disconnect(){this.cancelBehaviourOpen(),this.clearPopoverOpenAnimation(),this.teardownTeaser(),this.teardownOpeningSequence(),this.broadcastChannel.removeEventListener("message",this.onOutboundMessageSent),this.messagesContainerTarget.removeEventListener("scroll",this.onScroll),this.messagesContainerTarget.removeEventListener("wheel",this.stopHostScrollPropagation,Xs),this.messagesContainerTarget.removeEventListener("touchmove",this.stopHostScrollPropagation,Xs),window.removeEventListener("keydown",this.closePopoverOnEscape,!0),this.clearTypingIndicator(),this.broadcastChannel.close(),this.floatingUICleanup(),super.disconnect()}setupMessagesContainerScrollIsolation(){this.messagesContainerTarget.style.overscrollBehavior="contain",this.messagesContainerTarget.style.webkitOverflowScrolling="touch",this.messagesContainerTarget.style.touchAction="pan-y",this.messagesContainerTarget.setAttribute("data-lenis-prevent",""),this.messagesContainerTarget.setAttribute("data-lenis-prevent-wheel",""),this.messagesContainerTarget.setAttribute("data-lenis-prevent-touch","")}stopHostScrollPropagation(e){e.stopPropagation()}onTypingStart(){if(this.typingIndicatorVisible)return this.resetTypingIndicatorTimer();this.showTypingIndicator()}showOptimisticTypingIndicator(){this.typingIndicatorVisible||this.showTypingIndicator()}showTypingIndicator(){this.clearTypingIndicator(),this.typingIndicatorVisible=!0;const e=this.typingIndicatorTemplateTarget.cloneNode(!0);e.setAttribute("data-hellotext--webchat-target","typingIndicator"),e.style.display="flex",this.messagesContainerTarget.appendChild(e),requestAnimationFrame(()=>{this.messagesContainerTarget.scroll({top:this.messagesContainerTarget.scrollHeight,behavior:"instant"})});const t=this.typingIndicatorKeepAliveValue;this.incomingTypingIndicatorTimeout=setTimeout(()=>{this.clearTypingIndicator()},t)}resetTypingIndicatorTimer(){if(!this.typingIndicatorVisible)return;clearTimeout(this.incomingTypingIndicatorTimeout),clearTimeout(this.optimisticTypingTimeout);const e=this.typingIndicatorKeepAliveValue;this.incomingTypingIndicatorTimeout=setTimeout(()=>{this.clearTypingIndicator()},e)}clearTypingIndicator(){this.hasTypingIndicatorTarget&&this.typingIndicatorTarget.remove(),this.typingIndicatorVisible=!1,clearTimeout(this.incomingTypingIndicatorTimeout),clearTimeout(this.optimisticTypingTimeout)}onMessageInputChange(){this.resizeInput(),clearTimeout(this.typingIndicatorTimeout),this.hasSentTypingIndicator||(this.webChatChannel.startTypingIndicator(),this.hasSentTypingIndicator=!0),this.typingIndicatorTimeout=setTimeout(()=>{this.hasSentTypingIndicator=!1},3e3)}onOutboundMessageSent(e){const{data:t}=e,s={"message:sent":e=>{const t=(new DOMParser).parseFromString(e.element,"text/html").body.firstElementChild;this.localizeMessageTimestamps(t),this.typingIndicatorVisible&&this.hasTypingIndicatorTarget?this.messagesContainerTarget.insertBefore(t,this.typingIndicatorTarget):this.messagesContainerTarget.appendChild(t),t.scrollIntoView({behavior:"instant"})},"message:failed":e=>{const t=this.messagesContainerTarget.querySelector(`#${e.id}`);this.markMessageFailed(t,e.reason)}};s[t.type]?s[t.type](t):console.log(`Unhandled message event: ${t.type}`)}async onScroll(){if(this.messagesContainerTarget.scrollTop>300||!this.nextPageValue||this.fetchingNextPage)return;this.fetchingNextPage=!0;const e=await this.messagesAPI.index({page:this.nextPageValue,session:gt.session}),{next:t,messages:s}=await e.json();this.nextPageValue=t,this.oldScrollHeight=this.messagesContainerTarget.scrollHeight,s.forEach(e=>{const{body:t,attachments:s}=e,n=e.created_at||e.createdAt,i=this.messageTemplateTarget.cloneNode(!0);i.classList.add("hellotext--webchat-message"),i.setAttribute("data-hellotext--webchat-target","message"),i.setAttribute("data-id",e.id),n&&i.setAttribute("data-created-at",n),i.style.removeProperty("display"),nt(i.querySelector("[data-body]"),t),"received"===e.state?i.classList.add("received"):i.classList.remove("received"),s&&s.forEach(e=>{const t=this.attachmentImageTarget.cloneNode(!0);t.removeAttribute("data-hellotext--webchat-target"),t.src=e,t.style.display="block",this.messageAttachmentsContainer(i)?.appendChild(t)}),i.setAttribute("data-body",t),this.localizeMessageTimestamp(i.querySelector("[data-message-timestamp]"),n),this.messagesContainerTarget.prepend(i)}),this.messagesContainerTarget.scroll({top:this.messagesContainerTarget.scrollHeight-this.oldScrollHeight,behavior:"instant"}),this.fetchingNextPage=!1}onClickOutside(e){u.mode===h.POPOVER&&this.openValue&&e.target.nodeType&&!1===this.element.contains(e.target)&&(this.openValue=!1)}closePopover(){this.clearPopoverOpenAnimation(),this.popoverTarget.classList.remove(...this.fadeOutClasses),this.openValue=!1}preparePopoverOpenAnimation(){this.clearPopoverOpenAnimation(),this.popoverTarget.classList.remove(...this.fadeOutClasses),this.popoverTarget.classList.add("hellotext--webchat-popover-opening"),this.popoverOpenAnimationTimeout=setTimeout(()=>{this.popoverTarget.classList.remove("hellotext--webchat-popover-opening"),this.popoverOpenAnimationTimeout=null},120)}clearPopoverOpenAnimation(){this.popoverOpenAnimationTimeout&&(clearTimeout(this.popoverOpenAnimationTimeout),this.popoverOpenAnimationTimeout=null),this.popoverTarget?.classList.remove("hellotext--webchat-popover-opening")}onPopoverOpened(){this.popoverTarget.classList.remove(...this.fadeOutClasses),this.dismissTeaserForSession?.(),this.onMobile||this.focusComposeInput(),this.scrolled||(requestAnimationFrame(()=>{this.messagesContainerTarget.scroll({top:this.messagesContainerTarget.scrollHeight,behavior:"instant"})}),this.scrolled=!0),gt.eventEmitter.dispatch("webchat:opened"),localStorage.setItem(`hellotext--webchat--${this.idValue}`,"opened"),this.messageTeaserValue&&(this.messageTeaserValue=null),this.startOpeningSequence(),"none"!==this.unreadCounterTarget.style.display&&(this.unreadCounterTarget.style.display="none",this.unreadCounterTarget.innerText="0",this.messagesAPI.markAsSeen())}onPopoverClosed(){this.clearPopoverOpenAnimation(),gt.eventEmitter.dispatch("webchat:closed"),localStorage.setItem(`hellotext--webchat--${this.idValue}`,"closed")}onMessageReaction(e){const{message:t,reaction:s,type:n}=e,i=this.messageTargets.find(e=>e.dataset.id===t).querySelector("[data-reactions]");if("reaction.destroy"===n)return i.querySelector(`[data-id="${s.id}"]`).remove();if(i.querySelector(`[data-id="${s.id}"]`))i.querySelector(`[data-id="${s.id}"]`).innerText=s.emoji;else{const e=document.createElement("span");e.innerText=s.emoji,e.setAttribute("data-id",s.id),i.appendChild(e)}}onMessageReceived(e,t={}){const{id:s,body:n,attachments:i,teaser:r}=e,a=e.created_at||e.createdAt;if(!this.claimMessageId(s))return;if(this.hideTeaser?.(),e.carousel)return this.insertCarouselMessage(e,t);const o=this.messageTemplateTarget.cloneNode(!0);o.classList.add("hellotext--webchat-message"),o.style.display="flex",nt(o.querySelector("[data-body]"),n),o.setAttribute("data-id",s),o.setAttribute("data-hellotext--webchat-target","message"),this.setMessageCreatedAt(o,a),this.localizeMessageTimestamp(o.querySelector("[data-message-timestamp]"),a),i&&i.forEach(e=>{const t=this.attachmentImageTarget.cloneNode(!0);t.src=e,t.style.display="block",this.messageAttachmentsContainer(o)?.appendChild(t)}),this.clearTypingIndicator(),this.insertMessageElement(o),gt.eventEmitter.dispatch("webchat:message:received",{...e,body:o.querySelector("[data-body]").innerText}),!1!==t.scroll&&o.scrollIntoView({behavior:"smooth"}),this.updateMessageTeaser(r),this.openValue?this.messagesAPI.markAsSeen(s):this.incrementUnreadCounter()}claimMessageId(e){const t=this.messageTargets||[];return!this.messageIds.has(e)&&(this.messageIds.add(e),!t.some(t=>t.dataset.id===e))}captureCatchUpCursor(){this.catchUpAfterMessageId=this.lastRenderedMessageId}async catchUpMessages(){const e=this.catchUpAfterMessageId;if(e&&!this.fetchingCatchUpMessages){this.fetchingCatchUpMessages=!0;try{const t=await this.messagesAPI.catchUp(e),{messages:s=[]}=await t.json();s.forEach(e=>this.onMessageReceived(e,{scroll:!1})),this.catchUpAfterMessageId=this.lastRenderedMessageId}finally{this.fetchingCatchUpMessages=!1}}}get lastRenderedMessageId(){const e=this.persistedMessageElements;return e[e.length-1]?.dataset.id||null}get persistedMessageElements(){return Array.from(this.messagesContainerTarget.querySelectorAll(".hellotext--webchat-message[data-id]"))}setMessageCreatedAt(e,t){t&&e.setAttribute("data-created-at",t)}insertMessageElement(e){const t=this.nextMessageElementFor(e);t?this.messagesContainerTarget.insertBefore(e,t):this.messagesContainerTarget.appendChild(e)}nextMessageElementFor(e){const t=Date.parse(e.dataset.createdAt);return Number.isNaN(t)?null:this.persistedMessageElements.find(s=>{if(s===e)return!1;const n=Date.parse(s.dataset.createdAt);return!Number.isNaN(n)&&n>t})}updateMessageTeaser(e){this.messageTeaserValue=e,this.messageTeaserValue&&this.hasTeaserTarget&&this.hasInboundMessageTeaserTarget&&this.hasInboundMessageTeaserBodyTarget&&(this.teaserMessageTargets.forEach(e=>e.classList.add("hidden")),this.inboundMessageTeaserBodyTarget.textContent=this.messageTeaserValue,this.inboundMessageTeaserTarget.classList.remove("hidden"),this.teaserTarget.classList.toggle("invisible",this.openValue))}insertCarouselMessage(e,t={}){const s=e.html,n=e.created_at||e.createdAt,i=function(e){return st(e,tt)}(s).firstElementChild;i.classList.add("hellotext--webchat-message"),i.setAttribute("data-id",e.id),i.setAttribute("data-hellotext--webchat-target","message"),this.setMessageCreatedAt(i,n),this.localizeMessageTimestamps(i),this.clearTypingIndicator(),this.insertMessageElement(i),!1!==t.scroll&&i.scrollIntoView({behavior:"smooth"}),gt.eventEmitter.dispatch("webchat:message:received",{...e,body:i.querySelector("[data-body]")?.innerText||""}),this.updateMessageTeaser(e.teaser),this.openValue?this.messagesAPI.markAsSeen(e.id):this.incrementUnreadCounter()}resizeInput(){this.inputTarget.style.height="auto";const e=this.inputTarget.scrollHeight;this.inputTarget.style.height=`${Math.min(e,96)}px`}async sendQuickReplyMessage({detail:{id:e,product:t,buttonId:s,body:n,cardElement:i}}){this.dismissTeaserForSession?.();const r=new FormData;r.append("message[body]",n),e&&r.append("message[replied_to]",e),t&&r.append("message[product]",t),s&&r.append("message[button]",s),r.append("session",gt.session),r.append("locale",o.toString()),this.appendOpeningSequenceMessageIds(r);const a=this.buildMessageElement(),c=i?.querySelector("img")?.cloneNode(!0);a.querySelector("[data-body]").innerText=n,c&&(c.removeAttribute("width"),c.removeAttribute("height"),this.messageAttachmentsContainer(a)?.appendChild(c)),this.typingIndicatorVisible&&this.hasTypingIndicatorTarget?this.messagesContainerTarget.insertBefore(a,this.typingIndicatorTarget):this.messagesContainerTarget.appendChild(a),a.scrollIntoView({behavior:"smooth"}),this.broadcastChannel.postMessage({type:"message:sent",element:a.outerHTML});const l=await this.messagesAPI.create(r);if(l.failed)return clearTimeout(this.optimisticTypingTimeout),this.markMessageFailedFromResponse(l,a);const h=await l.json();this.dispatch("set:id",{target:a,detail:h.id}),this.localizeMessageTimestamp(a.querySelector("[data-message-timestamp]"),h.created_at||h.createdAt),this.clearRevealedOpeningSequenceMessageIds();const u={id:h.id,body:n,attachments:c?[c.src]:[],replied_to:e,product:t,button:s,type:"quick_reply"};gt.eventEmitter.dispatch("webchat:message:sent",u)}async sendTeaserQuickReply(e){e.preventDefault(),e.stopPropagation();const t=e.currentTarget,s=(t.dataset.value||"").trim(),n=[t.dataset.text,t.textContent].map(e=>(e||"").trim()).find(e=>e.length>0),i=s||n;if(!i)return;this.dismissTeaserForSession?.(),this.show();const r=(t.dataset.type||"").trim()||"quick_reply",a=new FormData;a.append("message[body]",i),a.append("session",gt.session),a.append("locale",o.toString()),this.appendOpeningSequenceMessageIds(a);const c=this.buildMessageElement();c.querySelector("[data-body]").innerText=i,this.typingIndicatorVisible&&this.hasTypingIndicatorTarget?this.messagesContainerTarget.insertBefore(c,this.typingIndicatorTarget):this.messagesContainerTarget.appendChild(c),c.scrollIntoView({behavior:"smooth"}),this.broadcastChannel.postMessage({type:"message:sent",element:c.outerHTML}),this.typingIndicatorVisible||(clearTimeout(this.optimisticTypingTimeout),this.optimisticTypingTimeout=setTimeout(()=>{this.showOptimisticTypingIndicator()},this.optimisticTypingIndicatorWaitValue));const l=await this.messagesAPI.create(a);if(l.failed)return clearTimeout(this.optimisticTypingTimeout),this.markMessageFailedFromResponse(l,c);const h=await l.json();c.setAttribute("data-id",h.id),this.localizeMessageTimestamp(c.querySelector("[data-message-timestamp]"),h.created_at||h.createdAt),this.clearRevealedOpeningSequenceMessageIds(),gt.eventEmitter.dispatch("webchat:message:sent",{id:h.id,body:i,attachments:[],type:"quick_reply",teaser:{text:n||i,value:s||i,type:r}}),h.conversation&&h.conversation!==this.conversationIdValue&&(this.conversationIdValue=h.conversation,this.webChatChannel.updateSubscriptionWith(this.conversationIdValue)),this.typingIndicatorVisible&&this.resetTypingIndicatorTimer()}async sendMessage(e){const t={body:this.inputTarget.value,attachments:this.files};if(0===this.inputTarget.value.trim().length&&0===this.files.length)return void(e&&e.target&&e.preventDefault());this.dismissTeaserForSession?.();const s=new FormData;this.inputTarget.value.trim().length>0?s.append("message[body]",this.inputTarget.value):delete t.body,this.files.forEach(e=>{s.append("message[attachments][]",e)}),s.append("session",gt.session),s.append("locale",o.toString()),this.appendOpeningSequenceMessageIds(s);const n=this.buildMessageElement();this.inputTarget.value.trim().length>0?n.querySelector("[data-body]").innerText=this.inputTarget.value:n.querySelector("[data-message-bubble]").remove();const i=this.attachmentContainerTarget.querySelectorAll("img");i.length>0&&i.forEach(e=>{this.messageAttachmentsContainer(n)?.appendChild(e.cloneNode(!0))}),this.typingIndicatorVisible&&this.hasTypingIndicatorTarget?this.messagesContainerTarget.insertBefore(n,this.typingIndicatorTarget):this.messagesContainerTarget.appendChild(n),n.scrollIntoView({behavior:"smooth"}),this.broadcastChannel.postMessage({type:"message:sent",element:n.outerHTML}),this.inputTarget.value="",this.resizeInput(),this.files=[],this.attachmentInputTarget.value="",this.attachmentContainerTarget.innerHTML="",this.attachmentContainerTarget.style.display="none",this.errorMessageContainerTarget.style.display="none",this.focusComposeInput(),this.typingIndicatorVisible||(clearTimeout(this.optimisticTypingTimeout),this.optimisticTypingTimeout=setTimeout(()=>{this.showOptimisticTypingIndicator()},this.optimisticTypingIndicatorWaitValue));const r=await this.messagesAPI.create(s);if(r.failed)return clearTimeout(this.optimisticTypingTimeout),this.markMessageFailedFromResponse(r,n);const a=await r.json();n.setAttribute("data-id",a.id),t.id=a.id,this.localizeMessageTimestamp(n.querySelector("[data-message-timestamp]"),a.created_at||a.createdAt),this.clearRevealedOpeningSequenceMessageIds(),gt.eventEmitter.dispatch("webchat:message:sent",t),a.conversation!==this.conversationIdValue&&(this.conversationIdValue=a.conversation,this.webChatChannel.updateSubscriptionWith(this.conversationIdValue)),this.typingIndicatorVisible&&this.resetTypingIndicatorTimer(),this.attachmentContainerTarget.style.display=""}buildMessageElement(){const e=this.messageTemplateTarget.cloneNode(!0);return e.id=`hellotext--webchat--${this.idValue}--message--${Date.now()}`,e.classList.add("received"),e.style.removeProperty("display"),e.setAttribute("data-controller","hellotext--message"),e.setAttribute("data-hellotext--webchat-target","message"),this.localizeMessageTimestamp(e.querySelector("[data-message-timestamp]"),new Date),e}focusCompose(e){const{target:t}=e,s=["button","a","input","textarea","select","label",'[role="button"]',"em-emoji-picker",'[data-hellotext--webchat--emoji-target~="popover"]','[data-controller~="hellotext--webchat--emoji"]'].join(", ");this.hasInputTarget&&!t.closest(s)&&this.focusComposeInput({moveCursorToEnd:!0})&&e.preventDefault()}closePopoverFromHeader(e){const{target:t}=e;t.closest(".hellotext--webchat-header-channel-button, .hellotext--webchat-close-button")||(e.preventDefault(),this.closePopover())}closePopoverOnEscape(e){"Escape"===e.key&&this.openValue&&(e.preventDefault(),e.stopPropagation(),this.closePopover(),this.triggerTarget?.focus?.())}async markMessageFailedFromResponse(e,t){const s=await this.messageFailureReason(e);this.markMessageFailed(t,s),this.broadcastChannel.postMessage({type:"message:failed",id:t.id,reason:s})}markMessageFailed(e,t){if(!e)return;if(e.classList.add("failed"),!t)return;const s=e.querySelector("[data-message-timestamp]");s&&(s.textContent=t)}localizeMessageTimestamps(e=this.element){e&&(e.matches?.("time[datetime][data-message-timestamp]")?[e]:Array.from(e.querySelectorAll?.("time[datetime][data-message-timestamp]")||[])).forEach(e=>this.localizeMessageTimestamp(e))}localizeMessageTimestamp(e,t=e?.getAttribute("datetime")){if(!e||!t)return;const s=t instanceof Date?t:new Date(t);Number.isNaN(s.getTime())||(e.setAttribute("datetime",s.toISOString()),e.textContent=this.formatMessageTimestamp(s))}formatMessageTimestamp(e){return this.constructor.messageTimestampFormatterFor(o.toString()).format(e)}static messageTimestampFormatterFor(e){const t=e||"default";return this.messageTimestampFormatters[t]||(this.messageTimestampFormatters[t]=this.buildMessageTimestampFormatter(e)),this.messageTimestampFormatters[t]}static buildMessageTimestampFormatter(e){try{return new Intl.DateTimeFormat(e||void 0,Ys)}catch(e){return new Intl.DateTimeFormat(void 0,Ys)}}async messageFailureReason(e){const t=e?.data||e?.response,s=t?.statusText||"Message failed";try{const e=t?.clone?t.clone():t,s=await(e?.json?.()),n=this.messageFailureReasonFromPayload(s);if(n)return n}catch(e){}try{const e=t?.clone?t.clone():t,n=await(e?.text?.());return this.messageFailureReasonFromText(n)||s}catch(e){return s}}messageFailureReasonFromText(e){if("string"!=typeof e)return null;const t=e.trim();if(!t||t.startsWith("<"))return null;try{return this.messageFailureReasonFromPayload(JSON.parse(t))||t}catch(e){return t}}messageFailureReasonFromPayload(e){return e?[e.error?.message,e.message,e.errors?.message,e.errors?.[0]?.message,e.errors?.[0]?.description].find(e=>"string"==typeof e&&e.trim().length>0):null}messageAttachmentsContainer(e){return e.querySelector("[data-attachments-container], [data-attachment-container]")}incrementUnreadCounter(){this.unreadCounterTarget.style.display="flex";const e=(parseInt(this.unreadCounterTarget.innerText)||0)+1;this.unreadCounterTarget.innerText=Math.min(e,9)}openAttachment(){this.attachmentInputTarget.click()}onFileInputChange(){this.errorMessageContainerTarget.style.display="none";const e=Array.from(this.attachmentInputTarget.files);this.attachmentInputTarget.value="";const t=e.find(e=>{const t=e.type.split("/")[0];return["image","video","audio"].includes(t)?this.mediaValue[t].max_sizethis.createAttachmentElement(e)),this.focusComposeInput()}createAttachmentElement(e){const t=this.attachmentElement();if(this.attachmentContainerTarget.style.display="",t.setAttribute("data-name",e.name),e.type.startsWith("image/")){const s=this.attachmentImageTarget.cloneNode(!0);s.src=URL.createObjectURL(e),s.style.display="block",t.appendChild(s),this.attachmentContainerTarget.appendChild(t),this.attachmentContainerTarget.style.display="flex"}else{const s=t.querySelector("main");s.style.height="5rem",s.style.borderRadius="0.375rem",s.style.backgroundColor="#e5e7eb",s.style.padding="0.25rem",t.querySelector("p[data-attachment-name]").innerText=e.name,this.attachmentContainerTarget.appendChild(t),this.attachmentContainerTarget.style.display="flex"}}removeAttachment({currentTarget:e}){const t=e.closest("[data-hellotext--webchat-target='attachment']");this.files=this.files.filter(e=>e.name!==t.dataset.name),this.attachmentInputTarget.value="",t.remove(),this.focusComposeInput()}attachmentTargetDisconnected(){0===this.attachmentTargets.length&&(this.attachmentContainerTarget.innerHTML="",this.attachmentContainerTarget.style.display="none")}attachmentElement(){const e=this.attachmentTemplateTarget.cloneNode(!0);return e.removeAttribute("hidden"),e.style.display="flex",e.setAttribute("data-hellotext--webchat-target","attachment"),e}onEmojiSelect({detail:e}){const t=this.inputTarget.value,s=this.inputTarget.selectionStart,n=this.inputTarget.selectionEnd;this.inputTarget.value=t.slice(0,s)+e+t.slice(n),this.inputTarget.selectionStart=this.inputTarget.selectionEnd=s+e.length,this.focusComposeInput()}focusComposeInput({moveCursorToEnd:e=!1}={}){if(!this.shouldAutofocusCompose)return!1;if(!1===this.hasInputTarget)return!1;if(void 0===this.hasInputTarget&&!this.inputTarget)return!1;if(this.inputTarget.focus(),e&&"number"==typeof this.inputTarget.selectionStart){const e=this.inputTarget.value.length;this.inputTarget.setSelectionRange(e,e)}return!0}byteToMegabyte(e){return Math.ceil(e/1024/1024)}get middlewares(){return[Rs(this.offsetValue),js({padding:this.paddingValue}),Bs()]}get shouldOpenOnMount(){return"opened"===localStorage.getItem(`hellotext--webchat--${this.idValue}`)&&!this.onMobile}get shouldAutofocusCompose(){return!this.usesVirtualKeyboard}get usesVirtualKeyboard(){if("undefined"==typeof navigator)return!1;const e=navigator.userAgent||"",t="MacIntel"===navigator.platform&&navigator.maxTouchPoints>1,s=Zs.test(e),n=!0===navigator.userAgentData?.mobile;return s||t||n||this.hasTouchOnlyPointer}get hasTouchOnlyPointer(){return"undefined"!=typeof window&&"function"==typeof window.matchMedia&&window.matchMedia("(pointer: coarse)").matches&&window.matchMedia("(hover: none)").matches}get onMobile(){return"undefined"!=typeof window&&"function"==typeof window.matchMedia&&window.matchMedia(`(max-width: ${this.fullScreenThresholdValue}px)`).matches}},en=n.lg.start();en.register("hellotext--form",ft),en.register("hellotext--webchat",Qs),en.register("hellotext--webchat--emoji",Vs),en.register("hellotext--message",bt),window.Hellotext=gt;const tn=gt}};const t={};function s(n){const i=t[n];if(void 0!==i)return i.exports;const r=t[n]={exports:{}};return e[n](r,r.exports,s),r.exports}s.m=e,(()=>{const e=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;let t;s.t=function(n,i){if(1&i&&(n=this(n)),8&i)return n;if("object"==typeof n&&n){if(4&i&&n.__esModule)return n;if(16&i&&"function"==typeof n.then)return n}const r=Object.create(null);s.r(r);const a={};t=t||[null,e({}),e([]),e(e)];for(var o=2&i&&n;("object"==typeof o||"function"==typeof o)&&!~t.indexOf(o);o=e(o))Object.getOwnPropertyNames(o).forEach(e=>a[e]=()=>n[e]);return a.default=()=>n,s.d(r,a),r}})(),s.d=(e,t)=>{if(Array.isArray(t))for(var n=0;nPromise.all(Object.keys(s.f).reduce((t,n)=>(s.f[n](e,t),t),[])),s.u=e=>({160:"webchat-emoji",200:"webchat-emoji-en",437:"webchat-emoji-es"}[e]+".js"),s.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),s.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{const e={},t="Hellotext:";s.l=(n,i,r,a)=>{if(e[n])return void e[n].push(i);let o,c;if(void 0!==r){const e=document.getElementsByTagName("script");for(var l=0;l{o.onerror=o.onload=null,clearTimeout(u);const i=e[n];if(delete e[n],o.parentNode?.removeChild(o),i?.forEach(e=>e(s)),t)return t(s)},u=setTimeout(h.bind(null,void 0,{type:"timeout",target:o}),12e4);o.onerror=h.bind(null,o.onerror),o.onload=h.bind(null,o.onload),c&&document.head.appendChild(o)}})(),s.r=e=>{Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{let e;s.g.importScripts&&(e=s.g.location+"");const t=s.g.document;if(!e&&t&&("SCRIPT"===t.currentScript?.tagName.toUpperCase()&&(e=t.currentScript.src),!e)){const s=t.getElementsByTagName("script");if(s.length){let t=s.length-1;for(;t>-1&&(!e||!/^http(s?):/.test(e));)e=s[t--].src}}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),s.p=e})(),(()=>{const e={792:0};s.f.j=(t,n)=>{let i=s.o(e,t)?e[t]:void 0;if(0!==i)if(i)n.push(i[2]);else{const r=new Promise((s,n)=>i=e[t]=[s,n]);n.push(i[2]=r);const a=s.p+s.u(t),o=new Error,c=n=>{if(s.o(e,t)&&(i=e[t],0!==i&&(e[t]=void 0),i)){const e=n&&("load"===n.type?"missing":n.type),s=n&&n.target&&n.target.src;o.message="Loading chunk "+t+" failed.\n("+e+": "+s+")",o.name="ChunkLoadError",o.type=e,o.request=s,i[1](o)}};s.l(a,c,"chunk-"+t,t)}};const t=(t,n)=>{let[i,r,a]=n;var o,c,l=0;if(i.some(t=>0!==e[t])){for(o in r)s.o(r,o)&&(s.m[o]=r[o]);a&&a(s)}for(t&&t(n);l(()=>{"use strict";var e={891(e,t,s){s.d(t,{lg:()=>G,xI:()=>ne});class i{constructor(e,t,s){this.eventTarget=e,this.eventName=t,this.eventOptions=s,this.unorderedBindings=new Set}connect(){this.eventTarget.addEventListener(this.eventName,this,this.eventOptions)}disconnect(){this.eventTarget.removeEventListener(this.eventName,this,this.eventOptions)}bindingConnected(e){this.unorderedBindings.add(e)}bindingDisconnected(e){this.unorderedBindings.delete(e)}handleEvent(e){const t=function(e){if("immediatePropagationStopped"in e)return e;{const{stopImmediatePropagation:t}=e;return Object.assign(e,{immediatePropagationStopped:!1,stopImmediatePropagation(){this.immediatePropagationStopped=!0,t.call(this)}})}}(e);for(const e of this.bindings){if(t.immediatePropagationStopped)break;e.handleEvent(t)}}hasBindings(){return this.unorderedBindings.size>0}get bindings(){return Array.from(this.unorderedBindings).sort((e,t)=>{const s=e.index,i=t.index;return si?1:0})}}class n{constructor(e){this.application=e,this.eventListenerMaps=new Map,this.started=!1}start(){this.started||(this.started=!0,this.eventListeners.forEach(e=>e.connect()))}stop(){this.started&&(this.started=!1,this.eventListeners.forEach(e=>e.disconnect()))}get eventListeners(){return Array.from(this.eventListenerMaps.values()).reduce((e,t)=>e.concat(Array.from(t.values())),[])}bindingConnected(e){this.fetchEventListenerForBinding(e).bindingConnected(e)}bindingDisconnected(e,t=!1){this.fetchEventListenerForBinding(e).bindingDisconnected(e),t&&this.clearEventListenersForBinding(e)}handleError(e,t,s={}){this.application.handleError(e,`Error ${t}`,s)}clearEventListenersForBinding(e){const t=this.fetchEventListenerForBinding(e);t.hasBindings()||(t.disconnect(),this.removeMappedEventListenerFor(e))}removeMappedEventListenerFor(e){const{eventTarget:t,eventName:s,eventOptions:i}=e,n=this.fetchEventListenerMapForEventTarget(t),r=this.cacheKey(s,i);n.delete(r),0==n.size&&this.eventListenerMaps.delete(t)}fetchEventListenerForBinding(e){const{eventTarget:t,eventName:s,eventOptions:i}=e;return this.fetchEventListener(t,s,i)}fetchEventListener(e,t,s){const i=this.fetchEventListenerMapForEventTarget(e),n=this.cacheKey(t,s);let r=i.get(n);return r||(r=this.createEventListener(e,t,s),i.set(n,r)),r}createEventListener(e,t,s){const n=new i(e,t,s);return this.started&&n.connect(),n}fetchEventListenerMapForEventTarget(e){let t=this.eventListenerMaps.get(e);return t||(t=new Map,this.eventListenerMaps.set(e,t)),t}cacheKey(e,t){const s=[e];return Object.keys(t).sort().forEach(e=>{s.push(`${t[e]?"":"!"}${e}`)}),s.join(":")}}const r={stop:({event:e,value:t})=>(t&&e.stopPropagation(),!0),prevent:({event:e,value:t})=>(t&&e.preventDefault(),!0),self:({event:e,value:t,element:s})=>!t||s===e.target},a=/^(?:(?:([^.]+?)\+)?(.+?)(?:\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;function o(e){return e.replace(/(?:[_-])([a-z0-9])/g,(e,t)=>t.toUpperCase())}function c(e){return o(e.replace(/--/g,"-").replace(/__/g,"_"))}function l(e){return e.charAt(0).toUpperCase()+e.slice(1)}function h(e){return e.replace(/([A-Z])/g,(e,t)=>`-${t.toLowerCase()}`)}function u(e){return null!=e}function d(e,t){return Object.prototype.hasOwnProperty.call(e,t)}const p=["meta","ctrl","alt","shift"];class m{constructor(e,t,s,i){this.element=e,this.index=t,this.eventTarget=s.eventTarget||e,this.eventName=s.eventName||function(e){const t=e.tagName.toLowerCase();if(t in g)return g[t](e)}(e)||f("missing event name"),this.eventOptions=s.eventOptions||{},this.identifier=s.identifier||f("missing identifier"),this.methodName=s.methodName||f("missing method name"),this.keyFilter=s.keyFilter||"",this.schema=i}static forToken(e,t){return new this(e.element,e.index,function(e){const t=e.trim().match(a)||[];let s=t[2],i=t[3];return i&&!["keydown","keyup","keypress"].includes(s)&&(s+=`.${i}`,i=""),{eventTarget:(n=t[4],"window"==n?window:"document"==n?document:void 0),eventName:s,eventOptions:t[7]?(r=t[7],r.split(":").reduce((e,t)=>Object.assign(e,{[t.replace(/^!/,"")]:!/^!/.test(t)}),{})):{},identifier:t[5],methodName:t[6],keyFilter:t[1]||i};var n,r}(e.content),t)}toString(){const e=this.keyFilter?`.${this.keyFilter}`:"",t=this.eventTargetName?`@${this.eventTargetName}`:"";return`${this.eventName}${e}${t}->${this.identifier}#${this.methodName}`}shouldIgnoreKeyboardEvent(e){if(!this.keyFilter)return!1;const t=this.keyFilter.split("+");if(this.keyFilterDissatisfied(e,t))return!0;const s=t.filter(e=>!p.includes(e))[0];return!!s&&(d(this.keyMappings,s)||f(`contains unknown key filter: ${this.keyFilter}`),this.keyMappings[s].toLowerCase()!==e.key.toLowerCase())}shouldIgnoreMouseEvent(e){if(!this.keyFilter)return!1;const t=[this.keyFilter];return!!this.keyFilterDissatisfied(e,t)}get params(){const e={},t=new RegExp(`^data-${this.identifier}-(.+)-param$`,"i");for(const{name:s,value:i}of Array.from(this.element.attributes)){const n=s.match(t),r=n&&n[1];r&&(e[o(r)]=b(i))}return e}get eventTargetName(){return(e=this.eventTarget)==window?"window":e==document?"document":void 0;var e}get keyMappings(){return this.schema.keyMappings}keyFilterDissatisfied(e,t){const[s,i,n,r]=p.map(e=>t.includes(e));return e.metaKey!==s||e.ctrlKey!==i||e.altKey!==n||e.shiftKey!==r}}const g={a:()=>"click",button:()=>"click",form:()=>"submit",details:()=>"toggle",input:e=>"submit"==e.getAttribute("type")?"click":"input",select:()=>"change",textarea:()=>"input"};function f(e){throw new Error(e)}function b(e){try{return JSON.parse(e)}catch(t){return e}}class y{constructor(e,t){this.context=e,this.action=t}get index(){return this.action.index}get eventTarget(){return this.action.eventTarget}get eventOptions(){return this.action.eventOptions}get identifier(){return this.context.identifier}handleEvent(e){const t=this.prepareActionEvent(e);this.willBeInvokedByEvent(e)&&this.applyEventModifiers(t)&&this.invokeWithEvent(t)}get eventName(){return this.action.eventName}get method(){const e=this.controller[this.methodName];if("function"==typeof e)return e;throw new Error(`Action "${this.action}" references undefined method "${this.methodName}"`)}applyEventModifiers(e){const{element:t}=this.action,{actionDescriptorFilters:s}=this.context.application,{controller:i}=this.context;let n=!0;for(const[r,a]of Object.entries(this.eventOptions))if(r in s){const o=s[r];n=n&&o({name:r,value:a,event:e,element:t,controller:i})}return n}prepareActionEvent(e){return Object.assign(e,{params:this.action.params})}invokeWithEvent(e){const{target:t,currentTarget:s}=e;try{this.method.call(this.controller,e),this.context.logDebugActivity(this.methodName,{event:e,target:t,currentTarget:s,action:this.methodName})}catch(t){const{identifier:s,controller:i,element:n,index:r}=this,a={identifier:s,controller:i,element:n,index:r,event:e};this.context.handleError(t,`invoking action "${this.action}"`,a)}}willBeInvokedByEvent(e){const t=e.target;return!(e instanceof KeyboardEvent&&this.action.shouldIgnoreKeyboardEvent(e))&&!(e instanceof MouseEvent&&this.action.shouldIgnoreMouseEvent(e))&&(this.element===t||(t instanceof Element&&this.element.contains(t)?this.scope.containsElement(t):this.scope.containsElement(this.action.element)))}get controller(){return this.context.controller}get methodName(){return this.action.methodName}get element(){return this.scope.element}get scope(){return this.context.scope}}class v{constructor(e,t){this.mutationObserverInit={attributes:!0,childList:!0,subtree:!0},this.element=e,this.started=!1,this.delegate=t,this.elements=new Set,this.mutationObserver=new MutationObserver(e=>this.processMutations(e))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,this.mutationObserverInit),this.refresh())}pause(e){this.started&&(this.mutationObserver.disconnect(),this.started=!1),e(),this.started||(this.mutationObserver.observe(this.element,this.mutationObserverInit),this.started=!0)}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started){const e=new Set(this.matchElementsInTree());for(const t of Array.from(this.elements))e.has(t)||this.removeElement(t);for(const t of Array.from(e))this.addElement(t)}}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){"attributes"==e.type?this.processAttributeChange(e.target,e.attributeName):"childList"==e.type&&(this.processRemovedNodes(e.removedNodes),this.processAddedNodes(e.addedNodes))}processAttributeChange(e,t){this.elements.has(e)?this.delegate.elementAttributeChanged&&this.matchElement(e)?this.delegate.elementAttributeChanged(e,t):this.removeElement(e):this.matchElement(e)&&this.addElement(e)}processRemovedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.processTree(e,this.removeElement)}}processAddedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.elementIsActive(e)&&this.processTree(e,this.addElement)}}matchElement(e){return this.delegate.matchElement(e)}matchElementsInTree(e=this.element){return this.delegate.matchElementsInTree(e)}processTree(e,t){for(const s of this.matchElementsInTree(e))t.call(this,s)}elementFromNode(e){if(e.nodeType==Node.ELEMENT_NODE)return e}elementIsActive(e){return e.isConnected==this.element.isConnected&&this.element.contains(e)}addElement(e){this.elements.has(e)||this.elementIsActive(e)&&(this.elements.add(e),this.delegate.elementMatched&&this.delegate.elementMatched(e))}removeElement(e){this.elements.has(e)&&(this.elements.delete(e),this.delegate.elementUnmatched&&this.delegate.elementUnmatched(e))}}class w{constructor(e,t,s){this.attributeName=t,this.delegate=s,this.elementObserver=new v(e,this)}get element(){return this.elementObserver.element}get selector(){return`[${this.attributeName}]`}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get started(){return this.elementObserver.started}matchElement(e){return e.hasAttribute(this.attributeName)}matchElementsInTree(e){const t=this.matchElement(e)?[e]:[],s=Array.from(e.querySelectorAll(this.selector));return t.concat(s)}elementMatched(e){this.delegate.elementMatchedAttribute&&this.delegate.elementMatchedAttribute(e,this.attributeName)}elementUnmatched(e){this.delegate.elementUnmatchedAttribute&&this.delegate.elementUnmatchedAttribute(e,this.attributeName)}elementAttributeChanged(e,t){this.delegate.elementAttributeValueChanged&&this.attributeName==t&&this.delegate.elementAttributeValueChanged(e,t)}}function T(e,t){let s=e.get(t);return s||(s=new Set,e.set(t,s)),s}class S{constructor(){this.valuesByKey=new Map}get keys(){return Array.from(this.valuesByKey.keys())}get values(){return Array.from(this.valuesByKey.values()).reduce((e,t)=>e.concat(Array.from(t)),[])}get size(){return Array.from(this.valuesByKey.values()).reduce((e,t)=>e+t.size,0)}add(e,t){!function(e,t,s){T(e,t).add(s)}(this.valuesByKey,e,t)}delete(e,t){!function(e,t,s){T(e,t).delete(s),function(e,t){const s=e.get(t);null!=s&&0==s.size&&e.delete(t)}(e,t)}(this.valuesByKey,e,t)}has(e,t){const s=this.valuesByKey.get(e);return null!=s&&s.has(t)}hasKey(e){return this.valuesByKey.has(e)}hasValue(e){return Array.from(this.valuesByKey.values()).some(t=>t.has(e))}getValuesForKey(e){const t=this.valuesByKey.get(e);return t?Array.from(t):[]}getKeysForValue(e){return Array.from(this.valuesByKey).filter(([t,s])=>s.has(e)).map(([e,t])=>e)}}class C{constructor(e,t,s,i){this._selector=t,this.details=i,this.elementObserver=new v(e,this),this.delegate=s,this.matchesByElement=new S}get started(){return this.elementObserver.started}get selector(){return this._selector}set selector(e){this._selector=e,this.refresh()}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get element(){return this.elementObserver.element}matchElement(e){const{selector:t}=this;if(t){const s=e.matches(t);return this.delegate.selectorMatchElement?s&&this.delegate.selectorMatchElement(e,this.details):s}return!1}matchElementsInTree(e){const{selector:t}=this;if(t){const s=this.matchElement(e)?[e]:[],i=Array.from(e.querySelectorAll(t)).filter(e=>this.matchElement(e));return s.concat(i)}return[]}elementMatched(e){const{selector:t}=this;t&&this.selectorMatched(e,t)}elementUnmatched(e){const t=this.matchesByElement.getKeysForValue(e);for(const s of t)this.selectorUnmatched(e,s)}elementAttributeChanged(e,t){const{selector:s}=this;if(s){const t=this.matchElement(e),i=this.matchesByElement.has(s,e);t&&!i?this.selectorMatched(e,s):!t&&i&&this.selectorUnmatched(e,s)}}selectorMatched(e,t){this.delegate.selectorMatched(e,t,this.details),this.matchesByElement.add(t,e)}selectorUnmatched(e,t){this.delegate.selectorUnmatched(e,t,this.details),this.matchesByElement.delete(t,e)}}class O{constructor(e,t){this.element=e,this.delegate=t,this.started=!1,this.stringMap=new Map,this.mutationObserver=new MutationObserver(e=>this.processMutations(e))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,{attributes:!0,attributeOldValue:!0}),this.refresh())}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started)for(const e of this.knownAttributeNames)this.refreshAttribute(e,null)}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){const t=e.attributeName;t&&this.refreshAttribute(t,e.oldValue)}refreshAttribute(e,t){const s=this.delegate.getStringMapKeyForAttribute(e);if(null!=s){this.stringMap.has(e)||this.stringMapKeyAdded(s,e);const i=this.element.getAttribute(e);if(this.stringMap.get(e)!=i&&this.stringMapValueChanged(i,s,t),null==i){const t=this.stringMap.get(e);this.stringMap.delete(e),t&&this.stringMapKeyRemoved(s,e,t)}else this.stringMap.set(e,i)}}stringMapKeyAdded(e,t){this.delegate.stringMapKeyAdded&&this.delegate.stringMapKeyAdded(e,t)}stringMapValueChanged(e,t,s){this.delegate.stringMapValueChanged&&this.delegate.stringMapValueChanged(e,t,s)}stringMapKeyRemoved(e,t,s){this.delegate.stringMapKeyRemoved&&this.delegate.stringMapKeyRemoved(e,t,s)}get knownAttributeNames(){return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)))}get currentAttributeNames(){return Array.from(this.element.attributes).map(e=>e.name)}get recordedAttributeNames(){return Array.from(this.stringMap.keys())}}class A{constructor(e,t,s){this.attributeObserver=new w(e,t,this),this.delegate=s,this.tokensByElement=new S}get started(){return this.attributeObserver.started}start(){this.attributeObserver.start()}pause(e){this.attributeObserver.pause(e)}stop(){this.attributeObserver.stop()}refresh(){this.attributeObserver.refresh()}get element(){return this.attributeObserver.element}get attributeName(){return this.attributeObserver.attributeName}elementMatchedAttribute(e){this.tokensMatched(this.readTokensForElement(e))}elementAttributeValueChanged(e){const[t,s]=this.refreshTokensForElement(e);this.tokensUnmatched(t),this.tokensMatched(s)}elementUnmatchedAttribute(e){this.tokensUnmatched(this.tokensByElement.getValuesForKey(e))}tokensMatched(e){e.forEach(e=>this.tokenMatched(e))}tokensUnmatched(e){e.forEach(e=>this.tokenUnmatched(e))}tokenMatched(e){this.delegate.tokenMatched(e),this.tokensByElement.add(e.element,e)}tokenUnmatched(e){this.delegate.tokenUnmatched(e),this.tokensByElement.delete(e.element,e)}refreshTokensForElement(e){const t=this.tokensByElement.getValuesForKey(e),s=this.readTokensForElement(e),i=function(e,t){const s=Math.max(e.length,t.length);return Array.from({length:s},(s,i)=>[e[i],t[i]])}(t,s).findIndex(([e,t])=>{return i=t,!((s=e)&&i&&s.index==i.index&&s.content==i.content);var s,i});return-1==i?[[],[]]:[t.slice(i),s.slice(i)]}readTokensForElement(e){const t=this.attributeName;return function(e,t,s){return e.trim().split(/\s+/).filter(e=>e.length).map((e,i)=>({element:t,attributeName:s,content:e,index:i}))}(e.getAttribute(t)||"",e,t)}}class E{constructor(e,t,s){this.tokenListObserver=new A(e,t,this),this.delegate=s,this.parseResultsByToken=new WeakMap,this.valuesByTokenByElement=new WeakMap}get started(){return this.tokenListObserver.started}start(){this.tokenListObserver.start()}stop(){this.tokenListObserver.stop()}refresh(){this.tokenListObserver.refresh()}get element(){return this.tokenListObserver.element}get attributeName(){return this.tokenListObserver.attributeName}tokenMatched(e){const{element:t}=e,{value:s}=this.fetchParseResultForToken(e);s&&(this.fetchValuesByTokenForElement(t).set(e,s),this.delegate.elementMatchedValue(t,s))}tokenUnmatched(e){const{element:t}=e,{value:s}=this.fetchParseResultForToken(e);s&&(this.fetchValuesByTokenForElement(t).delete(e),this.delegate.elementUnmatchedValue(t,s))}fetchParseResultForToken(e){let t=this.parseResultsByToken.get(e);return t||(t=this.parseToken(e),this.parseResultsByToken.set(e,t)),t}fetchValuesByTokenForElement(e){let t=this.valuesByTokenByElement.get(e);return t||(t=new Map,this.valuesByTokenByElement.set(e,t)),t}parseToken(e){try{return{value:this.delegate.parseValueForToken(e)}}catch(e){return{error:e}}}}class x{constructor(e,t){this.context=e,this.delegate=t,this.bindingsByAction=new Map}start(){this.valueListObserver||(this.valueListObserver=new E(this.element,this.actionAttribute,this),this.valueListObserver.start())}stop(){this.valueListObserver&&(this.valueListObserver.stop(),delete this.valueListObserver,this.disconnectAllActions())}get element(){return this.context.element}get identifier(){return this.context.identifier}get actionAttribute(){return this.schema.actionAttribute}get schema(){return this.context.schema}get bindings(){return Array.from(this.bindingsByAction.values())}connectAction(e){const t=new y(this.context,e);this.bindingsByAction.set(e,t),this.delegate.bindingConnected(t)}disconnectAction(e){const t=this.bindingsByAction.get(e);t&&(this.bindingsByAction.delete(e),this.delegate.bindingDisconnected(t))}disconnectAllActions(){this.bindings.forEach(e=>this.delegate.bindingDisconnected(e,!0)),this.bindingsByAction.clear()}parseValueForToken(e){const t=m.forToken(e,this.schema);if(t.identifier==this.identifier)return t}elementMatchedValue(e,t){this.connectAction(t)}elementUnmatchedValue(e,t){this.disconnectAction(t)}}class M{constructor(e,t){this.context=e,this.receiver=t,this.stringMapObserver=new O(this.element,this),this.valueDescriptorMap=this.controller.valueDescriptorMap}start(){this.stringMapObserver.start(),this.invokeChangedCallbacksForDefaultValues()}stop(){this.stringMapObserver.stop()}get element(){return this.context.element}get controller(){return this.context.controller}getStringMapKeyForAttribute(e){if(e in this.valueDescriptorMap)return this.valueDescriptorMap[e].name}stringMapKeyAdded(e,t){const s=this.valueDescriptorMap[t];this.hasValue(e)||this.invokeChangedCallback(e,s.writer(this.receiver[e]),s.writer(s.defaultValue))}stringMapValueChanged(e,t,s){const i=this.valueDescriptorNameMap[t];null!==e&&(null===s&&(s=i.writer(i.defaultValue)),this.invokeChangedCallback(t,e,s))}stringMapKeyRemoved(e,t,s){const i=this.valueDescriptorNameMap[e];this.hasValue(e)?this.invokeChangedCallback(e,i.writer(this.receiver[e]),s):this.invokeChangedCallback(e,i.writer(i.defaultValue),s)}invokeChangedCallbacksForDefaultValues(){for(const{key:e,name:t,defaultValue:s,writer:i}of this.valueDescriptors)null==s||this.controller.data.has(e)||this.invokeChangedCallback(t,i(s),void 0)}invokeChangedCallback(e,t,s){const i=`${e}Changed`,n=this.receiver[i];if("function"==typeof n){const i=this.valueDescriptorNameMap[e];try{const e=i.reader(t);let r=s;s&&(r=i.reader(s)),n.call(this.receiver,e,r)}catch(e){throw e instanceof TypeError&&(e.message=`Stimulus Value "${this.context.identifier}.${i.name}" - ${e.message}`),e}}}get valueDescriptors(){const{valueDescriptorMap:e}=this;return Object.keys(e).map(t=>e[t])}get valueDescriptorNameMap(){const e={};return Object.keys(this.valueDescriptorMap).forEach(t=>{const s=this.valueDescriptorMap[t];e[s.name]=s}),e}hasValue(e){const t=`has${l(this.valueDescriptorNameMap[e].name)}`;return this.receiver[t]}}class k{constructor(e,t){this.context=e,this.delegate=t,this.targetsByName=new S}start(){this.tokenListObserver||(this.tokenListObserver=new A(this.element,this.attributeName,this),this.tokenListObserver.start())}stop(){this.tokenListObserver&&(this.disconnectAllTargets(),this.tokenListObserver.stop(),delete this.tokenListObserver)}tokenMatched({element:e,content:t}){this.scope.containsElement(e)&&this.connectTarget(e,t)}tokenUnmatched({element:e,content:t}){this.disconnectTarget(e,t)}connectTarget(e,t){var s;this.targetsByName.has(t,e)||(this.targetsByName.add(t,e),null===(s=this.tokenListObserver)||void 0===s||s.pause(()=>this.delegate.targetConnected(e,t)))}disconnectTarget(e,t){var s;this.targetsByName.has(t,e)&&(this.targetsByName.delete(t,e),null===(s=this.tokenListObserver)||void 0===s||s.pause(()=>this.delegate.targetDisconnected(e,t)))}disconnectAllTargets(){for(const e of this.targetsByName.keys)for(const t of this.targetsByName.getValuesForKey(e))this.disconnectTarget(t,e)}get attributeName(){return`data-${this.context.identifier}-target`}get element(){return this.context.element}get scope(){return this.context.scope}}function I(e,t){const s=L(e);return Array.from(s.reduce((e,s)=>(function(e,t){const s=e[t];return Array.isArray(s)?s:[]}(s,t).forEach(t=>e.add(t)),e),new Set))}function L(e){const t=[];for(;e;)t.push(e),e=Object.getPrototypeOf(e);return t.reverse()}class _{constructor(e,t){this.started=!1,this.context=e,this.delegate=t,this.outletsByName=new S,this.outletElementsByName=new S,this.selectorObserverMap=new Map,this.attributeObserverMap=new Map}start(){this.started||(this.outletDefinitions.forEach(e=>{this.setupSelectorObserverForOutlet(e),this.setupAttributeObserverForOutlet(e)}),this.started=!0,this.dependentContexts.forEach(e=>e.refresh()))}refresh(){this.selectorObserverMap.forEach(e=>e.refresh()),this.attributeObserverMap.forEach(e=>e.refresh())}stop(){this.started&&(this.started=!1,this.disconnectAllOutlets(),this.stopSelectorObservers(),this.stopAttributeObservers())}stopSelectorObservers(){this.selectorObserverMap.size>0&&(this.selectorObserverMap.forEach(e=>e.stop()),this.selectorObserverMap.clear())}stopAttributeObservers(){this.attributeObserverMap.size>0&&(this.attributeObserverMap.forEach(e=>e.stop()),this.attributeObserverMap.clear())}selectorMatched(e,t,{outletName:s}){const i=this.getOutlet(e,s);i&&this.connectOutlet(i,e,s)}selectorUnmatched(e,t,{outletName:s}){const i=this.getOutletFromMap(e,s);i&&this.disconnectOutlet(i,e,s)}selectorMatchElement(e,{outletName:t}){const s=this.selector(t),i=this.hasOutlet(e,t),n=e.matches(`[${this.schema.controllerAttribute}~=${t}]`);return!!s&&i&&n&&e.matches(s)}elementMatchedAttribute(e,t){const s=this.getOutletNameFromOutletAttributeName(t);s&&this.updateSelectorObserverForOutlet(s)}elementAttributeValueChanged(e,t){const s=this.getOutletNameFromOutletAttributeName(t);s&&this.updateSelectorObserverForOutlet(s)}elementUnmatchedAttribute(e,t){const s=this.getOutletNameFromOutletAttributeName(t);s&&this.updateSelectorObserverForOutlet(s)}connectOutlet(e,t,s){var i;this.outletElementsByName.has(s,t)||(this.outletsByName.add(s,e),this.outletElementsByName.add(s,t),null===(i=this.selectorObserverMap.get(s))||void 0===i||i.pause(()=>this.delegate.outletConnected(e,t,s)))}disconnectOutlet(e,t,s){var i;this.outletElementsByName.has(s,t)&&(this.outletsByName.delete(s,e),this.outletElementsByName.delete(s,t),null===(i=this.selectorObserverMap.get(s))||void 0===i||i.pause(()=>this.delegate.outletDisconnected(e,t,s)))}disconnectAllOutlets(){for(const e of this.outletElementsByName.keys)for(const t of this.outletElementsByName.getValuesForKey(e))for(const s of this.outletsByName.getValuesForKey(e))this.disconnectOutlet(s,t,e)}updateSelectorObserverForOutlet(e){const t=this.selectorObserverMap.get(e);t&&(t.selector=this.selector(e))}setupSelectorObserverForOutlet(e){const t=this.selector(e),s=new C(document.body,t,this,{outletName:e});this.selectorObserverMap.set(e,s),s.start()}setupAttributeObserverForOutlet(e){const t=this.attributeNameForOutletName(e),s=new w(this.scope.element,t,this);this.attributeObserverMap.set(e,s),s.start()}selector(e){return this.scope.outlets.getSelectorForOutletName(e)}attributeNameForOutletName(e){return this.scope.schema.outletAttributeForScope(this.identifier,e)}getOutletNameFromOutletAttributeName(e){return this.outletDefinitions.find(t=>this.attributeNameForOutletName(t)===e)}get outletDependencies(){const e=new S;return this.router.modules.forEach(t=>{I(t.definition.controllerConstructor,"outlets").forEach(s=>e.add(s,t.identifier))}),e}get outletDefinitions(){return this.outletDependencies.getKeysForValue(this.identifier)}get dependentControllerIdentifiers(){return this.outletDependencies.getValuesForKey(this.identifier)}get dependentContexts(){const e=this.dependentControllerIdentifiers;return this.router.contexts.filter(t=>e.includes(t.identifier))}hasOutlet(e,t){return!!this.getOutlet(e,t)||!!this.getOutletFromMap(e,t)}getOutlet(e,t){return this.application.getControllerForElementAndIdentifier(e,t)}getOutletFromMap(e,t){return this.outletsByName.getValuesForKey(t).find(t=>t.element===e)}get scope(){return this.context.scope}get schema(){return this.context.schema}get identifier(){return this.context.identifier}get application(){return this.context.application}get router(){return this.application.router}}class N{constructor(e,t){this.logDebugActivity=(e,t={})=>{const{identifier:s,controller:i,element:n}=this;t=Object.assign({identifier:s,controller:i,element:n},t),this.application.logDebugActivity(this.identifier,e,t)},this.module=e,this.scope=t,this.controller=new e.controllerConstructor(this),this.bindingObserver=new x(this,this.dispatcher),this.valueObserver=new M(this,this.controller),this.targetObserver=new k(this,this),this.outletObserver=new _(this,this);try{this.controller.initialize(),this.logDebugActivity("initialize")}catch(e){this.handleError(e,"initializing controller")}}connect(){this.bindingObserver.start(),this.valueObserver.start(),this.targetObserver.start(),this.outletObserver.start();try{this.controller.connect(),this.logDebugActivity("connect")}catch(e){this.handleError(e,"connecting controller")}}refresh(){this.outletObserver.refresh()}disconnect(){try{this.controller.disconnect(),this.logDebugActivity("disconnect")}catch(e){this.handleError(e,"disconnecting controller")}this.outletObserver.stop(),this.targetObserver.stop(),this.valueObserver.stop(),this.bindingObserver.stop()}get application(){return this.module.application}get identifier(){return this.module.identifier}get schema(){return this.application.schema}get dispatcher(){return this.application.dispatcher}get element(){return this.scope.element}get parentElement(){return this.element.parentElement}handleError(e,t,s={}){const{identifier:i,controller:n,element:r}=this;s=Object.assign({identifier:i,controller:n,element:r},s),this.application.handleError(e,`Error ${t}`,s)}targetConnected(e,t){this.invokeControllerMethod(`${t}TargetConnected`,e)}targetDisconnected(e,t){this.invokeControllerMethod(`${t}TargetDisconnected`,e)}outletConnected(e,t,s){this.invokeControllerMethod(`${c(s)}OutletConnected`,e,t)}outletDisconnected(e,t,s){this.invokeControllerMethod(`${c(s)}OutletDisconnected`,e,t)}invokeControllerMethod(e,...t){const s=this.controller;"function"==typeof s[e]&&s[e](...t)}}const P="function"==typeof Object.getOwnPropertySymbols?e=>[...Object.getOwnPropertyNames(e),...Object.getOwnPropertySymbols(e)]:Object.getOwnPropertyNames,F=(()=>{function e(e){function t(){return Reflect.construct(e,arguments,new.target)}return t.prototype=Object.create(e.prototype,{constructor:{value:t}}),Reflect.setPrototypeOf(t,e),t}try{return function(){const t=e(function(){this.a.call(this)});t.prototype.a=function(){},new t}(),e}catch(e){return e=>class extends e{}}})();class R{constructor(e,t){this.application=e,this.definition=function(e){return{identifier:e.identifier,controllerConstructor:(t=e.controllerConstructor,function(e,t){const s=F(e),i=function(e,t){return P(t).reduce((s,i)=>{const n=function(e,t,s){const i=Object.getOwnPropertyDescriptor(e,s);if(!i||!("value"in i)){const e=Object.getOwnPropertyDescriptor(t,s).value;return i&&(e.get=i.get||e.get,e.set=i.set||e.set),e}}(e,t,i);return n&&Object.assign(s,{[i]:n}),s},{})}(e.prototype,t);return Object.defineProperties(s.prototype,i),s}(t,function(e){return I(e,"blessings").reduce((t,s)=>{const i=s(e);for(const e in i){const s=t[e]||{};t[e]=Object.assign(s,i[e])}return t},{})}(t)))};var t}(t),this.contextsByScope=new WeakMap,this.connectedContexts=new Set}get identifier(){return this.definition.identifier}get controllerConstructor(){return this.definition.controllerConstructor}get contexts(){return Array.from(this.connectedContexts)}connectContextForScope(e){const t=this.fetchContextForScope(e);this.connectedContexts.add(t),t.connect()}disconnectContextForScope(e){const t=this.contextsByScope.get(e);t&&(this.connectedContexts.delete(t),t.disconnect())}fetchContextForScope(e){let t=this.contextsByScope.get(e);return t||(t=new N(this,e),this.contextsByScope.set(e,t)),t}}class D{constructor(e){this.scope=e}has(e){return this.data.has(this.getDataKey(e))}get(e){return this.getAll(e)[0]}getAll(e){return(this.data.get(this.getDataKey(e))||"").match(/[^\s]+/g)||[]}getAttributeName(e){return this.data.getAttributeNameForKey(this.getDataKey(e))}getDataKey(e){return`${e}-class`}get data(){return this.scope.data}}class j{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get(e){const t=this.getAttributeNameForKey(e);return this.element.getAttribute(t)}set(e,t){const s=this.getAttributeNameForKey(e);return this.element.setAttribute(s,t),this.get(e)}has(e){const t=this.getAttributeNameForKey(e);return this.element.hasAttribute(t)}delete(e){if(this.has(e)){const t=this.getAttributeNameForKey(e);return this.element.removeAttribute(t),!0}return!1}getAttributeNameForKey(e){return`data-${this.identifier}-${h(e)}`}}class B{constructor(e){this.warnedKeysByObject=new WeakMap,this.logger=e}warn(e,t,s){let i=this.warnedKeysByObject.get(e);i||(i=new Set,this.warnedKeysByObject.set(e,i)),i.has(t)||(i.add(t),this.logger.warn(s,e))}}function $(e,t){return`[${e}~="${t}"]`}class V{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce((e,t)=>e||this.findTarget(t)||this.findLegacyTarget(t),void 0)}findAll(...e){return e.reduce((e,t)=>[...e,...this.findAllTargets(t),...this.findAllLegacyTargets(t)],[])}findTarget(e){const t=this.getSelectorForTargetName(e);return this.scope.findElement(t)}findAllTargets(e){const t=this.getSelectorForTargetName(e);return this.scope.findAllElements(t)}getSelectorForTargetName(e){return $(this.schema.targetAttributeForScope(this.identifier),e)}findLegacyTarget(e){const t=this.getLegacySelectorForTargetName(e);return this.deprecate(this.scope.findElement(t),e)}findAllLegacyTargets(e){const t=this.getLegacySelectorForTargetName(e);return this.scope.findAllElements(t).map(t=>this.deprecate(t,e))}getLegacySelectorForTargetName(e){const t=`${this.identifier}.${e}`;return $(this.schema.targetAttribute,t)}deprecate(e,t){if(e){const{identifier:s}=this,i=this.schema.targetAttribute,n=this.schema.targetAttributeForScope(s);this.guide.warn(e,`target:${t}`,`Please replace ${i}="${s}.${t}" with ${n}="${t}". The ${i} attribute is deprecated and will be removed in a future version of Stimulus.`)}return e}get guide(){return this.scope.guide}}class q{constructor(e,t){this.scope=e,this.controllerElement=t}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce((e,t)=>e||this.findOutlet(t),void 0)}findAll(...e){return e.reduce((e,t)=>[...e,...this.findAllOutlets(t)],[])}getSelectorForOutletName(e){const t=this.schema.outletAttributeForScope(this.identifier,e);return this.controllerElement.getAttribute(t)}findOutlet(e){const t=this.getSelectorForOutletName(e);if(t)return this.findElement(t,e)}findAllOutlets(e){const t=this.getSelectorForOutletName(e);return t?this.findAllElements(t,e):[]}findElement(e,t){return this.scope.queryElements(e).filter(s=>this.matchesElement(s,e,t))[0]}findAllElements(e,t){return this.scope.queryElements(e).filter(s=>this.matchesElement(s,e,t))}matchesElement(e,t,s){const i=e.getAttribute(this.scope.schema.controllerAttribute)||"";return e.matches(t)&&i.split(" ").includes(s)}}class U{constructor(e,t,s,i){this.targets=new V(this),this.classes=new D(this),this.data=new j(this),this.containsElement=e=>e.closest(this.controllerSelector)===this.element,this.schema=e,this.element=t,this.identifier=s,this.guide=new B(i),this.outlets=new q(this.documentScope,t)}findElement(e){return this.element.matches(e)?this.element:this.queryElements(e).find(this.containsElement)}findAllElements(e){return[...this.element.matches(e)?[this.element]:[],...this.queryElements(e).filter(this.containsElement)]}queryElements(e){return Array.from(this.element.querySelectorAll(e))}get controllerSelector(){return $(this.schema.controllerAttribute,this.identifier)}get isDocumentScope(){return this.element===document.documentElement}get documentScope(){return this.isDocumentScope?this:new U(this.schema,document.documentElement,this.identifier,this.guide.logger)}}class z{constructor(e,t,s){this.element=e,this.schema=t,this.delegate=s,this.valueListObserver=new E(this.element,this.controllerAttribute,this),this.scopesByIdentifierByElement=new WeakMap,this.scopeReferenceCounts=new WeakMap}start(){this.valueListObserver.start()}stop(){this.valueListObserver.stop()}get controllerAttribute(){return this.schema.controllerAttribute}parseValueForToken(e){const{element:t,content:s}=e;return this.parseValueForElementAndIdentifier(t,s)}parseValueForElementAndIdentifier(e,t){const s=this.fetchScopesByIdentifierForElement(e);let i=s.get(t);return i||(i=this.delegate.createScopeForElementAndIdentifier(e,t),s.set(t,i)),i}elementMatchedValue(e,t){const s=(this.scopeReferenceCounts.get(t)||0)+1;this.scopeReferenceCounts.set(t,s),1==s&&this.delegate.scopeConnected(t)}elementUnmatchedValue(e,t){const s=this.scopeReferenceCounts.get(t);s&&(this.scopeReferenceCounts.set(t,s-1),1==s&&this.delegate.scopeDisconnected(t))}fetchScopesByIdentifierForElement(e){let t=this.scopesByIdentifierByElement.get(e);return t||(t=new Map,this.scopesByIdentifierByElement.set(e,t)),t}}class W{constructor(e){this.application=e,this.scopeObserver=new z(this.element,this.schema,this),this.scopesByIdentifier=new S,this.modulesByIdentifier=new Map}get element(){return this.application.element}get schema(){return this.application.schema}get logger(){return this.application.logger}get controllerAttribute(){return this.schema.controllerAttribute}get modules(){return Array.from(this.modulesByIdentifier.values())}get contexts(){return this.modules.reduce((e,t)=>e.concat(t.contexts),[])}start(){this.scopeObserver.start()}stop(){this.scopeObserver.stop()}loadDefinition(e){this.unloadIdentifier(e.identifier);const t=new R(this.application,e);this.connectModule(t);const s=e.controllerConstructor.afterLoad;s&&s.call(e.controllerConstructor,e.identifier,this.application)}unloadIdentifier(e){const t=this.modulesByIdentifier.get(e);t&&this.disconnectModule(t)}getContextForElementAndIdentifier(e,t){const s=this.modulesByIdentifier.get(t);if(s)return s.contexts.find(t=>t.element==e)}proposeToConnectScopeForElementAndIdentifier(e,t){const s=this.scopeObserver.parseValueForElementAndIdentifier(e,t);s?this.scopeObserver.elementMatchedValue(s.element,s):console.error(`Couldn't find or create scope for identifier: "${t}" and element:`,e)}handleError(e,t,s){this.application.handleError(e,t,s)}createScopeForElementAndIdentifier(e,t){return new U(this.schema,e,t,this.logger)}scopeConnected(e){this.scopesByIdentifier.add(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.connectContextForScope(e)}scopeDisconnected(e){this.scopesByIdentifier.delete(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.disconnectContextForScope(e)}connectModule(e){this.modulesByIdentifier.set(e.identifier,e),this.scopesByIdentifier.getValuesForKey(e.identifier).forEach(t=>e.connectContextForScope(t))}disconnectModule(e){this.modulesByIdentifier.delete(e.identifier),this.scopesByIdentifier.getValuesForKey(e.identifier).forEach(t=>e.disconnectContextForScope(t))}}const H={controllerAttribute:"data-controller",actionAttribute:"data-action",targetAttribute:"data-target",targetAttributeForScope:e=>`data-${e}-target`,outletAttributeForScope:(e,t)=>`data-${e}-${t}-outlet`,keyMappings:Object.assign(Object.assign({enter:"Enter",tab:"Tab",esc:"Escape",space:" ",up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",home:"Home",end:"End",page_up:"PageUp",page_down:"PageDown"},K("abcdefghijklmnopqrstuvwxyz".split("").map(e=>[e,e]))),K("0123456789".split("").map(e=>[e,e])))};function K(e){return e.reduce((e,[t,s])=>Object.assign(Object.assign({},e),{[t]:s}),{})}class G{constructor(e=document.documentElement,t=H){this.logger=console,this.debug=!1,this.logDebugActivity=(e,t,s={})=>{this.debug&&this.logFormattedMessage(e,t,s)},this.element=e,this.schema=t,this.dispatcher=new n(this),this.router=new W(this),this.actionDescriptorFilters=Object.assign({},r)}static start(e,t){const s=new this(e,t);return s.start(),s}async start(){await new Promise(e=>{"loading"==document.readyState?document.addEventListener("DOMContentLoaded",()=>e()):e()}),this.logDebugActivity("application","starting"),this.dispatcher.start(),this.router.start(),this.logDebugActivity("application","start")}stop(){this.logDebugActivity("application","stopping"),this.dispatcher.stop(),this.router.stop(),this.logDebugActivity("application","stop")}register(e,t){this.load({identifier:e,controllerConstructor:t})}registerActionOption(e,t){this.actionDescriptorFilters[e]=t}load(e,...t){(Array.isArray(e)?e:[e,...t]).forEach(e=>{e.controllerConstructor.shouldLoad&&this.router.loadDefinition(e)})}unload(e,...t){(Array.isArray(e)?e:[e,...t]).forEach(e=>this.router.unloadIdentifier(e))}get controllers(){return this.router.contexts.map(e=>e.controller)}getControllerForElementAndIdentifier(e,t){const s=this.router.getContextForElementAndIdentifier(e,t);return s?s.controller:null}handleError(e,t,s){var i;this.logger.error("%s\n\n%o\n\n%o",t,e,s),null===(i=window.onerror)||void 0===i||i.call(window,t,"",0,0,e)}logFormattedMessage(e,t,s={}){s=Object.assign({application:this},s),this.logger.groupCollapsed(`${e} #${t}`),this.logger.log("details:",Object.assign({},s)),this.logger.groupEnd()}}function J(e,t,s){return e.application.getControllerForElementAndIdentifier(t,s)}function Y(e,t,s){let i=J(e,t,s);return i||(e.application.router.proposeToConnectScopeForElementAndIdentifier(t,s),i=J(e,t,s),i||void 0)}function Z([e,t],s){return function(e){const{token:t,typeDefinition:s}=e,i=`${h(t)}-value`,n=function(e){const{controller:t,token:s,typeDefinition:i}=e,n=function(e){const{controller:t,token:s,typeObject:i}=e,n=u(i.type),r=u(i.default),a=n&&r,o=n&&!r,c=!n&&r,l=X(i.type),h=Q(e.typeObject.default);if(o)return l;if(c)return h;if(l!==h)throw new Error(`The specified default value for the Stimulus Value "${t?`${t}.${s}`:s}" must match the defined type "${l}". The provided default value of "${i.default}" is of type "${h}".`);return a?l:void 0}({controller:t,token:s,typeObject:i}),r=Q(i),a=X(i),o=n||r||a;if(o)return o;throw new Error(`Unknown value type "${t?`${t}.${i}`:s}" for "${s}" value`)}(e);return{type:n,key:i,name:o(i),get defaultValue(){return function(e){const t=X(e);if(t)return ee[t];const s=d(e,"default"),i=d(e,"type"),n=e;if(s)return n.default;if(i){const{type:e}=n,t=X(e);if(t)return ee[t]}return e}(s)},get hasCustomDefaultValue(){return void 0!==Q(s)},reader:te[n],writer:se[n]||se.default}}({controller:s,token:e,typeDefinition:t})}function X(e){switch(e){case Array:return"array";case Boolean:return"boolean";case Number:return"number";case Object:return"object";case String:return"string"}}function Q(e){switch(typeof e){case"boolean":return"boolean";case"number":return"number";case"string":return"string"}return Array.isArray(e)?"array":"[object Object]"===Object.prototype.toString.call(e)?"object":void 0}const ee={get array(){return[]},boolean:!1,number:0,get object(){return{}},string:""},te={array(e){const t=JSON.parse(e);if(!Array.isArray(t))throw new TypeError(`expected value of type "array" but instead got value "${e}" of type "${Q(t)}"`);return t},boolean:e=>!("0"==e||"false"==String(e).toLowerCase()),number:e=>Number(e.replace(/_/g,"")),object(e){const t=JSON.parse(e);if(null===t||"object"!=typeof t||Array.isArray(t))throw new TypeError(`expected value of type "object" but instead got value "${e}" of type "${Q(t)}"`);return t},string:e=>e},se={default:function(e){return`${e}`},array:ie,object:ie};function ie(e){return JSON.stringify(e)}class ne{constructor(e){this.context=e}static get shouldLoad(){return!0}static afterLoad(e,t){}get application(){return this.context.application}get scope(){return this.context.scope}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get targets(){return this.scope.targets}get outlets(){return this.scope.outlets}get classes(){return this.scope.classes}get data(){return this.scope.data}initialize(){}connect(){}disconnect(){}dispatch(e,{target:t=this.element,detail:s={},prefix:i=this.identifier,bubbles:n=!0,cancelable:r=!0}={}){const a=new CustomEvent(i?`${i}:${e}`:e,{detail:s,bubbles:n,cancelable:r});return t.dispatchEvent(a),a}}ne.blessings=[function(e){return I(e,"classes").reduce((e,t)=>{return Object.assign(e,(s=t,{[`${s}Class`]:{get(){const{classes:e}=this;if(e.has(s))return e.get(s);{const t=e.getAttributeName(s);throw new Error(`Missing attribute "${t}"`)}}},[`${s}Classes`]:{get(){return this.classes.getAll(s)}},[`has${l(s)}Class`]:{get(){return this.classes.has(s)}}}));var s},{})},function(e){return I(e,"targets").reduce((e,t)=>{return Object.assign(e,(s=t,{[`${s}Target`]:{get(){const e=this.targets.find(s);if(e)return e;throw new Error(`Missing target element "${s}" for "${this.identifier}" controller`)}},[`${s}Targets`]:{get(){return this.targets.findAll(s)}},[`has${l(s)}Target`]:{get(){return this.targets.has(s)}}}));var s},{})},function(e){const t=function(e,t){return L(e).reduce((e,s)=>(e.push(...function(e,t){const s=e[t];return s?Object.keys(s).map(e=>[e,s[e]]):[]}(s,t)),e),[])}(e,"values"),s={valueDescriptorMap:{get(){return t.reduce((e,t)=>{const s=Z(t,this.identifier),i=this.data.getAttributeNameForKey(s.key);return Object.assign(e,{[i]:s})},{})}}};return t.reduce((e,t)=>Object.assign(e,function(e){const t=Z(e,void 0),{key:s,name:i,reader:n,writer:r}=t;return{[i]:{get(){const e=this.data.get(s);return null!==e?n(e):t.defaultValue},set(e){void 0===e?this.data.delete(s):this.data.set(s,r(e))}},[`has${l(i)}`]:{get(){return this.data.has(s)||t.hasCustomDefaultValue}}}}(t)),s)},function(e){return I(e,"outlets").reduce((e,t)=>Object.assign(e,function(e){const t=c(e);return{[`${t}Outlet`]:{get(){const t=this.outlets.find(e),s=this.outlets.getSelectorForOutletName(e);if(t){const s=Y(this,t,e);if(s)return s;throw new Error(`The provided outlet element is missing an outlet controller "${e}" instance for host controller "${this.identifier}"`)}throw new Error(`Missing outlet element "${e}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${s}".`)}},[`${t}Outlets`]:{get(){const t=this.outlets.findAll(e);return t.length>0?t.map(t=>{const s=Y(this,t,e);if(s)return s;console.warn(`The provided outlet element is missing an outlet controller "${e}" instance for host controller "${this.identifier}"`,t)}).filter(e=>e):[]}},[`${t}OutletElement`]:{get(){const t=this.outlets.find(e),s=this.outlets.getSelectorForOutletName(e);if(t)return t;throw new Error(`Missing outlet element "${e}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${s}".`)}},[`${t}OutletElements`]:{get(){return this.outlets.findAll(e)}},[`has${l(t)}Outlet`]:{get(){return this.outlets.has(e)}}}}(t)),{})}],ne.targets=[],ne.outlets=[],ne.values={}},434(e,t,s){s.d(t,{default:()=>ri});var i=s(891);class n extends Error{constructor(e){super(`${e} is not valid. Please provide a valid event name`),this.name="InvalidEvent"}}class r{static events=["session-set","utm-set","forms:collected","form:completed","alert:shown","alert:dismissed","alert:accepted","webchat:mounted","webchat:opened","webchat:closed","webchat:message:sent","webchat:message:received","cart.added"];static valid(e){return r.exists(e)}static invalid(e){return!this.valid(e)}static exists(e){return void 0!==this.events.find(t=>t===e)}constructor(){this.subscribers={}}addSubscriber(e,t){if(r.invalid(e))throw new n(e);this.subscribers={...this.subscribers,[e]:this.subscribers[e]?[...this.subscribers[e],t]:[t]}}removeSubscriber(e,t){if(r.invalid(e))throw new n(e);this.subscribers[e]&&(this.subscribers[e]=this.subscribers[e].filter(e=>e!==t))}dispatch(e,t){this.subscribers[e]?.forEach(e=>{e(t)})}get listeners(){return 0!==Object.keys(this.subscribers).length}}class a{static autoMount=!0;static successMessage=!0;static assign(e){return e&&Object.entries(e).forEach(([e,t])=>{this[e]=t}),this}static get shouldShowSuccessMessage(){return this.successMessage}}class o{static _identifier;static set identifier(e){this._identifier=e}static get identifier(){return this._identifier?this._identifier:this.#e||this.#t||this.#s||"en"}static toString(){return this.identifier}static get#e(){return document?.documentElement?.lang}static get#t(){return document?.querySelector('meta[name="locale"]')?.content}static get#s(){return navigator?.language?.split("-")[0]}}const c={TOP_LEFT:"top-left",TOP_RIGHT:"top-right",BOTTOM_LEFT:"bottom-left",BOTTOM_RIGHT:"bottom-right"},l={ABSOLUTE:"absolute",FIXED:"fixed"},h={MODAL:"modal",POPOVER:"popover"};class u{static _id;static _container="body";static _placement="bottom-right";static _style={};static _appearance={};static _whatsapp={};static _mode=h.POPOVER;static _behaviour=null;static _hasBehaviourOverride=!1;static _strategy=null;static set container(e){this._container=e}static get container(){return this._container}static set placement(e){if(!Object.values(c).includes(e))throw new Error(`Invalid placement value: ${e}`);this._placement=e}static get placement(){return this._placement}static set id(e){this._id=e}static get id(){return this._id}static get isSet(){return!!this._id}static get style(){return this._style}static set style(e){if("object"!=typeof e)throw new Error("Style must be an object");Object.entries(e).forEach(([e,t])=>{if(!["primaryColor","secondaryColor","typography"].includes(e))throw new Error(`Invalid style property: ${e}`);if("typography"!==e&&!this.isHexOrRgba(t))throw new Error(`Invalid color value: ${t} for ${e}. Colors must be hex or rgb/a.`)}),this._style=e}static get appearance(){return this._appearance}static set appearance(e){if(!this.isPlainObject(e))throw new Error("Appearance must be an object");Object.entries(e).forEach(([e,t])=>{if(!["header","launcher"].includes(e))throw new Error(`Invalid appearance property: ${e}`);if(!this.isPlainObject(t))throw new Error(`Appearance ${e} must be an object`);Object.entries(t).forEach(([t,s])=>{if("header"===e&&"name"!==t)throw new Error(`Invalid appearance header property: ${t}`);if("launcher"===e&&"iconUrl"!==t)throw new Error(`Invalid appearance launcher property: ${t}`);if(null!=s&&"string"!=typeof s)throw new Error(`Invalid appearance ${e}.${t} value: ${s}`)})}),this._appearance=e}static get whatsapp(){return this._whatsapp}static set whatsapp(e){if(!this.isPlainObject(e))throw new Error("WhatsApp must be an object");Object.entries(e).forEach(([e,t])=>{if(!["number","restrictToChannel"].includes(e))throw new Error(`Invalid WhatsApp property: ${e}`);if(null!=t){if("number"===e&&"string"!=typeof t)throw new Error(`Invalid WhatsApp number value: ${t}`);if("restrictToChannel"===e&&"boolean"!=typeof t)throw new Error(`Invalid WhatsApp restrictToChannel value: ${t}`)}}),this._whatsapp=e}static get mode(){return this._mode}static set mode(e){if(!Object.values(h).includes(e))throw new Error(`Invalid mode value: ${e}`);this._mode=e}static get behaviour(){return this._behaviour}static set behaviour(e){if(null!=e){if("object"!=typeof e||Array.isArray(e))throw new Error(`Invalid behaviour value: ${e}`);this._behaviour=e}else this._behaviour=e}static get hasBehaviourOverride(){return this._hasBehaviourOverride}static set behaviourOverride(e){this._hasBehaviourOverride=!!e}static get strategy(){return this._strategy?this._strategy:"body"==this.container?l.FIXED:l.ABSOLUTE}static set strategy(e){if(e&&!Object.values(l).includes(e))throw new Error(`Invalid strategy value: ${e}`);this._strategy=e}static assign(e){return e&&Object.entries(e).forEach(([e,t])=>{this[e]=t}),this}static isHexOrRgba(e){return/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(e)||/^rgba?\(\s*\d{1,3},\s*\d{1,3},\s*\d{1,3},?\s*(0|1|0?\.\d+)?\s*\)$/.test(e)}static isPlainObject(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}}const d={TOP_LEFT:"top-left",TOP_RIGHT:"top-right",BOTTOM_LEFT:"bottom-left",BOTTOM_RIGHT:"bottom-right"};class p{static _id;static _container="body";static _placement="bottom-right";static _appearance={};static _number=null;static _body=null;static set id(e){this._id=e}static get id(){return this._id}static set container(e){this._container=e}static get container(){return this._container}static set placement(e){if(!Object.values(d).includes(e))throw new Error(`Invalid placement value: ${e}`);this._placement=e}static get placement(){return this._placement}static get appearance(){return this._appearance}static set appearance(e){if(!this.isPlainObject(e))throw new Error("Appearance must be an object");Object.entries(e).forEach(([e,t])=>{if("launcher"!==e)throw new Error(`Invalid appearance property: ${e}`);if(!this.isPlainObject(t))throw new Error(`Appearance ${e} must be an object`);Object.entries(t).forEach(([t,s])=>{if("iconUrl"!==t)throw new Error(`Invalid appearance launcher property: ${t}`);if(null!=s&&"string"!=typeof s)throw new Error(`Invalid appearance ${e}.${t} value: ${s}`)})}),this._appearance=e}static get number(){return this._number}static set number(e){if(null!=e&&"string"!=typeof e)throw new Error(`Invalid number value: ${e}`);this._number=e}static get body(){return this._body}static set body(e){if(null!=e&&"string"!=typeof e)throw new Error(`Invalid body value: ${e}`);this._body=e}static assign(e){return e&&Object.entries(e).forEach(([e,t])=>{this[e]=t}),this}static isPlainObject(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}}class m{static serviceWorkerUrl=null;static channelId=null;static assign(e){return this.serviceWorkerUrl=e?.serviceWorkerUrl||null,this.channelId=e?.channelId||null,this}}class g{static apiRoot="https://api.hellotext.com/v1";static actionCableUrl="wss://www.hellotext.com/cable";static autoGenerateSession=!0;static session=null;static forms=a;static webchat=u;static whatsapp=p;static push=m;static assign(e){if(e){const t=Object.prototype.hasOwnProperty.call(e,"apiRoot")&&!Object.prototype.hasOwnProperty.call(e,"actionCableUrl");Object.entries(e).forEach(([e,t])=>{"forms"===e?this.forms=a.assign(t):"webchat"===e?this.webchat=u.assign(t):"whatsappWidget"===e?this.whatsapp=p.assign(t):"push"===e?this.push=m.assign(t):this[e]=t}),t&&(this.actionCableUrl=this.actionCableUrlForApiRoot(this.apiRoot))}return this}static set locale(e){o.identifier=e}static get locale(){return o.toString()}static endpoint(e){return`${this.apiRoot}/${e}`}static actionCableUrlForApiRoot(e){try{const t=new URL(e),s="https:"===t.protocol?"wss:":"ws:";return t.protocol=s,t.pathname="/cable",t.search="",t.hash="",t.toString()}catch(e){return this.actionCableUrl}}}const f=class{static get endpoint(){return g.endpoint("public/businesses")}static async get(e){return fetch(`${this.endpoint}/${e}`,{method:"GET",headers:{Authorization:`Bearer ${e}`,Accept:"application/json","Content-Type":"application/json"}})}};class b{static get inPreviewMode(){return(new this).inPreviewMode}constructor(){this.urlSearchParams=new URLSearchParams(window.location.search)}get(e){return this.urlSearchParams.get(this.toHellotextParam(e))}has(e){return this.urlSearchParams.has(this.toHellotextParam(e))}get inPreviewMode(){return this.has("preview")}get session(){return this.get("session")}toHellotextParam(e){return`hello_${e}`}}class y{#i;constructor(e,t){this.response=t,this.#i=e}get data(){return this.response}async json(){return await this.response.json()}get failed(){return!1===this.#i}get succeeded(){return!0===this.#i}}class v{static get endpoint(){return g.endpoint("track/events")}static async create({headers:e,body:t,keepalive:s=!1}){if(b.inPreviewMode)return new y(!0,{received:!0});const i={method:"POST",headers:e,body:JSON.stringify(t)};s&&(i.keepalive=!0);const n=await fetch(this.endpoint,i);return new y(200===n.status,await n.json())}}class w{static get endpoint(){return g.endpoint("public/forms")}static async get(e){const t=new URL(`${this.endpoint}/${e}`);return t.searchParams.append("session",bt.session),t.searchParams.append("locale",o.toString()),fetch(t,{method:"GET",headers:bt.headers})}static async submit(e,t){const s=await fetch(`${this.endpoint}/${e}/submissions`,{method:"POST",headers:bt.headers,body:JSON.stringify({session:bt.session,...t})});return new y(s.ok,s)}}const T=class{static get endpoint(){return g.endpoint("public/identifications")}static async create(e={}){const t=await fetch(this.endpoint,{method:"POST",headers:bt.headers,body:JSON.stringify({session:bt.session,...e})});return new y(t.ok,t)}},S=class{static get endpoint(){return g.endpoint("public/webchats")}static async get(e){const t=new URL(`${this.endpoint}/${e}`);t.searchParams.append("session",bt.session),t.searchParams.append("locale",o.toString()),Object.entries(g.webchat.style).forEach(([e,s])=>{t.searchParams.append(`style[${e}]`,s)}),this.appendWebchatOverrides(t),t.searchParams.append("placement",g.webchat.placement);const s=await fetch(t,{method:"GET",headers:bt.headers}),i=await s.json();return bt.business.data||(bt.business.setData(i.business),bt.business.setLocale(i.locale)),(new DOMParser).parseFromString(i.html,"text/html").querySelector("article")}static appendWebchatOverrides(e){const{appearance:t,whatsapp:s}=g.webchat;this.appendIfSupplied(e,"webchat[appearance][header][name]",t.header?.name),this.appendIfSupplied(e,"webchat[appearance][launcher][icon_url]",t.launcher?.iconUrl),this.appendIfSupplied(e,"webchat[handoff][identifier]",s.number),this.appendIfSupplied(e,"webchat[handoff][restrict_to_channel]",s.restrictToChannel)}static appendIfSupplied(e,t,s){null!=s&&e.searchParams.append(t,String(s))}},C=class{static get endpoint(){return g.endpoint("public/widgets/whatsapp")}static async get(e){const t=new URL(`${this.endpoint}/${e}`);t.searchParams.append("locale",o.toString()),t.searchParams.append("placement",g.whatsapp.placement),this.appendWhatsAppOverrides(t);const s=await this.fetchWidget(t);if(!s.ok)return null;const i=await this.parseWidgetResponse(s);return i?(bt.business.data||(bt.business.setData(i.business),bt.business.setLocale(i.locale)),(new DOMParser).parseFromString(i.html,"text/html").querySelector("article")):null}static appendWhatsAppOverrides(e){const{appearance:t,body:s,number:i}=g.whatsapp;this.appendIfSupplied(e,"whatsapp[appearance][launcher][icon_url]",t.launcher?.iconUrl),this.appendIfSupplied(e,"whatsapp[number]",i),this.appendIfSupplied(e,"whatsapp[body]",s)}static appendIfSupplied(e,t,s){null!=s&&e.searchParams.append(t,String(s))}static async fetchWidget(e){try{return await fetch(e,{method:"GET",headers:bt.headers})}catch(e){return{ok:!1}}}static async parseWidgetResponse(e){try{return await e.json()}catch(e){return null}}},O=class{static get endpoint(){return g.endpoint("public/acks")}static async send(e={}){const t={...e,session:bt.session,at:(new Date).toISOString()};fetch(this.endpoint,{method:"POST",headers:bt.headers,body:JSON.stringify(t),keepalive:!0})}},A=class{static get endpoint(){return g.endpoint("public/push/identities")}static async create(e={}){const t=await fetch(this.endpoint,{method:"POST",keepalive:!0,headers:bt.headers,body:JSON.stringify({...e,session:bt.session,origin:window.location.origin})});return new y(t.ok,t)}static async destroy(e={}){const t=await fetch(this.endpoint,{method:"DELETE",keepalive:!0,headers:bt.headers,body:JSON.stringify({...e,session:bt.session,origin:window.location.origin})});return new y(t.ok,t)}},E=class{static get endpoint(){return g.endpoint("public/push/alerts")}static async create({section:e,kind:t}){const s=await fetch(this.endpoint,{method:"POST",keepalive:!0,headers:bt.headers,body:JSON.stringify({session:bt.session,section:e,kind:t})});return new y(s.ok,s)}};function x(e){const t=JSON.stringify(e);return"undefined"==typeof Blob?t.length<6e4:new Blob([t]).size<6e4}class M{static get businesses(){return f}static get events(){return v}static get forms(){return w}static get webchats(){return S}static get whatsappWidgets(){return C}static get identifications(){return T}static get acks(){return O}static get pushAlerts(){return E}static get pushIdentities(){return A}}const k={en:{white_label:{powered_by:"By"},errors:{parameter_not_unique:"This value is taken.",blank:"This field is required."},forms:{phone:"Click the link sent via SMS to verify your submission.",email:"Click the link sent via email to verify your submission.",phone_and_email:"Click the links sent via SMS and email to verify your submission.",none:"Your submission has been received."}},es:{white_label:{powered_by:"Por"},errors:{parameter_not_unique:"Este valor ya está en uso.",blank:"Este campo es obligatorio."},forms:{phone:"Haga clic en el enlace enviado por SMS para verificar su envío.",email:"Haga clic en el enlace enviado por e-mail para verificar su envío.",phone_and_email:"Haga clic en los enlaces enviados por SMS y e-mail para verificar su envío.",none:"Su envío ha sido recibido."}}},I="data-hellotext-stylesheet";class L{constructor(e){this.id=e,this.data=null,this.stylesheet=null,this.stylesheetLoaded=Promise.resolve(!1)}async hydrate(){try{const e=await f.get(this.id);if(!1===e.ok)return null;const t=await e.json();return t?(this.setData(t),t.locale&&this.setLocale(t.locale),t):null}catch(e){return null}}setData(e){this.data=e,"undefined"!=typeof document&&e.style_url?(this.stylesheet=this.constructor.ensureStylesheet(e.style_url),this.stylesheetLoaded=this.constructor.waitForStylesheet(this.stylesheet)):(this.stylesheet=null,this.stylesheetLoaded=Promise.resolve(!1))}static get stylesheetSelector(){return`link[rel="stylesheet"][${I}]`}static ensureStylesheet(e){const t=this.normalizedStylesheetUrl(e),s=this.stylesheetLinks.find(e=>e.href===t);if(s)return s.setAttribute(I,"true"),s;const i=document.createElement("link");return i.rel="stylesheet",i.href=e,i.setAttribute(I,"true"),this.waitForStylesheet(i),document.head.append(i),i}static get stylesheetLinks(){return"undefined"==typeof document?[]:Array.from(document.querySelectorAll(this.stylesheetSelector))}static get latestStylesheet(){return this.stylesheetLinks[this.stylesheetLinks.length-1]}static normalizedStylesheetUrl(e){try{return new URL(e,document.baseURI).href}catch(t){return e}}static waitForStylesheet(e){return e?this.stylesheetIsLoaded(e)?Promise.resolve(!0):"false"===e.dataset.hellotextStylesheetLoaded?Promise.resolve(!1):(e._hellotextStylesheetLoaded||(e._hellotextStylesheetLoaded=new Promise(t=>{let s;const i=i=>{clearTimeout(s),e.removeEventListener("load",n),e.removeEventListener("error",r),e.dataset.hellotextStylesheetLoaded=i?"true":"false",t(i)},n=()=>i(this.stylesheetIsLoaded(e)),r=()=>i(!1);e.addEventListener("load",n),e.addEventListener("error",r),s=setTimeout(()=>i(this.stylesheetIsLoaded(e)),1e4),s.unref&&s.unref()})),e._hellotextStylesheetLoaded):Promise.resolve(!1)}static stylesheetIsLoaded(e){return"true"===e.dataset.hellotextStylesheetLoaded||!!e.sheet}get subscription(){return this.data.subscription}get country(){return this.data.country}get enabledWhitelist(){return"disabled"!==this.data.whitelist}setLocale(e){if(!k[e])return console.warn(`Locale ${e} not found`);this.data||(this.data={}),this.data.locale=e}get locale(){return k[this.data.locale]}get features(){return this.data.features}}class _{static set(e,t){if("undefined"!=typeof document){const s="https:"===window.location.protocol?"; Secure":"",i=P.getRootDomain(),n=31536e4;document.cookie=i?`${e}=${t}; path=/${s}; domain=${i}; max-age=${n}; SameSite=Lax`:`${e}=${t}; path=/${s}; max-age=${n}; SameSite=Lax`}return"hello_session"===e&&bt.eventEmitter.dispatch("session-set",t),"hello_utm"===e&&bt.eventEmitter.dispatch("utm-set",t),t}static get(e){return"undefined"!=typeof document?document.cookie.match("(^|;)\\s*"+e+"\\s*=\\s*([^;]+)")?.pop():void 0}static delete(e){if("undefined"!=typeof document){const t=P.getRootDomain(),s="https:"===window.location.protocol?"; Secure":"";document.cookie=t?`${e}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT${s}; domain=${t}; SameSite=Lax`:`${e}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT${s}; SameSite=Lax`}}}class N{constructor(){const e=new URLSearchParams(window.location.search),t={source:e.get("utm_source"),medium:e.get("utm_medium"),campaign:e.get("utm_campaign"),term:e.get("utm_term"),content:e.get("utm_content")};this.save(t)}save(e){if(!e.source||!e.medium)return;const t=Object.fromEntries(Object.entries(e).filter(([e,t])=>t));t.observed_at=(new Date).toISOString(),_.set("hello_utm",JSON.stringify(t))}get current(){try{return JSON.parse(_.get("hello_utm"))||{}}catch(e){return{}}}}class P{constructor(e=null){this.utm=new N,this._url=e}get url(){return null!==this._url&&void 0!==this._url?this._url:window.location.href}get title(){return document.title}get path(){if(this._url)try{return new URL(this._url).pathname}catch(e){return"/"}return window.location.pathname}get utmParams(){return this.utm.current}get trackingData(){return{page:{url:this.url,title:this.title,path:this.path},utm_params:this.utmParams}}get domain(){try{const e=this.url;if(!e)return null;const t=new URL(e).hostname;return P.getRootDomain(t)}catch(e){return null}}static getRootDomain(e=null){try{if(!e){if("undefined"==typeof window||!window.location?.hostname)return null;e=window.location.hostname}const t=e.split(".");if(t.length<=1)return e;const s=["myshopify.com","vtexcommercestable.com.br","myvtex.com","wixsite.com"];for(const e of s){const s=e.split(".");if(t.slice(-s.length).join(".")===e&&t.length>s.length)return`.${t.slice(-(s.length+1)).join(".")}`}const i=t[t.length-1],n=t[t.length-2];return t.length>2&&2===i.length&&n.length<=3?`.${t.slice(-3).join(".")}`:`.${t.slice(-2).join(".")}`}catch(e){return null}}}class F{static#n;static#r;static#a;static get session(){return this.#n}static get ackPayload(){return{utm_params:this.#a?.utmParams||{}}}static set session(e){const t=_.get("hello_session");return this.#n=e,_.set("hello_session",e),t!==e&&_.delete("hello_session_ack_at"),_.get("hello_session_ack_at")||(M.acks.send(this.ackPayload),_.set("hello_session_ack_at",(new Date).toISOString())),this.#n}static initialize(e=new P){this.#a=e,this.#r=new b,this.session=this.#r.session||g.session||_.get("hello_session"),!this.session&&g.autoGenerateSession&&(this.session=crypto.randomUUID())}}class R{static build(e){const t=document.createElement("article"),s=document.createElement("label"),i=document.createElement("input");s.innerText=e.label,i.type=e.type,i.required=e.required,i.placeholder=e.placeholder,["first_name","last_name"].includes(e.kind)?(i.type="text",i.id=i.name=e.kind,s.setAttribute("for",e.kind)):(i.type=e.type,"email"===e.type?(i.id=i.name="email",s.setAttribute("for","email")):"tel"===i.type?(i.id=i.name="phone",s.setAttribute("for","phone"),i.value=`+${bt.business.country.prefix}`,i.setAttribute("data-default-value",`+${bt.business.country.prefix}`)):(i.name=i.id=`property_by_id[${e.property}]`,s.setAttribute("for",`property_by_id[${e.property}]`)));const n=document.createElement("main");n.appendChild(s),n.appendChild(i),t.appendChild(n),t.setAttribute("data-hellotext--form-target","inputContainer"),i.setAttribute("data-hellotext--form-target","input");const r=document.createElement("div");return r.setAttribute("data-error-container",""),t.appendChild(r),t}}class D{static build(){const e=document.createElement("div");return e.innerHTML=this.#o(),e.firstElementChild}static#o(){const e=`https://www.hellotext.com?hello_session=${bt.session}`;return`\n
\n ${bt.business.locale.white_label.powered_by}\n\n \n \n Hellotext\n \n \n \n
\n `}}function j(e,t){(null==t||t>e.length)&&(t=e.length);for(var s=0,i=Array(t);s2?s-2:0),n=2;n1?t-1:0),i=1;i1?s-1:0),n=1;n2&&void 0!==arguments[2]?arguments[2]:ie;if(V&&V(e,null),!se(t))return e;let i=t.length;for(;i--;){let n=t[i];if("string"==typeof n){const e=s(n);e!==n&&(q(t)||(t[i]=e),n=e)}e[n]=!0}return e}function we(e){for(let t=0;t/g),Re=H(/\${[\w\W]*/g),De=H(/^data-[\-\w.\u00B7-\uFFFF]+$/),je=H(/^aria-[\-\w]+$/),Be=H(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),$e=H(/^(?:\w+script|data):/i),Ve=H(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),qe=H(/^html$/i),Ue=H(/^[a-z][.\w]*(-[.\w]+)+$/i),ze=H(/<[/\w!]/g),We=H(/<[/\w]/g),He=H(/<\/no(script|embed|frames)/i),Ke=H(/\/>/i),Ge=["style","script","xmp","iframe","noembed","noframes","plaintext","noscript"],Je=W(ve({},Ge)),Ye=function(){const e={};return Z(Ge,t=>{e[t]=H(new RegExp("])","i"))}),W(e)}(),Ze=function(){return"undefined"==typeof window?null:window},Xe=function(e,t,s,i){return pe(e,t)&&se(e[t])?ve(i.base?Te(i.base):{},e[t],i.transform):s},Qe=function(e,t,s){const i=pe(e,t)?e[t]:void 0;return i&&"object"==typeof i?Te(i):s()};var et=function e(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Ze();const s=t=>e(t);if(s.version="3.4.14",s.removed=[],!t||!t.document||9!==t.document.nodeType||!t.Element)return s.isSupported=!1,s;let i=t.document;const n=i,r=n.currentScript;t.DocumentFragment;const a=t.HTMLTemplateElement,o=t.Node,c=t.Element,l=t.NodeFilter;void 0===t.NamedNodeMap&&(t.NamedNodeMap||t.MozNamedAttrMap),t.HTMLFormElement;const h=t.DOMParser,u=t.trustedTypes,d=c.prototype,p=Se(d,"cloneNode"),m=Se(d,"remove"),g=Se(d,"nextSibling"),f=Se(d,"childNodes"),b=Se(d,"parentNode"),y=Se(d,"shadowRoot"),v=Se(d,"attributes"),w=o&&o.prototype?Se(o.prototype,"nodeType"):null,T=o&&o.prototype?Se(o.prototype,"nodeName"):null,S=o&&o.prototype?Se(o.prototype,"ownerDocument"):null,C=function(e){return w?w(e):e.nodeType},O=function(e){return T?T(e):e.nodeName};if("function"==typeof a){const e=i.createElement("template");e.content&&e.content.ownerDocument&&(i=e.content.ownerDocument)}let A,E,x="",M=!1,k=0;const I=function(){if(k>0)throw fe('A configured TRUSTED_TYPES_POLICY callback (createHTML or createScriptURL) must not call DOMPurify.sanitize, as that causes infinite recursion. Do not pass a policy whose callbacks wrap DOMPurify as TRUSTED_TYPES_POLICY; see the "DOMPurify and Trusted Types" section of the README.')},L=function(e){I(),k++;try{return A.createHTML(e)}finally{k--}},_=i,N=_.implementation,P=_.createNodeIterator,F=_.createDocumentFragment,R=_.getElementsByTagName,D=n.importNode;let j={afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]};s.isSupported="function"==typeof $&&"function"==typeof b&&N&&void 0!==N.createHTMLDocument;const B=Pe,V=Fe,q=Re,U=De,z=je,G=$e,J=Ve,Y=Ue;let be=Be,ye=null;const we=ve({},[...Ce,...Oe,...Ae,...xe,...ke]);let Ge=null;const et=ve({},[...Ie,...Le,..._e,...Ne]);let tt=Object.seal(K(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),st=null,it=null;const nt=Object.seal(K(null,{tagCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeCheck:{writable:!0,configurable:!1,enumerable:!0,value:null}}));let rt=!0,at=!0,ot=!1,ct=!0,lt=!1,ht=!0,ut=!1,dt=!1,pt=null,mt=null,gt=!1,ft=!1,bt=!1,yt=!1,vt=!0,wt=!1;const Tt="user-content-";let St=!0,Ct=!1,Ot={},At=null;const Et=ve({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","selectedcontent","style","svg","template","thead","title","video","xmp"]);let xt=null;const Mt=ve({},["audio","video","img","source","image","track"]);let kt=null;const It=ve({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Lt="http://www.w3.org/1998/Math/MathML",_t="http://www.w3.org/2000/svg",Nt="http://www.w3.org/1999/xhtml";let Pt=Nt,Ft=!1,Rt=null;const Dt=ve({},[Lt,_t,Nt],ne),jt=W(["mi","mo","mn","ms","mtext"]);let Bt=ve({},jt);const $t=W(["annotation-xml"]);let Vt=ve({},$t);const qt=ve({},["title","style","font","a","script"]);let Ut=null;const zt=["application/xhtml+xml","text/html"];let Wt=null,Ht=null;const Kt=i.createElement("form"),Gt=function(e){return e instanceof RegExp||e instanceof Function},Jt=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(Ht&&Ht===e)return;e&&"object"==typeof e||(e={}),e=Te(e),Ut=-1===zt.indexOf(e.PARSER_MEDIA_TYPE)?"text/html":e.PARSER_MEDIA_TYPE,Wt="application/xhtml+xml"===Ut?ne:ie,ye=Xe(e,"ALLOWED_TAGS",we,{transform:Wt}),Ge=Xe(e,"ALLOWED_ATTR",et,{transform:Wt}),Rt=Xe(e,"ALLOWED_NAMESPACES",Dt,{transform:ne}),kt=Xe(e,"ADD_URI_SAFE_ATTR",It,{transform:Wt,base:It}),xt=Xe(e,"ADD_DATA_URI_TAGS",Mt,{transform:Wt,base:Mt}),At=Xe(e,"FORBID_CONTENTS",Et,{transform:Wt}),st=Xe(e,"FORBID_TAGS",Te({}),{transform:Wt}),it=Xe(e,"FORBID_ATTR",Te({}),{transform:Wt}),Ot=!!pe(e,"USE_PROFILES")&&(e.USE_PROFILES&&"object"==typeof e.USE_PROFILES?Te(e.USE_PROFILES):e.USE_PROFILES),rt=!1!==e.ALLOW_ARIA_ATTR,at=!1!==e.ALLOW_DATA_ATTR,ot=e.ALLOW_UNKNOWN_PROTOCOLS||!1,ct=!1!==e.ALLOW_SELF_CLOSE_IN_ATTR,lt=e.SAFE_FOR_TEMPLATES||!1,ht=!1!==e.SAFE_FOR_XML,ut=e.WHOLE_DOCUMENT||!1,ft=e.RETURN_DOM||!1,bt=e.RETURN_DOM_FRAGMENT||!1,yt=e.RETURN_TRUSTED_TYPE||!1,gt=e.FORCE_BODY||!1,vt=!1!==e.SANITIZE_DOM,wt=e.SANITIZE_NAMED_PROPS||!1,St=!1!==e.KEEP_CONTENT,Ct=e.IN_PLACE||!1,be=function(e){try{return ge(e,""),!0}catch(e){return!1}}(e.ALLOWED_URI_REGEXP)?e.ALLOWED_URI_REGEXP:Be,Pt="string"==typeof e.NAMESPACE?e.NAMESPACE:Nt,Bt=Qe(e,"MATHML_TEXT_INTEGRATION_POINTS",()=>ve({},jt)),Vt=Qe(e,"HTML_INTEGRATION_POINTS",()=>ve({},$t));const t=Qe(e,"CUSTOM_ELEMENT_HANDLING",()=>K(null));if(tt=K(null),pe(t,"tagNameCheck")&&Gt(t.tagNameCheck)&&(tt.tagNameCheck=t.tagNameCheck),pe(t,"attributeNameCheck")&&Gt(t.attributeNameCheck)&&(tt.attributeNameCheck=t.attributeNameCheck),pe(t,"allowCustomizedBuiltInElements")&&"boolean"==typeof t.allowCustomizedBuiltInElements&&(tt.allowCustomizedBuiltInElements=t.allowCustomizedBuiltInElements),H(tt),lt&&(at=!1),bt&&(ft=!0),Ot&&(ye=ve({},ke),Ge=K(null),!0===Ot.html&&(ve(ye,Ce),ve(Ge,Ie)),!0===Ot.svg&&(ve(ye,Oe),ve(Ge,Le),ve(Ge,Ne)),!0===Ot.svgFilters&&(ve(ye,Ae),ve(Ge,Le),ve(Ge,Ne)),!0===Ot.mathMl&&(ve(ye,xe),ve(Ge,_e),ve(Ge,Ne))),nt.tagCheck=null,nt.attributeCheck=null,pe(e,"ADD_TAGS")&&("function"==typeof e.ADD_TAGS?nt.tagCheck=e.ADD_TAGS:se(e.ADD_TAGS)&&(ye===we&&(ye=Te(ye)),ve(ye,e.ADD_TAGS,Wt))),pe(e,"ADD_ATTR")&&("function"==typeof e.ADD_ATTR?nt.attributeCheck=e.ADD_ATTR:se(e.ADD_ATTR)&&(Ge===et&&(Ge=Te(Ge)),ve(Ge,e.ADD_ATTR,Wt))),pe(e,"ADD_FORBID_CONTENTS")&&se(e.ADD_FORBID_CONTENTS)&&(At===Et&&(At=Te(At)),ve(At,e.ADD_FORBID_CONTENTS,Wt)),St&&(ye["#text"]=!0),ut&&ve(ye,["html","head","body"]),ye.table&&(ve(ye,["tbody"]),delete st.tbody),e.TRUSTED_TYPES_POLICY){if("function"!=typeof e.TRUSTED_TYPES_POLICY.createHTML)throw fe('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof e.TRUSTED_TYPES_POLICY.createScriptURL)throw fe('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');const t=A;A=e.TRUSTED_TYPES_POLICY;try{x=L("")}catch(e){throw A=t,e}}else null===e.TRUSTED_TYPES_POLICY?(A=void 0,x=""):(void 0===A&&(M||(E=function(e,t){if("object"!=typeof e||"function"!=typeof e.createPolicy)return null;let s=null;const i="data-tt-policy-suffix";t&&t.hasAttribute(i)&&(s=t.getAttribute(i));const n="dompurify"+(s?"#"+s:"");try{return e.createPolicy(n,{createHTML:e=>e,createScriptURL:e=>e})}catch(e){return console.warn("TrustedTypes policy "+n+" could not be created."),null}}(u,r),M=!0),A=E),A&&"string"==typeof x&&(x=L("")));W&&W(e),Ht=e},Yt=ve({},[...Oe,...Ae,...Ee]),Zt=ve({},[...xe,...Me]),Xt=function(e){ee(s.removed,{element:e});try{b(e).removeChild(e)}catch(t){if(m(e),!b(e))throw fe("a node selected for removal could not be detached from its tree and cannot be safely returned; refusing to sanitize in place")}},Qt=function(e,t,s){try{e.removeAttributeNode(t)}catch(t){try{e.removeAttribute(s)}catch(e){}}},es=function(e){is(e);const t=f(e);if(t){const e=[];Z(t,t=>{ee(e,t)}),Z(e,e=>{try{m(e)}catch(e){}})}const s=v(e);if(s)for(let t=s.length-1;t>=0;--t){const i=s[t],n=i&&i.name;"string"==typeof n&&Qt(e,i,n)}},ts=function(e,t,i){if(!i)try{i=t.getAttributeNode(e)}catch(e){i=null}ee(s.removed,{attribute:i||null,from:t});try{i?t.removeAttributeNode(i):t.removeAttribute(e)}catch(s){try{t.removeAttribute(e)}catch(e){}}if("is"===e)if(ft||bt)try{Xt(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},ss=function(e){const t=v(e);if(t)for(let s=t.length-1;s>=0;--s){const i=t[s],n=i&&i.name;"string"!=typeof n||Ge[Wt(n)]||Qt(e,i,n)}},is=function(e){const t=[e];for(;t.length>0;){const e=t.pop();1===C(e)&&ss(e);const s=f(e);if(s)for(let e=s.length-1;e>=0;--e)t.push(s[e])}},ns=function(e,t){return!!ht&&("patchsrc"===e||"for"===e&&"label"!==t&&"output"!==t)},rs=function(e){let t=null,s=null;if(gt)e=""+e;else{const t=re(e,/^[\r\n\t ]+/);s=t&&t[0]}"application/xhtml+xml"===Ut&&Pt===Nt&&(e=''+e+"");const n=A?L(e):e;if(Pt===Nt)try{t=(new h).parseFromString(n,Ut)}catch(e){}if(!t||!t.documentElement){t=N.createDocument(Pt,"template",null);try{t.documentElement.innerHTML=Ft?x:n}catch(e){}}const r=t.body||t.documentElement;return e&&s&&r.insertBefore(i.createTextNode(s),r.childNodes[0]||null),Pt===Nt?R.call(t,ut?"html":"body")[0]:ut?t.documentElement:r},as=function(e){const t=S?S(e):e.ownerDocument;return P.call(t||e,e,l.SHOW_ELEMENT|l.SHOW_COMMENT|l.SHOW_TEXT|l.SHOW_PROCESSING_INSTRUCTION|l.SHOW_CDATA_SECTION,null)},os=function(e){return e=ae(e,B," "),e=ae(e,V," "),ae(e,q," ")},cs=function(e){var t;e.normalize();const s=S?S(e):e.ownerDocument,i=P.call(s||e,e,l.SHOW_TEXT|l.SHOW_COMMENT|l.SHOW_CDATA_SECTION|l.SHOW_PROCESSING_INSTRUCTION,null);let n=i.nextNode();for(;n;)n.data=os(n.data),n=i.nextNode();const r=null===(t=e.querySelectorAll)||void 0===t?void 0:t.call(e,"template");r&&Z(r,e=>{hs(e.content)&&cs(e.content)})},ls=function(e){const t=T?T(e):null;return"string"==typeof t&&"form"===Wt(t)&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||e.attributes!==v(e)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore||"function"!=typeof e.hasChildNodes||e.nodeType!==w(e)||e.childNodes!==f(e))},hs=function(e){if(!w||"object"!=typeof e||null===e)return!1;try{return 11===w(e)}catch(e){return!1}},us=function(e){if(!w||"object"!=typeof e||null===e)return!1;try{return"number"==typeof w(e)}catch(e){return!1}};function ds(e,t,i){0!==e.length&&Z(e,e=>{e.call(s,t,i,Ht)})}const ps=function(e,t){if(e instanceof RegExp)return ge(e,t);if(e instanceof Function){for(var s=arguments.length,i=new Array(s>2?s-2:0),n=2;n=0;--n){const r=e===s?p(i[n],!0):i[n];t.insertBefore(r,g(e))}}return Xt(e),!0}(e,i,t);return!1===s&&ds(j.afterSanitizeElements,e,null),s}if(1===C(e)&&!function(e){let t=b(e);t&&t.tagName||(t={namespaceURI:Pt,tagName:"template"});const s=ie(e.tagName),i=ie(t.tagName);return!!Rt[e.namespaceURI]&&(e.namespaceURI===_t?function(e,t,s){return t.namespaceURI===Nt?"svg"===e:t.namespaceURI===Lt?"svg"===e&&("annotation-xml"===s||Bt[s]):Boolean(Yt[e])}(s,t,i):e.namespaceURI===Lt?function(e,t,s){return t.namespaceURI===Nt?"math"===e:t.namespaceURI===_t?"math"===e&&Vt[s]:Boolean(Zt[e])}(s,t,i):e.namespaceURI===Nt?function(e,t,s){return!(t.namespaceURI===_t&&!Vt[s])&&!(t.namespaceURI===Lt&&!Bt[s])&&!Zt[e]&&(qt[e]||!Yt[e])}(s,t,i):!("application/xhtml+xml"!==Ut||!Rt[e.namespaceURI]))}(e))return Xt(e),!0;if(("noscript"===i||"noembed"===i||"noframes"===i)&&ge(He,e.innerHTML))return Xt(e),!0;if(lt&&3===e.nodeType){const t=os(e.textContent);e.textContent!==t&&(ee(s.removed,{element:e.cloneNode()}),e.textContent=t)}return ds(j.afterSanitizeElements,e,null),!1},bs=function(e,t,s){if(it[t])return!1;if(ns(t,e))return!1;if(vt&&("id"===t||"name"===t)&&(s in i||s in Kt))return!1;const n=Ge[t]||nt.attributeCheck instanceof Function&&nt.attributeCheck(t,e);return!(!at||!ge(U,t))||!(!rt||!ge(z,t))||(n?!(!kt[t]&&!ge(be,ae(s,J,""))&&("src"!==t&&"xlink:href"!==t&&"href"!==t||"script"===e||0!==oe(s,"data:")||!xt[e])&&(!ot||ge(G,ae(s,J,"")))&&s):vs(e)&&ps(tt.tagNameCheck,e)&&ps(tt.attributeNameCheck,t,e)||"is"===t&&tt.allowCustomizedBuiltInElements&&ps(tt.tagNameCheck,s))},ys=ve({},["annotation-xml","color-profile","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","missing-glyph"]),vs=function(e){return!ys[ie(e)]&&ge(Y,e)},ws=function(e,t,s,i){if(A&&"object"==typeof u&&"function"==typeof u.getAttributeType&&!s)switch(u.getAttributeType(e,t)){case"TrustedHTML":return L(i);case"TrustedScriptURL":return function(e){I(),k++;try{return A.createScriptURL(e)}finally{k--}}(i)}return i},Ts=function(e,t,i,n){try{i?e.setAttributeNS(i,t,n):e.setAttribute(t,n),ls(e)?Xt(e):Q(s.removed)}catch(s){ts(t,e)}},Ss=function(e){ds(j.beforeSanitizeAttributes,e,null);const t=e.attributes;if(!t||ls(e))return;Ge=ms(j.uponSanitizeAttribute,Ge,et,mt);const s={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:Ge,forceKeepAttr:void 0};let i=t.length;const n=Wt(e.nodeName);for(;i--;){const r=t[i],a=r.name,o=r.namespaceURI,c=r.value,l=Wt(a),h=c;let u="value"===a?h:ce(h);s.attrName=l,s.attrValue=u,s.keepAttr=!0,s.forceKeepAttr=void 0,ds(j.uponSanitizeAttribute,e,s),u=s.attrValue,!wt||"id"!==l&&"name"!==l||0===oe(u,Tt)||(ts(a,e,r),u=Tt+u),ht&&ge(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i,u)||"attributename"===l&&re(u,"href")?ts(a,e,r):s.forceKeepAttr||(!s.keepAttr||!ct&&ge(Ke,u)?ts(a,e,r):(lt&&(u=os(u)),bs(n,l,u)?(u=ws(n,l,o,u),u!==h&&Ts(e,a,o,u)):ts(a,e,r)))}ds(j.afterSanitizeAttributes,e,null)},Cs=function(e){let t=null;const s=as(e);for(ds(j.beforeSanitizeShadowDOM,e,null);t=s.nextNode();)if(ds(j.uponSanitizeShadowNode,t,null),fs(t,e),Ss(t),hs(t.content)&&Cs(t.content),1===C(t)){const e=y(t);hs(e)&&(Os(e),Cs(e))}ds(j.afterSanitizeShadowDOM,e,null)},Os=function(e){const t=[{node:e,shadow:null}];for(;t.length>0;){const e=t.pop();if(e.shadow){Cs(e.shadow);continue}const s=e.node,i=1===C(s),n=f(s);if(n)for(let e=n.length-1;e>=0;--e)t.push({node:n[e],shadow:null});if(i){const e=T?T(s):null;if("string"==typeof e&&"template"===Wt(e)){const e=s.content;hs(e)&&t.push({node:e,shadow:null})}}if(i){const e=y(s);hs(e)&&t.push({node:null,shadow:e},{node:e,shadow:null})}}};return s.sanitize=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=null,r=null,a=null,o=null;if(Ft=!e,Ft&&(e="\x3c!--\x3e"),"string"!=typeof e&&!us(e)&&"string"!=typeof(e=function(e){switch(typeof e){case"string":return e;case"number":return le(e);case"boolean":return he(e);case"bigint":return ue?ue(e):"0";case"symbol":return de?de(e):"Symbol()";case"undefined":default:return me(e);case"function":case"object":{if(null===e)return me(e);const t=e,s=Se(t,"toString");if("function"==typeof s){const e=s(t);return"string"==typeof e?e:me(e)}return me(e)}}}(e)))throw fe("dirty is not a string, aborting");if(!s.isSupported)return e;dt?(ye=pt,Ge=mt):Jt(t),(j.uponSanitizeElement.length>0||j.uponSanitizeAttribute.length>0)&&(ye=Te(ye)),j.uponSanitizeAttribute.length>0&&(Ge=Te(Ge)),s.removed=[];const c=Ct&&"string"!=typeof e&&us(e);if(c){!function(e){if(!ht)return;const t=[e];for(;t.length>0;){const e=t.pop(),s=C(e);if(7===s||8===s&&ge(We,e.data)){try{m(e)}catch(e){}continue}if(1===s){const t=e,s=Wt(O(e));try{t.hasAttribute&&t.hasAttribute("patchsrc")&&t.removeAttribute("patchsrc"),t.hasAttribute&&t.hasAttribute("for")&&ns("for",s)&&t.removeAttribute("for")}catch(e){}}const i=f(e);if(i)for(let e=i.length-1;e>=0;--e)t.push(i[e])}}(e);const t=O(e);if("string"==typeof t){const s=Wt(t);if(!ye[s]||st[s])throw es(e),fe("root node is forbidden and cannot be sanitized in-place")}if(ls(e))throw es(e),fe("root node is clobbered and cannot be sanitized in-place");try{Os(e)}catch(t){throw es(e),t}}else if(us(e))i=rs("\x3c!----\x3e"),r=i.ownerDocument.importNode(e,!0),1===r.nodeType&&"BODY"===r.nodeName||"HTML"===r.nodeName?i=r:i.appendChild(r),Os(r);else{if(!ft&&!lt&&!ut&&-1===e.indexOf("<"))return A&&yt?L(e):e;if(i=rs(e),!i)return ft?null:yt?x:""}i&>&&Xt(i.firstChild);const l=c?e:i;try{const e=as(l);for(;a=e.nextNode();)fs(a,l),Ss(a),hs(a.content)&&Cs(a.content)}catch(t){throw c&&(es(e),Z(s.removed,e=>{e.element&&is(e.element)})),t}if(c)return Z(s.removed,e=>{e.element&&is(e.element)}),lt&&cs(e),e;if(ft){if(lt&&cs(i),bt)for(o=F.call(i.ownerDocument);i.firstChild;)o.appendChild(i.firstChild);else o=i;return(Ge.shadowroot||Ge.shadowrootmode)&&(o=D.call(n,o,!0)),o}let h=ut?i.outerHTML:i.innerHTML;return ut&&ye["!doctype"]&&i.ownerDocument&&i.ownerDocument.doctype&&i.ownerDocument.doctype.name&&ge(qe,i.ownerDocument.doctype.name)&&(h="\n"+h),lt&&(h=os(h)),A&&yt?L(h):h},s.setConfig=function(){Jt(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),dt=!0,pt=ye,mt=Ge},s.clearConfig=function(){Ht=null,dt=!1,pt=null,mt=null,A=E,x=""},s.isValidAttribute=function(e,t,s){Ht||Jt({});const i=Wt(e),n=Wt(t);return bs(i,n,s)},s.addHook=function(e,t){"function"==typeof t&&pe(j,e)&&ee(j[e],t)},s.removeHook=function(e,t){if(pe(j,e)){if(void 0!==t){const s=X(j[e],t);return-1===s?void 0:te(j[e],s,1)[0]}return Q(j[e])}},s.removeHooks=function(e){pe(j,e)&&(j[e]=[])},s.removeAllHooks=function(){j={afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}},s}();const tt={ADD_ATTR:["target"],ALLOW_DATA_ATTR:!1,RETURN_DOM_FRAGMENT:!0,USE_PROFILES:{html:!0}},st={ADD_ATTR:["target"],ADD_TAGS:["hellotext-icon"],RETURN_DOM_FRAGMENT:!0,USE_PROFILES:{html:!0,svg:!0}};function it(e,t){const s=et.sanitize(e,t);return s.querySelectorAll('a[target="_blank"]').forEach(e=>{const t=new Set(e.rel.split(/\s+/).filter(Boolean));t.add("noopener"),t.add("noreferrer"),e.rel=Array.from(t).join(" ")}),s}function nt(e,t){e.replaceChildren(function(e){return it(e,tt)}(t))}class rt{constructor(e,t=null){this.data=e,this.element=t||document.querySelector(`[data-hello-form="${this.id}"]`)||document.createElement("form")}async mount({ifCompleted:e=!0}={}){if(e&&this.hasBeenCompleted)return this.element?.remove(),bt.eventEmitter.dispatch("form:completed",{id:this.id,...JSON.parse(localStorage.getItem(`hello-form-${this.id}`))});const t=this.data.steps[0];this.buildHeader(t.header),this.buildInputs(t.inputs),this.buildButton(t.button),this.buildFooter(t.footer),this.elementAttributes.forEach(e=>{this.element.setAttribute(e.name,e.value)}),document.contains(this.element)||document.body.appendChild(this.element),bt.business.features.white_label||this.element.prepend(D.build())}buildHeader(e){const t=this.#c("[data-form-header]","header");nt(t,e.content),this.element.querySelector("[data-form-header]")?this.element.querySelector("[data-form-header]").replaceWith(t):this.element.prepend(t)}buildInputs(e){const t=this.#c("[data-form-inputs]","main");e.map(e=>R.build(e)).forEach(e=>t.appendChild(e)),this.element.querySelector("[data-form-inputs]")?this.element.querySelector("[data-form-inputs]").replaceWith(t):this.element.querySelector("[data-form-header]").insertAdjacentHTML("afterend",t.outerHTML)}buildButton(e){const t=this.#c("[data-form-button]","button");t.innerText=e.text,t.setAttribute("data-action","click->hellotext--form#submit"),t.setAttribute("data-hellotext--form-target","button"),this.element.querySelector("[data-form-button]")?this.element.querySelector("[data-form-button]").replaceWith(t):this.element.querySelector("[data-form-inputs]").insertAdjacentHTML("afterend",t.outerHTML)}buildFooter(e){const t=this.#c("[data-form-footer]","footer");nt(t,e.content),this.element.querySelector("[data-form-footer]")?this.element.querySelector("[data-form-footer]").replaceWith(t):this.element.appendChild(t)}markAsCompleted(e){const t={state:"completed",id:this.id,data:e,completedAt:(new Date).getTime()};localStorage.setItem(`hello-form-${this.id}`,JSON.stringify(t)),bt.eventEmitter.dispatch("form:completed",t)}get hasBeenCompleted(){return null!==localStorage.getItem(`hello-form-${this.id}`)}get id(){return this.data.id}get localeAuthKey(){const e=this.data.steps[0];return e.inputs.some(e=>"email"===e.kind)&&e.inputs.some(e=>"phone"===e.kind)?"phone_and_email":e.inputs.some(e=>"email"===e.kind)?"email":e.inputs.some(e=>"phone"===e.kind)?"phone":"none"}get elementAttributes(){return[{name:"data-controller",value:"hellotext--form"},{name:"data-hello-form",value:this.id},{name:"data-hellotext--form-data-value",value:JSON.stringify(this.data)}]}#c(e,t){const s=this.element.querySelector(e);if(s)return s.cloneNode(!0);const i=document.createElement(t);return i.setAttribute(e.replace("[","").replace("]",""),""),i}}class at extends Error{constructor(){super("You need to initialize before tracking events. Call Hellotext.initialize and pass your public business id"),this.name="NotInitializedError"}}class ot{constructor(){this.forms=[],this.includes=this.includes.bind(this),this.excludes=this.excludes.bind(this),this.add=this.add.bind(this),"undefined"!=typeof MutationObserver&&(this.mutationObserver=new MutationObserver(this.formMutationObserver.bind(this)),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0}))}collectExistingFormsOnPage(){Array.from(document.querySelectorAll("[data-hello-form]")).length>0&&this.collect()}formMutationObserver(e){e.find(e=>"childList"===e.type&&e.addedNodes.length>0)&&Array.from(document.querySelectorAll("[data-hello-form]")).length>0&&this.collect()}async collect(){if(bt.notInitialized)throw new at;if(this.fetching)return;if("undefined"==typeof document||!("querySelectorAll"in document))return console.warn("Document is not defined, collection is not possible. Please make sure to initialize the library after the document is loaded.");const e=this.#l;if(0===e.length)return;const t=e.map(e=>w.get(e).then(e=>e.json()));this.fetching=!0,await Promise.all(t).then(e=>e.forEach(this.add)).then(()=>bt.eventEmitter.dispatch("forms:collected",this)).then(()=>this.fetching=!1),g.forms.autoMount&&this.forms.forEach(e=>e.mount())}forEach(e){this.forms.forEach(e)}map(e){return this.forms.map(e)}add(e){this.includes(e.id)||(bt.business.data||(bt.business.setData(e.business),bt.business.setLocale(o.toString())),bt.business.enabledWhitelist||console.warn("No whitelist has been configured. It is advised to whitelist the domain to avoid bots from submitting forms."),this.forms.push(new rt(e)))}getById(e){return this.forms.find(t=>t.id===e)}getByIndex(e){return this.forms[e]}includes(e){return this.forms.some(t=>t.id===e)}excludes(e){return!this.includes(e)}get length(){return this.forms.length}get#l(){return Array.from(document.querySelectorAll("[data-hello-form]")).map(e=>e.dataset.helloForm).filter(this.excludes)}}class ct{constructor(e){this.publicKey=e.public_key,this.serviceWorkerUrl=g.push.serviceWorkerUrl,this.channelId=g.push.channelId,this.ready=null,this.registrationPromise=null,this.subscribePromise=null,this.unsubscribePromise=null,this.syncPromise=null,this.subscription=null,this.retryTimeout=null,this.retryAttempts=0,this.disposed=!1}initialize(){return this.ready=this.restoreSubscription(),this.ready}async restoreSubscription(){const e=await this.getRegistration(),t=await e.pushManager.getSubscription();!this.disposed&&!this.unsubscribePromise&&t&&this.owns(t)&&(this.subscription=t,await this.sync())}subscribe(){if(this.disposed)return Promise.resolve();if(this.unsubscribePromise)return Promise.reject(new Error("Push unsubscribe is in progress"));if(this.subscribePromise)return this.subscribePromise;const e="default"===Notification.permission?Notification.requestPermission():Promise.resolve(Notification.permission);return this.subscribePromise=this.createSubscription(e).finally(()=>{this.subscribePromise=null}),this.subscribePromise}async createSubscription(e){if("granted"!==await e)throw new Error("Push permission was not granted");const t=await this.getRegistration();if(this.disposed)return;let s=await t.pushManager.getSubscription();if(!this.disposed){if(s&&!this.owns(s))throw new Error("The existing Push subscription belongs to a different application");if(s||=await t.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:this.applicationServerKey}),!this.disposed)return this.subscription=s,this.sync()}}unsubscribe(){return this.disposed?Promise.resolve():(this.unsubscribePromise||(this.clearRetryTimeout(),this.unsubscribePromise=this.removeSubscription().finally(()=>{this.unsubscribePromise=null})),this.unsubscribePromise)}async removeSubscription(){await(this.ready?.catch(()=>{})),await(this.subscribePromise?.catch(()=>{})),await(this.syncPromise?.catch(()=>{}));const e=await this.getRegistration(),t=await e.pushManager.getSubscription()||this.subscription;if(this.disposed)return;if(!t)return null;if(!this.owns(t))throw new Error("The existing Push subscription belongs to a different application");this.subscription=t;const s=await M.pushIdentities.destroy({subscription:t.toJSON()});return s.failed?s:this.disposed?void 0:(await t.unsubscribe(),this.subscription=null,this.clearRetryTimeout(),s)}sync(){return this.disposed?Promise.resolve():(this.syncPromise||(this.clearRetryTimeout(),this.syncPromise=this.registerIdentity().finally(()=>{this.syncPromise=null})),this.syncPromise)}async registerIdentity(){try{const e=await M.pushIdentities.create({subscription:this.subscription.toJSON(),...this.channelId?{channel_id:this.channelId}:{}});return e.succeeded?this.retryAttempts=0:this.scheduleRetry(),e}catch(e){throw this.scheduleRetry(),e}}scheduleRetry(){this.disposed||this.unsubscribePromise||this.retryTimeout||this.retryAttempts>=3||(this.retryTimeout=setTimeout(()=>{this.retryTimeout=null,this.sync().catch(()=>{})},1e3*2**this.retryAttempts),this.retryAttempts+=1)}clearRetryTimeout(){clearTimeout(this.retryTimeout),this.retryTimeout=null}dispose(){this.disposed=!0,this.clearRetryTimeout()}get subscribed(){return!!this.subscription}get applicationServerKey(){const e=this.publicKey.replace(/-/g,"+").replace(/_/g,"/");return Uint8Array.from(atob(e.padEnd(4*Math.ceil(e.length/4),"=")),e=>e.charCodeAt(0))}owns(e){const t=e.options?.applicationServerKey;if(!t)return!1;const s=new Uint8Array(t),i=this.applicationServerKey;return s.length===i.length&&s.every((e,t)=>e===i[t])}getRegistration(){return this.registrationPromise||(this.registrationPromise=this.loadRegistration().catch(e=>{throw this.registrationPromise=null,e})),this.registrationPromise}async loadRegistration(){if(this.serviceWorkerUrl){const e=await navigator.serviceWorker.register(this.serviceWorkerUrl);!e.active||e.installing||e.waiting||await e.update();const t=e.installing||e.waiting||e.active;return"activated"===t?.state?e:new Promise((s,i)=>{const n=setTimeout(()=>r(new Error("Push service worker did not become active")),1e4),r=r=>{clearTimeout(n),t?.removeEventListener("statechange",a),r?i(r):s(e)},a=()=>{"activated"===t?.state&&r(),"redundant"===t?.state&&r(new Error("Push service worker installation failed"))};t?.addEventListener("statechange",a),a()})}return new Promise((e,t)=>{const s=setTimeout(()=>t(new Error("Push service worker is not available")),1e4);navigator.serviceWorker.ready.then(t=>{clearTimeout(s),e(t)},e=>{clearTimeout(s),t(e)})})}static get supported(){return"undefined"!=typeof window&&!0===window.isSecureContext&&"undefined"!=typeof navigator&&"serviceWorker"in navigator&&"undefined"!=typeof PushManager&&"undefined"!=typeof Notification}}class lt{constructor(e,t,s){this.business=t,this.push=s,this.disposed=!1,this.showRequest=0,this.controller=null,this.element=(new DOMParser).parseFromString(e.html,"text/html").querySelector('[data-controller~="hellotext--alert"]'),this.connected=new Promise(e=>{this.resolveConnected=e}),this.onConnect=this.onConnect.bind(this),this.ready=this.render()}onConnect(e){this.controller=e.detail.controller,this.controller.alert=this,this.resolveConnected(!0)}async render(){return!!this.element&&(this.element.addEventListener("hellotext--alert:connected",this.onConnect),!(!await this.business.stylesheetLoaded||this.disposed)&&(document.body.appendChild(this.element),this.connected))}async show(e,t={}){const s=++this.showRequest;return!(!await this.ready||this.disposed||s!==this.showRequest)&&this.controller.show(e,t)}hide(){this.showRequest+=1,this.controller?.close()}dispose(){this.disposed=!0,this.hide(),this.resolveConnected(!1),this.element?.removeEventListener("hellotext--alert:connected",this.onConnect),this.element?.remove()}}class ht{static async load(e){const t=new ht({id:e,html:await M.webchats.get(e)});return t.rendered=t.render(),t}constructor(e){this.data=e,this.mounted=!1,this.rendered=Promise.resolve(!1)}async render(){return this.applyBehaviourOverride(),await this.stylesheetLoaded?(this.containerToAppendTo.appendChild(this.data.html),this.markCoexistingWidgets(),this.mounted=!0,!0):(console.warn("Hellotext webchat was not mounted because its stylesheet failed to load."),!1)}applyBehaviourOverride(){g.webchat.hasBehaviourOverride&&g.webchat.behaviour&&this.data.html.setAttribute("data-hellotext--webchat-behaviour-value",JSON.stringify(this.serializedBehaviour))}get serializedBehaviour(){const e=g.webchat.behaviour;return{trigger:this.serializeTrigger(e.trigger),delay_seconds:e.delaySeconds,first_visit_only:e.firstVisitOnly,once_per_session:e.oncePerSession}}serializeTrigger(e){return"onLoad"===e?"on_load":"onClick"===e?"on_click":e}get containerToAppendTo(){return document.querySelector(g.webchat.container)}get stylesheetLoaded(){return L.waitForStylesheet(L.latestStylesheet)}markCoexistingWidgets(){const e=this.data.html,t=document.querySelector(".hellotext--whatsapp-widget");e&&t&&(e.classList.add("hellotext--with-whatsapp-widget"),t.classList.add("hellotext--with-webchat"))}}class ut{static async load(e){const t=new ut({id:e,html:await M.whatsappWidgets.get(e)});return t.rendered=t.render(),t}constructor(e){this.data=e,this.mounted=!1,this.rendered=Promise.resolve(!1)}async render(){if(!this.data.html)return!1;const e=this.containerToAppendTo;return e?await this.stylesheetLoaded?(e.appendChild(this.data.html),this.markCoexistingWidgets(),this.mounted=!0,!0):(console.warn("Hellotext WhatsApp widget was not mounted because its stylesheet failed to load."),!1):(console.warn(`Hellotext WhatsApp widget was not mounted because the container ${g.whatsapp.container} was not found.`),!1)}get containerToAppendTo(){try{return document.querySelector(g.whatsapp.container)}catch(e){return null}}get stylesheetLoaded(){return L.waitForStylesheet(L.latestStylesheet)}markCoexistingWidgets(){const e=document.querySelector(".hellotext--webchat:not(.hellotext--whatsapp-widget)"),t=this.data.html;e&&t&&(e.classList.add("hellotext--with-whatsapp-widget"),t.classList.add("hellotext--with-webchat"))}}class dt{static get id(){return _.get("hello_user_id")}static get source(){return _.get("hello_user_source")}static get fingerprint(){return _.get("hello_user_identification_hash")}static remember(e,t,s){t&&_.set("hello_user_source",t),s&&_.set("hello_user_identification_hash",s),_.set("hello_user_id",e)}static forget(){_.delete("hello_user_id"),_.delete("hello_user_source"),_.delete("hello_user_identification_hash")}static get identificationData(){return this.id?{id:this.id,source:this.source}:{}}}function pt(e){if(null!=e){if("string"==typeof e){const t=e.trim();return""===t?void 0:t}if(Array.isArray(e))return e.map(e=>pt(e)).filter(e=>void 0!==e);if(e instanceof Date)return e.toISOString();if("object"==typeof e){const t=Object.keys(e).sort((e,t)=>e.localeCompare(t)).reduce((t,s)=>{const i=pt(e[s]);return void 0!==i&&(t[s]=i),t},{});return Object.keys(t).length>0?t:void 0}return"number"==typeof e||"boolean"==typeof e?e:void 0}}function mt(e,t,s={}){const i=pt({session:e,user_id:t,...s})||{};return JSON.stringify(i)}class gt{static matches(e,t){return!!e&&e===t}static async generate(e,t,s={}){return await async function(e){if(!globalThis.crypto?.subtle||"undefined"==typeof TextEncoder)return function(e){let t=5381;for(let s=0;s>>0).toString(16)}`}(e);const t=await globalThis.crypto.subtle.digest("SHA-256",(new TextEncoder).encode(e));return`v1:${Array.from(new Uint8Array(t)).map(e=>e.toString(16).padStart(2,"0")).join("")}`}(mt(e,t,s))}}class ft{static eventEmitter=new r;static forms;static business;static webchat;static whatsapp;static push;static alert;static async initialize(e,t={}){this.alert?.dispose(),this.alert=null,this.push?.dispose(),this.push=null;const s=new L(e);this.business=s,this.page=new P,g.assign({push:{},...t}),F.initialize(this.page),this.forms=new ot,this.query=new b;const i=await s.hydrate();if(this.business!==s)return;!1!==t.push&&i?.push?.public_key&&ct.supported&&(this.push=new ct(i.push),this.push.initialize().catch(e=>{console.warn("Hellotext Push initialization failed:",e)}),i.alert?.html&&(this.alert=new lt(i.alert,s,this.push)));const n=!1!==t.webchat&&this.mergeWebchatConfig(i&&i.webchat||{},t.webchat||{}),r=!1!==t.whatsappWidget&&this.mergeWhatsAppConfig(i&&i.whatsapp||{},t.whatsappWidget||{}),a=t.webchat&&!1!==t.webchat&&Object.prototype.hasOwnProperty.call(t.webchat,"behaviour");g.webchat.behaviourOverride=a,n&&n.id&&(g.webchat.assign(n),this.webchat=await ht.load(n.id)),r&&r.id&&(g.whatsapp.assign(r),this.whatsapp=await ut.load(r.id)),"undefined"!=typeof MutationObserver&&this.forms.collectExistingFormsOnPage()}static mergeWebchatConfig(e,t){return this.deepMergePlainObjects(e,t)}static mergeWhatsAppConfig(e,t){return this.deepMergePlainObjects(e,t)}static deepMergePlainObjects(e,t){const s={...e};return Object.entries(t).forEach(([e,t])=>{this.isPlainObject(t)&&this.isPlainObject(s[e])?s[e]=this.deepMergePlainObjects(s[e],t):s[e]=t}),s}static isPlainObject(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}static async track(e,t={}){if(this.notInitialized)throw new at;const s={...t&&t.headers||{},...this.headers},i={...dt.identificationData,...t.user_parameters||{}},n=t&&t.url?new P(t.url):this.page,r={session:this.session,user_parameters:i,action:e,...t,...n.trackingData};return delete r.headers,await M.events.create({headers:s,body:r,keepalive:x(r)})}static async identify(e,t={}){const s=await gt.generate(this.session,e,t);if(gt.matches(dt.fingerprint,s))return new y(!0,{json:async()=>({already_identified:!0})});const i=await M.identifications.create({user_id:e,...t});return i.succeeded&&dt.remember(e,t.source,s),i}static forget(){dt.forget()}static on(e,t){this.eventEmitter.addSubscriber(e,t)}static removeEventListener(e,t){this.eventEmitter.removeSubscriber(e,t)}static get session(){return F.session}static get isInitialized(){return void 0!==F.session}static get notInitialized(){return!this.business||void 0===this.business.id}static get headers(){if(this.notInitialized)throw new at;return{Authorization:`Bearer ${this.business.id}`,Accept:"application/json","Content-Type":"application/json"}}}const bt=ft,yt=new Map,vt=class extends i.xI{static values={sections:Array};static targets=["title","description","primaryAction","secondaryAction"];initialize(){this.showRequest=0,this.submitting=!1,this.onStorage=this.onStorage.bind(this)}connect(){this.dispatch("connected",{detail:{controller:this}}),window.addEventListener("storage",this.onStorage)}disconnect(){this.close(),window.removeEventListener("storage",this.onStorage)}onStorage(e){e.key===this.storageKey&&this.dismissal.dismissedUntil>Date.now()&&this.close()}async show(e,{force:t=!1,title:s,description:i,primaryAction:n,secondaryAction:r}={}){const a=++this.showRequest,o=this.sectionsValue.find(t=>t.kind===e);return o?(await(this.alert.push.ready?.catch(()=>{})),!(a!==this.showRequest||this.alert.disposed||!this.element.isConnected||(this.unavailable||!t&&this.dismissal.dismissedUntil>Date.now()?(this.close(),1):(this.titleTarget.textContent=s??o.title,this.descriptionTarget.textContent=i??o.description,this.primaryActionTarget.textContent=n??o.primary_action,this.secondaryActionTarget.textContent=r??o.secondary_action,this.kind=e,this.element.hidden=!1,this.record("shown"),bt.eventEmitter.dispatch("alert:shown",{kind:e}),0)))):(this.close(),!1)}hide(){if(this.element.hidden||this.submitting)return;const e=this.dismissal.dismissals+1,t={dismissals:e,dismissedUntil:Date.now()+864e5*(1===e?7:30)};yt.set(this.storageKey,t);try{localStorage.setItem(this.storageKey,JSON.stringify(t))}catch(e){}this.close(),this.record("dismissed"),bt.eventEmitter.dispatch("alert:dismissed",{kind:this.kind})}close(){this.showRequest+=1,this.element.hidden=!0}async subscribe(){if(!this.submitting&&!this.element.hidden){if(this.unavailable)return this.close();this.submitting=!0,this.primaryActionTarget.disabled=!0,this.secondaryActionTarget.disabled=!0,this.element.setAttribute("aria-busy","true");try{this.record("accepted"),bt.eventEmitter.dispatch("alert:accepted",{kind:this.kind});const e=await this.alert.push.subscribe();return this.unavailable&&this.close(),e?.failed&&this.dispatch("error",{detail:{response:e}}),e}catch(e){this.unavailable&&this.close(),this.dispatch("error",{detail:{error:e}})}finally{this.submitting=!1,this.primaryActionTarget.disabled=!1,this.secondaryActionTarget.disabled=!1,this.element.removeAttribute("aria-busy")}}}async record(e){try{const t=await M.pushAlerts.create({section:this.kind,kind:e});t.failed&&console.warn("Hellotext Smart Alert submission failed:",t)}catch(e){console.warn("Hellotext Smart Alert submission failed:",e)}}get unavailable(){return this.alert.push.disposed||this.alert.push.subscribed||"undefined"==typeof Notification||"denied"===Notification.permission}get storageKey(){return`hellotext:alert:${this.alert.business.id}`}get dismissal(){try{const e=JSON.parse(localStorage.getItem(this.storageKey));Number.isSafeInteger(e?.dismissals)&&e.dismissals>0&&Number.isFinite(e.dismissedUntil)&&e.dismissedUntil>=0&&yt.set(this.storageKey,e)}catch(e){}return yt.get(this.storageKey)||{dismissals:0,dismissedUntil:0}}},wt=class extends i.xI{static values={data:Object,step:{type:Number,default:1}};static targets=["inputContainer","input","button","otpContainer"];initialize(){this.form=new rt(this.dataValue,this.element)}connect(){super.connect(),this.element.addEventListener("submit",this.submit.bind(this)),"INPUT"!==document.activeElement.tagName&&this.inputTargets[0].focus()}async submit(e){if(e.preventDefault(),this.invalid)return this.showErrorMessages();this.clearErrorMessages(),this.formData=Object.fromEntries(new FormData(this.element)),this.buttonTarget.disabled=!0;const t=await w.submit(this.form.id,this.formData);this.buttonTarget.disabled=!1;const s=await t.json();if(t.failed)return s.errors.forEach(e=>{const{type:t,parameter:s}=e,i=this.inputTargets.find(e=>e.name===s);i.setCustomValidity(bt.business.locale.errors[t]),i.reportValidity(),i.addEventListener("input",()=>{i.setCustomValidity(""),i.reportValidity()})}),this.showErrorMessages();this.buttonTarget.style.display="none",this.element.querySelectorAll("input").forEach(e=>e.disabled=!0),this.completed()}completed(){if(this.form.markAsCompleted(this.formData),!g.forms.shouldShowSuccessMessage)return this.element.remove();"string"==typeof g.forms.successMessage?this.element.innerHTML=g.forms.successMessage:this.element.innerHTML=bt.business.locale.forms[this.form.localeAuthKey]}showErrorMessages(){this.inputTargets.forEach(e=>{const t=e.closest("article").querySelector("[data-error-container]");e.validity.valid?t.innerText="":t.innerText=e.validationMessage})}clearErrorMessages(){this.inputTargets.forEach(e=>{e.setCustomValidity(""),e.closest("article").querySelector("[data-error-container]").innerText=""})}inputTargetConnected(e){e.getAttribute("data-default-value")&&(e.value=e.getAttribute("data-default-value"))}get requiredInputs(){return this.inputTargets.filter(e=>e.required)}get invalid(){return!this.element.checkValidity()}},Tt=class extends i.xI{static values={fadeDistance:{type:Number,default:64},id:String,kind:String,pageStartOffset:{type:Number,default:0},utm:Object};static targets=["carouselContainer","leftFade","rightFade","carouselCard"];connect(){this.updateFades(),this.observeContainerSize()}disconnect(){this.resizeObserver?.disconnect()}setId({detail:e}){this.idValue=e,this.element.id=e}onScroll(){this.updateFades()}quickReply({currentTarget:e}){const t=e.closest('[data-hellotext--message-target="carouselCard"]'),s=e.closest('[data-controller~="hellotext--message"]'),i=e.dataset.text||e.textContent.trim();this.dispatch("quickReply",{detail:{id:this.idValue,product:t?.dataset.id,buttonId:e.dataset.id,body:i,cardElement:t||s||e}})}addToCart({currentTarget:e}){const t=e.closest('[data-hellotext--message-target="carouselCard"]'),{id:s,reference:i,source:n}=t.dataset,r={product:s,quantity:1};this.hasUtmValue&&bt.page.utm.save(this.utmValue),bt.eventEmitter.dispatch("cart.added",{object_parameters:{items:[{...r,...i&&{reference:i},...n&&{source:n}}]},source:{kind:this.kindValue,message_id:this.idValue,button_id:e.dataset.id}})}moveToLeft(){if(!this.hasCarouselContainerTarget)return;const e=this.getPreviousPageScrollLeft(),t=this.carouselContainerTarget.scrollLeft-e;t<1||this.carouselContainerTarget.scrollBy({left:-t,behavior:"smooth"})}moveToRight(){if(!this.hasCarouselContainerTarget)return;const e=this.getNextPageScrollLeft()-this.carouselContainerTarget.scrollLeft;e<1||this.carouselContainerTarget.scrollBy({left:e,behavior:"smooth"})}getScrollAmount(){return this.getCardScrollAmount()}getCardScrollAmount(){const e=this.carouselContainerTarget.querySelector(".message__carousel_card");return e?e.offsetWidth+this.getGap():280}getPageScrollAmount(){const e=this.carouselContainerTarget.clientWidth-this.getGap();return e>0?e:this.getCardScrollAmount()}getNextPageScrollLeft(){const e=this.getCurrentScrollLeft(),t=e+this.carouselContainerTarget.clientWidth,s=this.getCardMetrics().find(e=>e.end>t+1),i=s?this.getPageAlignedScrollLeft(s.start):e+this.getPageScrollAmount(),n=e+this.getPageScrollAmount();return this.clampScrollLeft(i>e+1?i:n)}getPreviousPageScrollLeft(){const e=this.getCurrentScrollLeft();if(e<=1)return 0;const t=Math.max(e-this.getPageScrollAmount(),0);if(t<=1)return 0;const s=this.getCardMetrics(),i=s.find(s=>s.start>=t-1&&s.startt.start{const t=this.getCardScrollLeft(e);return{start:t,end:t+e.offsetWidth}})}getCardScrollLeft(e){const t=e.getBoundingClientRect(),s=this.carouselContainerTarget.getBoundingClientRect();return t.left||t.width||s.left||s.width?t.left-s.left+this.carouselContainerTarget.scrollLeft:e.offsetLeft||0}getCurrentScrollLeft(){return this.clampScrollLeft(this.carouselContainerTarget.scrollLeft)}clampScrollLeft(e){const t=Math.max(this.carouselContainerTarget.scrollWidth-this.carouselContainerTarget.clientWidth,0);return Math.min(Math.max(e,0),t)}getGap(){const e=window.getComputedStyle(this.carouselContainerTarget),t=Number.parseFloat(e.columnGap||e.gap);return Number.isFinite(t)?t:16}getFadeDistance(){return Number.isFinite(this.fadeDistanceValue)?this.fadeDistanceValue:64}getPageStartOffset(){return Number.isFinite(this.pageStartOffsetValue)?this.pageStartOffsetValue:0}observeContainerSize(){this.hasCarouselContainerTarget&&window.ResizeObserver&&(this.resizeObserver=new ResizeObserver(()=>this.updateFades()),this.resizeObserver.observe(this.carouselContainerTarget))}updateFades(){if(!this.hasCarouselContainerTarget)return;const e=Math.max(this.carouselContainerTarget.scrollWidth-this.carouselContainerTarget.clientWidth,0);if(e<=1)return this.hideFade(this.leftFadeTarget),void this.hideFade(this.rightFadeTarget);const t=Math.min(Math.max(this.carouselContainerTarget.scrollLeft,0),e),s=this.getFadeDistance();this.setFadeOpacity(this.leftFadeTarget,t/s),this.setFadeOpacity(this.rightFadeTarget,(e-t)/s)}setFadeOpacity(e,t){const s=Math.min(Math.max(t,0),1);s<=.05?this.hideFade(e):(e.classList.remove("hidden"),e.removeAttribute("disabled"),e.removeAttribute("tabindex"),e.setAttribute("aria-hidden","false"),e.style.opacity=s.toFixed(3),e.style.pointerEvents="auto")}hideFade(e){e.style.opacity="0",e.style.pointerEvents="none",e.setAttribute("aria-hidden","true"),e.setAttribute("tabindex","-1"),"disabled"in e&&(e.disabled=!0),e.classList.add("hidden")}},St=["start","end"],Ct=["top","right","bottom","left"].reduce((e,t)=>e.concat(t,t+"-"+St[0],t+"-"+St[1]),[]),Ot=Math.min,At=Math.max,Et=Math.round,xt=Math.floor,Mt=e=>({x:e,y:e}),kt={left:"right",right:"left",bottom:"top",top:"bottom"},It={start:"end",end:"start"};function Lt(e,t,s){return At(e,Ot(t,s))}function _t(e,t){return"function"==typeof e?e(t):e}function Nt(e){return e.split("-")[0]}function Pt(e){return e.split("-")[1]}function Ft(e){return"x"===e?"y":"x"}function Rt(e){return"y"===e?"height":"width"}const Dt=new Set(["top","bottom"]);function jt(e){return Dt.has(Nt(e))?"y":"x"}function Bt(e){return Ft(jt(e))}function $t(e,t,s){void 0===s&&(s=!1);const i=Pt(e),n=Bt(e),r=Rt(n);let a="x"===n?i===(s?"end":"start")?"right":"left":"start"===i?"bottom":"top";return t.reference[r]>t.floating[r]&&(a=Ht(a)),[a,Ht(a)]}function Vt(e){return e.replace(/start|end/g,e=>It[e])}const qt=["left","right"],Ut=["right","left"],zt=["top","bottom"],Wt=["bottom","top"];function Ht(e){return e.replace(/left|right|bottom|top/g,e=>kt[e])}function Kt(e){const{x:t,y:s,width:i,height:n}=e;return{width:i,height:n,top:s,left:t,right:t+i,bottom:s+n,x:t,y:s}}function Gt(e,t,s){let{reference:i,floating:n}=e;const r=jt(t),a=Bt(t),o=Rt(a),c=Nt(t),l="y"===r,h=i.x+i.width/2-n.width/2,u=i.y+i.height/2-n.height/2,d=i[o]/2-n[o]/2;let p;switch(c){case"top":p={x:h,y:i.y-n.height};break;case"bottom":p={x:h,y:i.y+i.height};break;case"right":p={x:i.x+i.width,y:u};break;case"left":p={x:i.x-n.width,y:u};break;default:p={x:i.x,y:i.y}}switch(Pt(t)){case"start":p[a]-=d*(s&&l?-1:1);break;case"end":p[a]+=d*(s&&l?-1:1)}return p}async function Jt(e,t){var s;void 0===t&&(t={});const{x:i,y:n,platform:r,rects:a,elements:o,strategy:c}=e,{boundary:l="clippingAncestors",rootBoundary:h="viewport",elementContext:u="floating",altBoundary:d=!1,padding:p=0}=_t(t,e),m=function(e){return"number"!=typeof e?function(e){return{top:0,right:0,bottom:0,left:0,...e}}(e):{top:e,right:e,bottom:e,left:e}}(p),g=o[d?"floating"===u?"reference":"floating":u],f=Kt(await r.getClippingRect({element:null==(s=await(null==r.isElement?void 0:r.isElement(g)))||s?g:g.contextElement||await(null==r.getDocumentElement?void 0:r.getDocumentElement(o.floating)),boundary:l,rootBoundary:h,strategy:c})),b="floating"===u?{x:i,y:n,width:a.floating.width,height:a.floating.height}:a.reference,y=await(null==r.getOffsetParent?void 0:r.getOffsetParent(o.floating)),v=await(null==r.isElement?void 0:r.isElement(y))&&await(null==r.getScale?void 0:r.getScale(y))||{x:1,y:1},w=Kt(r.convertOffsetParentRelativeRectToViewportRelativeRect?await r.convertOffsetParentRelativeRectToViewportRelativeRect({elements:o,rect:b,offsetParent:y,strategy:c}):b);return{top:(f.top-w.top+m.top)/v.y,bottom:(w.bottom-f.bottom+m.bottom)/v.y,left:(f.left-w.left+m.left)/v.x,right:(w.right-f.right+m.right)/v.x}}const Yt=new Set(["left","top"]);function Zt(){return"undefined"!=typeof window}function Xt(e){return ts(e)?(e.nodeName||"").toLowerCase():"#document"}function Qt(e){var t;return(null==e||null==(t=e.ownerDocument)?void 0:t.defaultView)||window}function es(e){var t;return null==(t=(ts(e)?e.ownerDocument:e.document)||window.document)?void 0:t.documentElement}function ts(e){return!!Zt()&&(e instanceof Node||e instanceof Qt(e).Node)}function ss(e){return!!Zt()&&(e instanceof Element||e instanceof Qt(e).Element)}function is(e){return!!Zt()&&(e instanceof HTMLElement||e instanceof Qt(e).HTMLElement)}function ns(e){return!(!Zt()||"undefined"==typeof ShadowRoot)&&(e instanceof ShadowRoot||e instanceof Qt(e).ShadowRoot)}const rs=new Set(["inline","contents"]);function as(e){const{overflow:t,overflowX:s,overflowY:i,display:n}=ys(e);return/auto|scroll|overlay|hidden|clip/.test(t+i+s)&&!rs.has(n)}const os=new Set(["table","td","th"]);function cs(e){return os.has(Xt(e))}const ls=[":popover-open",":modal"];function hs(e){return ls.some(t=>{try{return e.matches(t)}catch(e){return!1}})}const us=["transform","translate","scale","rotate","perspective"],ds=["transform","translate","scale","rotate","perspective","filter"],ps=["paint","layout","strict","content"];function ms(e){const t=gs(),s=ss(e)?ys(e):e;return us.some(e=>!!s[e]&&"none"!==s[e])||!!s.containerType&&"normal"!==s.containerType||!t&&!!s.backdropFilter&&"none"!==s.backdropFilter||!t&&!!s.filter&&"none"!==s.filter||ds.some(e=>(s.willChange||"").includes(e))||ps.some(e=>(s.contain||"").includes(e))}function gs(){return!("undefined"==typeof CSS||!CSS.supports)&&CSS.supports("-webkit-backdrop-filter","none")}const fs=new Set(["html","body","#document"]);function bs(e){return fs.has(Xt(e))}function ys(e){return Qt(e).getComputedStyle(e)}function vs(e){return ss(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function ws(e){if("html"===Xt(e))return e;const t=e.assignedSlot||e.parentNode||ns(e)&&e.host||es(e);return ns(t)?t.host:t}function Ts(e){const t=ws(e);return bs(t)?e.ownerDocument?e.ownerDocument.body:e.body:is(t)&&as(t)?t:Ts(t)}function Ss(e,t,s){var i;void 0===t&&(t=[]),void 0===s&&(s=!0);const n=Ts(e),r=n===(null==(i=e.ownerDocument)?void 0:i.body),a=Qt(n);if(r){const e=Cs(a);return t.concat(a,a.visualViewport||[],as(n)?n:[],e&&s?Ss(e):[])}return t.concat(n,Ss(n,[],s))}function Cs(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}function Os(e){const t=ys(e);let s=parseFloat(t.width)||0,i=parseFloat(t.height)||0;const n=is(e),r=n?e.offsetWidth:s,a=n?e.offsetHeight:i,o=Et(s)!==r||Et(i)!==a;return o&&(s=r,i=a),{width:s,height:i,$:o}}function As(e){return ss(e)?e:e.contextElement}function Es(e){const t=As(e);if(!is(t))return Mt(1);const s=t.getBoundingClientRect(),{width:i,height:n,$:r}=Os(t);let a=(r?Et(s.width):s.width)/i,o=(r?Et(s.height):s.height)/n;return a&&Number.isFinite(a)||(a=1),o&&Number.isFinite(o)||(o=1),{x:a,y:o}}const xs=Mt(0);function Ms(e){const t=Qt(e);return gs()&&t.visualViewport?{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}:xs}function ks(e,t,s,i){void 0===t&&(t=!1),void 0===s&&(s=!1);const n=e.getBoundingClientRect(),r=As(e);let a=Mt(1);t&&(i?ss(i)&&(a=Es(i)):a=Es(e));const o=function(e,t,s){return void 0===t&&(t=!1),!(!s||t&&s!==Qt(e))&&t}(r,s,i)?Ms(r):Mt(0);let c=(n.left+o.x)/a.x,l=(n.top+o.y)/a.y,h=n.width/a.x,u=n.height/a.y;if(r){const e=Qt(r),t=i&&ss(i)?Qt(i):i;let s=e,n=Cs(s);for(;n&&i&&t!==s;){const e=Es(n),t=n.getBoundingClientRect(),i=ys(n),r=t.left+(n.clientLeft+parseFloat(i.paddingLeft))*e.x,a=t.top+(n.clientTop+parseFloat(i.paddingTop))*e.y;c*=e.x,l*=e.y,h*=e.x,u*=e.y,c+=r,l+=a,s=Qt(n),n=Cs(s)}}return Kt({width:h,height:u,x:c,y:l})}function Is(e,t){const s=vs(e).scrollLeft;return t?t.left+s:ks(es(e)).left+s}function Ls(e,t,s){void 0===s&&(s=!1);const i=e.getBoundingClientRect();return{x:i.left+t.scrollLeft-(s?0:Is(e,i)),y:i.top+t.scrollTop}}const _s=new Set(["absolute","fixed"]);function Ns(e,t,s){let i;if("viewport"===t)i=function(e,t){const s=Qt(e),i=es(e),n=s.visualViewport;let r=i.clientWidth,a=i.clientHeight,o=0,c=0;if(n){r=n.width,a=n.height;const e=gs();(!e||e&&"fixed"===t)&&(o=n.offsetLeft,c=n.offsetTop)}return{width:r,height:a,x:o,y:c}}(e,s);else if("document"===t)i=function(e){const t=es(e),s=vs(e),i=e.ownerDocument.body,n=At(t.scrollWidth,t.clientWidth,i.scrollWidth,i.clientWidth),r=At(t.scrollHeight,t.clientHeight,i.scrollHeight,i.clientHeight);let a=-s.scrollLeft+Is(e);const o=-s.scrollTop;return"rtl"===ys(i).direction&&(a+=At(t.clientWidth,i.clientWidth)-n),{width:n,height:r,x:a,y:o}}(es(e));else if(ss(t))i=function(e,t){const s=ks(e,!0,"fixed"===t),i=s.top+e.clientTop,n=s.left+e.clientLeft,r=is(e)?Es(e):Mt(1);return{width:e.clientWidth*r.x,height:e.clientHeight*r.y,x:n*r.x,y:i*r.y}}(t,s);else{const s=Ms(e);i={x:t.x-s.x,y:t.y-s.y,width:t.width,height:t.height}}return Kt(i)}function Ps(e,t){const s=ws(e);return!(s===t||!ss(s)||bs(s))&&("fixed"===ys(s).position||Ps(s,t))}function Fs(e,t,s){const i=is(t),n=es(t),r="fixed"===s,a=ks(e,!0,r,t);let o={scrollLeft:0,scrollTop:0};const c=Mt(0);function l(){c.x=Is(n)}if(i||!i&&!r)if(("body"!==Xt(t)||as(n))&&(o=vs(t)),i){const e=ks(t,!0,r,t);c.x=e.x+t.clientLeft,c.y=e.y+t.clientTop}else n&&l();r&&!i&&n&&l();const h=!n||i||r?Mt(0):Ls(n,o);return{x:a.left+o.scrollLeft-c.x-h.x,y:a.top+o.scrollTop-c.y-h.y,width:a.width,height:a.height}}function Rs(e){return"static"===ys(e).position}function Ds(e,t){if(!is(e)||"fixed"===ys(e).position)return null;if(t)return t(e);let s=e.offsetParent;return es(e)===s&&(s=s.ownerDocument.body),s}function js(e,t){const s=Qt(e);if(hs(e))return s;if(!is(e)){let t=ws(e);for(;t&&!bs(t);){if(ss(t)&&!Rs(t))return t;t=ws(t)}return s}let i=Ds(e,t);for(;i&&cs(i)&&Rs(i);)i=Ds(i,t);return i&&bs(i)&&Rs(i)&&!ms(i)?s:i||function(e){let t=ws(e);for(;is(t)&&!bs(t);){if(ms(t))return t;if(hs(t))return null;t=ws(t)}return null}(e)||s}const Bs={convertOffsetParentRelativeRectToViewportRelativeRect:function(e){let{elements:t,rect:s,offsetParent:i,strategy:n}=e;const r="fixed"===n,a=es(i),o=!!t&&hs(t.floating);if(i===a||o&&r)return s;let c={scrollLeft:0,scrollTop:0},l=Mt(1);const h=Mt(0),u=is(i);if((u||!u&&!r)&&(("body"!==Xt(i)||as(a))&&(c=vs(i)),is(i))){const e=ks(i);l=Es(i),h.x=e.x+i.clientLeft,h.y=e.y+i.clientTop}const d=!a||u||r?Mt(0):Ls(a,c,!0);return{width:s.width*l.x,height:s.height*l.y,x:s.x*l.x-c.scrollLeft*l.x+h.x+d.x,y:s.y*l.y-c.scrollTop*l.y+h.y+d.y}},getDocumentElement:es,getClippingRect:function(e){let{element:t,boundary:s,rootBoundary:i,strategy:n}=e;const r=[..."clippingAncestors"===s?hs(t)?[]:function(e,t){const s=t.get(e);if(s)return s;let i=Ss(e,[],!1).filter(e=>ss(e)&&"body"!==Xt(e)),n=null;const r="fixed"===ys(e).position;let a=r?ws(e):e;for(;ss(a)&&!bs(a);){const t=ys(a),s=ms(a);s||"fixed"!==t.position||(n=null),(r?!s&&!n:!s&&"static"===t.position&&n&&_s.has(n.position)||as(a)&&!s&&Ps(e,a))?i=i.filter(e=>e!==a):n=t,a=ws(a)}return t.set(e,i),i}(t,this._c):[].concat(s),i],a=r[0],o=r.reduce((e,s)=>{const i=Ns(t,s,n);return e.top=At(i.top,e.top),e.right=Ot(i.right,e.right),e.bottom=Ot(i.bottom,e.bottom),e.left=At(i.left,e.left),e},Ns(t,a,n));return{width:o.right-o.left,height:o.bottom-o.top,x:o.left,y:o.top}},getOffsetParent:js,getElementRects:async function(e){const t=this.getOffsetParent||js,s=this.getDimensions,i=await s(e.floating);return{reference:Fs(e.reference,await t(e.floating),e.strategy),floating:{x:0,y:0,width:i.width,height:i.height}}},getClientRects:function(e){return Array.from(e.getClientRects())},getDimensions:function(e){const{width:t,height:s}=Os(e);return{width:t,height:s}},getScale:Es,isElement:ss,isRTL:function(e){return"rtl"===ys(e).direction}};function $s(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}const Vs=function(e){return void 0===e&&(e=0),{name:"offset",options:e,async fn(t){var s,i;const{x:n,y:r,placement:a,middlewareData:o}=t,c=await async function(e,t){const{placement:s,platform:i,elements:n}=e,r=await(null==i.isRTL?void 0:i.isRTL(n.floating)),a=Nt(s),o=Pt(s),c="y"===jt(s),l=Yt.has(a)?-1:1,h=r&&c?-1:1,u=_t(t,e);let{mainAxis:d,crossAxis:p,alignmentAxis:m}="number"==typeof u?{mainAxis:u,crossAxis:0,alignmentAxis:null}:{mainAxis:u.mainAxis||0,crossAxis:u.crossAxis||0,alignmentAxis:u.alignmentAxis};return o&&"number"==typeof m&&(p="end"===o?-1*m:m),c?{x:p*h,y:d*l}:{x:d*l,y:p*h}}(t,e);return a===(null==(s=o.offset)?void 0:s.placement)&&null!=(i=o.arrow)&&i.alignmentOffset?{}:{x:n+c.x,y:r+c.y,data:{...c,placement:a}}}}},qs=function(e){return void 0===e&&(e={}),{name:"shift",options:e,async fn(t){const{x:s,y:i,placement:n}=t,{mainAxis:r=!0,crossAxis:a=!1,limiter:o={fn:e=>{let{x:t,y:s}=e;return{x:t,y:s}}},...c}=_t(e,t),l={x:s,y:i},h=await Jt(t,c),u=jt(Nt(n)),d=Ft(u);let p=l[d],m=l[u];if(r){const e="y"===d?"bottom":"right";p=Lt(p+h["y"===d?"top":"left"],p,p-h[e])}if(a){const e="y"===u?"bottom":"right";m=Lt(m+h["y"===u?"top":"left"],m,m-h[e])}const g=o.fn({...t,[d]:p,[u]:m});return{...g,data:{x:g.x-s,y:g.y-i,enabled:{[d]:r,[u]:a}}}}}},Us=function(e){return void 0===e&&(e={}),{name:"flip",options:e,async fn(t){var s,i;const{placement:n,middlewareData:r,rects:a,initialPlacement:o,platform:c,elements:l}=t,{mainAxis:h=!0,crossAxis:u=!0,fallbackPlacements:d,fallbackStrategy:p="bestFit",fallbackAxisSideDirection:m="none",flipAlignment:g=!0,...f}=_t(e,t);if(null!=(s=r.arrow)&&s.alignmentOffset)return{};const b=Nt(n),y=jt(o),v=Nt(o)===o,w=await(null==c.isRTL?void 0:c.isRTL(l.floating)),T=d||(v||!g?[Ht(o)]:function(e){const t=Ht(e);return[Vt(e),t,Vt(t)]}(o)),S="none"!==m;!d&&S&&T.push(...function(e,t,s,i){const n=Pt(e);let r=function(e,t,s){switch(e){case"top":case"bottom":return s?t?Ut:qt:t?qt:Ut;case"left":case"right":return t?zt:Wt;default:return[]}}(Nt(e),"start"===s,i);return n&&(r=r.map(e=>e+"-"+n),t&&(r=r.concat(r.map(Vt)))),r}(o,g,m,w));const C=[o,...T],O=await Jt(t,f),A=[];let E=(null==(i=r.flip)?void 0:i.overflows)||[];if(h&&A.push(O[b]),u){const e=$t(n,a,w);A.push(O[e[0]],O[e[1]])}if(E=[...E,{placement:n,overflows:A}],!A.every(e=>e<=0)){var x,M;const e=((null==(x=r.flip)?void 0:x.index)||0)+1,t=C[e];if(t&&("alignment"!==u||y===jt(t)||E.every(e=>jt(e.placement)!==y||e.overflows[0]>0)))return{data:{index:e,overflows:E},reset:{placement:t}};let s=null==(M=E.filter(e=>e.overflows[0]<=0).sort((e,t)=>e.overflows[1]-t.overflows[1])[0])?void 0:M.placement;if(!s)switch(p){case"bestFit":{var k;const e=null==(k=E.filter(e=>{if(S){const t=jt(e.placement);return t===y||"y"===t}return!0}).map(e=>[e.placement,e.overflows.filter(e=>e>0).reduce((e,t)=>e+t,0)]).sort((e,t)=>e[1]-t[1])[0])?void 0:k[0];e&&(s=e);break}case"initialPlacement":s=o}if(n!==s)return{reset:{placement:s}}}return{}}}},zs=e=>{Object.assign(e,{show(){this.cancelBehaviourOpen?.(),this.openValue=!0},hide(){this.openValue=!1},toggle(){this.cancelBehaviourOpen?.(),this.openValue=!this.openValue},setupFloatingUI({trigger:e,popover:t,strategy:s}){this.floatingUICleanup=function(e,t,s,i){void 0===i&&(i={});const{ancestorScroll:n=!0,ancestorResize:r=!0,elementResize:a="function"==typeof ResizeObserver,layoutShift:o="function"==typeof IntersectionObserver,animationFrame:c=!1}=i,l=As(e),h=n||r?[...l?Ss(l):[],...Ss(t)]:[];h.forEach(e=>{n&&e.addEventListener("scroll",s,{passive:!0}),r&&e.addEventListener("resize",s)});const u=l&&o?function(e,t){let s,i=null;const n=es(e);function r(){var e;clearTimeout(s),null==(e=i)||e.disconnect(),i=null}return function a(o,c){void 0===o&&(o=!1),void 0===c&&(c=1),r();const l=e.getBoundingClientRect(),{left:h,top:u,width:d,height:p}=l;if(o||t(),!d||!p)return;const m={rootMargin:-xt(u)+"px "+-xt(n.clientWidth-(h+d))+"px "+-xt(n.clientHeight-(u+p))+"px "+-xt(h)+"px",threshold:At(0,Ot(1,c))||1};let g=!0;function f(t){const i=t[0].intersectionRatio;if(i!==c){if(!g)return a();i?a(!1,i):s=setTimeout(()=>{a(!1,1e-7)},1e3)}1!==i||$s(l,e.getBoundingClientRect())||a(),g=!1}try{i=new IntersectionObserver(f,{...m,root:n.ownerDocument})}catch(e){i=new IntersectionObserver(f,m)}i.observe(e)}(!0),r}(l,s):null;let d,p=-1,m=null;a&&(m=new ResizeObserver(e=>{let[i]=e;i&&i.target===l&&m&&(m.unobserve(t),cancelAnimationFrame(p),p=requestAnimationFrame(()=>{var e;null==(e=m)||e.observe(t)})),s()}),l&&!c&&m.observe(l),m.observe(t));let g=c?ks(e):null;return c&&function t(){const i=ks(e);g&&!$s(g,i)&&s(),g=i,d=requestAnimationFrame(t)}(),s(),()=>{var e;h.forEach(e=>{n&&e.removeEventListener("scroll",s),r&&e.removeEventListener("resize",s)}),null==u||u(),null==(e=m)||e.disconnect(),m=null,c&&cancelAnimationFrame(d)}}(e,t,()=>{((e,t,s)=>{const i=new Map,n={platform:Bs,...s},r={...n.platform,_c:i};return(async(e,t,s)=>{const{placement:i="bottom",strategy:n="absolute",middleware:r=[],platform:a}=s,o=r.filter(Boolean),c=await(null==a.isRTL?void 0:a.isRTL(t));let l=await a.getElementRects({reference:e,floating:t,strategy:n}),{x:h,y:u}=Gt(l,i,c),d=i,p={},m=0;for(let s=0;s{const n={left:`${e}px`,top:`${s}px`,position:i};Object.assign(t.style,n)})})},openValueChanged(){this.disabledValue||(this.openValue?(this.preparePopoverOpenAnimation?.(),this.popoverTarget.showPopover(),this.popoverTarget.setAttribute("aria-expanded","true"),this.onPopoverOpened&&this.onPopoverOpened()):(this.popoverTarget.hidePopover(),this.popoverTarget.removeAttribute("aria-expanded"),this.onPopoverClosed&&this.onPopoverClosed()))}})},Ws=class extends i.xI{static targets=["button","popover"];static values={placement:{type:String,default:"bottom-end"},open:{type:Boolean,default:!1},autoPlacement:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},size:{type:Number,default:24},perLine:{type:Number,default:9}};initialize(){this.onEmojiSelect=this.onEmojiSelect.bind(this),this.pickerLoaded=!1,this.pickerLoadPromise=null,this.connected=!1,super.initialize()}connect(){this.connected=!0,zs(this),this.setupFloatingUI({trigger:this.buttonTarget,popover:this.popoverTarget,strategy:"absolute"}),super.connect()}disconnect(){this.connected=!1,this.pickerLoadPromise=null,this.floatingUICleanup(),super.disconnect()}onEmojiSelect(e){this.dispatch("selected",{detail:e.native}),this.hide()}onClickOutside(e){this.openValue&&e.target.nodeType&&!1===this.element.contains(e.target)&&(this.openValue=!1)}async onPopoverOpened(){await this.loadPicker()}async loadPicker(){if(this.pickerLoaded)return;this.pickerLoadPromise||=this.loadPickerDependencies();const{Picker:e,i18n:t}=await this.pickerLoadPromise;this.connected&&!this.pickerLoaded&&(this.popoverTarget.appendChild(this.buildPicker(e,t)),this.pickerLoaded=!0)}async loadPickerDependencies(){const[e,t]=await Promise.all([s.e(160).then(s.bind(s,405)),this.loadI18n()]);return{Picker:e.Picker,i18n:t.default||t}}loadI18n(){return"es"===Hellotext.business.locale?s.e(437).then(s.t.bind(s,9,19)):s.e(200).then(s.t.bind(s,714,19))}buildPicker(e,t){return new e({onEmojiSelect:this.onEmojiSelect,theme:"light",dynamicWidth:!0,previewPosition:"none",skinTonePosition:"none",emojiSize:this.sizeValue,perLine:this.perLineValue,i18n:t})}get middlewares(){return[Vs(5),qs({padding:24}),(e={allowedPlacements:["top","bottom"]},void 0===e&&(e={}),{name:"autoPlacement",options:e,async fn(t){var s,i,n;const{rects:r,middlewareData:a,placement:o,platform:c,elements:l}=t,{crossAxis:h=!1,alignment:u,allowedPlacements:d=Ct,autoAlignment:p=!0,...m}=_t(e,t),g=void 0!==u||d===Ct?function(e,t,s){return(e?[...s.filter(t=>Pt(t)===e),...s.filter(t=>Pt(t)!==e)]:s.filter(e=>Nt(e)===e)).filter(s=>!e||Pt(s)===e||!!t&&Vt(s)!==s)}(u||null,p,d):d,f=await Jt(t,m),b=(null==(s=a.autoPlacement)?void 0:s.index)||0,y=g[b];if(null==y)return{};const v=$t(y,r,await(null==c.isRTL?void 0:c.isRTL(l.floating)));if(o!==y)return{reset:{placement:g[0]}};const w=[f[Nt(y)],f[v[0]],f[v[1]]],T=[...(null==(i=a.autoPlacement)?void 0:i.overflows)||[],{placement:y,overflows:w}],S=g[b+1];if(S)return{data:{index:b+1,overflows:T},reset:{placement:S}};const C=T.map(e=>{const t=Pt(e.placement);return[e.placement,t&&h?e.overflows.slice(0,2).reduce((e,t)=>e+t,0):e.overflows[0],e.overflows]}).sort((e,t)=>e[1]-t[1]),O=(null==(n=C.filter(e=>e[2].slice(0,Pt(e[0])?2:3).every(e=>e<=0))[0])?void 0:n[0])||C[0][0];return O!==o?{data:{index:b+1,overflows:T},reset:{placement:O}}:{}}})];var e}};class Hs{static get endpoint(){return g.endpoint("public/webchats/:id/messages")}constructor(e){this.webchatId=e}async index(e){const t=new URL(this.url);return Object.entries(e).forEach(([e,s])=>{t.searchParams.append(e,s)}),await fetch(t,{method:"GET",headers:bt.headers})}catchUp(e){return this.index({after_id:e,session:bt.session})}async create(e){const t=await fetch(this.url,{method:"POST",headers:{Authorization:`Bearer ${bt.business.id}`},body:e});return new y(t.ok,t)}markAsSeen(e=null){const t=e?this.url+`/${e}`:this.url+"/seen";fetch(t,{method:"PATCH",headers:bt.headers,body:JSON.stringify({session:bt.session})})}get url(){return Hs.endpoint.replace(":id",this.webchatId)}}const Ks=Hs;class Gs{static webSocket;static channels=new Set;static messageHandlers=new Set;static disconnectHandlers=new Set;static subscriptionConfirmHandlers=new Set;static reconnectTimeout=null;static reconnectAttempts=0;static reconnectBaseDelay=500;static reconnectMaxDelay=1e4;static reconnectJitter=.3;static needsResubscribe=!1;constructor(){Gs.channels.add(this)}send({command:e,identifier:t,data:s}){const i={command:e,identifier:JSON.stringify(t),data:JSON.stringify(s||{})},n=Gs.ensureWebSocket(),r=JSON.stringify(i);n.readyState===WebSocket.OPEN?n.send(r):n.addEventListener("open",()=>{n.send(r)})}onMessage(e){const t=t=>{const s=JSON.parse(t.data),{type:i,message:n}=s;this.ignoredEvents.includes(i)||e(n)};Gs.messageHandlers.add(t),Gs.ensureWebSocket().addEventListener("message",t)}onDisconnect(e){Gs.disconnectHandlers.add(e)}onSubscriptionConfirmed(e){Gs.subscriptionConfirmHandlers.add(e)}get webSocket(){return Gs.ensureWebSocket()}static ensureWebSocket(){return this.webSocket&&!this.closedWebSocket(this.webSocket)?this.webSocket:(this.webSocket&&(this.needsResubscribe=!0),this.openWebSocket())}static openWebSocket(){this.clearReconnectTimeout();const e=new WebSocket(g.actionCableUrl);return this.webSocket=e,this.installWebSocketHandlers(e),e}static installWebSocketHandlers(e){e.addEventListener("open",()=>this.handleOpen(e)),e.addEventListener("close",()=>this.handleDisconnect(e)),e.addEventListener("error",()=>this.handleDisconnect(e)),e.addEventListener("message",e=>this.handleControlMessage(e)),this.messageHandlers.forEach(t=>{e.addEventListener("message",t)})}static handleOpen(e){e===this.webSocket&&(this.reconnectAttempts=0,this.needsResubscribe&&(this.needsResubscribe=!1,this.resubscribeChannels()))}static handleControlMessage(e){let t;try{t=JSON.parse(e.data)}catch{return}"confirm_subscription"===t.type&&this.subscriptionConfirmHandlers.forEach(e=>e(t.identifier))}static handleDisconnect(e){e===this.webSocket&&(this.disconnectHandlers.forEach(e=>e()),this.webSocket=null,this.needsResubscribe=!0,this.scheduleReconnect())}static scheduleReconnect(){this.reconnectTimeout||(this.reconnectTimeout=setTimeout(()=>{this.reconnectTimeout=null,this.reconnectAttempts+=1,this.openWebSocket()},this.reconnectDelay))}static clearReconnectTimeout(){this.reconnectTimeout&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=null)}static resubscribeChannels(){this.channels.forEach(e=>{const t=e.resubscribe||e.subscribe;"function"==typeof t&&t.call(e)})}static closedWebSocket(e){return e.readyState===WebSocket.CLOSED||e.readyState===WebSocket.CLOSING}static get reconnectDelay(){const e=Math.min(this.reconnectMaxDelay,this.reconnectBaseDelay*2**this.reconnectAttempts);return e+Math.round(e*this.reconnectJitter*Math.random())}get ignoredEvents(){return["ping","confirm_subscription","welcome"]}}const Js=Gs,Ys=class extends Js{constructor(e,t,s){super(),this.id=e,this.session=t,this.conversation=s,this.subscribed=!1,this.awaitingReconnectConfirmation=!1,this.reconnectCallbacks=new Set,this.onSubscriptionConfirmed(e=>this.handleSubscriptionConfirmed(e)),this.subscribe()}subscribe(){this.subscribed=!0;const e={channel:"WebchatChannel",id:this.id,session:this.session,conversation:this.conversation};this.send({command:"subscribe",identifier:e})}unsubscribe(){this.subscribed=!1;const e={channel:"WebchatChannel",id:this.id,session:this.session,conversation:this.conversation};this.send({command:"unsubscribe",identifier:e})}resubscribe(){!1!==this.subscribed&&(this.awaitingReconnectConfirmation=!0,this.subscribe())}onReconnect(e){this.reconnectCallbacks.add(e)}handleSubscriptionConfirmed(e){this.awaitingReconnectConfirmation&&this.matchesIdentifier(e)&&(this.awaitingReconnectConfirmation=!1,this.reconnectCallbacks.forEach(e=>e()))}matchesIdentifier(e){let t;try{t="string"==typeof e?JSON.parse(e):e}catch{return!1}return"WebchatChannel"===t.channel&&t.id===this.id&&t.session===this.session&&t.conversation===this.conversation}startTypingIndicator(){const e={channel:"WebchatChannel",id:this.id,session:this.session,conversation:this.conversation};this.send({command:"message",identifier:e,data:{action:"started_typing"}})}stopTypingIndicator(){const e={channel:"WebchatChannel",id:this.id,session:this.session,conversation:this.conversation};this.send({command:"typing:stop",identifier:e,data:{action:"stopped_typing"}})}onMessage(e){super.onMessage(t=>{"message"===t.type&&e(t)})}onReaction(e){super.onMessage(t=>{"reaction.create"!==t.type&&"reaction.destroy"!==t.type||e(t)})}onTypingStart(e){super.onMessage(t=>{"started_typing"===t.type&&e(t)})}updateSubscriptionWith(e){this.unsubscribe(),setTimeout(()=>{this.conversation=e,this.subscribe()},1e3)}},Zs=e=>{Object.assign(e,{scheduleBehaviourOpen(){if(!this.shouldAutoOpenFromBehaviour())return;const e=1e3*Number(this.behaviourValue.delay_seconds||0);this.behaviourOpenTimeout=window.setTimeout(()=>{this.behaviourOpenTimeout=null,this.openValue||(this.openValue=!0,this.markBehaviourAutoOpened())},e)},cancelBehaviourOpen(){window.clearTimeout(this.behaviourOpenTimeout),this.behaviourOpenTimeout=null},shouldAutoOpenFromBehaviour(){const e=this.behaviourValue;return!(!e||"on_load"!==e.trigger||e.first_visit_only&&localStorage.getItem(this.firstVisitKey())||e.once_per_session&&sessionStorage.getItem(this.sessionKey()))},markBehaviourAutoOpened(){this.behaviourValue.first_visit_only&&localStorage.setItem(this.firstVisitKey(),"1"),this.behaviourValue.once_per_session&&sessionStorage.setItem(this.sessionKey(),"1")},firstVisitKey(){return`hellotext--webchat--${this.idValue}--auto-opened`},sessionKey(){return`hellotext--webchat--${this.idValue}--auto-opened-session`}})},Xs=e=>{Object.assign(e,{setupOpeningSequence(){this.openingSequenceStarted=!1,this.openingSequenceCancelled=!1,this.openingSequenceTimeout=null,this.openingSequenceMessages=[],this.revealedOpeningSequenceMessageIds=[]},teardownOpeningSequence(){this.cancelOpeningSequence()},startOpeningSequence(){this.openingSequenceMessages=Array.from(this.openingSequenceMessageTargets||[]),this.openingSequenceCanStart()&&(this.openingSequenceStarted=!0,this.openingSequenceCancelled=!1,this.revealedOpeningSequenceMessageIds=[],this.playOpeningSequenceMessageAt(0))},openingSequenceCanStart(){return!this.conversationIdValue&&this.hasOpeningSequenceTarget&&this.openingSequenceMessages.length>0&&!this.openingSequenceStarted},playOpeningSequenceMessageAt(e){const t=this.openingSequenceMessages[e];if(!t)return;const s=1e3*this.openingSequenceMessageDelay(t);this.openingSequenceTimeout=window.setTimeout(()=>{this.openingSequenceTimeout=null,this.openingSequenceCancelled||(this.revealOpeningSequenceMessage(t),this.playOpeningSequenceMessageAt(e+1))},s)},revealOpeningSequenceMessage(e){this.messagesContainerTarget.insertBefore(e,this.messageTemplateTarget),e.hidden=!1,this.recordOpeningSequenceMessage(e),this.scrollOpeningSequenceToBottom()},recordOpeningSequenceMessage(e){const t=e.dataset.openingSequenceMessageId;t&&!this.revealedOpeningSequenceMessageIds.includes(t)&&this.revealedOpeningSequenceMessageIds.push(t)},openingSequenceMessageDelay(e){const t=Number(e.dataset.delaySeconds||0);return Number.isFinite(t)?t:0},scrollOpeningSequenceToBottom(){this.messagesContainerTarget.scroll&&this.messagesContainerTarget.scroll({top:this.messagesContainerTarget.scrollHeight,behavior:"smooth"})},cancelOpeningSequence(){this.openingSequenceCancelled=!0,null!==this.openingSequenceTimeout&&void 0!==this.openingSequenceTimeout&&(window.clearTimeout(this.openingSequenceTimeout),this.openingSequenceTimeout=null)},appendOpeningSequenceMessageIds(e){this.cancelOpeningSequence(),(this.revealedOpeningSequenceMessageIds||[]).forEach(t=>{e.append("message[opening_sequence_message_ids][]",t)})},clearRevealedOpeningSequenceMessageIds(){this.revealedOpeningSequenceMessageIds=[]}})},Qs=e=>{Object.assign(e,{setupTeaser(){this.teaserCycleTimeout=null,this.teaserMessages=[],this.boundOnTeaserClick=this.boundOnTeaserClick||this.onTeaserClick.bind(this),this.hasTeaserTarget&&(this.teaserTarget.addEventListener("click",this.boundOnTeaserClick),this.startTeaserPresentation())},teardownTeaser(){this.stopTeaserCycle(),this.hasTeaserTarget&&this.boundOnTeaserClick&&this.teaserTarget.removeEventListener("click",this.boundOnTeaserClick)},collectTeaserMessages(){return this.hasTeaserTarget?Array.from(this.teaserTarget.querySelectorAll("[data-teaser-message]")):[]},startTeaserPresentation(){this.stopTeaserCycle(),this.teaserMessages=this.collectTeaserMessages(),this.hasTeaserTarget&&(0!==this.teaserMessages.length?this.openValue||this.conversationIdValue||this.hasRenderedConversationMessages()?this.dismissTeaserForSession():this.teaserSeenForSession()?this.hideTeaser():(this.teaserTarget.classList.remove("invisible"),this.showTeaserMessage(0),this.teaserMessages.length<2||this.scheduleNextTeaserMessage(0)):this.hideTeaser())},scheduleNextTeaserMessage(e){const t=e+1;if(t>=this.teaserMessages.length)return;const s=this.teaserMessages[e],i=this.teaserPresentationDelay(s);this.teaserCycleTimeout=window.setTimeout(()=>{this.teaserCycleTimeout=null,this.showTeaserMessage(t),this.scheduleNextTeaserMessage(t)},i)},showTeaserMessage(e){this.teaserMessages.forEach((t,s)=>{t.classList.toggle("hidden",s!==e)})},stopTeaserCycle(){null!==this.teaserCycleTimeout&&void 0!==this.teaserCycleTimeout&&(window.clearTimeout(this.teaserCycleTimeout),this.teaserCycleTimeout=null)},teaserMessageDelay(e){const t=Number(e.dataset.delaySeconds||0);return Number.isFinite(t)?t:0},teaserPresentationDelay(e){return Math.max(1e3*this.teaserMessageDelay(e),250)},hasRenderedConversationMessages(){let e=[];try{e=Array.from(this.messageTargets||[])}catch(t){e=[]}return e.some(e=>e!==this.messageTemplateTarget)},teaserSeenKey(){const e=this.hasTeaserTarget?this.teaserTarget.dataset.teaserVersion:"",t=e?`:${e}`:"";return`hellotext:webchat:${this.idValue||this.element.id}:teaser-seen${t}`},teaserSeenForSession(){try{return"true"===window.sessionStorage.getItem(this.teaserSeenKey())}catch(e){return!1}},markTeaserSeenForSession(){try{window.sessionStorage.setItem(this.teaserSeenKey(),"true")}catch(e){}},dismissTeaserForSession(){this.markTeaserSeenForSession(),this.hideTeaser()},hideTeaser(){this.stopTeaserCycle(),this.hasTeaserTarget&&this.teaserTarget.classList.add("invisible")},onTeaserClick(e){e.target.closest("a")||(this.dismissTeaserForSession(),this.show())}})},ei={hour:"numeric",minute:"2-digit"},ti=/Android|iPhone|iPad|iPod/i,si={capture:!0,passive:!0},ii=class extends i.xI{static messageTimestampFormatters={};static values={id:String,conversationId:String,media:Object,fileSizeErrorMessage:String,placement:{type:String,default:"bottom-end"},open:{type:Boolean,default:!1},autoPlacement:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},nextPage:{type:Number,default:void 0},fullScreenThreshold:{type:Number,default:1024},typingIndicatorKeepAlive:{type:Number,default:3e4},offset:{type:Number,default:24},padding:{type:Number,default:24},optimisticTypingIndicatorWait:{type:Number,default:1e3},teaser:Object,messageTeaser:String,behaviour:Object};static classes=["fadeOut"];static targets=["trigger","popover","input","attachmentInput","attachmentButton","errorMessageContainer","attachmentTemplate","attachmentContainer","attachment","messageTemplate","messagesContainer","title","attachmentImage","footer","toolbar","message","unreadCounter","typingIndicator","typingIndicatorTemplate","teaser","teaserMessage","inboundMessageTeaser","inboundMessageTeaserBody","openingSequence","openingSequenceMessage"];initialize(){this.messagesAPI=new Ks(this.idValue),this.webChatChannel=new Ys(this.idValue,bt.session,this.conversationIdValue),this.files=[],this.messageIds=new Set,this.catchUpAfterMessageId=null,this.fetchingCatchUpMessages=!1,this.onMessageReceived=this.onMessageReceived.bind(this),this.onMessageReaction=this.onMessageReaction.bind(this),this.onTypingStart=this.onTypingStart.bind(this),this.captureCatchUpCursor=this.captureCatchUpCursor.bind(this),this.catchUpMessages=this.catchUpMessages.bind(this),this.onScroll=this.onScroll.bind(this),this.onOutboundMessageSent=this.onOutboundMessageSent.bind(this),this.closePopoverOnEscape=this.closePopoverOnEscape.bind(this),this.broadcastChannel=new BroadcastChannel(`hellotext--webchat--${this.idValue}`),this.webChatChannel.onDisconnect(this.captureCatchUpCursor),this.webChatChannel.onReconnect(this.catchUpMessages),super.initialize()}connect(){Zs(this),zs(this),Xs(this),Qs(this),this.setupFloatingUI({trigger:this.triggerTarget,popover:this.popoverTarget}),this.hasTeaserTarget&&this.setupFloatingUI({trigger:this.triggerTarget,popover:this.teaserTarget,strategy:"absolute"}),this.setupTeaser(),this.setupOpeningSequence(),this.localizeMessageTimestamps(),this.webChatChannel.onMessage(this.onMessageReceived),this.webChatChannel.onTypingStart(this.onTypingStart),this.webChatChannel.onReaction(this.onMessageReaction),this.setupMessagesContainerScrollIsolation(),this.messagesContainerTarget.addEventListener("scroll",this.onScroll),this.messagesContainerTarget.addEventListener("wheel",this.stopHostScrollPropagation,si),this.messagesContainerTarget.addEventListener("touchmove",this.stopHostScrollPropagation,si),this.shouldOpenOnMount&&(this.openValue=!0),bt.eventEmitter.dispatch("webchat:mounted"),this.broadcastChannel.addEventListener("message",this.onOutboundMessageSent),window.addEventListener("keydown",this.closePopoverOnEscape,!0),this.scheduleBehaviourOpen(),super.connect()}disconnect(){this.cancelBehaviourOpen(),this.clearPopoverOpenAnimation(),this.teardownTeaser(),this.teardownOpeningSequence(),this.broadcastChannel.removeEventListener("message",this.onOutboundMessageSent),this.messagesContainerTarget.removeEventListener("scroll",this.onScroll),this.messagesContainerTarget.removeEventListener("wheel",this.stopHostScrollPropagation,si),this.messagesContainerTarget.removeEventListener("touchmove",this.stopHostScrollPropagation,si),window.removeEventListener("keydown",this.closePopoverOnEscape,!0),this.clearTypingIndicator(),this.broadcastChannel.close(),this.floatingUICleanup(),super.disconnect()}setupMessagesContainerScrollIsolation(){this.messagesContainerTarget.style.overscrollBehavior="contain",this.messagesContainerTarget.style.webkitOverflowScrolling="touch",this.messagesContainerTarget.style.touchAction="pan-y",this.messagesContainerTarget.setAttribute("data-lenis-prevent",""),this.messagesContainerTarget.setAttribute("data-lenis-prevent-wheel",""),this.messagesContainerTarget.setAttribute("data-lenis-prevent-touch","")}stopHostScrollPropagation(e){e.stopPropagation()}onTypingStart(){if(this.typingIndicatorVisible)return this.resetTypingIndicatorTimer();this.showTypingIndicator()}showOptimisticTypingIndicator(){this.typingIndicatorVisible||this.showTypingIndicator()}showTypingIndicator(){this.clearTypingIndicator(),this.typingIndicatorVisible=!0;const e=this.typingIndicatorTemplateTarget.cloneNode(!0);e.setAttribute("data-hellotext--webchat-target","typingIndicator"),e.style.display="flex",this.messagesContainerTarget.appendChild(e),requestAnimationFrame(()=>{this.messagesContainerTarget.scroll({top:this.messagesContainerTarget.scrollHeight,behavior:"instant"})});const t=this.typingIndicatorKeepAliveValue;this.incomingTypingIndicatorTimeout=setTimeout(()=>{this.clearTypingIndicator()},t)}resetTypingIndicatorTimer(){if(!this.typingIndicatorVisible)return;clearTimeout(this.incomingTypingIndicatorTimeout),clearTimeout(this.optimisticTypingTimeout);const e=this.typingIndicatorKeepAliveValue;this.incomingTypingIndicatorTimeout=setTimeout(()=>{this.clearTypingIndicator()},e)}clearTypingIndicator(){this.hasTypingIndicatorTarget&&this.typingIndicatorTarget.remove(),this.typingIndicatorVisible=!1,clearTimeout(this.incomingTypingIndicatorTimeout),clearTimeout(this.optimisticTypingTimeout)}onMessageInputChange(){this.resizeInput(),clearTimeout(this.typingIndicatorTimeout),this.hasSentTypingIndicator||(this.webChatChannel.startTypingIndicator(),this.hasSentTypingIndicator=!0),this.typingIndicatorTimeout=setTimeout(()=>{this.hasSentTypingIndicator=!1},3e3)}onOutboundMessageSent(e){const{data:t}=e,s={"message:sent":e=>{const t=(new DOMParser).parseFromString(e.element,"text/html").body.firstElementChild;this.localizeMessageTimestamps(t),this.typingIndicatorVisible&&this.hasTypingIndicatorTarget?this.messagesContainerTarget.insertBefore(t,this.typingIndicatorTarget):this.messagesContainerTarget.appendChild(t),t.scrollIntoView({behavior:"instant"})},"message:failed":e=>{const t=this.messagesContainerTarget.querySelector(`#${e.id}`);this.markMessageFailed(t,e.reason)}};s[t.type]?s[t.type](t):console.log(`Unhandled message event: ${t.type}`)}async onScroll(){if(this.messagesContainerTarget.scrollTop>300||!this.nextPageValue||this.fetchingNextPage)return;this.fetchingNextPage=!0;const e=await this.messagesAPI.index({page:this.nextPageValue,session:bt.session}),{next:t,messages:s}=await e.json();this.nextPageValue=t,this.oldScrollHeight=this.messagesContainerTarget.scrollHeight,s.forEach(e=>{const{body:t,attachments:s}=e,i=e.created_at||e.createdAt,n=this.messageTemplateTarget.cloneNode(!0);n.classList.add("hellotext--webchat-message"),n.setAttribute("data-hellotext--webchat-target","message"),n.setAttribute("data-id",e.id),i&&n.setAttribute("data-created-at",i),n.style.removeProperty("display"),nt(n.querySelector("[data-body]"),t),"received"===e.state?n.classList.add("received"):n.classList.remove("received"),s&&s.forEach(e=>{const t=this.attachmentImageTarget.cloneNode(!0);t.removeAttribute("data-hellotext--webchat-target"),t.src=e,t.style.display="block",this.messageAttachmentsContainer(n)?.appendChild(t)}),n.setAttribute("data-body",t),this.localizeMessageTimestamp(n.querySelector("[data-message-timestamp]"),i),this.messagesContainerTarget.prepend(n)}),this.messagesContainerTarget.scroll({top:this.messagesContainerTarget.scrollHeight-this.oldScrollHeight,behavior:"instant"}),this.fetchingNextPage=!1}onClickOutside(e){u.mode===h.POPOVER&&this.openValue&&e.target.nodeType&&!1===this.element.contains(e.target)&&(this.openValue=!1)}closePopover(){this.clearPopoverOpenAnimation(),this.popoverTarget.classList.remove(...this.fadeOutClasses),this.openValue=!1}preparePopoverOpenAnimation(){this.clearPopoverOpenAnimation(),this.popoverTarget.classList.remove(...this.fadeOutClasses),this.popoverTarget.classList.add("hellotext--webchat-popover-opening"),this.popoverOpenAnimationTimeout=setTimeout(()=>{this.popoverTarget.classList.remove("hellotext--webchat-popover-opening"),this.popoverOpenAnimationTimeout=null},120)}clearPopoverOpenAnimation(){this.popoverOpenAnimationTimeout&&(clearTimeout(this.popoverOpenAnimationTimeout),this.popoverOpenAnimationTimeout=null),this.popoverTarget?.classList.remove("hellotext--webchat-popover-opening")}onPopoverOpened(){this.popoverTarget.classList.remove(...this.fadeOutClasses),this.dismissTeaserForSession?.(),this.onMobile||this.focusComposeInput(),this.scrolled||(requestAnimationFrame(()=>{this.messagesContainerTarget.scroll({top:this.messagesContainerTarget.scrollHeight,behavior:"instant"})}),this.scrolled=!0),bt.eventEmitter.dispatch("webchat:opened"),localStorage.setItem(`hellotext--webchat--${this.idValue}`,"opened"),this.messageTeaserValue&&(this.messageTeaserValue=null),this.startOpeningSequence(),"none"!==this.unreadCounterTarget.style.display&&(this.unreadCounterTarget.style.display="none",this.unreadCounterTarget.innerText="0",this.messagesAPI.markAsSeen())}onPopoverClosed(){this.clearPopoverOpenAnimation(),bt.eventEmitter.dispatch("webchat:closed"),localStorage.setItem(`hellotext--webchat--${this.idValue}`,"closed")}onMessageReaction(e){const{message:t,reaction:s,type:i}=e,n=this.messageTargets.find(e=>e.dataset.id===t).querySelector("[data-reactions]");if("reaction.destroy"===i)return n.querySelector(`[data-id="${s.id}"]`).remove();if(n.querySelector(`[data-id="${s.id}"]`))n.querySelector(`[data-id="${s.id}"]`).innerText=s.emoji;else{const e=document.createElement("span");e.innerText=s.emoji,e.setAttribute("data-id",s.id),n.appendChild(e)}}onMessageReceived(e,t={}){const{id:s,body:i,attachments:n,teaser:r}=e,a=e.created_at||e.createdAt;if(!this.claimMessageId(s))return;if(this.hideTeaser?.(),e.carousel)return this.insertCarouselMessage(e,t);const o=this.messageTemplateTarget.cloneNode(!0);o.classList.add("hellotext--webchat-message"),o.style.display="flex",nt(o.querySelector("[data-body]"),i),o.setAttribute("data-id",s),o.setAttribute("data-hellotext--webchat-target","message"),this.setMessageCreatedAt(o,a),this.localizeMessageTimestamp(o.querySelector("[data-message-timestamp]"),a),n&&n.forEach(e=>{const t=this.attachmentImageTarget.cloneNode(!0);t.src=e,t.style.display="block",this.messageAttachmentsContainer(o)?.appendChild(t)}),this.clearTypingIndicator(),this.insertMessageElement(o),bt.eventEmitter.dispatch("webchat:message:received",{...e,body:o.querySelector("[data-body]").innerText}),!1!==t.scroll&&o.scrollIntoView({behavior:"smooth"}),this.updateMessageTeaser(r),this.openValue?this.messagesAPI.markAsSeen(s):this.incrementUnreadCounter()}claimMessageId(e){const t=this.messageTargets||[];return!this.messageIds.has(e)&&(this.messageIds.add(e),!t.some(t=>t.dataset.id===e))}captureCatchUpCursor(){this.catchUpAfterMessageId=this.lastRenderedMessageId}async catchUpMessages(){const e=this.catchUpAfterMessageId;if(e&&!this.fetchingCatchUpMessages){this.fetchingCatchUpMessages=!0;try{const t=await this.messagesAPI.catchUp(e),{messages:s=[]}=await t.json();s.forEach(e=>this.onMessageReceived(e,{scroll:!1})),this.catchUpAfterMessageId=this.lastRenderedMessageId}finally{this.fetchingCatchUpMessages=!1}}}get lastRenderedMessageId(){const e=this.persistedMessageElements;return e[e.length-1]?.dataset.id||null}get persistedMessageElements(){return Array.from(this.messagesContainerTarget.querySelectorAll(".hellotext--webchat-message[data-id]"))}setMessageCreatedAt(e,t){t&&e.setAttribute("data-created-at",t)}insertMessageElement(e){const t=this.nextMessageElementFor(e);t?this.messagesContainerTarget.insertBefore(e,t):this.messagesContainerTarget.appendChild(e)}nextMessageElementFor(e){const t=Date.parse(e.dataset.createdAt);return Number.isNaN(t)?null:this.persistedMessageElements.find(s=>{if(s===e)return!1;const i=Date.parse(s.dataset.createdAt);return!Number.isNaN(i)&&i>t})}updateMessageTeaser(e){this.messageTeaserValue=e,this.messageTeaserValue&&this.hasTeaserTarget&&this.hasInboundMessageTeaserTarget&&this.hasInboundMessageTeaserBodyTarget&&(this.teaserMessageTargets.forEach(e=>e.classList.add("hidden")),this.inboundMessageTeaserBodyTarget.textContent=this.messageTeaserValue,this.inboundMessageTeaserTarget.classList.remove("hidden"),this.teaserTarget.classList.toggle("invisible",this.openValue))}insertCarouselMessage(e,t={}){const s=e.html,i=e.created_at||e.createdAt,n=function(e){return it(e,st)}(s).firstElementChild;n.classList.add("hellotext--webchat-message"),n.setAttribute("data-id",e.id),n.setAttribute("data-hellotext--webchat-target","message"),this.setMessageCreatedAt(n,i),this.localizeMessageTimestamps(n),this.clearTypingIndicator(),this.insertMessageElement(n),!1!==t.scroll&&n.scrollIntoView({behavior:"smooth"}),bt.eventEmitter.dispatch("webchat:message:received",{...e,body:n.querySelector("[data-body]")?.innerText||""}),this.updateMessageTeaser(e.teaser),this.openValue?this.messagesAPI.markAsSeen(e.id):this.incrementUnreadCounter()}resizeInput(){this.inputTarget.style.height="auto";const e=this.inputTarget.scrollHeight;this.inputTarget.style.height=`${Math.min(e,96)}px`}async sendQuickReplyMessage({detail:{id:e,product:t,buttonId:s,body:i,cardElement:n}}){this.dismissTeaserForSession?.();const r=new FormData;r.append("message[body]",i),e&&r.append("message[replied_to]",e),t&&r.append("message[product]",t),s&&r.append("message[button]",s),r.append("session",bt.session),r.append("locale",o.toString()),this.appendOpeningSequenceMessageIds(r);const a=this.buildMessageElement(),c=n?.querySelector("img")?.cloneNode(!0);a.querySelector("[data-body]").innerText=i,c&&(c.removeAttribute("width"),c.removeAttribute("height"),this.messageAttachmentsContainer(a)?.appendChild(c)),this.typingIndicatorVisible&&this.hasTypingIndicatorTarget?this.messagesContainerTarget.insertBefore(a,this.typingIndicatorTarget):this.messagesContainerTarget.appendChild(a),a.scrollIntoView({behavior:"smooth"}),this.broadcastChannel.postMessage({type:"message:sent",element:a.outerHTML});const l=await this.messagesAPI.create(r);if(l.failed)return clearTimeout(this.optimisticTypingTimeout),this.markMessageFailedFromResponse(l,a);const h=await l.json();this.dispatch("set:id",{target:a,detail:h.id}),this.localizeMessageTimestamp(a.querySelector("[data-message-timestamp]"),h.created_at||h.createdAt),this.clearRevealedOpeningSequenceMessageIds();const u={id:h.id,body:i,attachments:c?[c.src]:[],replied_to:e,product:t,button:s,type:"quick_reply"};bt.eventEmitter.dispatch("webchat:message:sent",u)}async sendTeaserQuickReply(e){e.preventDefault(),e.stopPropagation();const t=e.currentTarget,s=(t.dataset.value||"").trim(),i=[t.dataset.text,t.textContent].map(e=>(e||"").trim()).find(e=>e.length>0),n=s||i;if(!n)return;this.dismissTeaserForSession?.(),this.show();const r=(t.dataset.type||"").trim()||"quick_reply",a=new FormData;a.append("message[body]",n),a.append("session",bt.session),a.append("locale",o.toString()),this.appendOpeningSequenceMessageIds(a);const c=this.buildMessageElement();c.querySelector("[data-body]").innerText=n,this.typingIndicatorVisible&&this.hasTypingIndicatorTarget?this.messagesContainerTarget.insertBefore(c,this.typingIndicatorTarget):this.messagesContainerTarget.appendChild(c),c.scrollIntoView({behavior:"smooth"}),this.broadcastChannel.postMessage({type:"message:sent",element:c.outerHTML}),this.typingIndicatorVisible||(clearTimeout(this.optimisticTypingTimeout),this.optimisticTypingTimeout=setTimeout(()=>{this.showOptimisticTypingIndicator()},this.optimisticTypingIndicatorWaitValue));const l=await this.messagesAPI.create(a);if(l.failed)return clearTimeout(this.optimisticTypingTimeout),this.markMessageFailedFromResponse(l,c);const h=await l.json();c.setAttribute("data-id",h.id),this.localizeMessageTimestamp(c.querySelector("[data-message-timestamp]"),h.created_at||h.createdAt),this.clearRevealedOpeningSequenceMessageIds(),bt.eventEmitter.dispatch("webchat:message:sent",{id:h.id,body:n,attachments:[],type:"quick_reply",teaser:{text:i||n,value:s||n,type:r}}),h.conversation&&h.conversation!==this.conversationIdValue&&(this.conversationIdValue=h.conversation,this.webChatChannel.updateSubscriptionWith(this.conversationIdValue)),this.typingIndicatorVisible&&this.resetTypingIndicatorTimer()}async sendMessage(e){const t={body:this.inputTarget.value,attachments:this.files};if(0===this.inputTarget.value.trim().length&&0===this.files.length)return void(e&&e.target&&e.preventDefault());this.dismissTeaserForSession?.();const s=new FormData;this.inputTarget.value.trim().length>0?s.append("message[body]",this.inputTarget.value):delete t.body,this.files.forEach(e=>{s.append("message[attachments][]",e)}),s.append("session",bt.session),s.append("locale",o.toString()),this.appendOpeningSequenceMessageIds(s);const i=this.buildMessageElement();this.inputTarget.value.trim().length>0?i.querySelector("[data-body]").innerText=this.inputTarget.value:i.querySelector("[data-message-bubble]").remove();const n=this.attachmentContainerTarget.querySelectorAll("img");n.length>0&&n.forEach(e=>{this.messageAttachmentsContainer(i)?.appendChild(e.cloneNode(!0))}),this.typingIndicatorVisible&&this.hasTypingIndicatorTarget?this.messagesContainerTarget.insertBefore(i,this.typingIndicatorTarget):this.messagesContainerTarget.appendChild(i),i.scrollIntoView({behavior:"smooth"}),this.broadcastChannel.postMessage({type:"message:sent",element:i.outerHTML}),this.inputTarget.value="",this.resizeInput(),this.files=[],this.attachmentInputTarget.value="",this.attachmentContainerTarget.innerHTML="",this.attachmentContainerTarget.style.display="none",this.errorMessageContainerTarget.style.display="none",this.focusComposeInput(),this.typingIndicatorVisible||(clearTimeout(this.optimisticTypingTimeout),this.optimisticTypingTimeout=setTimeout(()=>{this.showOptimisticTypingIndicator()},this.optimisticTypingIndicatorWaitValue));const r=await this.messagesAPI.create(s);if(r.failed)return clearTimeout(this.optimisticTypingTimeout),this.markMessageFailedFromResponse(r,i);const a=await r.json();i.setAttribute("data-id",a.id),t.id=a.id,this.localizeMessageTimestamp(i.querySelector("[data-message-timestamp]"),a.created_at||a.createdAt),this.clearRevealedOpeningSequenceMessageIds(),bt.eventEmitter.dispatch("webchat:message:sent",t),a.conversation!==this.conversationIdValue&&(this.conversationIdValue=a.conversation,this.webChatChannel.updateSubscriptionWith(this.conversationIdValue)),this.typingIndicatorVisible&&this.resetTypingIndicatorTimer(),this.attachmentContainerTarget.style.display=""}buildMessageElement(){const e=this.messageTemplateTarget.cloneNode(!0);return e.id=`hellotext--webchat--${this.idValue}--message--${Date.now()}`,e.classList.add("received"),e.style.removeProperty("display"),e.setAttribute("data-controller","hellotext--message"),e.setAttribute("data-hellotext--webchat-target","message"),this.localizeMessageTimestamp(e.querySelector("[data-message-timestamp]"),new Date),e}focusCompose(e){const{target:t}=e,s=["button","a","input","textarea","select","label",'[role="button"]',"em-emoji-picker",'[data-hellotext--webchat--emoji-target~="popover"]','[data-controller~="hellotext--webchat--emoji"]'].join(", ");this.hasInputTarget&&!t.closest(s)&&this.focusComposeInput({moveCursorToEnd:!0})&&e.preventDefault()}closePopoverFromHeader(e){const{target:t}=e;t.closest(".hellotext--webchat-header-channel-button, .hellotext--webchat-close-button")||(e.preventDefault(),this.closePopover())}closePopoverOnEscape(e){"Escape"===e.key&&this.openValue&&(e.preventDefault(),e.stopPropagation(),this.closePopover(),this.triggerTarget?.focus?.())}async markMessageFailedFromResponse(e,t){const s=await this.messageFailureReason(e);this.markMessageFailed(t,s),this.broadcastChannel.postMessage({type:"message:failed",id:t.id,reason:s})}markMessageFailed(e,t){if(!e)return;if(e.classList.add("failed"),!t)return;const s=e.querySelector("[data-message-timestamp]");s&&(s.textContent=t)}localizeMessageTimestamps(e=this.element){e&&(e.matches?.("time[datetime][data-message-timestamp]")?[e]:Array.from(e.querySelectorAll?.("time[datetime][data-message-timestamp]")||[])).forEach(e=>this.localizeMessageTimestamp(e))}localizeMessageTimestamp(e,t=e?.getAttribute("datetime")){if(!e||!t)return;const s=t instanceof Date?t:new Date(t);Number.isNaN(s.getTime())||(e.setAttribute("datetime",s.toISOString()),e.textContent=this.formatMessageTimestamp(s))}formatMessageTimestamp(e){return this.constructor.messageTimestampFormatterFor(o.toString()).format(e)}static messageTimestampFormatterFor(e){const t=e||"default";return this.messageTimestampFormatters[t]||(this.messageTimestampFormatters[t]=this.buildMessageTimestampFormatter(e)),this.messageTimestampFormatters[t]}static buildMessageTimestampFormatter(e){try{return new Intl.DateTimeFormat(e||void 0,ei)}catch(e){return new Intl.DateTimeFormat(void 0,ei)}}async messageFailureReason(e){const t=e?.data||e?.response,s=t?.statusText||"Message failed";try{const e=t?.clone?t.clone():t,s=await(e?.json?.()),i=this.messageFailureReasonFromPayload(s);if(i)return i}catch(e){}try{const e=t?.clone?t.clone():t,i=await(e?.text?.());return this.messageFailureReasonFromText(i)||s}catch(e){return s}}messageFailureReasonFromText(e){if("string"!=typeof e)return null;const t=e.trim();if(!t||t.startsWith("<"))return null;try{return this.messageFailureReasonFromPayload(JSON.parse(t))||t}catch(e){return t}}messageFailureReasonFromPayload(e){return e?[e.error?.message,e.message,e.errors?.message,e.errors?.[0]?.message,e.errors?.[0]?.description].find(e=>"string"==typeof e&&e.trim().length>0):null}messageAttachmentsContainer(e){return e.querySelector("[data-attachments-container], [data-attachment-container]")}incrementUnreadCounter(){this.unreadCounterTarget.style.display="flex";const e=(parseInt(this.unreadCounterTarget.innerText)||0)+1;this.unreadCounterTarget.innerText=Math.min(e,9)}openAttachment(){this.attachmentInputTarget.click()}onFileInputChange(){this.errorMessageContainerTarget.style.display="none";const e=Array.from(this.attachmentInputTarget.files);this.attachmentInputTarget.value="";const t=e.find(e=>{const t=e.type.split("/")[0];return["image","video","audio"].includes(t)?this.mediaValue[t].max_sizethis.createAttachmentElement(e)),this.focusComposeInput()}createAttachmentElement(e){const t=this.attachmentElement();if(this.attachmentContainerTarget.style.display="",t.setAttribute("data-name",e.name),e.type.startsWith("image/")){const s=this.attachmentImageTarget.cloneNode(!0);s.src=URL.createObjectURL(e),s.style.display="block",t.appendChild(s),this.attachmentContainerTarget.appendChild(t),this.attachmentContainerTarget.style.display="flex"}else{const s=t.querySelector("main");s.style.height="5rem",s.style.borderRadius="0.375rem",s.style.backgroundColor="#e5e7eb",s.style.padding="0.25rem",t.querySelector("p[data-attachment-name]").innerText=e.name,this.attachmentContainerTarget.appendChild(t),this.attachmentContainerTarget.style.display="flex"}}removeAttachment({currentTarget:e}){const t=e.closest("[data-hellotext--webchat-target='attachment']");this.files=this.files.filter(e=>e.name!==t.dataset.name),this.attachmentInputTarget.value="",t.remove(),this.focusComposeInput()}attachmentTargetDisconnected(){0===this.attachmentTargets.length&&(this.attachmentContainerTarget.innerHTML="",this.attachmentContainerTarget.style.display="none")}attachmentElement(){const e=this.attachmentTemplateTarget.cloneNode(!0);return e.removeAttribute("hidden"),e.style.display="flex",e.setAttribute("data-hellotext--webchat-target","attachment"),e}onEmojiSelect({detail:e}){const t=this.inputTarget.value,s=this.inputTarget.selectionStart,i=this.inputTarget.selectionEnd;this.inputTarget.value=t.slice(0,s)+e+t.slice(i),this.inputTarget.selectionStart=this.inputTarget.selectionEnd=s+e.length,this.focusComposeInput()}focusComposeInput({moveCursorToEnd:e=!1}={}){if(!this.shouldAutofocusCompose)return!1;if(!1===this.hasInputTarget)return!1;if(void 0===this.hasInputTarget&&!this.inputTarget)return!1;if(this.inputTarget.focus(),e&&"number"==typeof this.inputTarget.selectionStart){const e=this.inputTarget.value.length;this.inputTarget.setSelectionRange(e,e)}return!0}byteToMegabyte(e){return Math.ceil(e/1024/1024)}get middlewares(){return[Vs(this.offsetValue),qs({padding:this.paddingValue}),Us()]}get shouldOpenOnMount(){return"opened"===localStorage.getItem(`hellotext--webchat--${this.idValue}`)&&!this.onMobile}get shouldAutofocusCompose(){return!this.usesVirtualKeyboard}get usesVirtualKeyboard(){if("undefined"==typeof navigator)return!1;const e=navigator.userAgent||"",t="MacIntel"===navigator.platform&&navigator.maxTouchPoints>1,s=ti.test(e),i=!0===navigator.userAgentData?.mobile;return s||t||i||this.hasTouchOnlyPointer}get hasTouchOnlyPointer(){return"undefined"!=typeof window&&"function"==typeof window.matchMedia&&window.matchMedia("(pointer: coarse)").matches&&window.matchMedia("(hover: none)").matches}get onMobile(){return"undefined"!=typeof window&&"function"==typeof window.matchMedia&&window.matchMedia(`(max-width: ${this.fullScreenThresholdValue}px)`).matches}},ni=i.lg.start();ni.register("hellotext--alert",vt),ni.register("hellotext--form",wt),ni.register("hellotext--webchat",ii),ni.register("hellotext--webchat--emoji",Ws),ni.register("hellotext--message",Tt),window.Hellotext=bt;const ri=bt}};const t={};function s(i){const n=t[i];if(void 0!==n)return n.exports;const r=t[i]={exports:{}};return e[i](r,r.exports,s),r.exports}s.m=e,(()=>{const e=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;let t;s.t=function(i,n){if(1&n&&(i=this(i)),8&n)return i;if("object"==typeof i&&i){if(4&n&&i.__esModule)return i;if(16&n&&"function"==typeof i.then)return i}const r=Object.create(null);s.r(r);const a={};t=t||[null,e({}),e([]),e(e)];for(var o=2&n&&i;("object"==typeof o||"function"==typeof o)&&!~t.indexOf(o);o=e(o))Object.getOwnPropertyNames(o).forEach(e=>a[e]=()=>i[e]);return a.default=()=>i,s.d(r,a),r}})(),s.d=(e,t)=>{if(Array.isArray(t))for(var i=0;iPromise.all(Object.keys(s.f).reduce((t,i)=>(s.f[i](e,t),t),[])),s.u=e=>({160:"webchat-emoji",200:"webchat-emoji-en",437:"webchat-emoji-es"}[e]+".js"),s.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),s.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{const e={},t="Hellotext:";s.l=(i,n,r,a)=>{if(e[i])return void e[i].push(n);let o,c;if(void 0!==r){const e=document.getElementsByTagName("script");for(var l=0;l{o.onerror=o.onload=null,clearTimeout(u);const n=e[i];if(delete e[i],o.parentNode?.removeChild(o),n?.forEach(e=>e(s)),t)return t(s)},u=setTimeout(h.bind(null,void 0,{type:"timeout",target:o}),12e4);o.onerror=h.bind(null,o.onerror),o.onload=h.bind(null,o.onload),c&&document.head.appendChild(o)}})(),s.r=e=>{Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{let e;s.g.importScripts&&(e=s.g.location+"");const t=s.g.document;if(!e&&t&&("SCRIPT"===t.currentScript?.tagName.toUpperCase()&&(e=t.currentScript.src),!e)){const s=t.getElementsByTagName("script");if(s.length){let t=s.length-1;for(;t>-1&&(!e||!/^http(s?):/.test(e));)e=s[t--].src}}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),s.p=e})(),(()=>{const e={792:0};s.f.j=(t,i)=>{let n=s.o(e,t)?e[t]:void 0;if(0!==n)if(n)i.push(n[2]);else{const r=new Promise((s,i)=>n=e[t]=[s,i]);i.push(n[2]=r);const a=s.p+s.u(t),o=new Error,c=i=>{if(s.o(e,t)&&(n=e[t],0!==n&&(e[t]=void 0),n)){const e=i&&("load"===i.type?"missing":i.type),s=i&&i.target&&i.target.src;o.message="Loading chunk "+t+" failed.\n("+e+": "+s+")",o.name="ChunkLoadError",o.type=e,o.request=s,n[1](o)}};s.l(a,c,"chunk-"+t,t)}};const t=(t,i)=>{let[n,r,a]=i;var o,c,l=0;if(n.some(t=>0!==e[t])){for(o in r)s.o(r,o)&&(s.m[o]=r[o]);a&&a(s)}for(t&&t(i);l { + console.log('Alert accepted in', kind) +}) +``` + ## Disable Push on a page If you do not want to enable Push for a particular page, pass `push: false` when initializing Hellotext: diff --git a/index.d.ts b/index.d.ts index adfa5d5b..b2eeaa1a 100644 --- a/index.d.ts +++ b/index.d.ts @@ -80,6 +80,22 @@ export interface HellotextPush { unsubscribe(): Promise } +export type HellotextAlertSection = 'homepage' | 'product_collection' | 'product_details' + +export interface HellotextAlertShowOptions { + force?: boolean + title?: string + description?: string + primaryAction?: string + secondaryAction?: string +} + +export interface HellotextAlert { + readonly ready: Promise + show(section: HellotextAlertSection, options?: HellotextAlertShowOptions): Promise + hide(): void +} + export interface HellotextBusinessCountry { code?: string prefix?: string @@ -95,6 +111,7 @@ export interface HellotextBusinessData { webchat?: HellotextWebchatConfig | null whatsapp?: HellotextWhatsAppWidgetConfig | null push?: { public_key: string } | null + alert?: { html: string } | null whitelist?: string | string[] | null subscription?: string | null [key: string]: any @@ -157,6 +174,7 @@ declare class Hellotext { static webchat: any static whatsapp: any static push: HellotextPush | null + static alert: HellotextAlert | null } export declare class User { diff --git a/lib/api/index.cjs b/lib/api/index.cjs index 2df3cf29..83d570cc 100644 --- a/lib/api/index.cjs +++ b/lib/api/index.cjs @@ -19,6 +19,7 @@ var _webchats = _interopRequireDefault(require("./webchats")); var _whatsapp_widgets = _interopRequireDefault(require("./whatsapp_widgets")); var _acks = _interopRequireDefault(require("./acks")); var _identities = _interopRequireDefault(require("./push/identities")); +var _alerts = _interopRequireDefault(require("./push/alerts")); var _response = require("./response"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // Browsers keep `fetch(..., { keepalive: true })` requests alive during page @@ -63,6 +64,9 @@ class API { static get acks() { return _acks.default; } + static get pushAlerts() { + return _alerts.default; + } static get pushIdentities() { return _identities.default; } diff --git a/lib/api/index.js b/lib/api/index.js index 3d82aad5..e01daba3 100644 --- a/lib/api/index.js +++ b/lib/api/index.js @@ -6,6 +6,7 @@ import WebchatsAPI from './webchats'; import WhatsAppWidgetsAPI from './whatsapp_widgets'; import AcksAPI from './acks'; import PushIdentitiesAPI from './push/identities'; +import PushAlertsAPI from './push/alerts'; // Browsers keep `fetch(..., { keepalive: true })` requests alive during page // unload/navigation, which is exactly the failure mode for analytics events @@ -49,6 +50,9 @@ export default class API { static get acks() { return AcksAPI; } + static get pushAlerts() { + return PushAlertsAPI; + } static get pushIdentities() { return PushIdentitiesAPI; } diff --git a/lib/api/push/alerts.cjs b/lib/api/push/alerts.cjs new file mode 100644 index 00000000..f0614ab9 --- /dev/null +++ b/lib/api/push/alerts.cjs @@ -0,0 +1,45 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _hellotext = _interopRequireDefault(require("../../hellotext")); +var _core = require("../../core"); +var _response = require("../response"); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +/** + * Records Smart Alert interactions for the current business and session. + */ +class PushAlertsAPI { + static get endpoint() { + return _core.Configuration.endpoint('public/push/alerts'); + } + + /** + * Posts an interaction without parsing the endpoint's empty success response. + * + * @param {Object} data - Alert interaction. + * @param {import('../../../index').HellotextAlertSection} data.section - Displayed section. + * @param {'shown'|'dismissed'|'accepted'} data.kind - Interaction to record. + * @returns {Promise} Whether the server accepted the interaction. + */ + static async create({ + section, + kind + }) { + const response = await fetch(this.endpoint, { + method: 'POST', + keepalive: true, + headers: _hellotext.default.headers, + body: JSON.stringify({ + session: _hellotext.default.session, + section, + kind + }) + }); + return new _response.Response(response.ok, response); + } +} +var _default = PushAlertsAPI; +exports.default = _default; \ No newline at end of file diff --git a/lib/api/push/alerts.js b/lib/api/push/alerts.js new file mode 100644 index 00000000..76384143 --- /dev/null +++ b/lib/api/push/alerts.js @@ -0,0 +1,38 @@ +import Hellotext from '../../hellotext'; +import { Configuration } from '../../core'; +import { Response } from '../response'; + +/** + * Records Smart Alert interactions for the current business and session. + */ +class PushAlertsAPI { + static get endpoint() { + return Configuration.endpoint('public/push/alerts'); + } + + /** + * Posts an interaction without parsing the endpoint's empty success response. + * + * @param {Object} data - Alert interaction. + * @param {import('../../../index').HellotextAlertSection} data.section - Displayed section. + * @param {'shown'|'dismissed'|'accepted'} data.kind - Interaction to record. + * @returns {Promise} Whether the server accepted the interaction. + */ + static async create({ + section, + kind + }) { + const response = await fetch(this.endpoint, { + method: 'POST', + keepalive: true, + headers: Hellotext.headers, + body: JSON.stringify({ + session: Hellotext.session, + section, + kind + }) + }); + return new Response(response.ok, response); + } +} +export default PushAlertsAPI; \ No newline at end of file diff --git a/lib/controllers/alert_controller.cjs b/lib/controllers/alert_controller.cjs new file mode 100644 index 00000000..94560ab1 --- /dev/null +++ b/lib/controllers/alert_controller.cjs @@ -0,0 +1,265 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +var _stimulus = require("@hotwired/stimulus"); +var _hellotext = _interopRequireDefault(require("../hellotext")); +var _api = _interopRequireDefault(require("../api")); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +const DAY = 24 * 60 * 60 * 1000; +const dismissals = new Map(); + +/** + * Displays Smart Alert sections and handles Push subscription and visitor dismissal. + * Dismissal history is shared across this business's sections on the current origin. + * + * @property {import('../models/alert').Alert} alert - Owning SDK alert, assigned on connection. + */ +class _default extends _stimulus.Controller { + static values = { + sections: Array + }; + static targets = ['title', 'description', 'primaryAction', 'secondaryAction']; + + /** + * Initializes display state and binds the cross-tab storage handler. + * + * @returns {void} + */ + initialize() { + this.showRequest = 0; + this.submitting = false; + this.onStorage = this.onStorage.bind(this); + } + + /** + * Announces readiness and listens for dismissals in other tabs. + * + * @fires hellotext--alert:connected + * @returns {void} + */ + connect() { + this.dispatch('connected', { + detail: { + controller: this + } + }); + window.addEventListener('storage', this.onStorage); + } + + /** + * Cancels pending display and removes the storage listener. + * + * @returns {void} + */ + disconnect() { + this.close(); + window.removeEventListener('storage', this.onStorage); + } + + /** + * Hides the alert when another tab records an active cooldown for this business. + * + * @param {StorageEvent} event - Browser storage change notification. + * @returns {void} + */ + onStorage(event) { + if (event.key === this.storageKey && this.dismissal.dismissedUntil > Date.now()) { + this.close(); + } + } + + /** + * Displays an enabled section after Push subscription restoration finishes. + * Text overrides apply only to this call and are rendered as plain text. + * Force bypasses the cooldown without changing dismissal history; section availability, + * existing subscriptions, and denied notification permission still prevent display. + * + * @param {import('../../index').HellotextAlertSection} kind - Section to display. + * @param {import('../../index').HellotextAlertShowOptions} [options={}] - Display overrides. + * @param {boolean} [options.force=false] - Bypass the current dismissal cooldown. + * @param {string} [options.title] - Override the section title. + * @param {string} [options.description] - Override the section description. + * @param {string} [options.primaryAction] - Override the Subscribe button label. + * @param {string} [options.secondaryAction] - Override the Dismiss button label. + * @fires alert:shown + * @returns {Promise} Whether the section was displayed. + */ + async show(kind, { + force = false, + title, + description, + primaryAction, + secondaryAction + } = {}) { + const request = ++this.showRequest; + const section = this.sectionsValue.find(section => section.kind === kind); + if (!section) { + this.close(); + return false; + } + await this.alert.push.ready?.catch(() => {}); + if (request !== this.showRequest || this.alert.disposed || !this.element.isConnected) return false; + if (this.unavailable || !force && this.dismissal.dismissedUntil > Date.now()) { + this.close(); + return false; + } + this.titleTarget.textContent = title ?? section.title; + this.descriptionTarget.textContent = description ?? section.description; + this.primaryActionTarget.textContent = primaryAction ?? section.primary_action; + this.secondaryActionTarget.textContent = secondaryAction ?? section.secondary_action; + this.kind = kind; + this.element.hidden = false; + this.record('shown'); + _hellotext.default.eventEmitter.dispatch('alert:shown', { + kind + }); + return true; + } + + /** + * Records a visitor dismissal from the secondary button and hides the alert. + * The first dismissal starts a seven-day cooldown; later dismissals start thirty days. + * Hidden alerts and pending subscriptions do not record another dismissal. + * + * @fires alert:dismissed + * @returns {void} + */ + hide() { + if (this.element.hidden || this.submitting) return; + const count = this.dismissal.dismissals + 1; + const dismissal = { + dismissals: count, + dismissedUntil: Date.now() + (count === 1 ? 7 : 30) * DAY + }; + dismissals.set(this.storageKey, dismissal); + try { + localStorage.setItem(this.storageKey, JSON.stringify(dismissal)); + } catch (_error) { + // Keep the cooldown for this page when browser storage is unavailable. + } + this.close(); + this.record('dismissed'); + _hellotext.default.eventEmitter.dispatch('alert:dismissed', { + kind: this.kind + }); + } + + /** + * Hides the alert and cancels pending display without recording a dismissal. + * + * @returns {void} + */ + close() { + this.showRequest += 1; + this.element.hidden = true; + } + + /** + * Requests Push subscription directly from the primary button's click handler. + * Disables both buttons while pending and hides once subscribed or permission is denied. + * Subscription failures are reported through an event so the page can handle them. + * Acceptance records the primary action, independently of the browser permission result. + * + * @fires alert:accepted + * @fires hellotext--alert:error + * @returns {Promise} Server response when available. + */ + async subscribe() { + if (this.submitting || this.element.hidden) return; + if (this.unavailable) return this.close(); + this.submitting = true; + this.primaryActionTarget.disabled = true; + this.secondaryActionTarget.disabled = true; + this.element.setAttribute('aria-busy', 'true'); + try { + this.record('accepted'); + _hellotext.default.eventEmitter.dispatch('alert:accepted', { + kind: this.kind + }); + + // Call before any await so the browser permission prompt retains the click's activation. + const response = await this.alert.push.subscribe(); + if (this.unavailable) this.close(); + if (response?.failed) this.dispatch('error', { + detail: { + response + } + }); + return response; + } catch (error) { + if (this.unavailable) this.close(); + this.dispatch('error', { + detail: { + error + } + }); + } finally { + this.submitting = false; + this.primaryActionTarget.disabled = false; + this.secondaryActionTarget.disabled = false; + this.element.removeAttribute('aria-busy'); + } + } + + /** + * Posts an interaction without delaying display, dismissal, or native permission. + * Recording failures leave the alert interaction unchanged. + * + * @private + * @param {'shown'|'dismissed'|'accepted'} kind - Interaction to record. + * @returns {Promise} + */ + async record(kind) { + try { + const response = await _api.default.pushAlerts.create({ + section: this.kind, + kind + }); + if (response.failed) console.warn('Hellotext Smart Alert submission failed:', response); + } catch (error) { + console.warn('Hellotext Smart Alert submission failed:', error); + } + } + + /** + * Whether Push state or notification permission prevents showing this alert. + * + * @returns {boolean} + */ + get unavailable() { + return this.alert.push.disposed || this.alert.push.subscribed || typeof Notification === 'undefined' || Notification.permission === 'denied'; + } + + /** + * Storage key shared by all sections for this business on the current origin. + * + * @returns {string} + */ + get storageKey() { + return `hellotext:alert:${this.alert.business.id}`; + } + + /** + * Reads valid saved dismissal history, falling back to page memory when storage fails. + * + * @returns {{dismissals: number, dismissedUntil: number}} Count and expiry in Unix milliseconds. + */ + get dismissal() { + try { + const saved = JSON.parse(localStorage.getItem(this.storageKey)); + if (Number.isSafeInteger(saved?.dismissals) && saved.dismissals > 0 && Number.isFinite(saved.dismissedUntil) && saved.dismissedUntil >= 0) { + dismissals.set(this.storageKey, saved); + } + } catch (_error) { + // Use the page's last known cooldown if storage is blocked or malformed. + } + return dismissals.get(this.storageKey) || { + dismissals: 0, + dismissedUntil: 0 + }; + } +} +exports.default = _default; \ No newline at end of file diff --git a/lib/controllers/alert_controller.js b/lib/controllers/alert_controller.js new file mode 100644 index 00000000..b90feb2c --- /dev/null +++ b/lib/controllers/alert_controller.js @@ -0,0 +1,257 @@ +import { Controller } from '@hotwired/stimulus'; +import Hellotext from '../hellotext'; +import API from '../api'; +const DAY = 24 * 60 * 60 * 1000; +const dismissals = new Map(); + +/** + * Displays Smart Alert sections and handles Push subscription and visitor dismissal. + * Dismissal history is shared across this business's sections on the current origin. + * + * @property {import('../models/alert').Alert} alert - Owning SDK alert, assigned on connection. + */ +export default class extends Controller { + static values = { + sections: Array + }; + static targets = ['title', 'description', 'primaryAction', 'secondaryAction']; + + /** + * Initializes display state and binds the cross-tab storage handler. + * + * @returns {void} + */ + initialize() { + this.showRequest = 0; + this.submitting = false; + this.onStorage = this.onStorage.bind(this); + } + + /** + * Announces readiness and listens for dismissals in other tabs. + * + * @fires hellotext--alert:connected + * @returns {void} + */ + connect() { + this.dispatch('connected', { + detail: { + controller: this + } + }); + window.addEventListener('storage', this.onStorage); + } + + /** + * Cancels pending display and removes the storage listener. + * + * @returns {void} + */ + disconnect() { + this.close(); + window.removeEventListener('storage', this.onStorage); + } + + /** + * Hides the alert when another tab records an active cooldown for this business. + * + * @param {StorageEvent} event - Browser storage change notification. + * @returns {void} + */ + onStorage(event) { + if (event.key === this.storageKey && this.dismissal.dismissedUntil > Date.now()) { + this.close(); + } + } + + /** + * Displays an enabled section after Push subscription restoration finishes. + * Text overrides apply only to this call and are rendered as plain text. + * Force bypasses the cooldown without changing dismissal history; section availability, + * existing subscriptions, and denied notification permission still prevent display. + * + * @param {import('../../index').HellotextAlertSection} kind - Section to display. + * @param {import('../../index').HellotextAlertShowOptions} [options={}] - Display overrides. + * @param {boolean} [options.force=false] - Bypass the current dismissal cooldown. + * @param {string} [options.title] - Override the section title. + * @param {string} [options.description] - Override the section description. + * @param {string} [options.primaryAction] - Override the Subscribe button label. + * @param {string} [options.secondaryAction] - Override the Dismiss button label. + * @fires alert:shown + * @returns {Promise} Whether the section was displayed. + */ + async show(kind, { + force = false, + title, + description, + primaryAction, + secondaryAction + } = {}) { + const request = ++this.showRequest; + const section = this.sectionsValue.find(section => section.kind === kind); + if (!section) { + this.close(); + return false; + } + await this.alert.push.ready?.catch(() => {}); + if (request !== this.showRequest || this.alert.disposed || !this.element.isConnected) return false; + if (this.unavailable || !force && this.dismissal.dismissedUntil > Date.now()) { + this.close(); + return false; + } + this.titleTarget.textContent = title ?? section.title; + this.descriptionTarget.textContent = description ?? section.description; + this.primaryActionTarget.textContent = primaryAction ?? section.primary_action; + this.secondaryActionTarget.textContent = secondaryAction ?? section.secondary_action; + this.kind = kind; + this.element.hidden = false; + this.record('shown'); + Hellotext.eventEmitter.dispatch('alert:shown', { + kind + }); + return true; + } + + /** + * Records a visitor dismissal from the secondary button and hides the alert. + * The first dismissal starts a seven-day cooldown; later dismissals start thirty days. + * Hidden alerts and pending subscriptions do not record another dismissal. + * + * @fires alert:dismissed + * @returns {void} + */ + hide() { + if (this.element.hidden || this.submitting) return; + const count = this.dismissal.dismissals + 1; + const dismissal = { + dismissals: count, + dismissedUntil: Date.now() + (count === 1 ? 7 : 30) * DAY + }; + dismissals.set(this.storageKey, dismissal); + try { + localStorage.setItem(this.storageKey, JSON.stringify(dismissal)); + } catch (_error) { + // Keep the cooldown for this page when browser storage is unavailable. + } + this.close(); + this.record('dismissed'); + Hellotext.eventEmitter.dispatch('alert:dismissed', { + kind: this.kind + }); + } + + /** + * Hides the alert and cancels pending display without recording a dismissal. + * + * @returns {void} + */ + close() { + this.showRequest += 1; + this.element.hidden = true; + } + + /** + * Requests Push subscription directly from the primary button's click handler. + * Disables both buttons while pending and hides once subscribed or permission is denied. + * Subscription failures are reported through an event so the page can handle them. + * Acceptance records the primary action, independently of the browser permission result. + * + * @fires alert:accepted + * @fires hellotext--alert:error + * @returns {Promise} Server response when available. + */ + async subscribe() { + if (this.submitting || this.element.hidden) return; + if (this.unavailable) return this.close(); + this.submitting = true; + this.primaryActionTarget.disabled = true; + this.secondaryActionTarget.disabled = true; + this.element.setAttribute('aria-busy', 'true'); + try { + this.record('accepted'); + Hellotext.eventEmitter.dispatch('alert:accepted', { + kind: this.kind + }); + + // Call before any await so the browser permission prompt retains the click's activation. + const response = await this.alert.push.subscribe(); + if (this.unavailable) this.close(); + if (response?.failed) this.dispatch('error', { + detail: { + response + } + }); + return response; + } catch (error) { + if (this.unavailable) this.close(); + this.dispatch('error', { + detail: { + error + } + }); + } finally { + this.submitting = false; + this.primaryActionTarget.disabled = false; + this.secondaryActionTarget.disabled = false; + this.element.removeAttribute('aria-busy'); + } + } + + /** + * Posts an interaction without delaying display, dismissal, or native permission. + * Recording failures leave the alert interaction unchanged. + * + * @private + * @param {'shown'|'dismissed'|'accepted'} kind - Interaction to record. + * @returns {Promise} + */ + async record(kind) { + try { + const response = await API.pushAlerts.create({ + section: this.kind, + kind + }); + if (response.failed) console.warn('Hellotext Smart Alert submission failed:', response); + } catch (error) { + console.warn('Hellotext Smart Alert submission failed:', error); + } + } + + /** + * Whether Push state or notification permission prevents showing this alert. + * + * @returns {boolean} + */ + get unavailable() { + return this.alert.push.disposed || this.alert.push.subscribed || typeof Notification === 'undefined' || Notification.permission === 'denied'; + } + + /** + * Storage key shared by all sections for this business on the current origin. + * + * @returns {string} + */ + get storageKey() { + return `hellotext:alert:${this.alert.business.id}`; + } + + /** + * Reads valid saved dismissal history, falling back to page memory when storage fails. + * + * @returns {{dismissals: number, dismissedUntil: number}} Count and expiry in Unix milliseconds. + */ + get dismissal() { + try { + const saved = JSON.parse(localStorage.getItem(this.storageKey)); + if (Number.isSafeInteger(saved?.dismissals) && saved.dismissals > 0 && Number.isFinite(saved.dismissedUntil) && saved.dismissedUntil >= 0) { + dismissals.set(this.storageKey, saved); + } + } catch (_error) { + // Use the page's last known cooldown if storage is blocked or malformed. + } + return dismissals.get(this.storageKey) || { + dismissals: 0, + dismissedUntil: 0 + }; + } +} \ No newline at end of file diff --git a/lib/core/event.cjs b/lib/core/event.cjs index cb8214e2..6e130273 100644 --- a/lib/core/event.cjs +++ b/lib/core/event.cjs @@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { exports.default = void 0; var _errors = require("../errors"); class Event { - static events = ['session-set', 'utm-set', 'forms:collected', 'form:completed', 'webchat:mounted', 'webchat:opened', 'webchat:closed', 'webchat:message:sent', 'webchat:message:received', 'cart.added']; + static events = ['session-set', 'utm-set', 'forms:collected', 'form:completed', 'alert:shown', 'alert:dismissed', 'alert:accepted', 'webchat:mounted', 'webchat:opened', 'webchat:closed', 'webchat:message:sent', 'webchat:message:received', 'cart.added']; static valid(name) { return Event.exists(name); } diff --git a/lib/core/event.js b/lib/core/event.js index e521aeb7..621dc5a1 100644 --- a/lib/core/event.js +++ b/lib/core/event.js @@ -1,6 +1,6 @@ import { InvalidEvent } from '../errors'; export default class Event { - static events = ['session-set', 'utm-set', 'forms:collected', 'form:completed', 'webchat:mounted', 'webchat:opened', 'webchat:closed', 'webchat:message:sent', 'webchat:message:received', 'cart.added']; + static events = ['session-set', 'utm-set', 'forms:collected', 'form:completed', 'alert:shown', 'alert:dismissed', 'alert:accepted', 'webchat:mounted', 'webchat:opened', 'webchat:closed', 'webchat:message:sent', 'webchat:message:received', 'cart.added']; static valid(name) { return Event.exists(name); } diff --git a/lib/hellotext.cjs b/lib/hellotext.cjs index 4b6057b2..c53f0d29 100644 --- a/lib/hellotext.cjs +++ b/lib/hellotext.cjs @@ -17,6 +17,7 @@ class Hellotext { static webchat; static whatsapp; static push; + static alert; /** * initialize the module. @@ -24,9 +25,12 @@ class Hellotext { * @param { Configuration } config */ static async initialize(business, config = {}) { + this.alert?.dispose(); + this.alert = null; this.push?.dispose(); this.push = null; - this.business = new _models.Business(business); + const businessContext = new _models.Business(business); + this.business = businessContext; this.page = new _models.Page(); _core.Configuration.assign({ push: {}, @@ -35,12 +39,16 @@ class Hellotext { _models.Session.initialize(this.page); this.forms = new _models.FormCollection(); this.query = new _models.Query(); - const businessData = await this.business.hydrate(); + const businessData = await businessContext.hydrate(); + if (this.business !== businessContext) return; if (config.push !== false && businessData?.push?.public_key && _models.Push.supported) { this.push = new _models.Push(businessData.push); this.push.initialize().catch(error => { console.warn('Hellotext Push initialization failed:', error); }); + if (businessData.alert?.html) { + this.alert = new _models.Alert(businessData.alert, businessContext, this.push); + } } const webchatConfig = config.webchat === false ? false : this.mergeWebchatConfig(businessData && businessData.webchat || {}, config.webchat || {}); const whatsappConfig = config.whatsappWidget === false ? false : this.mergeWhatsAppConfig(businessData && businessData.whatsapp || {}, config.whatsappWidget || {}); diff --git a/lib/hellotext.js b/lib/hellotext.js index a202f671..d5718b77 100644 --- a/lib/hellotext.js +++ b/lib/hellotext.js @@ -1,6 +1,6 @@ import { Configuration, Event } from './core'; import API, { Response, keepaliveFor } from './api'; -import { Business, Fingerprint, FormCollection, Page, Push, Query, Session, User, Webchat, WhatsAppWidget } from './models'; +import { Alert, Business, Fingerprint, FormCollection, Page, Push, Query, Session, User, Webchat, WhatsAppWidget } from './models'; import { NotInitializedError } from './errors'; class Hellotext { static eventEmitter = new Event(); @@ -9,6 +9,7 @@ class Hellotext { static webchat; static whatsapp; static push; + static alert; /** * initialize the module. @@ -16,9 +17,12 @@ class Hellotext { * @param { Configuration } config */ static async initialize(business, config = {}) { + this.alert?.dispose(); + this.alert = null; this.push?.dispose(); this.push = null; - this.business = new Business(business); + const businessContext = new Business(business); + this.business = businessContext; this.page = new Page(); Configuration.assign({ push: {}, @@ -27,12 +31,16 @@ class Hellotext { Session.initialize(this.page); this.forms = new FormCollection(); this.query = new Query(); - const businessData = await this.business.hydrate(); + const businessData = await businessContext.hydrate(); + if (this.business !== businessContext) return; if (config.push !== false && businessData?.push?.public_key && Push.supported) { this.push = new Push(businessData.push); this.push.initialize().catch(error => { console.warn('Hellotext Push initialization failed:', error); }); + if (businessData.alert?.html) { + this.alert = new Alert(businessData.alert, businessContext, this.push); + } } const webchatConfig = config.webchat === false ? false : this.mergeWebchatConfig(businessData && businessData.webchat || {}, config.webchat || {}); const whatsappConfig = config.whatsappWidget === false ? false : this.mergeWhatsAppConfig(businessData && businessData.whatsapp || {}, config.whatsappWidget || {}); diff --git a/lib/index.cjs b/lib/index.cjs index b63d8a77..5590c6f9 100644 --- a/lib/index.cjs +++ b/lib/index.cjs @@ -6,12 +6,14 @@ Object.defineProperty(exports, "__esModule", { exports.default = void 0; var _stimulus = require("@hotwired/stimulus"); var _hellotext = _interopRequireDefault(require("./hellotext")); +var _alert_controller = _interopRequireDefault(require("./controllers/alert_controller")); var _form_controller = _interopRequireDefault(require("./controllers/form_controller")); var _message_controller = _interopRequireDefault(require("./controllers/message_controller")); var _emoji_picker_controller = _interopRequireDefault(require("./controllers/webchat/emoji_picker_controller")); var _webchat_controller = _interopRequireDefault(require("./controllers/webchat_controller")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const application = _stimulus.Application.start(); +application.register('hellotext--alert', _alert_controller.default); application.register('hellotext--form', _form_controller.default); application.register('hellotext--webchat', _webchat_controller.default); application.register('hellotext--webchat--emoji', _emoji_picker_controller.default); diff --git a/lib/index.js b/lib/index.js index bae5f8f8..4fdd4a34 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,10 +1,12 @@ import { Application } from '@hotwired/stimulus'; import Hellotext from './hellotext'; +import AlertController from './controllers/alert_controller'; import FormController from './controllers/form_controller'; import MessageController from './controllers/message_controller'; import WebChatEmojiController from './controllers/webchat/emoji_picker_controller'; import WebchatController from './controllers/webchat_controller'; const application = Application.start(); +application.register('hellotext--alert', AlertController); application.register('hellotext--form', FormController); application.register('hellotext--webchat', WebchatController); application.register('hellotext--webchat--emoji', WebChatEmojiController); diff --git a/lib/models/alert.cjs b/lib/models/alert.cjs new file mode 100644 index 00000000..c5db99a9 --- /dev/null +++ b/lib/models/alert.cjs @@ -0,0 +1,100 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Alert = void 0; +/** + * Mounts Smart Alert markup and coordinates access to its Stimulus controller. + * + * @property {Promise} ready - Resolves when mounted and connected, or false if skipped. + */ +class Alert { + /** + * Prepares the server markup and starts mounting the alert. + * + * @param {{html: string}} data - Alert payload from the business response. + * @param {import('./business').Business} business - Business context and stylesheet readiness. + * @param {import('./push').Push} push - Push subscription manager used by the controller. + */ + constructor(data, business, push) { + this.business = business; + this.push = push; + this.disposed = false; + this.showRequest = 0; + this.controller = null; + this.element = new DOMParser().parseFromString(data.html, 'text/html').querySelector('[data-controller~="hellotext--alert"]'); + this.connected = new Promise(resolve => { + this.resolveConnected = resolve; + }); + this.onConnect = this.onConnect.bind(this); + this.ready = this.render(); + } + + /** + * Links the connected controller to this alert and releases waiting display requests. + * + * @private + * @param {CustomEvent} event - Connection event containing the Stimulus controller. + * @returns {void} + */ + onConnect(event) { + this.controller = event.detail.controller; + this.controller.alert = this; + this.resolveConnected(true); + } + + /** + * Mounts the server markup after its stylesheet loads and waits for controller connection. + * The markup retains its server-provided hidden state until a section is shown. + * + * @private + * @returns {Promise} Whether mounting and controller connection completed. + */ + async render() { + if (!this.element) return false; + this.element.addEventListener('hellotext--alert:connected', this.onConnect); + if (!(await this.business.stylesheetLoaded) || this.disposed) return false; + document.body.appendChild(this.element); + return this.connected; + } + + /** + * Waits for mounting and forwards the latest display request to the controller. + * Later show, hide, or dispose calls cancel older requests that are still waiting. + * + * @param {import('../../index').HellotextAlertSection} kind - Enabled section to display. + * @param {import('../../index').HellotextAlertShowOptions} [options={}] - Text and cooldown overrides. + * @returns {Promise} Whether the requested section was displayed. + */ + async show(kind, options = {}) { + const request = ++this.showRequest; + if (!(await this.ready) || this.disposed || request !== this.showRequest) return false; + return this.controller.show(kind, options); + } + + /** + * Hides the alert and cancels pending display without recording a visitor dismissal. + * + * @returns {void} + */ + hide() { + this.showRequest += 1; + this.controller?.close(); + } + + /** + * Cancels display, resolves any pending controller connection, and removes the alert. + * Called when the SDK reinitializes so the previous business's alert cannot appear later. + * + * @returns {void} + */ + dispose() { + this.disposed = true; + this.hide(); + this.resolveConnected(false); + this.element?.removeEventListener('hellotext--alert:connected', this.onConnect); + this.element?.remove(); + } +} +exports.Alert = Alert; \ No newline at end of file diff --git a/lib/models/alert.js b/lib/models/alert.js new file mode 100644 index 00000000..43f2f416 --- /dev/null +++ b/lib/models/alert.js @@ -0,0 +1,94 @@ +/** + * Mounts Smart Alert markup and coordinates access to its Stimulus controller. + * + * @property {Promise} ready - Resolves when mounted and connected, or false if skipped. + */ +class Alert { + /** + * Prepares the server markup and starts mounting the alert. + * + * @param {{html: string}} data - Alert payload from the business response. + * @param {import('./business').Business} business - Business context and stylesheet readiness. + * @param {import('./push').Push} push - Push subscription manager used by the controller. + */ + constructor(data, business, push) { + this.business = business; + this.push = push; + this.disposed = false; + this.showRequest = 0; + this.controller = null; + this.element = new DOMParser().parseFromString(data.html, 'text/html').querySelector('[data-controller~="hellotext--alert"]'); + this.connected = new Promise(resolve => { + this.resolveConnected = resolve; + }); + this.onConnect = this.onConnect.bind(this); + this.ready = this.render(); + } + + /** + * Links the connected controller to this alert and releases waiting display requests. + * + * @private + * @param {CustomEvent} event - Connection event containing the Stimulus controller. + * @returns {void} + */ + onConnect(event) { + this.controller = event.detail.controller; + this.controller.alert = this; + this.resolveConnected(true); + } + + /** + * Mounts the server markup after its stylesheet loads and waits for controller connection. + * The markup retains its server-provided hidden state until a section is shown. + * + * @private + * @returns {Promise} Whether mounting and controller connection completed. + */ + async render() { + if (!this.element) return false; + this.element.addEventListener('hellotext--alert:connected', this.onConnect); + if (!(await this.business.stylesheetLoaded) || this.disposed) return false; + document.body.appendChild(this.element); + return this.connected; + } + + /** + * Waits for mounting and forwards the latest display request to the controller. + * Later show, hide, or dispose calls cancel older requests that are still waiting. + * + * @param {import('../../index').HellotextAlertSection} kind - Enabled section to display. + * @param {import('../../index').HellotextAlertShowOptions} [options={}] - Text and cooldown overrides. + * @returns {Promise} Whether the requested section was displayed. + */ + async show(kind, options = {}) { + const request = ++this.showRequest; + if (!(await this.ready) || this.disposed || request !== this.showRequest) return false; + return this.controller.show(kind, options); + } + + /** + * Hides the alert and cancels pending display without recording a visitor dismissal. + * + * @returns {void} + */ + hide() { + this.showRequest += 1; + this.controller?.close(); + } + + /** + * Cancels display, resolves any pending controller connection, and removes the alert. + * Called when the SDK reinitializes so the previous business's alert cannot appear later. + * + * @returns {void} + */ + dispose() { + this.disposed = true; + this.hide(); + this.resolveConnected(false); + this.element?.removeEventListener('hellotext--alert:connected', this.onConnect); + this.element?.remove(); + } +} +export { Alert }; \ No newline at end of file diff --git a/lib/models/business.cjs b/lib/models/business.cjs index b1e44737..da651045 100644 --- a/lib/models/business.cjs +++ b/lib/models/business.cjs @@ -33,7 +33,8 @@ const stylesheetLoadTimeout = 10000; * @property {String} [locale] - Default dashboard locale for the business. * @property {String} [style_url] - Stylesheet URL to inject for dashboard-managed surfaces. * @property {BusinessWebchat|null} [webchat] - Dashboard webchat defaults. - * @property {{public_key: String}|null} [push] - Public VAPID key for push subscriptions. + * @property {{public_key: String}|null} [push] - Push public key. + * @property {{html: String}|null} [alert] - Smart Alert HTML. * @property {String|Array} [whitelist] - Domain whitelist configuration. * @property {String} [subscription] - Current business subscription tier. */ diff --git a/lib/models/business.js b/lib/models/business.js index 8ee0d372..4c0de5b4 100644 --- a/lib/models/business.js +++ b/lib/models/business.js @@ -26,7 +26,8 @@ const stylesheetLoadTimeout = 10000; * @property {String} [locale] - Default dashboard locale for the business. * @property {String} [style_url] - Stylesheet URL to inject for dashboard-managed surfaces. * @property {BusinessWebchat|null} [webchat] - Dashboard webchat defaults. - * @property {{public_key: String}|null} [push] - Public VAPID key for push subscriptions. + * @property {{public_key: String}|null} [push] - Push public key. + * @property {{html: String}|null} [alert] - Smart Alert HTML. * @property {String|Array} [whitelist] - Domain whitelist configuration. * @property {String} [subscription] - Current business subscription tier. */ diff --git a/lib/models/index.cjs b/lib/models/index.cjs index 2abb588d..e3ee34c8 100644 --- a/lib/models/index.cjs +++ b/lib/models/index.cjs @@ -3,6 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true }); +Object.defineProperty(exports, "Alert", { + enumerable: true, + get: function () { + return _alert.Alert; + } +}); Object.defineProperty(exports, "Business", { enumerable: true, get: function () { @@ -81,6 +87,7 @@ Object.defineProperty(exports, "WhatsAppWidget", { return _whatsapp_widget.WhatsAppWidget; } }); +var _alert = require("./alert"); var _business = require("./business"); var _cookies = require("./cookies"); var _fingerprint = require("./fingerprint"); diff --git a/lib/models/index.js b/lib/models/index.js index 4583aa57..d1c64931 100644 --- a/lib/models/index.js +++ b/lib/models/index.js @@ -1,3 +1,4 @@ +export { Alert } from './alert'; export { Business } from './business'; export { Cookies } from './cookies'; export { Fingerprint } from './fingerprint'; diff --git a/src/api/index.js b/src/api/index.js index b890d6bc..d60fe29f 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -6,6 +6,7 @@ import WebchatsAPI from './webchats' import WhatsAppWidgetsAPI from './whatsapp_widgets' import AcksAPI from './acks' import PushIdentitiesAPI from './push/identities' +import PushAlertsAPI from './push/alerts' // Browsers keep `fetch(..., { keepalive: true })` requests alive during page // unload/navigation, which is exactly the failure mode for analytics events @@ -59,6 +60,10 @@ export default class API { return AcksAPI } + static get pushAlerts() { + return PushAlertsAPI + } + static get pushIdentities() { return PushIdentitiesAPI } diff --git a/src/api/push/alerts.js b/src/api/push/alerts.js new file mode 100644 index 00000000..e1e12877 --- /dev/null +++ b/src/api/push/alerts.js @@ -0,0 +1,33 @@ +import Hellotext from '../../hellotext' +import { Configuration } from '../../core' +import { Response } from '../response' + +/** + * Records Smart Alert interactions for the current business and session. + */ +class PushAlertsAPI { + static get endpoint() { + return Configuration.endpoint('public/push/alerts') + } + + /** + * Posts an interaction without parsing the endpoint's empty success response. + * + * @param {Object} data - Alert interaction. + * @param {import('../../../index').HellotextAlertSection} data.section - Displayed section. + * @param {'shown'|'dismissed'|'accepted'} data.kind - Interaction to record. + * @returns {Promise} Whether the server accepted the interaction. + */ + static async create({ section, kind }) { + const response = await fetch(this.endpoint, { + method: 'POST', + keepalive: true, + headers: Hellotext.headers, + body: JSON.stringify({ session: Hellotext.session, section, kind }), + }) + + return new Response(response.ok, response) + } +} + +export default PushAlertsAPI diff --git a/src/controllers/alert_controller.js b/src/controllers/alert_controller.js new file mode 100644 index 00000000..2dbcd769 --- /dev/null +++ b/src/controllers/alert_controller.js @@ -0,0 +1,258 @@ +import { Controller } from '@hotwired/stimulus' +import Hellotext from '../hellotext' +import API from '../api' + +const DAY = 24 * 60 * 60 * 1000 +const dismissals = new Map() + +/** + * Displays Smart Alert sections and handles Push subscription and visitor dismissal. + * Dismissal history is shared across this business's sections on the current origin. + * + * @property {import('../models/alert').Alert} alert - Owning SDK alert, assigned on connection. + */ +export default class extends Controller { + static values = { sections: Array } + static targets = ['title', 'description', 'primaryAction', 'secondaryAction'] + + /** + * Initializes display state and binds the cross-tab storage handler. + * + * @returns {void} + */ + initialize() { + this.showRequest = 0 + this.submitting = false + this.onStorage = this.onStorage.bind(this) + } + + /** + * Announces readiness and listens for dismissals in other tabs. + * + * @fires hellotext--alert:connected + * @returns {void} + */ + connect() { + this.dispatch('connected', { detail: { controller: this } }) + window.addEventListener('storage', this.onStorage) + } + + /** + * Cancels pending display and removes the storage listener. + * + * @returns {void} + */ + disconnect() { + this.close() + window.removeEventListener('storage', this.onStorage) + } + + /** + * Hides the alert when another tab records an active cooldown for this business. + * + * @param {StorageEvent} event - Browser storage change notification. + * @returns {void} + */ + onStorage(event) { + if (event.key === this.storageKey && this.dismissal.dismissedUntil > Date.now()) { + this.close() + } + } + + /** + * Displays an enabled section after Push subscription restoration finishes. + * Text overrides apply only to this call and are rendered as plain text. + * Force bypasses the cooldown without changing dismissal history; section availability, + * existing subscriptions, and denied notification permission still prevent display. + * + * @param {import('../../index').HellotextAlertSection} kind - Section to display. + * @param {import('../../index').HellotextAlertShowOptions} [options={}] - Display overrides. + * @param {boolean} [options.force=false] - Bypass the current dismissal cooldown. + * @param {string} [options.title] - Override the section title. + * @param {string} [options.description] - Override the section description. + * @param {string} [options.primaryAction] - Override the Subscribe button label. + * @param {string} [options.secondaryAction] - Override the Dismiss button label. + * @fires alert:shown + * @returns {Promise} Whether the section was displayed. + */ + async show(kind, { force = false, title, description, primaryAction, secondaryAction } = {}) { + const request = ++this.showRequest + const section = this.sectionsValue.find(section => section.kind === kind) + + if (!section) { + this.close() + return false + } + + await this.alert.push.ready?.catch(() => {}) + + if (request !== this.showRequest || this.alert.disposed || !this.element.isConnected) + return false + + if (this.unavailable || (!force && this.dismissal.dismissedUntil > Date.now())) { + this.close() + return false + } + + this.titleTarget.textContent = title ?? section.title + this.descriptionTarget.textContent = description ?? section.description + + this.primaryActionTarget.textContent = primaryAction ?? section.primary_action + this.secondaryActionTarget.textContent = secondaryAction ?? section.secondary_action + + this.kind = kind + this.element.hidden = false + + this.record('shown') + Hellotext.eventEmitter.dispatch('alert:shown', { kind }) + + return true + } + + /** + * Records a visitor dismissal from the secondary button and hides the alert. + * The first dismissal starts a seven-day cooldown; later dismissals start thirty days. + * Hidden alerts and pending subscriptions do not record another dismissal. + * + * @fires alert:dismissed + * @returns {void} + */ + hide() { + if (this.element.hidden || this.submitting) return + + const count = this.dismissal.dismissals + 1 + const dismissal = { + dismissals: count, + dismissedUntil: Date.now() + (count === 1 ? 7 : 30) * DAY, + } + + dismissals.set(this.storageKey, dismissal) + try { + localStorage.setItem(this.storageKey, JSON.stringify(dismissal)) + } catch (_error) { + // Keep the cooldown for this page when browser storage is unavailable. + } + + this.close() + + this.record('dismissed') + Hellotext.eventEmitter.dispatch('alert:dismissed', { kind: this.kind }) + } + + /** + * Hides the alert and cancels pending display without recording a dismissal. + * + * @returns {void} + */ + close() { + this.showRequest += 1 + this.element.hidden = true + } + + /** + * Requests Push subscription directly from the primary button's click handler. + * Disables both buttons while pending and hides once subscribed or permission is denied. + * Subscription failures are reported through an event so the page can handle them. + * Acceptance records the primary action, independently of the browser permission result. + * + * @fires alert:accepted + * @fires hellotext--alert:error + * @returns {Promise} Server response when available. + */ + async subscribe() { + if (this.submitting || this.element.hidden) return + if (this.unavailable) return this.close() + + this.submitting = true + this.primaryActionTarget.disabled = true + this.secondaryActionTarget.disabled = true + this.element.setAttribute('aria-busy', 'true') + + try { + this.record('accepted') + Hellotext.eventEmitter.dispatch('alert:accepted', { kind: this.kind }) + + // Call before any await so the browser permission prompt retains the click's activation. + const response = await this.alert.push.subscribe() + + if (this.unavailable) this.close() + if (response?.failed) this.dispatch('error', { detail: { response } }) + return response + } catch (error) { + if (this.unavailable) this.close() + this.dispatch('error', { detail: { error } }) + } finally { + this.submitting = false + + this.primaryActionTarget.disabled = false + this.secondaryActionTarget.disabled = false + + this.element.removeAttribute('aria-busy') + } + } + + /** + * Posts an interaction without delaying display, dismissal, or native permission. + * Recording failures leave the alert interaction unchanged. + * + * @private + * @param {'shown'|'dismissed'|'accepted'} kind - Interaction to record. + * @returns {Promise} + */ + async record(kind) { + try { + const response = await API.pushAlerts.create({ section: this.kind, kind }) + + if (response.failed) console.warn('Hellotext Smart Alert submission failed:', response) + } catch (error) { + console.warn('Hellotext Smart Alert submission failed:', error) + } + } + + /** + * Whether Push state or notification permission prevents showing this alert. + * + * @returns {boolean} + */ + get unavailable() { + return ( + this.alert.push.disposed || + this.alert.push.subscribed || + typeof Notification === 'undefined' || + Notification.permission === 'denied' + ) + } + + /** + * Storage key shared by all sections for this business on the current origin. + * + * @returns {string} + */ + get storageKey() { + return `hellotext:alert:${this.alert.business.id}` + } + + /** + * Reads valid saved dismissal history, falling back to page memory when storage fails. + * + * @returns {{dismissals: number, dismissedUntil: number}} Count and expiry in Unix milliseconds. + */ + get dismissal() { + try { + const saved = JSON.parse(localStorage.getItem(this.storageKey)) + + if ( + Number.isSafeInteger(saved?.dismissals) && + saved.dismissals > 0 && + Number.isFinite(saved.dismissedUntil) && + saved.dismissedUntil >= 0 + ) { + dismissals.set(this.storageKey, saved) + } + } catch (_error) { + // Use the page's last known cooldown if storage is blocked or malformed. + } + + return dismissals.get(this.storageKey) || { dismissals: 0, dismissedUntil: 0 } + } +} diff --git a/src/core/event.js b/src/core/event.js index 95b5edd5..47fdf986 100644 --- a/src/core/event.js +++ b/src/core/event.js @@ -6,6 +6,9 @@ export default class Event { 'utm-set', 'forms:collected', 'form:completed', + 'alert:shown', + 'alert:dismissed', + 'alert:accepted', 'webchat:mounted', 'webchat:opened', 'webchat:closed', diff --git a/src/hellotext.js b/src/hellotext.js index ae4b59f8..c5add347 100644 --- a/src/hellotext.js +++ b/src/hellotext.js @@ -2,6 +2,7 @@ import { Configuration, Event } from './core' import API, { Response, keepaliveFor } from './api' import { + Alert, Business, Fingerprint, FormCollection, @@ -23,6 +24,7 @@ class Hellotext { static webchat static whatsapp static push + static alert /** * initialize the module. @@ -30,10 +32,13 @@ class Hellotext { * @param { Configuration } config */ static async initialize(business, config = {}) { + this.alert?.dispose() + this.alert = null this.push?.dispose() this.push = null - this.business = new Business(business) + const businessContext = new Business(business) + this.business = businessContext this.page = new Page() Configuration.assign({ push: {}, ...config }) @@ -43,7 +48,8 @@ class Hellotext { this.query = new Query() - const businessData = await this.business.hydrate() + const businessData = await businessContext.hydrate() + if (this.business !== businessContext) return if (config.push !== false && businessData?.push?.public_key && Push.supported) { this.push = new Push(businessData.push) @@ -51,6 +57,10 @@ class Hellotext { this.push.initialize().catch(error => { console.warn('Hellotext Push initialization failed:', error) }) + + if (businessData.alert?.html) { + this.alert = new Alert(businessData.alert, businessContext, this.push) + } } const webchatConfig = diff --git a/src/index.js b/src/index.js index fc838ec6..f84b4315 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,7 @@ import { Application } from '@hotwired/stimulus' import Hellotext from './hellotext' +import AlertController from './controllers/alert_controller' import FormController from './controllers/form_controller' import MessageController from './controllers/message_controller' import WebChatEmojiController from './controllers/webchat/emoji_picker_controller' @@ -8,6 +9,7 @@ import WebchatController from './controllers/webchat_controller' const application = Application.start() +application.register('hellotext--alert', AlertController) application.register('hellotext--form', FormController) application.register('hellotext--webchat', WebchatController) application.register('hellotext--webchat--emoji', WebChatEmojiController) diff --git a/src/models/alert.js b/src/models/alert.js new file mode 100644 index 00000000..f1ec6ede --- /dev/null +++ b/src/models/alert.js @@ -0,0 +1,109 @@ +/** + * Mounts Smart Alert markup and coordinates access to its Stimulus controller. + * + * @property {Promise} ready - Resolves when mounted and connected, or false if skipped. + */ +class Alert { + /** + * Prepares the server markup and starts mounting the alert. + * + * @param {{html: string}} data - Alert payload from the business response. + * @param {import('./business').Business} business - Business context and stylesheet readiness. + * @param {import('./push').Push} push - Push subscription manager used by the controller. + */ + constructor(data, business, push) { + this.business = business + this.push = push + + this.disposed = false + this.showRequest = 0 + this.controller = null + + this.element = new DOMParser() + .parseFromString(data.html, 'text/html') + .querySelector('[data-controller~="hellotext--alert"]') + + this.connected = new Promise(resolve => { + this.resolveConnected = resolve + }) + + this.onConnect = this.onConnect.bind(this) + this.ready = this.render() + } + + /** + * Links the connected controller to this alert and releases waiting display requests. + * + * @private + * @param {CustomEvent} event - Connection event containing the Stimulus controller. + * @returns {void} + */ + onConnect(event) { + this.controller = event.detail.controller + this.controller.alert = this + + this.resolveConnected(true) + } + + /** + * Mounts the server markup after its stylesheet loads and waits for controller connection. + * The markup retains its server-provided hidden state until a section is shown. + * + * @private + * @returns {Promise} Whether mounting and controller connection completed. + */ + async render() { + if (!this.element) return false + + this.element.addEventListener('hellotext--alert:connected', this.onConnect) + + if (!(await this.business.stylesheetLoaded) || this.disposed) return false + + document.body.appendChild(this.element) + + return this.connected + } + + /** + * Waits for mounting and forwards the latest display request to the controller. + * Later show, hide, or dispose calls cancel older requests that are still waiting. + * + * @param {import('../../index').HellotextAlertSection} kind - Enabled section to display. + * @param {import('../../index').HellotextAlertShowOptions} [options={}] - Text and cooldown overrides. + * @returns {Promise} Whether the requested section was displayed. + */ + async show(kind, options = {}) { + const request = ++this.showRequest + + if (!(await this.ready) || this.disposed || request !== this.showRequest) return false + + return this.controller.show(kind, options) + } + + /** + * Hides the alert and cancels pending display without recording a visitor dismissal. + * + * @returns {void} + */ + hide() { + this.showRequest += 1 + this.controller?.close() + } + + /** + * Cancels display, resolves any pending controller connection, and removes the alert. + * Called when the SDK reinitializes so the previous business's alert cannot appear later. + * + * @returns {void} + */ + dispose() { + this.disposed = true + this.hide() + + this.resolveConnected(false) + this.element?.removeEventListener('hellotext--alert:connected', this.onConnect) + this.element?.remove() + } +} + +export { Alert } diff --git a/src/models/business.js b/src/models/business.js index ae7b840f..4221147e 100644 --- a/src/models/business.js +++ b/src/models/business.js @@ -27,7 +27,8 @@ const stylesheetLoadTimeout = 10000 * @property {String} [locale] - Default dashboard locale for the business. * @property {String} [style_url] - Stylesheet URL to inject for dashboard-managed surfaces. * @property {BusinessWebchat|null} [webchat] - Dashboard webchat defaults. - * @property {{public_key: String}|null} [push] - Public VAPID key for push subscriptions. + * @property {{public_key: String}|null} [push] - Push public key. + * @property {{html: String}|null} [alert] - Smart Alert HTML. * @property {String|Array} [whitelist] - Domain whitelist configuration. * @property {String} [subscription] - Current business subscription tier. */ diff --git a/src/models/index.js b/src/models/index.js index 22feea4a..146c0915 100644 --- a/src/models/index.js +++ b/src/models/index.js @@ -1,3 +1,4 @@ +export { Alert } from './alert' export { Business } from './business' export { Cookies } from './cookies' export { Fingerprint } from './fingerprint' From 7d5e90cc4782234877dd5c9226944a493a7408c1 Mon Sep 17 00:00:00 2001 From: rockwellll Date: Sun, 6 Sep 2026 19:10:17 -0300 Subject: [PATCH 2/4] Include page snapshots in Smart Alert interactions --- __tests__/api/push/alerts_test.js | 7 +-- .../controllers/alert_controller_test.js | 44 ++++++++++++++++--- __tests__/models/alert_test.js | 6 +++ src/api/push/alerts.js | 5 ++- src/controllers/alert_controller.js | 6 ++- 5 files changed, 54 insertions(+), 14 deletions(-) diff --git a/__tests__/api/push/alerts_test.js b/__tests__/api/push/alerts_test.js index 4ca62690..0592bd35 100644 --- a/__tests__/api/push/alerts_test.js +++ b/__tests__/api/push/alerts_test.js @@ -20,8 +20,9 @@ describe('PushAlertsAPI', () => { Hellotext.business = previousBusiness }) - it.each(['shown', 'dismissed', 'accepted'])('posts %s with the current session and section', async kind => { - const response = await API.pushAlerts.create({ section: 'homepage', kind }) + it.each(['shown', 'dismissed', 'accepted'])('posts %s with the current session, section, and page', async kind => { + const page = { url: 'https://shop.example.com/?utm_source=email#offers', title: 'Shop', path: '/' } + const response = await API.pushAlerts.create({ section: 'homepage', kind, page }) expect(global.fetch).toHaveBeenCalledWith('https://api.hellotext.test/v1/public/push/alerts', { method: 'POST', @@ -31,7 +32,7 @@ describe('PushAlertsAPI', () => { Accept: 'application/json', 'Content-Type': 'application/json', }, - body: JSON.stringify({ session: 'session-id', section: 'homepage', kind }), + body: JSON.stringify({ session: 'session-id', section: 'homepage', kind, page }), }) expect(response.succeeded).toBe(true) }) diff --git a/__tests__/controllers/alert_controller_test.js b/__tests__/controllers/alert_controller_test.js index 0cba4124..bfa578ff 100644 --- a/__tests__/controllers/alert_controller_test.js +++ b/__tests__/controllers/alert_controller_test.js @@ -3,6 +3,7 @@ import AlertController from '../../src/controllers/alert_controller' import Hellotext from '../../src/hellotext' import API from '../../src/api' import { Alert } from '../../src/models/alert' +import { Page } from '../../src/models/page' const DAY = 24 * 60 * 60 * 1000 const sections = ['homepage', 'product_collection', 'product_details'].map(kind => ({ @@ -38,12 +39,15 @@ describe('Smart Alert interactions', () => { let originalNotification let events let businessNumber = 0 + let previousPage const primary = () => alert.element.querySelector('[data-hellotext--alert-target="primaryAction"]') const secondary = () => alert.element.querySelector('[data-hellotext--alert-target="secondaryAction"]') const saved = () => JSON.parse(localStorage.getItem(`hellotext:alert:${business.id}`)) beforeEach(async () => { + previousPage = Hellotext.page + Hellotext.page = new Page() jest.spyOn(API.pushAlerts, 'create').mockResolvedValue({ succeeded: true }) localStorage.clear() document.body.innerHTML = '' @@ -76,6 +80,7 @@ describe('Smart Alert interactions', () => { application.stop() jest.restoreAllMocks() global.Notification = originalNotification + Hellotext.page = previousPage document.body.innerHTML = '' Object.entries(events).forEach(([name, callback]) => Hellotext.removeEventListener(`alert:${name}`, callback)) }) @@ -95,11 +100,36 @@ describe('Smart Alert interactions', () => { expect(push.subscribe).not.toHaveBeenCalled() expect(Notification.requestPermission).not.toHaveBeenCalled() expect(events.shown.mock.calls).toEqual(sections.map(({ kind }) => [{ kind }])) - expect(API.pushAlerts.create.mock.calls).toEqual(sections.map(({ kind }) => [{ section: kind, kind: 'shown' }])) + expect(API.pushAlerts.create.mock.calls).toEqual(sections.map(({ kind }) => [{ section: kind, kind: 'shown', page: Hellotext.page.trackingData.page }])) expect(events.dismissed).not.toHaveBeenCalled() expect(events.accepted).not.toHaveBeenCalled() }) + it.each(['accepted', 'dismissed'])('keeps the displayed page snapshot when %s after navigation', async kind => { + Hellotext.page = new Page('https://shop.example.com/products/shirt?variant=42&utm_source=email#details') + const page = Hellotext.page.trackingData.page + await alert.show('product_details') + + Hellotext.page = new Page('https://shop.example.com/collections/shoes') + if (kind === 'accepted') primary().click() + else secondary().click() + + expect(API.pushAlerts.create.mock.calls).toEqual([ + [{ section: 'product_details', kind: 'shown', page }], + [{ section: 'product_details', kind, page }], + ]) + }) + + it('captures fresh page data for the next display', async () => { + await alert.show('homepage') + Hellotext.page = new Page('https://shop.example.com/collections/shoes?color=red#products') + const page = Hellotext.page.trackingData.page + + await alert.show('product_collection') + + expect(API.pushAlerts.create).toHaveBeenLastCalledWith({ section: 'product_collection', kind: 'shown', page }) + }) + it('renders merchant copy as text and hides the previous section for an unknown kind', async () => { alert.controller.sectionsValue = [{ ...sections[0], title: '' }] await alert.show('homepage') @@ -157,7 +187,7 @@ describe('Smart Alert interactions', () => { expect(alert.element.hidden).toBe(true) expect(events.dismissed).toHaveBeenCalledTimes(1) expect(events.dismissed).toHaveBeenCalledWith({ kind: 'homepage' }) - expect(API.pushAlerts.create).toHaveBeenLastCalledWith({ section: 'homepage', kind: 'dismissed' }) + expect(API.pushAlerts.create).toHaveBeenLastCalledWith({ section: 'homepage', kind: 'dismissed', page: Hellotext.page.trackingData.page }) alert.dispose() alert = new Alert({ html: alertHTML() }, business, push) @@ -338,7 +368,7 @@ describe('Smart Alert interactions', () => { expect(push.subscribe).toHaveBeenCalledTimes(1) expect(events.accepted).toHaveBeenCalledTimes(1) expect(events.accepted).toHaveBeenCalledWith({ kind: 'homepage' }) - expect(API.pushAlerts.create).toHaveBeenLastCalledWith({ section: 'homepage', kind: 'accepted' }) + expect(API.pushAlerts.create).toHaveBeenLastCalledWith({ section: 'homepage', kind: 'accepted', page: Hellotext.page.trackingData.page }) expect(primary().disabled).toBe(true) expect(secondary().disabled).toBe(true) expect(alert.element.getAttribute('aria-busy')).toBe('true') @@ -371,10 +401,10 @@ describe('Smart Alert interactions', () => { primary().click() expect(push.subscribe).toHaveBeenCalledTimes(1) expect(API.pushAlerts.create.mock.calls).toEqual([ - [{ section: 'homepage', kind: 'shown' }], - [{ section: 'homepage', kind: 'dismissed' }], - [{ section: 'product_details', kind: 'shown' }], - [{ section: 'product_details', kind: 'accepted' }], + [{ section: 'homepage', kind: 'shown', page: Hellotext.page.trackingData.page }], + [{ section: 'homepage', kind: 'dismissed', page: Hellotext.page.trackingData.page }], + [{ section: 'product_details', kind: 'shown', page: Hellotext.page.trackingData.page }], + [{ section: 'product_details', kind: 'accepted', page: Hellotext.page.trackingData.page }], ]) await Promise.resolve() }) diff --git a/__tests__/models/alert_test.js b/__tests__/models/alert_test.js index 39568640..d6817a98 100644 --- a/__tests__/models/alert_test.js +++ b/__tests__/models/alert_test.js @@ -2,6 +2,8 @@ import { Application } from '@hotwired/stimulus' import AlertController from '../../src/controllers/alert_controller' import { Alert } from '../../src/models/alert' import API from '../../src/api' +import Hellotext from '../../src/hellotext' +import { Page } from '../../src/models/page' const sections = [ { @@ -44,8 +46,11 @@ describe('Alert', () => { let business let push let notificationDescriptor + let previousPage beforeEach(async () => { + previousPage = Hellotext.page + Hellotext.page = new Page() document.body.innerHTML = '' localStorage.clear() jest.spyOn(API.pushAlerts, 'create').mockResolvedValue({ succeeded: true }) @@ -65,6 +70,7 @@ describe('Alert', () => { alert?.dispose() application.stop() jest.restoreAllMocks() + Hellotext.page = previousPage document.body.innerHTML = '' if (notificationDescriptor) { Object.defineProperty(window, 'Notification', notificationDescriptor) diff --git a/src/api/push/alerts.js b/src/api/push/alerts.js index e1e12877..f2d5c15e 100644 --- a/src/api/push/alerts.js +++ b/src/api/push/alerts.js @@ -16,14 +16,15 @@ class PushAlertsAPI { * @param {Object} data - Alert interaction. * @param {import('../../../index').HellotextAlertSection} data.section - Displayed section. * @param {'shown'|'dismissed'|'accepted'} data.kind - Interaction to record. + * @param {{url: string, title: string, path: string}} data.page - Page snapshot from display. * @returns {Promise} Whether the server accepted the interaction. */ - static async create({ section, kind }) { + static async create({ section, kind, page }) { const response = await fetch(this.endpoint, { method: 'POST', keepalive: true, headers: Hellotext.headers, - body: JSON.stringify({ session: Hellotext.session, section, kind }), + body: JSON.stringify({ session: Hellotext.session, section, kind, page }), }) return new Response(response.ok, response) diff --git a/src/controllers/alert_controller.js b/src/controllers/alert_controller.js index 2dbcd769..2ef9664e 100644 --- a/src/controllers/alert_controller.js +++ b/src/controllers/alert_controller.js @@ -101,6 +101,7 @@ export default class extends Controller { this.secondaryActionTarget.textContent = secondaryAction ?? section.secondary_action this.kind = kind + this.page = Hellotext.page.trackingData.page this.element.hidden = false this.record('shown') @@ -192,7 +193,8 @@ export default class extends Controller { } /** - * Posts an interaction without delaying display, dismissal, or native permission. + * Posts an interaction with the page snapshot captured when the alert was shown. + * Does not delay display, dismissal, or native permission. * Recording failures leave the alert interaction unchanged. * * @private @@ -201,7 +203,7 @@ export default class extends Controller { */ async record(kind) { try { - const response = await API.pushAlerts.create({ section: this.kind, kind }) + const response = await API.pushAlerts.create({ section: this.kind, kind, page: this.page }) if (response.failed) console.warn('Hellotext Smart Alert submission failed:', response) } catch (error) { From b061e260b38844d827dd9579b378f88773b024c3 Mon Sep 17 00:00:00 2001 From: rockwellll Date: Sun, 6 Sep 2026 19:20:04 -0300 Subject: [PATCH 3/4] Document SDK events by feature in README --- README.md | 78 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 079704ae..2e76b59f 100644 --- a/README.md +++ b/README.md @@ -61,31 +61,81 @@ Follow these guides to set up tracking, forms, chat widgets, and Push notificati ## Events -This library emits events that you can listen to and perform specific action when the event happens. -Think of it like `addEventListener` for HTML elements. You can listen for events, and remove events as well. - -To listen to an event, you can call the `on` method, like so +Use `Hellotext.on` to listen for SDK events. The callback receives the event's payload directly. +Register listeners before `Hellotext.initialize` to receive events emitted during initialization. ```javascript Hellotext.on(eventName, callback) ``` -To remove an event listener, you can call `removeEventListener` +To unsubscribe, pass the same callback to `Hellotext.removeEventListener`: ```javascript Hellotext.removeEventListener(eventName, callback) ``` -### List of events +### Sessions and attribution + +| Event | When it fires | Callback payload | +| --- | --- | --- | +| `session-set` | The session value is set, including when an existing session is restored during initialization. | The current session value, also available as `Hellotext.session`. | +| `utm-set` | UTM parameters are saved. | A JSON string containing the saved UTM parameters and `observed_at`. Use `JSON.parse` to read it as an object. | + +See [Understanding Sessions](/docs/sessions.md) and [Tracking Events](/docs/tracking.md). + +### Forms + +| Event | When it fires | Callback payload | +| --- | --- | --- | +| `forms:collected` | Forms found on the page have finished loading, before automatic mounting. | The `FormCollection` instance, with methods such as `getById`, `getByIndex`, and `forEach`. | +| `form:completed` | A form completes, or a previously completed form is restored from local storage during mounting. | `{ id, state, data, completedAt }`, where `data` contains the submitted values and `completedAt` is a timestamp in milliseconds. | + +See [Forms](/docs/forms.md) for collection, mounting, and completion details. + +### Smart Alerts + +Each alert event receives `{ kind }`, where `kind` identifies the section: `homepage`, +`product_collection`, or `product_details`. + +| Event | When it fires | Callback payload | +| --- | --- | --- | +| `alert:shown` | A section is displayed by a successful `show` call, including forced calls. | `{ kind }` | +| `alert:dismissed` | The visitor clicks the secondary action, hiding the alert and starting its dismissal cooldown. | `{ kind }` | +| `alert:accepted` | The visitor clicks the primary action, before the browser permission result or subscription completion. | `{ kind }` | + +`alert:accepted` does not confirm that the visitor granted permission or subscribed. +Programmatic hiding, cleanup, and dismissals received from another tab do not emit `alert:dismissed`. + +```javascript +Hellotext.on('alert:accepted', ({ kind }) => { + console.log('Alert accepted in', kind) +}) +``` + +See [Smart Alerts](/docs/push.md#show-a-smart-alert) for display options and dismissal behavior. + +### Webchat + +| Event | When it fires | Callback payload | +| --- | --- | --- | +| `webchat:mounted` | The Webchat widget is mounted. | None. | +| `webchat:opened` | The Webchat conversation opens. | None. | +| `webchat:closed` | The Webchat conversation closes. | None. | +| `webchat:message:sent` | A visitor's message or quick reply is successfully sent. | The message object, including `id`, `body`, and `attachments`, with additional context for quick replies and product cards. | +| `webchat:message:received` | An incoming message is added to the Webchat conversation. | The message object, with `body` containing its displayed text. | + +See [Webchat events](/docs/webchat.md#events) for message payload examples. + +### Cart + +| Event | When it fires | Callback payload | +| --- | --- | --- | +| `cart.added` | The visitor clicks an add-to-cart button in a Webchat product card. | `{ object_parameters: { items }, source }`. Each item contains `product`, `quantity`, and optional `reference` and `source`; the outer `source` contains `kind`, `message_id`, and `button_id`. | -- `session-set`: This event is fired when the session value for `Hellotext.session` is set. Either through an API request, or if the session was found in the cookie. -- `utm-set`: this event is fired when the UTM value is collected, useful to store the UTM on your side. -- `forms:collected` This event is fired when forms are collected. The callback will receive the array of forms collected. -- `form:completed` This event is fired when a form has been completed. A form is completed when the user fills all required inputs and verifies their OTP(One-Time Password). The callback will receive the form object that was completed, alongside the data the user filled in the form. -- View Webchat events [here](/docs/webchat.md#events) -- `cart.added` This event is fired when a customer adds a product to their cart from a Webchat message. +Handle `cart.added` in your storefront integration to update the cart. This event records the button +click; it does not confirm that your storefront added the item successfully. -### Configuration +## Configuration When initializing the library, you may pass an optional configuration object as the second argument. @@ -93,7 +143,7 @@ When initializing the library, you may pass an optional configuration object as Hellotext.initialize('HELLOTEXT_BUSINESS_ID', configurationOptions) ``` -#### Configuration Options +### Configuration Options | Property | Description | Type | Default | | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ----------------------------------------- | From 6705862ac19275bcea49e502041dc4c9040ae92d Mon Sep 17 00:00:00 2001 From: rockwellll Date: Sun, 6 Sep 2026 19:34:19 -0300 Subject: [PATCH 4/4] yarn build --- dist/hellotext.js | 2 +- lib/api/push/alerts.cjs | 7 +++++-- lib/api/push/alerts.js | 7 +++++-- lib/controllers/alert_controller.cjs | 7 +++++-- lib/controllers/alert_controller.js | 7 +++++-- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/dist/hellotext.js b/dist/hellotext.js index 943a0c26..713aef82 100644 --- a/dist/hellotext.js +++ b/dist/hellotext.js @@ -1,2 +1,2 @@ /*! For license information please see hellotext.js.LICENSE.txt */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Hellotext=t():e.Hellotext=t()}(Object("undefined"!=typeof self?self:this),()=>(()=>{"use strict";var e={891(e,t,s){s.d(t,{lg:()=>G,xI:()=>ne});class i{constructor(e,t,s){this.eventTarget=e,this.eventName=t,this.eventOptions=s,this.unorderedBindings=new Set}connect(){this.eventTarget.addEventListener(this.eventName,this,this.eventOptions)}disconnect(){this.eventTarget.removeEventListener(this.eventName,this,this.eventOptions)}bindingConnected(e){this.unorderedBindings.add(e)}bindingDisconnected(e){this.unorderedBindings.delete(e)}handleEvent(e){const t=function(e){if("immediatePropagationStopped"in e)return e;{const{stopImmediatePropagation:t}=e;return Object.assign(e,{immediatePropagationStopped:!1,stopImmediatePropagation(){this.immediatePropagationStopped=!0,t.call(this)}})}}(e);for(const e of this.bindings){if(t.immediatePropagationStopped)break;e.handleEvent(t)}}hasBindings(){return this.unorderedBindings.size>0}get bindings(){return Array.from(this.unorderedBindings).sort((e,t)=>{const s=e.index,i=t.index;return si?1:0})}}class n{constructor(e){this.application=e,this.eventListenerMaps=new Map,this.started=!1}start(){this.started||(this.started=!0,this.eventListeners.forEach(e=>e.connect()))}stop(){this.started&&(this.started=!1,this.eventListeners.forEach(e=>e.disconnect()))}get eventListeners(){return Array.from(this.eventListenerMaps.values()).reduce((e,t)=>e.concat(Array.from(t.values())),[])}bindingConnected(e){this.fetchEventListenerForBinding(e).bindingConnected(e)}bindingDisconnected(e,t=!1){this.fetchEventListenerForBinding(e).bindingDisconnected(e),t&&this.clearEventListenersForBinding(e)}handleError(e,t,s={}){this.application.handleError(e,`Error ${t}`,s)}clearEventListenersForBinding(e){const t=this.fetchEventListenerForBinding(e);t.hasBindings()||(t.disconnect(),this.removeMappedEventListenerFor(e))}removeMappedEventListenerFor(e){const{eventTarget:t,eventName:s,eventOptions:i}=e,n=this.fetchEventListenerMapForEventTarget(t),r=this.cacheKey(s,i);n.delete(r),0==n.size&&this.eventListenerMaps.delete(t)}fetchEventListenerForBinding(e){const{eventTarget:t,eventName:s,eventOptions:i}=e;return this.fetchEventListener(t,s,i)}fetchEventListener(e,t,s){const i=this.fetchEventListenerMapForEventTarget(e),n=this.cacheKey(t,s);let r=i.get(n);return r||(r=this.createEventListener(e,t,s),i.set(n,r)),r}createEventListener(e,t,s){const n=new i(e,t,s);return this.started&&n.connect(),n}fetchEventListenerMapForEventTarget(e){let t=this.eventListenerMaps.get(e);return t||(t=new Map,this.eventListenerMaps.set(e,t)),t}cacheKey(e,t){const s=[e];return Object.keys(t).sort().forEach(e=>{s.push(`${t[e]?"":"!"}${e}`)}),s.join(":")}}const r={stop:({event:e,value:t})=>(t&&e.stopPropagation(),!0),prevent:({event:e,value:t})=>(t&&e.preventDefault(),!0),self:({event:e,value:t,element:s})=>!t||s===e.target},a=/^(?:(?:([^.]+?)\+)?(.+?)(?:\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;function o(e){return e.replace(/(?:[_-])([a-z0-9])/g,(e,t)=>t.toUpperCase())}function c(e){return o(e.replace(/--/g,"-").replace(/__/g,"_"))}function l(e){return e.charAt(0).toUpperCase()+e.slice(1)}function h(e){return e.replace(/([A-Z])/g,(e,t)=>`-${t.toLowerCase()}`)}function u(e){return null!=e}function d(e,t){return Object.prototype.hasOwnProperty.call(e,t)}const p=["meta","ctrl","alt","shift"];class m{constructor(e,t,s,i){this.element=e,this.index=t,this.eventTarget=s.eventTarget||e,this.eventName=s.eventName||function(e){const t=e.tagName.toLowerCase();if(t in g)return g[t](e)}(e)||f("missing event name"),this.eventOptions=s.eventOptions||{},this.identifier=s.identifier||f("missing identifier"),this.methodName=s.methodName||f("missing method name"),this.keyFilter=s.keyFilter||"",this.schema=i}static forToken(e,t){return new this(e.element,e.index,function(e){const t=e.trim().match(a)||[];let s=t[2],i=t[3];return i&&!["keydown","keyup","keypress"].includes(s)&&(s+=`.${i}`,i=""),{eventTarget:(n=t[4],"window"==n?window:"document"==n?document:void 0),eventName:s,eventOptions:t[7]?(r=t[7],r.split(":").reduce((e,t)=>Object.assign(e,{[t.replace(/^!/,"")]:!/^!/.test(t)}),{})):{},identifier:t[5],methodName:t[6],keyFilter:t[1]||i};var n,r}(e.content),t)}toString(){const e=this.keyFilter?`.${this.keyFilter}`:"",t=this.eventTargetName?`@${this.eventTargetName}`:"";return`${this.eventName}${e}${t}->${this.identifier}#${this.methodName}`}shouldIgnoreKeyboardEvent(e){if(!this.keyFilter)return!1;const t=this.keyFilter.split("+");if(this.keyFilterDissatisfied(e,t))return!0;const s=t.filter(e=>!p.includes(e))[0];return!!s&&(d(this.keyMappings,s)||f(`contains unknown key filter: ${this.keyFilter}`),this.keyMappings[s].toLowerCase()!==e.key.toLowerCase())}shouldIgnoreMouseEvent(e){if(!this.keyFilter)return!1;const t=[this.keyFilter];return!!this.keyFilterDissatisfied(e,t)}get params(){const e={},t=new RegExp(`^data-${this.identifier}-(.+)-param$`,"i");for(const{name:s,value:i}of Array.from(this.element.attributes)){const n=s.match(t),r=n&&n[1];r&&(e[o(r)]=b(i))}return e}get eventTargetName(){return(e=this.eventTarget)==window?"window":e==document?"document":void 0;var e}get keyMappings(){return this.schema.keyMappings}keyFilterDissatisfied(e,t){const[s,i,n,r]=p.map(e=>t.includes(e));return e.metaKey!==s||e.ctrlKey!==i||e.altKey!==n||e.shiftKey!==r}}const g={a:()=>"click",button:()=>"click",form:()=>"submit",details:()=>"toggle",input:e=>"submit"==e.getAttribute("type")?"click":"input",select:()=>"change",textarea:()=>"input"};function f(e){throw new Error(e)}function b(e){try{return JSON.parse(e)}catch(t){return e}}class y{constructor(e,t){this.context=e,this.action=t}get index(){return this.action.index}get eventTarget(){return this.action.eventTarget}get eventOptions(){return this.action.eventOptions}get identifier(){return this.context.identifier}handleEvent(e){const t=this.prepareActionEvent(e);this.willBeInvokedByEvent(e)&&this.applyEventModifiers(t)&&this.invokeWithEvent(t)}get eventName(){return this.action.eventName}get method(){const e=this.controller[this.methodName];if("function"==typeof e)return e;throw new Error(`Action "${this.action}" references undefined method "${this.methodName}"`)}applyEventModifiers(e){const{element:t}=this.action,{actionDescriptorFilters:s}=this.context.application,{controller:i}=this.context;let n=!0;for(const[r,a]of Object.entries(this.eventOptions))if(r in s){const o=s[r];n=n&&o({name:r,value:a,event:e,element:t,controller:i})}return n}prepareActionEvent(e){return Object.assign(e,{params:this.action.params})}invokeWithEvent(e){const{target:t,currentTarget:s}=e;try{this.method.call(this.controller,e),this.context.logDebugActivity(this.methodName,{event:e,target:t,currentTarget:s,action:this.methodName})}catch(t){const{identifier:s,controller:i,element:n,index:r}=this,a={identifier:s,controller:i,element:n,index:r,event:e};this.context.handleError(t,`invoking action "${this.action}"`,a)}}willBeInvokedByEvent(e){const t=e.target;return!(e instanceof KeyboardEvent&&this.action.shouldIgnoreKeyboardEvent(e))&&!(e instanceof MouseEvent&&this.action.shouldIgnoreMouseEvent(e))&&(this.element===t||(t instanceof Element&&this.element.contains(t)?this.scope.containsElement(t):this.scope.containsElement(this.action.element)))}get controller(){return this.context.controller}get methodName(){return this.action.methodName}get element(){return this.scope.element}get scope(){return this.context.scope}}class v{constructor(e,t){this.mutationObserverInit={attributes:!0,childList:!0,subtree:!0},this.element=e,this.started=!1,this.delegate=t,this.elements=new Set,this.mutationObserver=new MutationObserver(e=>this.processMutations(e))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,this.mutationObserverInit),this.refresh())}pause(e){this.started&&(this.mutationObserver.disconnect(),this.started=!1),e(),this.started||(this.mutationObserver.observe(this.element,this.mutationObserverInit),this.started=!0)}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started){const e=new Set(this.matchElementsInTree());for(const t of Array.from(this.elements))e.has(t)||this.removeElement(t);for(const t of Array.from(e))this.addElement(t)}}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){"attributes"==e.type?this.processAttributeChange(e.target,e.attributeName):"childList"==e.type&&(this.processRemovedNodes(e.removedNodes),this.processAddedNodes(e.addedNodes))}processAttributeChange(e,t){this.elements.has(e)?this.delegate.elementAttributeChanged&&this.matchElement(e)?this.delegate.elementAttributeChanged(e,t):this.removeElement(e):this.matchElement(e)&&this.addElement(e)}processRemovedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.processTree(e,this.removeElement)}}processAddedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.elementIsActive(e)&&this.processTree(e,this.addElement)}}matchElement(e){return this.delegate.matchElement(e)}matchElementsInTree(e=this.element){return this.delegate.matchElementsInTree(e)}processTree(e,t){for(const s of this.matchElementsInTree(e))t.call(this,s)}elementFromNode(e){if(e.nodeType==Node.ELEMENT_NODE)return e}elementIsActive(e){return e.isConnected==this.element.isConnected&&this.element.contains(e)}addElement(e){this.elements.has(e)||this.elementIsActive(e)&&(this.elements.add(e),this.delegate.elementMatched&&this.delegate.elementMatched(e))}removeElement(e){this.elements.has(e)&&(this.elements.delete(e),this.delegate.elementUnmatched&&this.delegate.elementUnmatched(e))}}class w{constructor(e,t,s){this.attributeName=t,this.delegate=s,this.elementObserver=new v(e,this)}get element(){return this.elementObserver.element}get selector(){return`[${this.attributeName}]`}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get started(){return this.elementObserver.started}matchElement(e){return e.hasAttribute(this.attributeName)}matchElementsInTree(e){const t=this.matchElement(e)?[e]:[],s=Array.from(e.querySelectorAll(this.selector));return t.concat(s)}elementMatched(e){this.delegate.elementMatchedAttribute&&this.delegate.elementMatchedAttribute(e,this.attributeName)}elementUnmatched(e){this.delegate.elementUnmatchedAttribute&&this.delegate.elementUnmatchedAttribute(e,this.attributeName)}elementAttributeChanged(e,t){this.delegate.elementAttributeValueChanged&&this.attributeName==t&&this.delegate.elementAttributeValueChanged(e,t)}}function T(e,t){let s=e.get(t);return s||(s=new Set,e.set(t,s)),s}class S{constructor(){this.valuesByKey=new Map}get keys(){return Array.from(this.valuesByKey.keys())}get values(){return Array.from(this.valuesByKey.values()).reduce((e,t)=>e.concat(Array.from(t)),[])}get size(){return Array.from(this.valuesByKey.values()).reduce((e,t)=>e+t.size,0)}add(e,t){!function(e,t,s){T(e,t).add(s)}(this.valuesByKey,e,t)}delete(e,t){!function(e,t,s){T(e,t).delete(s),function(e,t){const s=e.get(t);null!=s&&0==s.size&&e.delete(t)}(e,t)}(this.valuesByKey,e,t)}has(e,t){const s=this.valuesByKey.get(e);return null!=s&&s.has(t)}hasKey(e){return this.valuesByKey.has(e)}hasValue(e){return Array.from(this.valuesByKey.values()).some(t=>t.has(e))}getValuesForKey(e){const t=this.valuesByKey.get(e);return t?Array.from(t):[]}getKeysForValue(e){return Array.from(this.valuesByKey).filter(([t,s])=>s.has(e)).map(([e,t])=>e)}}class C{constructor(e,t,s,i){this._selector=t,this.details=i,this.elementObserver=new v(e,this),this.delegate=s,this.matchesByElement=new S}get started(){return this.elementObserver.started}get selector(){return this._selector}set selector(e){this._selector=e,this.refresh()}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get element(){return this.elementObserver.element}matchElement(e){const{selector:t}=this;if(t){const s=e.matches(t);return this.delegate.selectorMatchElement?s&&this.delegate.selectorMatchElement(e,this.details):s}return!1}matchElementsInTree(e){const{selector:t}=this;if(t){const s=this.matchElement(e)?[e]:[],i=Array.from(e.querySelectorAll(t)).filter(e=>this.matchElement(e));return s.concat(i)}return[]}elementMatched(e){const{selector:t}=this;t&&this.selectorMatched(e,t)}elementUnmatched(e){const t=this.matchesByElement.getKeysForValue(e);for(const s of t)this.selectorUnmatched(e,s)}elementAttributeChanged(e,t){const{selector:s}=this;if(s){const t=this.matchElement(e),i=this.matchesByElement.has(s,e);t&&!i?this.selectorMatched(e,s):!t&&i&&this.selectorUnmatched(e,s)}}selectorMatched(e,t){this.delegate.selectorMatched(e,t,this.details),this.matchesByElement.add(t,e)}selectorUnmatched(e,t){this.delegate.selectorUnmatched(e,t,this.details),this.matchesByElement.delete(t,e)}}class O{constructor(e,t){this.element=e,this.delegate=t,this.started=!1,this.stringMap=new Map,this.mutationObserver=new MutationObserver(e=>this.processMutations(e))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,{attributes:!0,attributeOldValue:!0}),this.refresh())}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started)for(const e of this.knownAttributeNames)this.refreshAttribute(e,null)}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){const t=e.attributeName;t&&this.refreshAttribute(t,e.oldValue)}refreshAttribute(e,t){const s=this.delegate.getStringMapKeyForAttribute(e);if(null!=s){this.stringMap.has(e)||this.stringMapKeyAdded(s,e);const i=this.element.getAttribute(e);if(this.stringMap.get(e)!=i&&this.stringMapValueChanged(i,s,t),null==i){const t=this.stringMap.get(e);this.stringMap.delete(e),t&&this.stringMapKeyRemoved(s,e,t)}else this.stringMap.set(e,i)}}stringMapKeyAdded(e,t){this.delegate.stringMapKeyAdded&&this.delegate.stringMapKeyAdded(e,t)}stringMapValueChanged(e,t,s){this.delegate.stringMapValueChanged&&this.delegate.stringMapValueChanged(e,t,s)}stringMapKeyRemoved(e,t,s){this.delegate.stringMapKeyRemoved&&this.delegate.stringMapKeyRemoved(e,t,s)}get knownAttributeNames(){return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)))}get currentAttributeNames(){return Array.from(this.element.attributes).map(e=>e.name)}get recordedAttributeNames(){return Array.from(this.stringMap.keys())}}class A{constructor(e,t,s){this.attributeObserver=new w(e,t,this),this.delegate=s,this.tokensByElement=new S}get started(){return this.attributeObserver.started}start(){this.attributeObserver.start()}pause(e){this.attributeObserver.pause(e)}stop(){this.attributeObserver.stop()}refresh(){this.attributeObserver.refresh()}get element(){return this.attributeObserver.element}get attributeName(){return this.attributeObserver.attributeName}elementMatchedAttribute(e){this.tokensMatched(this.readTokensForElement(e))}elementAttributeValueChanged(e){const[t,s]=this.refreshTokensForElement(e);this.tokensUnmatched(t),this.tokensMatched(s)}elementUnmatchedAttribute(e){this.tokensUnmatched(this.tokensByElement.getValuesForKey(e))}tokensMatched(e){e.forEach(e=>this.tokenMatched(e))}tokensUnmatched(e){e.forEach(e=>this.tokenUnmatched(e))}tokenMatched(e){this.delegate.tokenMatched(e),this.tokensByElement.add(e.element,e)}tokenUnmatched(e){this.delegate.tokenUnmatched(e),this.tokensByElement.delete(e.element,e)}refreshTokensForElement(e){const t=this.tokensByElement.getValuesForKey(e),s=this.readTokensForElement(e),i=function(e,t){const s=Math.max(e.length,t.length);return Array.from({length:s},(s,i)=>[e[i],t[i]])}(t,s).findIndex(([e,t])=>{return i=t,!((s=e)&&i&&s.index==i.index&&s.content==i.content);var s,i});return-1==i?[[],[]]:[t.slice(i),s.slice(i)]}readTokensForElement(e){const t=this.attributeName;return function(e,t,s){return e.trim().split(/\s+/).filter(e=>e.length).map((e,i)=>({element:t,attributeName:s,content:e,index:i}))}(e.getAttribute(t)||"",e,t)}}class E{constructor(e,t,s){this.tokenListObserver=new A(e,t,this),this.delegate=s,this.parseResultsByToken=new WeakMap,this.valuesByTokenByElement=new WeakMap}get started(){return this.tokenListObserver.started}start(){this.tokenListObserver.start()}stop(){this.tokenListObserver.stop()}refresh(){this.tokenListObserver.refresh()}get element(){return this.tokenListObserver.element}get attributeName(){return this.tokenListObserver.attributeName}tokenMatched(e){const{element:t}=e,{value:s}=this.fetchParseResultForToken(e);s&&(this.fetchValuesByTokenForElement(t).set(e,s),this.delegate.elementMatchedValue(t,s))}tokenUnmatched(e){const{element:t}=e,{value:s}=this.fetchParseResultForToken(e);s&&(this.fetchValuesByTokenForElement(t).delete(e),this.delegate.elementUnmatchedValue(t,s))}fetchParseResultForToken(e){let t=this.parseResultsByToken.get(e);return t||(t=this.parseToken(e),this.parseResultsByToken.set(e,t)),t}fetchValuesByTokenForElement(e){let t=this.valuesByTokenByElement.get(e);return t||(t=new Map,this.valuesByTokenByElement.set(e,t)),t}parseToken(e){try{return{value:this.delegate.parseValueForToken(e)}}catch(e){return{error:e}}}}class x{constructor(e,t){this.context=e,this.delegate=t,this.bindingsByAction=new Map}start(){this.valueListObserver||(this.valueListObserver=new E(this.element,this.actionAttribute,this),this.valueListObserver.start())}stop(){this.valueListObserver&&(this.valueListObserver.stop(),delete this.valueListObserver,this.disconnectAllActions())}get element(){return this.context.element}get identifier(){return this.context.identifier}get actionAttribute(){return this.schema.actionAttribute}get schema(){return this.context.schema}get bindings(){return Array.from(this.bindingsByAction.values())}connectAction(e){const t=new y(this.context,e);this.bindingsByAction.set(e,t),this.delegate.bindingConnected(t)}disconnectAction(e){const t=this.bindingsByAction.get(e);t&&(this.bindingsByAction.delete(e),this.delegate.bindingDisconnected(t))}disconnectAllActions(){this.bindings.forEach(e=>this.delegate.bindingDisconnected(e,!0)),this.bindingsByAction.clear()}parseValueForToken(e){const t=m.forToken(e,this.schema);if(t.identifier==this.identifier)return t}elementMatchedValue(e,t){this.connectAction(t)}elementUnmatchedValue(e,t){this.disconnectAction(t)}}class M{constructor(e,t){this.context=e,this.receiver=t,this.stringMapObserver=new O(this.element,this),this.valueDescriptorMap=this.controller.valueDescriptorMap}start(){this.stringMapObserver.start(),this.invokeChangedCallbacksForDefaultValues()}stop(){this.stringMapObserver.stop()}get element(){return this.context.element}get controller(){return this.context.controller}getStringMapKeyForAttribute(e){if(e in this.valueDescriptorMap)return this.valueDescriptorMap[e].name}stringMapKeyAdded(e,t){const s=this.valueDescriptorMap[t];this.hasValue(e)||this.invokeChangedCallback(e,s.writer(this.receiver[e]),s.writer(s.defaultValue))}stringMapValueChanged(e,t,s){const i=this.valueDescriptorNameMap[t];null!==e&&(null===s&&(s=i.writer(i.defaultValue)),this.invokeChangedCallback(t,e,s))}stringMapKeyRemoved(e,t,s){const i=this.valueDescriptorNameMap[e];this.hasValue(e)?this.invokeChangedCallback(e,i.writer(this.receiver[e]),s):this.invokeChangedCallback(e,i.writer(i.defaultValue),s)}invokeChangedCallbacksForDefaultValues(){for(const{key:e,name:t,defaultValue:s,writer:i}of this.valueDescriptors)null==s||this.controller.data.has(e)||this.invokeChangedCallback(t,i(s),void 0)}invokeChangedCallback(e,t,s){const i=`${e}Changed`,n=this.receiver[i];if("function"==typeof n){const i=this.valueDescriptorNameMap[e];try{const e=i.reader(t);let r=s;s&&(r=i.reader(s)),n.call(this.receiver,e,r)}catch(e){throw e instanceof TypeError&&(e.message=`Stimulus Value "${this.context.identifier}.${i.name}" - ${e.message}`),e}}}get valueDescriptors(){const{valueDescriptorMap:e}=this;return Object.keys(e).map(t=>e[t])}get valueDescriptorNameMap(){const e={};return Object.keys(this.valueDescriptorMap).forEach(t=>{const s=this.valueDescriptorMap[t];e[s.name]=s}),e}hasValue(e){const t=`has${l(this.valueDescriptorNameMap[e].name)}`;return this.receiver[t]}}class k{constructor(e,t){this.context=e,this.delegate=t,this.targetsByName=new S}start(){this.tokenListObserver||(this.tokenListObserver=new A(this.element,this.attributeName,this),this.tokenListObserver.start())}stop(){this.tokenListObserver&&(this.disconnectAllTargets(),this.tokenListObserver.stop(),delete this.tokenListObserver)}tokenMatched({element:e,content:t}){this.scope.containsElement(e)&&this.connectTarget(e,t)}tokenUnmatched({element:e,content:t}){this.disconnectTarget(e,t)}connectTarget(e,t){var s;this.targetsByName.has(t,e)||(this.targetsByName.add(t,e),null===(s=this.tokenListObserver)||void 0===s||s.pause(()=>this.delegate.targetConnected(e,t)))}disconnectTarget(e,t){var s;this.targetsByName.has(t,e)&&(this.targetsByName.delete(t,e),null===(s=this.tokenListObserver)||void 0===s||s.pause(()=>this.delegate.targetDisconnected(e,t)))}disconnectAllTargets(){for(const e of this.targetsByName.keys)for(const t of this.targetsByName.getValuesForKey(e))this.disconnectTarget(t,e)}get attributeName(){return`data-${this.context.identifier}-target`}get element(){return this.context.element}get scope(){return this.context.scope}}function I(e,t){const s=L(e);return Array.from(s.reduce((e,s)=>(function(e,t){const s=e[t];return Array.isArray(s)?s:[]}(s,t).forEach(t=>e.add(t)),e),new Set))}function L(e){const t=[];for(;e;)t.push(e),e=Object.getPrototypeOf(e);return t.reverse()}class _{constructor(e,t){this.started=!1,this.context=e,this.delegate=t,this.outletsByName=new S,this.outletElementsByName=new S,this.selectorObserverMap=new Map,this.attributeObserverMap=new Map}start(){this.started||(this.outletDefinitions.forEach(e=>{this.setupSelectorObserverForOutlet(e),this.setupAttributeObserverForOutlet(e)}),this.started=!0,this.dependentContexts.forEach(e=>e.refresh()))}refresh(){this.selectorObserverMap.forEach(e=>e.refresh()),this.attributeObserverMap.forEach(e=>e.refresh())}stop(){this.started&&(this.started=!1,this.disconnectAllOutlets(),this.stopSelectorObservers(),this.stopAttributeObservers())}stopSelectorObservers(){this.selectorObserverMap.size>0&&(this.selectorObserverMap.forEach(e=>e.stop()),this.selectorObserverMap.clear())}stopAttributeObservers(){this.attributeObserverMap.size>0&&(this.attributeObserverMap.forEach(e=>e.stop()),this.attributeObserverMap.clear())}selectorMatched(e,t,{outletName:s}){const i=this.getOutlet(e,s);i&&this.connectOutlet(i,e,s)}selectorUnmatched(e,t,{outletName:s}){const i=this.getOutletFromMap(e,s);i&&this.disconnectOutlet(i,e,s)}selectorMatchElement(e,{outletName:t}){const s=this.selector(t),i=this.hasOutlet(e,t),n=e.matches(`[${this.schema.controllerAttribute}~=${t}]`);return!!s&&i&&n&&e.matches(s)}elementMatchedAttribute(e,t){const s=this.getOutletNameFromOutletAttributeName(t);s&&this.updateSelectorObserverForOutlet(s)}elementAttributeValueChanged(e,t){const s=this.getOutletNameFromOutletAttributeName(t);s&&this.updateSelectorObserverForOutlet(s)}elementUnmatchedAttribute(e,t){const s=this.getOutletNameFromOutletAttributeName(t);s&&this.updateSelectorObserverForOutlet(s)}connectOutlet(e,t,s){var i;this.outletElementsByName.has(s,t)||(this.outletsByName.add(s,e),this.outletElementsByName.add(s,t),null===(i=this.selectorObserverMap.get(s))||void 0===i||i.pause(()=>this.delegate.outletConnected(e,t,s)))}disconnectOutlet(e,t,s){var i;this.outletElementsByName.has(s,t)&&(this.outletsByName.delete(s,e),this.outletElementsByName.delete(s,t),null===(i=this.selectorObserverMap.get(s))||void 0===i||i.pause(()=>this.delegate.outletDisconnected(e,t,s)))}disconnectAllOutlets(){for(const e of this.outletElementsByName.keys)for(const t of this.outletElementsByName.getValuesForKey(e))for(const s of this.outletsByName.getValuesForKey(e))this.disconnectOutlet(s,t,e)}updateSelectorObserverForOutlet(e){const t=this.selectorObserverMap.get(e);t&&(t.selector=this.selector(e))}setupSelectorObserverForOutlet(e){const t=this.selector(e),s=new C(document.body,t,this,{outletName:e});this.selectorObserverMap.set(e,s),s.start()}setupAttributeObserverForOutlet(e){const t=this.attributeNameForOutletName(e),s=new w(this.scope.element,t,this);this.attributeObserverMap.set(e,s),s.start()}selector(e){return this.scope.outlets.getSelectorForOutletName(e)}attributeNameForOutletName(e){return this.scope.schema.outletAttributeForScope(this.identifier,e)}getOutletNameFromOutletAttributeName(e){return this.outletDefinitions.find(t=>this.attributeNameForOutletName(t)===e)}get outletDependencies(){const e=new S;return this.router.modules.forEach(t=>{I(t.definition.controllerConstructor,"outlets").forEach(s=>e.add(s,t.identifier))}),e}get outletDefinitions(){return this.outletDependencies.getKeysForValue(this.identifier)}get dependentControllerIdentifiers(){return this.outletDependencies.getValuesForKey(this.identifier)}get dependentContexts(){const e=this.dependentControllerIdentifiers;return this.router.contexts.filter(t=>e.includes(t.identifier))}hasOutlet(e,t){return!!this.getOutlet(e,t)||!!this.getOutletFromMap(e,t)}getOutlet(e,t){return this.application.getControllerForElementAndIdentifier(e,t)}getOutletFromMap(e,t){return this.outletsByName.getValuesForKey(t).find(t=>t.element===e)}get scope(){return this.context.scope}get schema(){return this.context.schema}get identifier(){return this.context.identifier}get application(){return this.context.application}get router(){return this.application.router}}class N{constructor(e,t){this.logDebugActivity=(e,t={})=>{const{identifier:s,controller:i,element:n}=this;t=Object.assign({identifier:s,controller:i,element:n},t),this.application.logDebugActivity(this.identifier,e,t)},this.module=e,this.scope=t,this.controller=new e.controllerConstructor(this),this.bindingObserver=new x(this,this.dispatcher),this.valueObserver=new M(this,this.controller),this.targetObserver=new k(this,this),this.outletObserver=new _(this,this);try{this.controller.initialize(),this.logDebugActivity("initialize")}catch(e){this.handleError(e,"initializing controller")}}connect(){this.bindingObserver.start(),this.valueObserver.start(),this.targetObserver.start(),this.outletObserver.start();try{this.controller.connect(),this.logDebugActivity("connect")}catch(e){this.handleError(e,"connecting controller")}}refresh(){this.outletObserver.refresh()}disconnect(){try{this.controller.disconnect(),this.logDebugActivity("disconnect")}catch(e){this.handleError(e,"disconnecting controller")}this.outletObserver.stop(),this.targetObserver.stop(),this.valueObserver.stop(),this.bindingObserver.stop()}get application(){return this.module.application}get identifier(){return this.module.identifier}get schema(){return this.application.schema}get dispatcher(){return this.application.dispatcher}get element(){return this.scope.element}get parentElement(){return this.element.parentElement}handleError(e,t,s={}){const{identifier:i,controller:n,element:r}=this;s=Object.assign({identifier:i,controller:n,element:r},s),this.application.handleError(e,`Error ${t}`,s)}targetConnected(e,t){this.invokeControllerMethod(`${t}TargetConnected`,e)}targetDisconnected(e,t){this.invokeControllerMethod(`${t}TargetDisconnected`,e)}outletConnected(e,t,s){this.invokeControllerMethod(`${c(s)}OutletConnected`,e,t)}outletDisconnected(e,t,s){this.invokeControllerMethod(`${c(s)}OutletDisconnected`,e,t)}invokeControllerMethod(e,...t){const s=this.controller;"function"==typeof s[e]&&s[e](...t)}}const P="function"==typeof Object.getOwnPropertySymbols?e=>[...Object.getOwnPropertyNames(e),...Object.getOwnPropertySymbols(e)]:Object.getOwnPropertyNames,F=(()=>{function e(e){function t(){return Reflect.construct(e,arguments,new.target)}return t.prototype=Object.create(e.prototype,{constructor:{value:t}}),Reflect.setPrototypeOf(t,e),t}try{return function(){const t=e(function(){this.a.call(this)});t.prototype.a=function(){},new t}(),e}catch(e){return e=>class extends e{}}})();class R{constructor(e,t){this.application=e,this.definition=function(e){return{identifier:e.identifier,controllerConstructor:(t=e.controllerConstructor,function(e,t){const s=F(e),i=function(e,t){return P(t).reduce((s,i)=>{const n=function(e,t,s){const i=Object.getOwnPropertyDescriptor(e,s);if(!i||!("value"in i)){const e=Object.getOwnPropertyDescriptor(t,s).value;return i&&(e.get=i.get||e.get,e.set=i.set||e.set),e}}(e,t,i);return n&&Object.assign(s,{[i]:n}),s},{})}(e.prototype,t);return Object.defineProperties(s.prototype,i),s}(t,function(e){return I(e,"blessings").reduce((t,s)=>{const i=s(e);for(const e in i){const s=t[e]||{};t[e]=Object.assign(s,i[e])}return t},{})}(t)))};var t}(t),this.contextsByScope=new WeakMap,this.connectedContexts=new Set}get identifier(){return this.definition.identifier}get controllerConstructor(){return this.definition.controllerConstructor}get contexts(){return Array.from(this.connectedContexts)}connectContextForScope(e){const t=this.fetchContextForScope(e);this.connectedContexts.add(t),t.connect()}disconnectContextForScope(e){const t=this.contextsByScope.get(e);t&&(this.connectedContexts.delete(t),t.disconnect())}fetchContextForScope(e){let t=this.contextsByScope.get(e);return t||(t=new N(this,e),this.contextsByScope.set(e,t)),t}}class D{constructor(e){this.scope=e}has(e){return this.data.has(this.getDataKey(e))}get(e){return this.getAll(e)[0]}getAll(e){return(this.data.get(this.getDataKey(e))||"").match(/[^\s]+/g)||[]}getAttributeName(e){return this.data.getAttributeNameForKey(this.getDataKey(e))}getDataKey(e){return`${e}-class`}get data(){return this.scope.data}}class j{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get(e){const t=this.getAttributeNameForKey(e);return this.element.getAttribute(t)}set(e,t){const s=this.getAttributeNameForKey(e);return this.element.setAttribute(s,t),this.get(e)}has(e){const t=this.getAttributeNameForKey(e);return this.element.hasAttribute(t)}delete(e){if(this.has(e)){const t=this.getAttributeNameForKey(e);return this.element.removeAttribute(t),!0}return!1}getAttributeNameForKey(e){return`data-${this.identifier}-${h(e)}`}}class B{constructor(e){this.warnedKeysByObject=new WeakMap,this.logger=e}warn(e,t,s){let i=this.warnedKeysByObject.get(e);i||(i=new Set,this.warnedKeysByObject.set(e,i)),i.has(t)||(i.add(t),this.logger.warn(s,e))}}function $(e,t){return`[${e}~="${t}"]`}class V{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce((e,t)=>e||this.findTarget(t)||this.findLegacyTarget(t),void 0)}findAll(...e){return e.reduce((e,t)=>[...e,...this.findAllTargets(t),...this.findAllLegacyTargets(t)],[])}findTarget(e){const t=this.getSelectorForTargetName(e);return this.scope.findElement(t)}findAllTargets(e){const t=this.getSelectorForTargetName(e);return this.scope.findAllElements(t)}getSelectorForTargetName(e){return $(this.schema.targetAttributeForScope(this.identifier),e)}findLegacyTarget(e){const t=this.getLegacySelectorForTargetName(e);return this.deprecate(this.scope.findElement(t),e)}findAllLegacyTargets(e){const t=this.getLegacySelectorForTargetName(e);return this.scope.findAllElements(t).map(t=>this.deprecate(t,e))}getLegacySelectorForTargetName(e){const t=`${this.identifier}.${e}`;return $(this.schema.targetAttribute,t)}deprecate(e,t){if(e){const{identifier:s}=this,i=this.schema.targetAttribute,n=this.schema.targetAttributeForScope(s);this.guide.warn(e,`target:${t}`,`Please replace ${i}="${s}.${t}" with ${n}="${t}". The ${i} attribute is deprecated and will be removed in a future version of Stimulus.`)}return e}get guide(){return this.scope.guide}}class q{constructor(e,t){this.scope=e,this.controllerElement=t}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce((e,t)=>e||this.findOutlet(t),void 0)}findAll(...e){return e.reduce((e,t)=>[...e,...this.findAllOutlets(t)],[])}getSelectorForOutletName(e){const t=this.schema.outletAttributeForScope(this.identifier,e);return this.controllerElement.getAttribute(t)}findOutlet(e){const t=this.getSelectorForOutletName(e);if(t)return this.findElement(t,e)}findAllOutlets(e){const t=this.getSelectorForOutletName(e);return t?this.findAllElements(t,e):[]}findElement(e,t){return this.scope.queryElements(e).filter(s=>this.matchesElement(s,e,t))[0]}findAllElements(e,t){return this.scope.queryElements(e).filter(s=>this.matchesElement(s,e,t))}matchesElement(e,t,s){const i=e.getAttribute(this.scope.schema.controllerAttribute)||"";return e.matches(t)&&i.split(" ").includes(s)}}class U{constructor(e,t,s,i){this.targets=new V(this),this.classes=new D(this),this.data=new j(this),this.containsElement=e=>e.closest(this.controllerSelector)===this.element,this.schema=e,this.element=t,this.identifier=s,this.guide=new B(i),this.outlets=new q(this.documentScope,t)}findElement(e){return this.element.matches(e)?this.element:this.queryElements(e).find(this.containsElement)}findAllElements(e){return[...this.element.matches(e)?[this.element]:[],...this.queryElements(e).filter(this.containsElement)]}queryElements(e){return Array.from(this.element.querySelectorAll(e))}get controllerSelector(){return $(this.schema.controllerAttribute,this.identifier)}get isDocumentScope(){return this.element===document.documentElement}get documentScope(){return this.isDocumentScope?this:new U(this.schema,document.documentElement,this.identifier,this.guide.logger)}}class z{constructor(e,t,s){this.element=e,this.schema=t,this.delegate=s,this.valueListObserver=new E(this.element,this.controllerAttribute,this),this.scopesByIdentifierByElement=new WeakMap,this.scopeReferenceCounts=new WeakMap}start(){this.valueListObserver.start()}stop(){this.valueListObserver.stop()}get controllerAttribute(){return this.schema.controllerAttribute}parseValueForToken(e){const{element:t,content:s}=e;return this.parseValueForElementAndIdentifier(t,s)}parseValueForElementAndIdentifier(e,t){const s=this.fetchScopesByIdentifierForElement(e);let i=s.get(t);return i||(i=this.delegate.createScopeForElementAndIdentifier(e,t),s.set(t,i)),i}elementMatchedValue(e,t){const s=(this.scopeReferenceCounts.get(t)||0)+1;this.scopeReferenceCounts.set(t,s),1==s&&this.delegate.scopeConnected(t)}elementUnmatchedValue(e,t){const s=this.scopeReferenceCounts.get(t);s&&(this.scopeReferenceCounts.set(t,s-1),1==s&&this.delegate.scopeDisconnected(t))}fetchScopesByIdentifierForElement(e){let t=this.scopesByIdentifierByElement.get(e);return t||(t=new Map,this.scopesByIdentifierByElement.set(e,t)),t}}class W{constructor(e){this.application=e,this.scopeObserver=new z(this.element,this.schema,this),this.scopesByIdentifier=new S,this.modulesByIdentifier=new Map}get element(){return this.application.element}get schema(){return this.application.schema}get logger(){return this.application.logger}get controllerAttribute(){return this.schema.controllerAttribute}get modules(){return Array.from(this.modulesByIdentifier.values())}get contexts(){return this.modules.reduce((e,t)=>e.concat(t.contexts),[])}start(){this.scopeObserver.start()}stop(){this.scopeObserver.stop()}loadDefinition(e){this.unloadIdentifier(e.identifier);const t=new R(this.application,e);this.connectModule(t);const s=e.controllerConstructor.afterLoad;s&&s.call(e.controllerConstructor,e.identifier,this.application)}unloadIdentifier(e){const t=this.modulesByIdentifier.get(e);t&&this.disconnectModule(t)}getContextForElementAndIdentifier(e,t){const s=this.modulesByIdentifier.get(t);if(s)return s.contexts.find(t=>t.element==e)}proposeToConnectScopeForElementAndIdentifier(e,t){const s=this.scopeObserver.parseValueForElementAndIdentifier(e,t);s?this.scopeObserver.elementMatchedValue(s.element,s):console.error(`Couldn't find or create scope for identifier: "${t}" and element:`,e)}handleError(e,t,s){this.application.handleError(e,t,s)}createScopeForElementAndIdentifier(e,t){return new U(this.schema,e,t,this.logger)}scopeConnected(e){this.scopesByIdentifier.add(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.connectContextForScope(e)}scopeDisconnected(e){this.scopesByIdentifier.delete(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.disconnectContextForScope(e)}connectModule(e){this.modulesByIdentifier.set(e.identifier,e),this.scopesByIdentifier.getValuesForKey(e.identifier).forEach(t=>e.connectContextForScope(t))}disconnectModule(e){this.modulesByIdentifier.delete(e.identifier),this.scopesByIdentifier.getValuesForKey(e.identifier).forEach(t=>e.disconnectContextForScope(t))}}const H={controllerAttribute:"data-controller",actionAttribute:"data-action",targetAttribute:"data-target",targetAttributeForScope:e=>`data-${e}-target`,outletAttributeForScope:(e,t)=>`data-${e}-${t}-outlet`,keyMappings:Object.assign(Object.assign({enter:"Enter",tab:"Tab",esc:"Escape",space:" ",up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",home:"Home",end:"End",page_up:"PageUp",page_down:"PageDown"},K("abcdefghijklmnopqrstuvwxyz".split("").map(e=>[e,e]))),K("0123456789".split("").map(e=>[e,e])))};function K(e){return e.reduce((e,[t,s])=>Object.assign(Object.assign({},e),{[t]:s}),{})}class G{constructor(e=document.documentElement,t=H){this.logger=console,this.debug=!1,this.logDebugActivity=(e,t,s={})=>{this.debug&&this.logFormattedMessage(e,t,s)},this.element=e,this.schema=t,this.dispatcher=new n(this),this.router=new W(this),this.actionDescriptorFilters=Object.assign({},r)}static start(e,t){const s=new this(e,t);return s.start(),s}async start(){await new Promise(e=>{"loading"==document.readyState?document.addEventListener("DOMContentLoaded",()=>e()):e()}),this.logDebugActivity("application","starting"),this.dispatcher.start(),this.router.start(),this.logDebugActivity("application","start")}stop(){this.logDebugActivity("application","stopping"),this.dispatcher.stop(),this.router.stop(),this.logDebugActivity("application","stop")}register(e,t){this.load({identifier:e,controllerConstructor:t})}registerActionOption(e,t){this.actionDescriptorFilters[e]=t}load(e,...t){(Array.isArray(e)?e:[e,...t]).forEach(e=>{e.controllerConstructor.shouldLoad&&this.router.loadDefinition(e)})}unload(e,...t){(Array.isArray(e)?e:[e,...t]).forEach(e=>this.router.unloadIdentifier(e))}get controllers(){return this.router.contexts.map(e=>e.controller)}getControllerForElementAndIdentifier(e,t){const s=this.router.getContextForElementAndIdentifier(e,t);return s?s.controller:null}handleError(e,t,s){var i;this.logger.error("%s\n\n%o\n\n%o",t,e,s),null===(i=window.onerror)||void 0===i||i.call(window,t,"",0,0,e)}logFormattedMessage(e,t,s={}){s=Object.assign({application:this},s),this.logger.groupCollapsed(`${e} #${t}`),this.logger.log("details:",Object.assign({},s)),this.logger.groupEnd()}}function J(e,t,s){return e.application.getControllerForElementAndIdentifier(t,s)}function Y(e,t,s){let i=J(e,t,s);return i||(e.application.router.proposeToConnectScopeForElementAndIdentifier(t,s),i=J(e,t,s),i||void 0)}function Z([e,t],s){return function(e){const{token:t,typeDefinition:s}=e,i=`${h(t)}-value`,n=function(e){const{controller:t,token:s,typeDefinition:i}=e,n=function(e){const{controller:t,token:s,typeObject:i}=e,n=u(i.type),r=u(i.default),a=n&&r,o=n&&!r,c=!n&&r,l=X(i.type),h=Q(e.typeObject.default);if(o)return l;if(c)return h;if(l!==h)throw new Error(`The specified default value for the Stimulus Value "${t?`${t}.${s}`:s}" must match the defined type "${l}". The provided default value of "${i.default}" is of type "${h}".`);return a?l:void 0}({controller:t,token:s,typeObject:i}),r=Q(i),a=X(i),o=n||r||a;if(o)return o;throw new Error(`Unknown value type "${t?`${t}.${i}`:s}" for "${s}" value`)}(e);return{type:n,key:i,name:o(i),get defaultValue(){return function(e){const t=X(e);if(t)return ee[t];const s=d(e,"default"),i=d(e,"type"),n=e;if(s)return n.default;if(i){const{type:e}=n,t=X(e);if(t)return ee[t]}return e}(s)},get hasCustomDefaultValue(){return void 0!==Q(s)},reader:te[n],writer:se[n]||se.default}}({controller:s,token:e,typeDefinition:t})}function X(e){switch(e){case Array:return"array";case Boolean:return"boolean";case Number:return"number";case Object:return"object";case String:return"string"}}function Q(e){switch(typeof e){case"boolean":return"boolean";case"number":return"number";case"string":return"string"}return Array.isArray(e)?"array":"[object Object]"===Object.prototype.toString.call(e)?"object":void 0}const ee={get array(){return[]},boolean:!1,number:0,get object(){return{}},string:""},te={array(e){const t=JSON.parse(e);if(!Array.isArray(t))throw new TypeError(`expected value of type "array" but instead got value "${e}" of type "${Q(t)}"`);return t},boolean:e=>!("0"==e||"false"==String(e).toLowerCase()),number:e=>Number(e.replace(/_/g,"")),object(e){const t=JSON.parse(e);if(null===t||"object"!=typeof t||Array.isArray(t))throw new TypeError(`expected value of type "object" but instead got value "${e}" of type "${Q(t)}"`);return t},string:e=>e},se={default:function(e){return`${e}`},array:ie,object:ie};function ie(e){return JSON.stringify(e)}class ne{constructor(e){this.context=e}static get shouldLoad(){return!0}static afterLoad(e,t){}get application(){return this.context.application}get scope(){return this.context.scope}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get targets(){return this.scope.targets}get outlets(){return this.scope.outlets}get classes(){return this.scope.classes}get data(){return this.scope.data}initialize(){}connect(){}disconnect(){}dispatch(e,{target:t=this.element,detail:s={},prefix:i=this.identifier,bubbles:n=!0,cancelable:r=!0}={}){const a=new CustomEvent(i?`${i}:${e}`:e,{detail:s,bubbles:n,cancelable:r});return t.dispatchEvent(a),a}}ne.blessings=[function(e){return I(e,"classes").reduce((e,t)=>{return Object.assign(e,(s=t,{[`${s}Class`]:{get(){const{classes:e}=this;if(e.has(s))return e.get(s);{const t=e.getAttributeName(s);throw new Error(`Missing attribute "${t}"`)}}},[`${s}Classes`]:{get(){return this.classes.getAll(s)}},[`has${l(s)}Class`]:{get(){return this.classes.has(s)}}}));var s},{})},function(e){return I(e,"targets").reduce((e,t)=>{return Object.assign(e,(s=t,{[`${s}Target`]:{get(){const e=this.targets.find(s);if(e)return e;throw new Error(`Missing target element "${s}" for "${this.identifier}" controller`)}},[`${s}Targets`]:{get(){return this.targets.findAll(s)}},[`has${l(s)}Target`]:{get(){return this.targets.has(s)}}}));var s},{})},function(e){const t=function(e,t){return L(e).reduce((e,s)=>(e.push(...function(e,t){const s=e[t];return s?Object.keys(s).map(e=>[e,s[e]]):[]}(s,t)),e),[])}(e,"values"),s={valueDescriptorMap:{get(){return t.reduce((e,t)=>{const s=Z(t,this.identifier),i=this.data.getAttributeNameForKey(s.key);return Object.assign(e,{[i]:s})},{})}}};return t.reduce((e,t)=>Object.assign(e,function(e){const t=Z(e,void 0),{key:s,name:i,reader:n,writer:r}=t;return{[i]:{get(){const e=this.data.get(s);return null!==e?n(e):t.defaultValue},set(e){void 0===e?this.data.delete(s):this.data.set(s,r(e))}},[`has${l(i)}`]:{get(){return this.data.has(s)||t.hasCustomDefaultValue}}}}(t)),s)},function(e){return I(e,"outlets").reduce((e,t)=>Object.assign(e,function(e){const t=c(e);return{[`${t}Outlet`]:{get(){const t=this.outlets.find(e),s=this.outlets.getSelectorForOutletName(e);if(t){const s=Y(this,t,e);if(s)return s;throw new Error(`The provided outlet element is missing an outlet controller "${e}" instance for host controller "${this.identifier}"`)}throw new Error(`Missing outlet element "${e}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${s}".`)}},[`${t}Outlets`]:{get(){const t=this.outlets.findAll(e);return t.length>0?t.map(t=>{const s=Y(this,t,e);if(s)return s;console.warn(`The provided outlet element is missing an outlet controller "${e}" instance for host controller "${this.identifier}"`,t)}).filter(e=>e):[]}},[`${t}OutletElement`]:{get(){const t=this.outlets.find(e),s=this.outlets.getSelectorForOutletName(e);if(t)return t;throw new Error(`Missing outlet element "${e}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${s}".`)}},[`${t}OutletElements`]:{get(){return this.outlets.findAll(e)}},[`has${l(t)}Outlet`]:{get(){return this.outlets.has(e)}}}}(t)),{})}],ne.targets=[],ne.outlets=[],ne.values={}},434(e,t,s){s.d(t,{default:()=>ri});var i=s(891);class n extends Error{constructor(e){super(`${e} is not valid. Please provide a valid event name`),this.name="InvalidEvent"}}class r{static events=["session-set","utm-set","forms:collected","form:completed","alert:shown","alert:dismissed","alert:accepted","webchat:mounted","webchat:opened","webchat:closed","webchat:message:sent","webchat:message:received","cart.added"];static valid(e){return r.exists(e)}static invalid(e){return!this.valid(e)}static exists(e){return void 0!==this.events.find(t=>t===e)}constructor(){this.subscribers={}}addSubscriber(e,t){if(r.invalid(e))throw new n(e);this.subscribers={...this.subscribers,[e]:this.subscribers[e]?[...this.subscribers[e],t]:[t]}}removeSubscriber(e,t){if(r.invalid(e))throw new n(e);this.subscribers[e]&&(this.subscribers[e]=this.subscribers[e].filter(e=>e!==t))}dispatch(e,t){this.subscribers[e]?.forEach(e=>{e(t)})}get listeners(){return 0!==Object.keys(this.subscribers).length}}class a{static autoMount=!0;static successMessage=!0;static assign(e){return e&&Object.entries(e).forEach(([e,t])=>{this[e]=t}),this}static get shouldShowSuccessMessage(){return this.successMessage}}class o{static _identifier;static set identifier(e){this._identifier=e}static get identifier(){return this._identifier?this._identifier:this.#e||this.#t||this.#s||"en"}static toString(){return this.identifier}static get#e(){return document?.documentElement?.lang}static get#t(){return document?.querySelector('meta[name="locale"]')?.content}static get#s(){return navigator?.language?.split("-")[0]}}const c={TOP_LEFT:"top-left",TOP_RIGHT:"top-right",BOTTOM_LEFT:"bottom-left",BOTTOM_RIGHT:"bottom-right"},l={ABSOLUTE:"absolute",FIXED:"fixed"},h={MODAL:"modal",POPOVER:"popover"};class u{static _id;static _container="body";static _placement="bottom-right";static _style={};static _appearance={};static _whatsapp={};static _mode=h.POPOVER;static _behaviour=null;static _hasBehaviourOverride=!1;static _strategy=null;static set container(e){this._container=e}static get container(){return this._container}static set placement(e){if(!Object.values(c).includes(e))throw new Error(`Invalid placement value: ${e}`);this._placement=e}static get placement(){return this._placement}static set id(e){this._id=e}static get id(){return this._id}static get isSet(){return!!this._id}static get style(){return this._style}static set style(e){if("object"!=typeof e)throw new Error("Style must be an object");Object.entries(e).forEach(([e,t])=>{if(!["primaryColor","secondaryColor","typography"].includes(e))throw new Error(`Invalid style property: ${e}`);if("typography"!==e&&!this.isHexOrRgba(t))throw new Error(`Invalid color value: ${t} for ${e}. Colors must be hex or rgb/a.`)}),this._style=e}static get appearance(){return this._appearance}static set appearance(e){if(!this.isPlainObject(e))throw new Error("Appearance must be an object");Object.entries(e).forEach(([e,t])=>{if(!["header","launcher"].includes(e))throw new Error(`Invalid appearance property: ${e}`);if(!this.isPlainObject(t))throw new Error(`Appearance ${e} must be an object`);Object.entries(t).forEach(([t,s])=>{if("header"===e&&"name"!==t)throw new Error(`Invalid appearance header property: ${t}`);if("launcher"===e&&"iconUrl"!==t)throw new Error(`Invalid appearance launcher property: ${t}`);if(null!=s&&"string"!=typeof s)throw new Error(`Invalid appearance ${e}.${t} value: ${s}`)})}),this._appearance=e}static get whatsapp(){return this._whatsapp}static set whatsapp(e){if(!this.isPlainObject(e))throw new Error("WhatsApp must be an object");Object.entries(e).forEach(([e,t])=>{if(!["number","restrictToChannel"].includes(e))throw new Error(`Invalid WhatsApp property: ${e}`);if(null!=t){if("number"===e&&"string"!=typeof t)throw new Error(`Invalid WhatsApp number value: ${t}`);if("restrictToChannel"===e&&"boolean"!=typeof t)throw new Error(`Invalid WhatsApp restrictToChannel value: ${t}`)}}),this._whatsapp=e}static get mode(){return this._mode}static set mode(e){if(!Object.values(h).includes(e))throw new Error(`Invalid mode value: ${e}`);this._mode=e}static get behaviour(){return this._behaviour}static set behaviour(e){if(null!=e){if("object"!=typeof e||Array.isArray(e))throw new Error(`Invalid behaviour value: ${e}`);this._behaviour=e}else this._behaviour=e}static get hasBehaviourOverride(){return this._hasBehaviourOverride}static set behaviourOverride(e){this._hasBehaviourOverride=!!e}static get strategy(){return this._strategy?this._strategy:"body"==this.container?l.FIXED:l.ABSOLUTE}static set strategy(e){if(e&&!Object.values(l).includes(e))throw new Error(`Invalid strategy value: ${e}`);this._strategy=e}static assign(e){return e&&Object.entries(e).forEach(([e,t])=>{this[e]=t}),this}static isHexOrRgba(e){return/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(e)||/^rgba?\(\s*\d{1,3},\s*\d{1,3},\s*\d{1,3},?\s*(0|1|0?\.\d+)?\s*\)$/.test(e)}static isPlainObject(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}}const d={TOP_LEFT:"top-left",TOP_RIGHT:"top-right",BOTTOM_LEFT:"bottom-left",BOTTOM_RIGHT:"bottom-right"};class p{static _id;static _container="body";static _placement="bottom-right";static _appearance={};static _number=null;static _body=null;static set id(e){this._id=e}static get id(){return this._id}static set container(e){this._container=e}static get container(){return this._container}static set placement(e){if(!Object.values(d).includes(e))throw new Error(`Invalid placement value: ${e}`);this._placement=e}static get placement(){return this._placement}static get appearance(){return this._appearance}static set appearance(e){if(!this.isPlainObject(e))throw new Error("Appearance must be an object");Object.entries(e).forEach(([e,t])=>{if("launcher"!==e)throw new Error(`Invalid appearance property: ${e}`);if(!this.isPlainObject(t))throw new Error(`Appearance ${e} must be an object`);Object.entries(t).forEach(([t,s])=>{if("iconUrl"!==t)throw new Error(`Invalid appearance launcher property: ${t}`);if(null!=s&&"string"!=typeof s)throw new Error(`Invalid appearance ${e}.${t} value: ${s}`)})}),this._appearance=e}static get number(){return this._number}static set number(e){if(null!=e&&"string"!=typeof e)throw new Error(`Invalid number value: ${e}`);this._number=e}static get body(){return this._body}static set body(e){if(null!=e&&"string"!=typeof e)throw new Error(`Invalid body value: ${e}`);this._body=e}static assign(e){return e&&Object.entries(e).forEach(([e,t])=>{this[e]=t}),this}static isPlainObject(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}}class m{static serviceWorkerUrl=null;static channelId=null;static assign(e){return this.serviceWorkerUrl=e?.serviceWorkerUrl||null,this.channelId=e?.channelId||null,this}}class g{static apiRoot="https://api.hellotext.com/v1";static actionCableUrl="wss://www.hellotext.com/cable";static autoGenerateSession=!0;static session=null;static forms=a;static webchat=u;static whatsapp=p;static push=m;static assign(e){if(e){const t=Object.prototype.hasOwnProperty.call(e,"apiRoot")&&!Object.prototype.hasOwnProperty.call(e,"actionCableUrl");Object.entries(e).forEach(([e,t])=>{"forms"===e?this.forms=a.assign(t):"webchat"===e?this.webchat=u.assign(t):"whatsappWidget"===e?this.whatsapp=p.assign(t):"push"===e?this.push=m.assign(t):this[e]=t}),t&&(this.actionCableUrl=this.actionCableUrlForApiRoot(this.apiRoot))}return this}static set locale(e){o.identifier=e}static get locale(){return o.toString()}static endpoint(e){return`${this.apiRoot}/${e}`}static actionCableUrlForApiRoot(e){try{const t=new URL(e),s="https:"===t.protocol?"wss:":"ws:";return t.protocol=s,t.pathname="/cable",t.search="",t.hash="",t.toString()}catch(e){return this.actionCableUrl}}}const f=class{static get endpoint(){return g.endpoint("public/businesses")}static async get(e){return fetch(`${this.endpoint}/${e}`,{method:"GET",headers:{Authorization:`Bearer ${e}`,Accept:"application/json","Content-Type":"application/json"}})}};class b{static get inPreviewMode(){return(new this).inPreviewMode}constructor(){this.urlSearchParams=new URLSearchParams(window.location.search)}get(e){return this.urlSearchParams.get(this.toHellotextParam(e))}has(e){return this.urlSearchParams.has(this.toHellotextParam(e))}get inPreviewMode(){return this.has("preview")}get session(){return this.get("session")}toHellotextParam(e){return`hello_${e}`}}class y{#i;constructor(e,t){this.response=t,this.#i=e}get data(){return this.response}async json(){return await this.response.json()}get failed(){return!1===this.#i}get succeeded(){return!0===this.#i}}class v{static get endpoint(){return g.endpoint("track/events")}static async create({headers:e,body:t,keepalive:s=!1}){if(b.inPreviewMode)return new y(!0,{received:!0});const i={method:"POST",headers:e,body:JSON.stringify(t)};s&&(i.keepalive=!0);const n=await fetch(this.endpoint,i);return new y(200===n.status,await n.json())}}class w{static get endpoint(){return g.endpoint("public/forms")}static async get(e){const t=new URL(`${this.endpoint}/${e}`);return t.searchParams.append("session",bt.session),t.searchParams.append("locale",o.toString()),fetch(t,{method:"GET",headers:bt.headers})}static async submit(e,t){const s=await fetch(`${this.endpoint}/${e}/submissions`,{method:"POST",headers:bt.headers,body:JSON.stringify({session:bt.session,...t})});return new y(s.ok,s)}}const T=class{static get endpoint(){return g.endpoint("public/identifications")}static async create(e={}){const t=await fetch(this.endpoint,{method:"POST",headers:bt.headers,body:JSON.stringify({session:bt.session,...e})});return new y(t.ok,t)}},S=class{static get endpoint(){return g.endpoint("public/webchats")}static async get(e){const t=new URL(`${this.endpoint}/${e}`);t.searchParams.append("session",bt.session),t.searchParams.append("locale",o.toString()),Object.entries(g.webchat.style).forEach(([e,s])=>{t.searchParams.append(`style[${e}]`,s)}),this.appendWebchatOverrides(t),t.searchParams.append("placement",g.webchat.placement);const s=await fetch(t,{method:"GET",headers:bt.headers}),i=await s.json();return bt.business.data||(bt.business.setData(i.business),bt.business.setLocale(i.locale)),(new DOMParser).parseFromString(i.html,"text/html").querySelector("article")}static appendWebchatOverrides(e){const{appearance:t,whatsapp:s}=g.webchat;this.appendIfSupplied(e,"webchat[appearance][header][name]",t.header?.name),this.appendIfSupplied(e,"webchat[appearance][launcher][icon_url]",t.launcher?.iconUrl),this.appendIfSupplied(e,"webchat[handoff][identifier]",s.number),this.appendIfSupplied(e,"webchat[handoff][restrict_to_channel]",s.restrictToChannel)}static appendIfSupplied(e,t,s){null!=s&&e.searchParams.append(t,String(s))}},C=class{static get endpoint(){return g.endpoint("public/widgets/whatsapp")}static async get(e){const t=new URL(`${this.endpoint}/${e}`);t.searchParams.append("locale",o.toString()),t.searchParams.append("placement",g.whatsapp.placement),this.appendWhatsAppOverrides(t);const s=await this.fetchWidget(t);if(!s.ok)return null;const i=await this.parseWidgetResponse(s);return i?(bt.business.data||(bt.business.setData(i.business),bt.business.setLocale(i.locale)),(new DOMParser).parseFromString(i.html,"text/html").querySelector("article")):null}static appendWhatsAppOverrides(e){const{appearance:t,body:s,number:i}=g.whatsapp;this.appendIfSupplied(e,"whatsapp[appearance][launcher][icon_url]",t.launcher?.iconUrl),this.appendIfSupplied(e,"whatsapp[number]",i),this.appendIfSupplied(e,"whatsapp[body]",s)}static appendIfSupplied(e,t,s){null!=s&&e.searchParams.append(t,String(s))}static async fetchWidget(e){try{return await fetch(e,{method:"GET",headers:bt.headers})}catch(e){return{ok:!1}}}static async parseWidgetResponse(e){try{return await e.json()}catch(e){return null}}},O=class{static get endpoint(){return g.endpoint("public/acks")}static async send(e={}){const t={...e,session:bt.session,at:(new Date).toISOString()};fetch(this.endpoint,{method:"POST",headers:bt.headers,body:JSON.stringify(t),keepalive:!0})}},A=class{static get endpoint(){return g.endpoint("public/push/identities")}static async create(e={}){const t=await fetch(this.endpoint,{method:"POST",keepalive:!0,headers:bt.headers,body:JSON.stringify({...e,session:bt.session,origin:window.location.origin})});return new y(t.ok,t)}static async destroy(e={}){const t=await fetch(this.endpoint,{method:"DELETE",keepalive:!0,headers:bt.headers,body:JSON.stringify({...e,session:bt.session,origin:window.location.origin})});return new y(t.ok,t)}},E=class{static get endpoint(){return g.endpoint("public/push/alerts")}static async create({section:e,kind:t}){const s=await fetch(this.endpoint,{method:"POST",keepalive:!0,headers:bt.headers,body:JSON.stringify({session:bt.session,section:e,kind:t})});return new y(s.ok,s)}};function x(e){const t=JSON.stringify(e);return"undefined"==typeof Blob?t.length<6e4:new Blob([t]).size<6e4}class M{static get businesses(){return f}static get events(){return v}static get forms(){return w}static get webchats(){return S}static get whatsappWidgets(){return C}static get identifications(){return T}static get acks(){return O}static get pushAlerts(){return E}static get pushIdentities(){return A}}const k={en:{white_label:{powered_by:"By"},errors:{parameter_not_unique:"This value is taken.",blank:"This field is required."},forms:{phone:"Click the link sent via SMS to verify your submission.",email:"Click the link sent via email to verify your submission.",phone_and_email:"Click the links sent via SMS and email to verify your submission.",none:"Your submission has been received."}},es:{white_label:{powered_by:"Por"},errors:{parameter_not_unique:"Este valor ya está en uso.",blank:"Este campo es obligatorio."},forms:{phone:"Haga clic en el enlace enviado por SMS para verificar su envío.",email:"Haga clic en el enlace enviado por e-mail para verificar su envío.",phone_and_email:"Haga clic en los enlaces enviados por SMS y e-mail para verificar su envío.",none:"Su envío ha sido recibido."}}},I="data-hellotext-stylesheet";class L{constructor(e){this.id=e,this.data=null,this.stylesheet=null,this.stylesheetLoaded=Promise.resolve(!1)}async hydrate(){try{const e=await f.get(this.id);if(!1===e.ok)return null;const t=await e.json();return t?(this.setData(t),t.locale&&this.setLocale(t.locale),t):null}catch(e){return null}}setData(e){this.data=e,"undefined"!=typeof document&&e.style_url?(this.stylesheet=this.constructor.ensureStylesheet(e.style_url),this.stylesheetLoaded=this.constructor.waitForStylesheet(this.stylesheet)):(this.stylesheet=null,this.stylesheetLoaded=Promise.resolve(!1))}static get stylesheetSelector(){return`link[rel="stylesheet"][${I}]`}static ensureStylesheet(e){const t=this.normalizedStylesheetUrl(e),s=this.stylesheetLinks.find(e=>e.href===t);if(s)return s.setAttribute(I,"true"),s;const i=document.createElement("link");return i.rel="stylesheet",i.href=e,i.setAttribute(I,"true"),this.waitForStylesheet(i),document.head.append(i),i}static get stylesheetLinks(){return"undefined"==typeof document?[]:Array.from(document.querySelectorAll(this.stylesheetSelector))}static get latestStylesheet(){return this.stylesheetLinks[this.stylesheetLinks.length-1]}static normalizedStylesheetUrl(e){try{return new URL(e,document.baseURI).href}catch(t){return e}}static waitForStylesheet(e){return e?this.stylesheetIsLoaded(e)?Promise.resolve(!0):"false"===e.dataset.hellotextStylesheetLoaded?Promise.resolve(!1):(e._hellotextStylesheetLoaded||(e._hellotextStylesheetLoaded=new Promise(t=>{let s;const i=i=>{clearTimeout(s),e.removeEventListener("load",n),e.removeEventListener("error",r),e.dataset.hellotextStylesheetLoaded=i?"true":"false",t(i)},n=()=>i(this.stylesheetIsLoaded(e)),r=()=>i(!1);e.addEventListener("load",n),e.addEventListener("error",r),s=setTimeout(()=>i(this.stylesheetIsLoaded(e)),1e4),s.unref&&s.unref()})),e._hellotextStylesheetLoaded):Promise.resolve(!1)}static stylesheetIsLoaded(e){return"true"===e.dataset.hellotextStylesheetLoaded||!!e.sheet}get subscription(){return this.data.subscription}get country(){return this.data.country}get enabledWhitelist(){return"disabled"!==this.data.whitelist}setLocale(e){if(!k[e])return console.warn(`Locale ${e} not found`);this.data||(this.data={}),this.data.locale=e}get locale(){return k[this.data.locale]}get features(){return this.data.features}}class _{static set(e,t){if("undefined"!=typeof document){const s="https:"===window.location.protocol?"; Secure":"",i=P.getRootDomain(),n=31536e4;document.cookie=i?`${e}=${t}; path=/${s}; domain=${i}; max-age=${n}; SameSite=Lax`:`${e}=${t}; path=/${s}; max-age=${n}; SameSite=Lax`}return"hello_session"===e&&bt.eventEmitter.dispatch("session-set",t),"hello_utm"===e&&bt.eventEmitter.dispatch("utm-set",t),t}static get(e){return"undefined"!=typeof document?document.cookie.match("(^|;)\\s*"+e+"\\s*=\\s*([^;]+)")?.pop():void 0}static delete(e){if("undefined"!=typeof document){const t=P.getRootDomain(),s="https:"===window.location.protocol?"; Secure":"";document.cookie=t?`${e}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT${s}; domain=${t}; SameSite=Lax`:`${e}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT${s}; SameSite=Lax`}}}class N{constructor(){const e=new URLSearchParams(window.location.search),t={source:e.get("utm_source"),medium:e.get("utm_medium"),campaign:e.get("utm_campaign"),term:e.get("utm_term"),content:e.get("utm_content")};this.save(t)}save(e){if(!e.source||!e.medium)return;const t=Object.fromEntries(Object.entries(e).filter(([e,t])=>t));t.observed_at=(new Date).toISOString(),_.set("hello_utm",JSON.stringify(t))}get current(){try{return JSON.parse(_.get("hello_utm"))||{}}catch(e){return{}}}}class P{constructor(e=null){this.utm=new N,this._url=e}get url(){return null!==this._url&&void 0!==this._url?this._url:window.location.href}get title(){return document.title}get path(){if(this._url)try{return new URL(this._url).pathname}catch(e){return"/"}return window.location.pathname}get utmParams(){return this.utm.current}get trackingData(){return{page:{url:this.url,title:this.title,path:this.path},utm_params:this.utmParams}}get domain(){try{const e=this.url;if(!e)return null;const t=new URL(e).hostname;return P.getRootDomain(t)}catch(e){return null}}static getRootDomain(e=null){try{if(!e){if("undefined"==typeof window||!window.location?.hostname)return null;e=window.location.hostname}const t=e.split(".");if(t.length<=1)return e;const s=["myshopify.com","vtexcommercestable.com.br","myvtex.com","wixsite.com"];for(const e of s){const s=e.split(".");if(t.slice(-s.length).join(".")===e&&t.length>s.length)return`.${t.slice(-(s.length+1)).join(".")}`}const i=t[t.length-1],n=t[t.length-2];return t.length>2&&2===i.length&&n.length<=3?`.${t.slice(-3).join(".")}`:`.${t.slice(-2).join(".")}`}catch(e){return null}}}class F{static#n;static#r;static#a;static get session(){return this.#n}static get ackPayload(){return{utm_params:this.#a?.utmParams||{}}}static set session(e){const t=_.get("hello_session");return this.#n=e,_.set("hello_session",e),t!==e&&_.delete("hello_session_ack_at"),_.get("hello_session_ack_at")||(M.acks.send(this.ackPayload),_.set("hello_session_ack_at",(new Date).toISOString())),this.#n}static initialize(e=new P){this.#a=e,this.#r=new b,this.session=this.#r.session||g.session||_.get("hello_session"),!this.session&&g.autoGenerateSession&&(this.session=crypto.randomUUID())}}class R{static build(e){const t=document.createElement("article"),s=document.createElement("label"),i=document.createElement("input");s.innerText=e.label,i.type=e.type,i.required=e.required,i.placeholder=e.placeholder,["first_name","last_name"].includes(e.kind)?(i.type="text",i.id=i.name=e.kind,s.setAttribute("for",e.kind)):(i.type=e.type,"email"===e.type?(i.id=i.name="email",s.setAttribute("for","email")):"tel"===i.type?(i.id=i.name="phone",s.setAttribute("for","phone"),i.value=`+${bt.business.country.prefix}`,i.setAttribute("data-default-value",`+${bt.business.country.prefix}`)):(i.name=i.id=`property_by_id[${e.property}]`,s.setAttribute("for",`property_by_id[${e.property}]`)));const n=document.createElement("main");n.appendChild(s),n.appendChild(i),t.appendChild(n),t.setAttribute("data-hellotext--form-target","inputContainer"),i.setAttribute("data-hellotext--form-target","input");const r=document.createElement("div");return r.setAttribute("data-error-container",""),t.appendChild(r),t}}class D{static build(){const e=document.createElement("div");return e.innerHTML=this.#o(),e.firstElementChild}static#o(){const e=`https://www.hellotext.com?hello_session=${bt.session}`;return`\n
\n ${bt.business.locale.white_label.powered_by}\n\n \n \n Hellotext\n \n \n \n
\n `}}function j(e,t){(null==t||t>e.length)&&(t=e.length);for(var s=0,i=Array(t);s2?s-2:0),n=2;n1?t-1:0),i=1;i1?s-1:0),n=1;n2&&void 0!==arguments[2]?arguments[2]:ie;if(V&&V(e,null),!se(t))return e;let i=t.length;for(;i--;){let n=t[i];if("string"==typeof n){const e=s(n);e!==n&&(q(t)||(t[i]=e),n=e)}e[n]=!0}return e}function we(e){for(let t=0;t/g),Re=H(/\${[\w\W]*/g),De=H(/^data-[\-\w.\u00B7-\uFFFF]+$/),je=H(/^aria-[\-\w]+$/),Be=H(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),$e=H(/^(?:\w+script|data):/i),Ve=H(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),qe=H(/^html$/i),Ue=H(/^[a-z][.\w]*(-[.\w]+)+$/i),ze=H(/<[/\w!]/g),We=H(/<[/\w]/g),He=H(/<\/no(script|embed|frames)/i),Ke=H(/\/>/i),Ge=["style","script","xmp","iframe","noembed","noframes","plaintext","noscript"],Je=W(ve({},Ge)),Ye=function(){const e={};return Z(Ge,t=>{e[t]=H(new RegExp("])","i"))}),W(e)}(),Ze=function(){return"undefined"==typeof window?null:window},Xe=function(e,t,s,i){return pe(e,t)&&se(e[t])?ve(i.base?Te(i.base):{},e[t],i.transform):s},Qe=function(e,t,s){const i=pe(e,t)?e[t]:void 0;return i&&"object"==typeof i?Te(i):s()};var et=function e(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Ze();const s=t=>e(t);if(s.version="3.4.14",s.removed=[],!t||!t.document||9!==t.document.nodeType||!t.Element)return s.isSupported=!1,s;let i=t.document;const n=i,r=n.currentScript;t.DocumentFragment;const a=t.HTMLTemplateElement,o=t.Node,c=t.Element,l=t.NodeFilter;void 0===t.NamedNodeMap&&(t.NamedNodeMap||t.MozNamedAttrMap),t.HTMLFormElement;const h=t.DOMParser,u=t.trustedTypes,d=c.prototype,p=Se(d,"cloneNode"),m=Se(d,"remove"),g=Se(d,"nextSibling"),f=Se(d,"childNodes"),b=Se(d,"parentNode"),y=Se(d,"shadowRoot"),v=Se(d,"attributes"),w=o&&o.prototype?Se(o.prototype,"nodeType"):null,T=o&&o.prototype?Se(o.prototype,"nodeName"):null,S=o&&o.prototype?Se(o.prototype,"ownerDocument"):null,C=function(e){return w?w(e):e.nodeType},O=function(e){return T?T(e):e.nodeName};if("function"==typeof a){const e=i.createElement("template");e.content&&e.content.ownerDocument&&(i=e.content.ownerDocument)}let A,E,x="",M=!1,k=0;const I=function(){if(k>0)throw fe('A configured TRUSTED_TYPES_POLICY callback (createHTML or createScriptURL) must not call DOMPurify.sanitize, as that causes infinite recursion. Do not pass a policy whose callbacks wrap DOMPurify as TRUSTED_TYPES_POLICY; see the "DOMPurify and Trusted Types" section of the README.')},L=function(e){I(),k++;try{return A.createHTML(e)}finally{k--}},_=i,N=_.implementation,P=_.createNodeIterator,F=_.createDocumentFragment,R=_.getElementsByTagName,D=n.importNode;let j={afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]};s.isSupported="function"==typeof $&&"function"==typeof b&&N&&void 0!==N.createHTMLDocument;const B=Pe,V=Fe,q=Re,U=De,z=je,G=$e,J=Ve,Y=Ue;let be=Be,ye=null;const we=ve({},[...Ce,...Oe,...Ae,...xe,...ke]);let Ge=null;const et=ve({},[...Ie,...Le,..._e,...Ne]);let tt=Object.seal(K(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),st=null,it=null;const nt=Object.seal(K(null,{tagCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeCheck:{writable:!0,configurable:!1,enumerable:!0,value:null}}));let rt=!0,at=!0,ot=!1,ct=!0,lt=!1,ht=!0,ut=!1,dt=!1,pt=null,mt=null,gt=!1,ft=!1,bt=!1,yt=!1,vt=!0,wt=!1;const Tt="user-content-";let St=!0,Ct=!1,Ot={},At=null;const Et=ve({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","selectedcontent","style","svg","template","thead","title","video","xmp"]);let xt=null;const Mt=ve({},["audio","video","img","source","image","track"]);let kt=null;const It=ve({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Lt="http://www.w3.org/1998/Math/MathML",_t="http://www.w3.org/2000/svg",Nt="http://www.w3.org/1999/xhtml";let Pt=Nt,Ft=!1,Rt=null;const Dt=ve({},[Lt,_t,Nt],ne),jt=W(["mi","mo","mn","ms","mtext"]);let Bt=ve({},jt);const $t=W(["annotation-xml"]);let Vt=ve({},$t);const qt=ve({},["title","style","font","a","script"]);let Ut=null;const zt=["application/xhtml+xml","text/html"];let Wt=null,Ht=null;const Kt=i.createElement("form"),Gt=function(e){return e instanceof RegExp||e instanceof Function},Jt=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(Ht&&Ht===e)return;e&&"object"==typeof e||(e={}),e=Te(e),Ut=-1===zt.indexOf(e.PARSER_MEDIA_TYPE)?"text/html":e.PARSER_MEDIA_TYPE,Wt="application/xhtml+xml"===Ut?ne:ie,ye=Xe(e,"ALLOWED_TAGS",we,{transform:Wt}),Ge=Xe(e,"ALLOWED_ATTR",et,{transform:Wt}),Rt=Xe(e,"ALLOWED_NAMESPACES",Dt,{transform:ne}),kt=Xe(e,"ADD_URI_SAFE_ATTR",It,{transform:Wt,base:It}),xt=Xe(e,"ADD_DATA_URI_TAGS",Mt,{transform:Wt,base:Mt}),At=Xe(e,"FORBID_CONTENTS",Et,{transform:Wt}),st=Xe(e,"FORBID_TAGS",Te({}),{transform:Wt}),it=Xe(e,"FORBID_ATTR",Te({}),{transform:Wt}),Ot=!!pe(e,"USE_PROFILES")&&(e.USE_PROFILES&&"object"==typeof e.USE_PROFILES?Te(e.USE_PROFILES):e.USE_PROFILES),rt=!1!==e.ALLOW_ARIA_ATTR,at=!1!==e.ALLOW_DATA_ATTR,ot=e.ALLOW_UNKNOWN_PROTOCOLS||!1,ct=!1!==e.ALLOW_SELF_CLOSE_IN_ATTR,lt=e.SAFE_FOR_TEMPLATES||!1,ht=!1!==e.SAFE_FOR_XML,ut=e.WHOLE_DOCUMENT||!1,ft=e.RETURN_DOM||!1,bt=e.RETURN_DOM_FRAGMENT||!1,yt=e.RETURN_TRUSTED_TYPE||!1,gt=e.FORCE_BODY||!1,vt=!1!==e.SANITIZE_DOM,wt=e.SANITIZE_NAMED_PROPS||!1,St=!1!==e.KEEP_CONTENT,Ct=e.IN_PLACE||!1,be=function(e){try{return ge(e,""),!0}catch(e){return!1}}(e.ALLOWED_URI_REGEXP)?e.ALLOWED_URI_REGEXP:Be,Pt="string"==typeof e.NAMESPACE?e.NAMESPACE:Nt,Bt=Qe(e,"MATHML_TEXT_INTEGRATION_POINTS",()=>ve({},jt)),Vt=Qe(e,"HTML_INTEGRATION_POINTS",()=>ve({},$t));const t=Qe(e,"CUSTOM_ELEMENT_HANDLING",()=>K(null));if(tt=K(null),pe(t,"tagNameCheck")&&Gt(t.tagNameCheck)&&(tt.tagNameCheck=t.tagNameCheck),pe(t,"attributeNameCheck")&&Gt(t.attributeNameCheck)&&(tt.attributeNameCheck=t.attributeNameCheck),pe(t,"allowCustomizedBuiltInElements")&&"boolean"==typeof t.allowCustomizedBuiltInElements&&(tt.allowCustomizedBuiltInElements=t.allowCustomizedBuiltInElements),H(tt),lt&&(at=!1),bt&&(ft=!0),Ot&&(ye=ve({},ke),Ge=K(null),!0===Ot.html&&(ve(ye,Ce),ve(Ge,Ie)),!0===Ot.svg&&(ve(ye,Oe),ve(Ge,Le),ve(Ge,Ne)),!0===Ot.svgFilters&&(ve(ye,Ae),ve(Ge,Le),ve(Ge,Ne)),!0===Ot.mathMl&&(ve(ye,xe),ve(Ge,_e),ve(Ge,Ne))),nt.tagCheck=null,nt.attributeCheck=null,pe(e,"ADD_TAGS")&&("function"==typeof e.ADD_TAGS?nt.tagCheck=e.ADD_TAGS:se(e.ADD_TAGS)&&(ye===we&&(ye=Te(ye)),ve(ye,e.ADD_TAGS,Wt))),pe(e,"ADD_ATTR")&&("function"==typeof e.ADD_ATTR?nt.attributeCheck=e.ADD_ATTR:se(e.ADD_ATTR)&&(Ge===et&&(Ge=Te(Ge)),ve(Ge,e.ADD_ATTR,Wt))),pe(e,"ADD_FORBID_CONTENTS")&&se(e.ADD_FORBID_CONTENTS)&&(At===Et&&(At=Te(At)),ve(At,e.ADD_FORBID_CONTENTS,Wt)),St&&(ye["#text"]=!0),ut&&ve(ye,["html","head","body"]),ye.table&&(ve(ye,["tbody"]),delete st.tbody),e.TRUSTED_TYPES_POLICY){if("function"!=typeof e.TRUSTED_TYPES_POLICY.createHTML)throw fe('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof e.TRUSTED_TYPES_POLICY.createScriptURL)throw fe('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');const t=A;A=e.TRUSTED_TYPES_POLICY;try{x=L("")}catch(e){throw A=t,e}}else null===e.TRUSTED_TYPES_POLICY?(A=void 0,x=""):(void 0===A&&(M||(E=function(e,t){if("object"!=typeof e||"function"!=typeof e.createPolicy)return null;let s=null;const i="data-tt-policy-suffix";t&&t.hasAttribute(i)&&(s=t.getAttribute(i));const n="dompurify"+(s?"#"+s:"");try{return e.createPolicy(n,{createHTML:e=>e,createScriptURL:e=>e})}catch(e){return console.warn("TrustedTypes policy "+n+" could not be created."),null}}(u,r),M=!0),A=E),A&&"string"==typeof x&&(x=L("")));W&&W(e),Ht=e},Yt=ve({},[...Oe,...Ae,...Ee]),Zt=ve({},[...xe,...Me]),Xt=function(e){ee(s.removed,{element:e});try{b(e).removeChild(e)}catch(t){if(m(e),!b(e))throw fe("a node selected for removal could not be detached from its tree and cannot be safely returned; refusing to sanitize in place")}},Qt=function(e,t,s){try{e.removeAttributeNode(t)}catch(t){try{e.removeAttribute(s)}catch(e){}}},es=function(e){is(e);const t=f(e);if(t){const e=[];Z(t,t=>{ee(e,t)}),Z(e,e=>{try{m(e)}catch(e){}})}const s=v(e);if(s)for(let t=s.length-1;t>=0;--t){const i=s[t],n=i&&i.name;"string"==typeof n&&Qt(e,i,n)}},ts=function(e,t,i){if(!i)try{i=t.getAttributeNode(e)}catch(e){i=null}ee(s.removed,{attribute:i||null,from:t});try{i?t.removeAttributeNode(i):t.removeAttribute(e)}catch(s){try{t.removeAttribute(e)}catch(e){}}if("is"===e)if(ft||bt)try{Xt(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},ss=function(e){const t=v(e);if(t)for(let s=t.length-1;s>=0;--s){const i=t[s],n=i&&i.name;"string"!=typeof n||Ge[Wt(n)]||Qt(e,i,n)}},is=function(e){const t=[e];for(;t.length>0;){const e=t.pop();1===C(e)&&ss(e);const s=f(e);if(s)for(let e=s.length-1;e>=0;--e)t.push(s[e])}},ns=function(e,t){return!!ht&&("patchsrc"===e||"for"===e&&"label"!==t&&"output"!==t)},rs=function(e){let t=null,s=null;if(gt)e=""+e;else{const t=re(e,/^[\r\n\t ]+/);s=t&&t[0]}"application/xhtml+xml"===Ut&&Pt===Nt&&(e=''+e+"");const n=A?L(e):e;if(Pt===Nt)try{t=(new h).parseFromString(n,Ut)}catch(e){}if(!t||!t.documentElement){t=N.createDocument(Pt,"template",null);try{t.documentElement.innerHTML=Ft?x:n}catch(e){}}const r=t.body||t.documentElement;return e&&s&&r.insertBefore(i.createTextNode(s),r.childNodes[0]||null),Pt===Nt?R.call(t,ut?"html":"body")[0]:ut?t.documentElement:r},as=function(e){const t=S?S(e):e.ownerDocument;return P.call(t||e,e,l.SHOW_ELEMENT|l.SHOW_COMMENT|l.SHOW_TEXT|l.SHOW_PROCESSING_INSTRUCTION|l.SHOW_CDATA_SECTION,null)},os=function(e){return e=ae(e,B," "),e=ae(e,V," "),ae(e,q," ")},cs=function(e){var t;e.normalize();const s=S?S(e):e.ownerDocument,i=P.call(s||e,e,l.SHOW_TEXT|l.SHOW_COMMENT|l.SHOW_CDATA_SECTION|l.SHOW_PROCESSING_INSTRUCTION,null);let n=i.nextNode();for(;n;)n.data=os(n.data),n=i.nextNode();const r=null===(t=e.querySelectorAll)||void 0===t?void 0:t.call(e,"template");r&&Z(r,e=>{hs(e.content)&&cs(e.content)})},ls=function(e){const t=T?T(e):null;return"string"==typeof t&&"form"===Wt(t)&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||e.attributes!==v(e)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore||"function"!=typeof e.hasChildNodes||e.nodeType!==w(e)||e.childNodes!==f(e))},hs=function(e){if(!w||"object"!=typeof e||null===e)return!1;try{return 11===w(e)}catch(e){return!1}},us=function(e){if(!w||"object"!=typeof e||null===e)return!1;try{return"number"==typeof w(e)}catch(e){return!1}};function ds(e,t,i){0!==e.length&&Z(e,e=>{e.call(s,t,i,Ht)})}const ps=function(e,t){if(e instanceof RegExp)return ge(e,t);if(e instanceof Function){for(var s=arguments.length,i=new Array(s>2?s-2:0),n=2;n=0;--n){const r=e===s?p(i[n],!0):i[n];t.insertBefore(r,g(e))}}return Xt(e),!0}(e,i,t);return!1===s&&ds(j.afterSanitizeElements,e,null),s}if(1===C(e)&&!function(e){let t=b(e);t&&t.tagName||(t={namespaceURI:Pt,tagName:"template"});const s=ie(e.tagName),i=ie(t.tagName);return!!Rt[e.namespaceURI]&&(e.namespaceURI===_t?function(e,t,s){return t.namespaceURI===Nt?"svg"===e:t.namespaceURI===Lt?"svg"===e&&("annotation-xml"===s||Bt[s]):Boolean(Yt[e])}(s,t,i):e.namespaceURI===Lt?function(e,t,s){return t.namespaceURI===Nt?"math"===e:t.namespaceURI===_t?"math"===e&&Vt[s]:Boolean(Zt[e])}(s,t,i):e.namespaceURI===Nt?function(e,t,s){return!(t.namespaceURI===_t&&!Vt[s])&&!(t.namespaceURI===Lt&&!Bt[s])&&!Zt[e]&&(qt[e]||!Yt[e])}(s,t,i):!("application/xhtml+xml"!==Ut||!Rt[e.namespaceURI]))}(e))return Xt(e),!0;if(("noscript"===i||"noembed"===i||"noframes"===i)&&ge(He,e.innerHTML))return Xt(e),!0;if(lt&&3===e.nodeType){const t=os(e.textContent);e.textContent!==t&&(ee(s.removed,{element:e.cloneNode()}),e.textContent=t)}return ds(j.afterSanitizeElements,e,null),!1},bs=function(e,t,s){if(it[t])return!1;if(ns(t,e))return!1;if(vt&&("id"===t||"name"===t)&&(s in i||s in Kt))return!1;const n=Ge[t]||nt.attributeCheck instanceof Function&&nt.attributeCheck(t,e);return!(!at||!ge(U,t))||!(!rt||!ge(z,t))||(n?!(!kt[t]&&!ge(be,ae(s,J,""))&&("src"!==t&&"xlink:href"!==t&&"href"!==t||"script"===e||0!==oe(s,"data:")||!xt[e])&&(!ot||ge(G,ae(s,J,"")))&&s):vs(e)&&ps(tt.tagNameCheck,e)&&ps(tt.attributeNameCheck,t,e)||"is"===t&&tt.allowCustomizedBuiltInElements&&ps(tt.tagNameCheck,s))},ys=ve({},["annotation-xml","color-profile","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","missing-glyph"]),vs=function(e){return!ys[ie(e)]&&ge(Y,e)},ws=function(e,t,s,i){if(A&&"object"==typeof u&&"function"==typeof u.getAttributeType&&!s)switch(u.getAttributeType(e,t)){case"TrustedHTML":return L(i);case"TrustedScriptURL":return function(e){I(),k++;try{return A.createScriptURL(e)}finally{k--}}(i)}return i},Ts=function(e,t,i,n){try{i?e.setAttributeNS(i,t,n):e.setAttribute(t,n),ls(e)?Xt(e):Q(s.removed)}catch(s){ts(t,e)}},Ss=function(e){ds(j.beforeSanitizeAttributes,e,null);const t=e.attributes;if(!t||ls(e))return;Ge=ms(j.uponSanitizeAttribute,Ge,et,mt);const s={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:Ge,forceKeepAttr:void 0};let i=t.length;const n=Wt(e.nodeName);for(;i--;){const r=t[i],a=r.name,o=r.namespaceURI,c=r.value,l=Wt(a),h=c;let u="value"===a?h:ce(h);s.attrName=l,s.attrValue=u,s.keepAttr=!0,s.forceKeepAttr=void 0,ds(j.uponSanitizeAttribute,e,s),u=s.attrValue,!wt||"id"!==l&&"name"!==l||0===oe(u,Tt)||(ts(a,e,r),u=Tt+u),ht&&ge(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i,u)||"attributename"===l&&re(u,"href")?ts(a,e,r):s.forceKeepAttr||(!s.keepAttr||!ct&&ge(Ke,u)?ts(a,e,r):(lt&&(u=os(u)),bs(n,l,u)?(u=ws(n,l,o,u),u!==h&&Ts(e,a,o,u)):ts(a,e,r)))}ds(j.afterSanitizeAttributes,e,null)},Cs=function(e){let t=null;const s=as(e);for(ds(j.beforeSanitizeShadowDOM,e,null);t=s.nextNode();)if(ds(j.uponSanitizeShadowNode,t,null),fs(t,e),Ss(t),hs(t.content)&&Cs(t.content),1===C(t)){const e=y(t);hs(e)&&(Os(e),Cs(e))}ds(j.afterSanitizeShadowDOM,e,null)},Os=function(e){const t=[{node:e,shadow:null}];for(;t.length>0;){const e=t.pop();if(e.shadow){Cs(e.shadow);continue}const s=e.node,i=1===C(s),n=f(s);if(n)for(let e=n.length-1;e>=0;--e)t.push({node:n[e],shadow:null});if(i){const e=T?T(s):null;if("string"==typeof e&&"template"===Wt(e)){const e=s.content;hs(e)&&t.push({node:e,shadow:null})}}if(i){const e=y(s);hs(e)&&t.push({node:null,shadow:e},{node:e,shadow:null})}}};return s.sanitize=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=null,r=null,a=null,o=null;if(Ft=!e,Ft&&(e="\x3c!--\x3e"),"string"!=typeof e&&!us(e)&&"string"!=typeof(e=function(e){switch(typeof e){case"string":return e;case"number":return le(e);case"boolean":return he(e);case"bigint":return ue?ue(e):"0";case"symbol":return de?de(e):"Symbol()";case"undefined":default:return me(e);case"function":case"object":{if(null===e)return me(e);const t=e,s=Se(t,"toString");if("function"==typeof s){const e=s(t);return"string"==typeof e?e:me(e)}return me(e)}}}(e)))throw fe("dirty is not a string, aborting");if(!s.isSupported)return e;dt?(ye=pt,Ge=mt):Jt(t),(j.uponSanitizeElement.length>0||j.uponSanitizeAttribute.length>0)&&(ye=Te(ye)),j.uponSanitizeAttribute.length>0&&(Ge=Te(Ge)),s.removed=[];const c=Ct&&"string"!=typeof e&&us(e);if(c){!function(e){if(!ht)return;const t=[e];for(;t.length>0;){const e=t.pop(),s=C(e);if(7===s||8===s&&ge(We,e.data)){try{m(e)}catch(e){}continue}if(1===s){const t=e,s=Wt(O(e));try{t.hasAttribute&&t.hasAttribute("patchsrc")&&t.removeAttribute("patchsrc"),t.hasAttribute&&t.hasAttribute("for")&&ns("for",s)&&t.removeAttribute("for")}catch(e){}}const i=f(e);if(i)for(let e=i.length-1;e>=0;--e)t.push(i[e])}}(e);const t=O(e);if("string"==typeof t){const s=Wt(t);if(!ye[s]||st[s])throw es(e),fe("root node is forbidden and cannot be sanitized in-place")}if(ls(e))throw es(e),fe("root node is clobbered and cannot be sanitized in-place");try{Os(e)}catch(t){throw es(e),t}}else if(us(e))i=rs("\x3c!----\x3e"),r=i.ownerDocument.importNode(e,!0),1===r.nodeType&&"BODY"===r.nodeName||"HTML"===r.nodeName?i=r:i.appendChild(r),Os(r);else{if(!ft&&!lt&&!ut&&-1===e.indexOf("<"))return A&&yt?L(e):e;if(i=rs(e),!i)return ft?null:yt?x:""}i&>&&Xt(i.firstChild);const l=c?e:i;try{const e=as(l);for(;a=e.nextNode();)fs(a,l),Ss(a),hs(a.content)&&Cs(a.content)}catch(t){throw c&&(es(e),Z(s.removed,e=>{e.element&&is(e.element)})),t}if(c)return Z(s.removed,e=>{e.element&&is(e.element)}),lt&&cs(e),e;if(ft){if(lt&&cs(i),bt)for(o=F.call(i.ownerDocument);i.firstChild;)o.appendChild(i.firstChild);else o=i;return(Ge.shadowroot||Ge.shadowrootmode)&&(o=D.call(n,o,!0)),o}let h=ut?i.outerHTML:i.innerHTML;return ut&&ye["!doctype"]&&i.ownerDocument&&i.ownerDocument.doctype&&i.ownerDocument.doctype.name&&ge(qe,i.ownerDocument.doctype.name)&&(h="\n"+h),lt&&(h=os(h)),A&&yt?L(h):h},s.setConfig=function(){Jt(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),dt=!0,pt=ye,mt=Ge},s.clearConfig=function(){Ht=null,dt=!1,pt=null,mt=null,A=E,x=""},s.isValidAttribute=function(e,t,s){Ht||Jt({});const i=Wt(e),n=Wt(t);return bs(i,n,s)},s.addHook=function(e,t){"function"==typeof t&&pe(j,e)&&ee(j[e],t)},s.removeHook=function(e,t){if(pe(j,e)){if(void 0!==t){const s=X(j[e],t);return-1===s?void 0:te(j[e],s,1)[0]}return Q(j[e])}},s.removeHooks=function(e){pe(j,e)&&(j[e]=[])},s.removeAllHooks=function(){j={afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}},s}();const tt={ADD_ATTR:["target"],ALLOW_DATA_ATTR:!1,RETURN_DOM_FRAGMENT:!0,USE_PROFILES:{html:!0}},st={ADD_ATTR:["target"],ADD_TAGS:["hellotext-icon"],RETURN_DOM_FRAGMENT:!0,USE_PROFILES:{html:!0,svg:!0}};function it(e,t){const s=et.sanitize(e,t);return s.querySelectorAll('a[target="_blank"]').forEach(e=>{const t=new Set(e.rel.split(/\s+/).filter(Boolean));t.add("noopener"),t.add("noreferrer"),e.rel=Array.from(t).join(" ")}),s}function nt(e,t){e.replaceChildren(function(e){return it(e,tt)}(t))}class rt{constructor(e,t=null){this.data=e,this.element=t||document.querySelector(`[data-hello-form="${this.id}"]`)||document.createElement("form")}async mount({ifCompleted:e=!0}={}){if(e&&this.hasBeenCompleted)return this.element?.remove(),bt.eventEmitter.dispatch("form:completed",{id:this.id,...JSON.parse(localStorage.getItem(`hello-form-${this.id}`))});const t=this.data.steps[0];this.buildHeader(t.header),this.buildInputs(t.inputs),this.buildButton(t.button),this.buildFooter(t.footer),this.elementAttributes.forEach(e=>{this.element.setAttribute(e.name,e.value)}),document.contains(this.element)||document.body.appendChild(this.element),bt.business.features.white_label||this.element.prepend(D.build())}buildHeader(e){const t=this.#c("[data-form-header]","header");nt(t,e.content),this.element.querySelector("[data-form-header]")?this.element.querySelector("[data-form-header]").replaceWith(t):this.element.prepend(t)}buildInputs(e){const t=this.#c("[data-form-inputs]","main");e.map(e=>R.build(e)).forEach(e=>t.appendChild(e)),this.element.querySelector("[data-form-inputs]")?this.element.querySelector("[data-form-inputs]").replaceWith(t):this.element.querySelector("[data-form-header]").insertAdjacentHTML("afterend",t.outerHTML)}buildButton(e){const t=this.#c("[data-form-button]","button");t.innerText=e.text,t.setAttribute("data-action","click->hellotext--form#submit"),t.setAttribute("data-hellotext--form-target","button"),this.element.querySelector("[data-form-button]")?this.element.querySelector("[data-form-button]").replaceWith(t):this.element.querySelector("[data-form-inputs]").insertAdjacentHTML("afterend",t.outerHTML)}buildFooter(e){const t=this.#c("[data-form-footer]","footer");nt(t,e.content),this.element.querySelector("[data-form-footer]")?this.element.querySelector("[data-form-footer]").replaceWith(t):this.element.appendChild(t)}markAsCompleted(e){const t={state:"completed",id:this.id,data:e,completedAt:(new Date).getTime()};localStorage.setItem(`hello-form-${this.id}`,JSON.stringify(t)),bt.eventEmitter.dispatch("form:completed",t)}get hasBeenCompleted(){return null!==localStorage.getItem(`hello-form-${this.id}`)}get id(){return this.data.id}get localeAuthKey(){const e=this.data.steps[0];return e.inputs.some(e=>"email"===e.kind)&&e.inputs.some(e=>"phone"===e.kind)?"phone_and_email":e.inputs.some(e=>"email"===e.kind)?"email":e.inputs.some(e=>"phone"===e.kind)?"phone":"none"}get elementAttributes(){return[{name:"data-controller",value:"hellotext--form"},{name:"data-hello-form",value:this.id},{name:"data-hellotext--form-data-value",value:JSON.stringify(this.data)}]}#c(e,t){const s=this.element.querySelector(e);if(s)return s.cloneNode(!0);const i=document.createElement(t);return i.setAttribute(e.replace("[","").replace("]",""),""),i}}class at extends Error{constructor(){super("You need to initialize before tracking events. Call Hellotext.initialize and pass your public business id"),this.name="NotInitializedError"}}class ot{constructor(){this.forms=[],this.includes=this.includes.bind(this),this.excludes=this.excludes.bind(this),this.add=this.add.bind(this),"undefined"!=typeof MutationObserver&&(this.mutationObserver=new MutationObserver(this.formMutationObserver.bind(this)),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0}))}collectExistingFormsOnPage(){Array.from(document.querySelectorAll("[data-hello-form]")).length>0&&this.collect()}formMutationObserver(e){e.find(e=>"childList"===e.type&&e.addedNodes.length>0)&&Array.from(document.querySelectorAll("[data-hello-form]")).length>0&&this.collect()}async collect(){if(bt.notInitialized)throw new at;if(this.fetching)return;if("undefined"==typeof document||!("querySelectorAll"in document))return console.warn("Document is not defined, collection is not possible. Please make sure to initialize the library after the document is loaded.");const e=this.#l;if(0===e.length)return;const t=e.map(e=>w.get(e).then(e=>e.json()));this.fetching=!0,await Promise.all(t).then(e=>e.forEach(this.add)).then(()=>bt.eventEmitter.dispatch("forms:collected",this)).then(()=>this.fetching=!1),g.forms.autoMount&&this.forms.forEach(e=>e.mount())}forEach(e){this.forms.forEach(e)}map(e){return this.forms.map(e)}add(e){this.includes(e.id)||(bt.business.data||(bt.business.setData(e.business),bt.business.setLocale(o.toString())),bt.business.enabledWhitelist||console.warn("No whitelist has been configured. It is advised to whitelist the domain to avoid bots from submitting forms."),this.forms.push(new rt(e)))}getById(e){return this.forms.find(t=>t.id===e)}getByIndex(e){return this.forms[e]}includes(e){return this.forms.some(t=>t.id===e)}excludes(e){return!this.includes(e)}get length(){return this.forms.length}get#l(){return Array.from(document.querySelectorAll("[data-hello-form]")).map(e=>e.dataset.helloForm).filter(this.excludes)}}class ct{constructor(e){this.publicKey=e.public_key,this.serviceWorkerUrl=g.push.serviceWorkerUrl,this.channelId=g.push.channelId,this.ready=null,this.registrationPromise=null,this.subscribePromise=null,this.unsubscribePromise=null,this.syncPromise=null,this.subscription=null,this.retryTimeout=null,this.retryAttempts=0,this.disposed=!1}initialize(){return this.ready=this.restoreSubscription(),this.ready}async restoreSubscription(){const e=await this.getRegistration(),t=await e.pushManager.getSubscription();!this.disposed&&!this.unsubscribePromise&&t&&this.owns(t)&&(this.subscription=t,await this.sync())}subscribe(){if(this.disposed)return Promise.resolve();if(this.unsubscribePromise)return Promise.reject(new Error("Push unsubscribe is in progress"));if(this.subscribePromise)return this.subscribePromise;const e="default"===Notification.permission?Notification.requestPermission():Promise.resolve(Notification.permission);return this.subscribePromise=this.createSubscription(e).finally(()=>{this.subscribePromise=null}),this.subscribePromise}async createSubscription(e){if("granted"!==await e)throw new Error("Push permission was not granted");const t=await this.getRegistration();if(this.disposed)return;let s=await t.pushManager.getSubscription();if(!this.disposed){if(s&&!this.owns(s))throw new Error("The existing Push subscription belongs to a different application");if(s||=await t.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:this.applicationServerKey}),!this.disposed)return this.subscription=s,this.sync()}}unsubscribe(){return this.disposed?Promise.resolve():(this.unsubscribePromise||(this.clearRetryTimeout(),this.unsubscribePromise=this.removeSubscription().finally(()=>{this.unsubscribePromise=null})),this.unsubscribePromise)}async removeSubscription(){await(this.ready?.catch(()=>{})),await(this.subscribePromise?.catch(()=>{})),await(this.syncPromise?.catch(()=>{}));const e=await this.getRegistration(),t=await e.pushManager.getSubscription()||this.subscription;if(this.disposed)return;if(!t)return null;if(!this.owns(t))throw new Error("The existing Push subscription belongs to a different application");this.subscription=t;const s=await M.pushIdentities.destroy({subscription:t.toJSON()});return s.failed?s:this.disposed?void 0:(await t.unsubscribe(),this.subscription=null,this.clearRetryTimeout(),s)}sync(){return this.disposed?Promise.resolve():(this.syncPromise||(this.clearRetryTimeout(),this.syncPromise=this.registerIdentity().finally(()=>{this.syncPromise=null})),this.syncPromise)}async registerIdentity(){try{const e=await M.pushIdentities.create({subscription:this.subscription.toJSON(),...this.channelId?{channel_id:this.channelId}:{}});return e.succeeded?this.retryAttempts=0:this.scheduleRetry(),e}catch(e){throw this.scheduleRetry(),e}}scheduleRetry(){this.disposed||this.unsubscribePromise||this.retryTimeout||this.retryAttempts>=3||(this.retryTimeout=setTimeout(()=>{this.retryTimeout=null,this.sync().catch(()=>{})},1e3*2**this.retryAttempts),this.retryAttempts+=1)}clearRetryTimeout(){clearTimeout(this.retryTimeout),this.retryTimeout=null}dispose(){this.disposed=!0,this.clearRetryTimeout()}get subscribed(){return!!this.subscription}get applicationServerKey(){const e=this.publicKey.replace(/-/g,"+").replace(/_/g,"/");return Uint8Array.from(atob(e.padEnd(4*Math.ceil(e.length/4),"=")),e=>e.charCodeAt(0))}owns(e){const t=e.options?.applicationServerKey;if(!t)return!1;const s=new Uint8Array(t),i=this.applicationServerKey;return s.length===i.length&&s.every((e,t)=>e===i[t])}getRegistration(){return this.registrationPromise||(this.registrationPromise=this.loadRegistration().catch(e=>{throw this.registrationPromise=null,e})),this.registrationPromise}async loadRegistration(){if(this.serviceWorkerUrl){const e=await navigator.serviceWorker.register(this.serviceWorkerUrl);!e.active||e.installing||e.waiting||await e.update();const t=e.installing||e.waiting||e.active;return"activated"===t?.state?e:new Promise((s,i)=>{const n=setTimeout(()=>r(new Error("Push service worker did not become active")),1e4),r=r=>{clearTimeout(n),t?.removeEventListener("statechange",a),r?i(r):s(e)},a=()=>{"activated"===t?.state&&r(),"redundant"===t?.state&&r(new Error("Push service worker installation failed"))};t?.addEventListener("statechange",a),a()})}return new Promise((e,t)=>{const s=setTimeout(()=>t(new Error("Push service worker is not available")),1e4);navigator.serviceWorker.ready.then(t=>{clearTimeout(s),e(t)},e=>{clearTimeout(s),t(e)})})}static get supported(){return"undefined"!=typeof window&&!0===window.isSecureContext&&"undefined"!=typeof navigator&&"serviceWorker"in navigator&&"undefined"!=typeof PushManager&&"undefined"!=typeof Notification}}class lt{constructor(e,t,s){this.business=t,this.push=s,this.disposed=!1,this.showRequest=0,this.controller=null,this.element=(new DOMParser).parseFromString(e.html,"text/html").querySelector('[data-controller~="hellotext--alert"]'),this.connected=new Promise(e=>{this.resolveConnected=e}),this.onConnect=this.onConnect.bind(this),this.ready=this.render()}onConnect(e){this.controller=e.detail.controller,this.controller.alert=this,this.resolveConnected(!0)}async render(){return!!this.element&&(this.element.addEventListener("hellotext--alert:connected",this.onConnect),!(!await this.business.stylesheetLoaded||this.disposed)&&(document.body.appendChild(this.element),this.connected))}async show(e,t={}){const s=++this.showRequest;return!(!await this.ready||this.disposed||s!==this.showRequest)&&this.controller.show(e,t)}hide(){this.showRequest+=1,this.controller?.close()}dispose(){this.disposed=!0,this.hide(),this.resolveConnected(!1),this.element?.removeEventListener("hellotext--alert:connected",this.onConnect),this.element?.remove()}}class ht{static async load(e){const t=new ht({id:e,html:await M.webchats.get(e)});return t.rendered=t.render(),t}constructor(e){this.data=e,this.mounted=!1,this.rendered=Promise.resolve(!1)}async render(){return this.applyBehaviourOverride(),await this.stylesheetLoaded?(this.containerToAppendTo.appendChild(this.data.html),this.markCoexistingWidgets(),this.mounted=!0,!0):(console.warn("Hellotext webchat was not mounted because its stylesheet failed to load."),!1)}applyBehaviourOverride(){g.webchat.hasBehaviourOverride&&g.webchat.behaviour&&this.data.html.setAttribute("data-hellotext--webchat-behaviour-value",JSON.stringify(this.serializedBehaviour))}get serializedBehaviour(){const e=g.webchat.behaviour;return{trigger:this.serializeTrigger(e.trigger),delay_seconds:e.delaySeconds,first_visit_only:e.firstVisitOnly,once_per_session:e.oncePerSession}}serializeTrigger(e){return"onLoad"===e?"on_load":"onClick"===e?"on_click":e}get containerToAppendTo(){return document.querySelector(g.webchat.container)}get stylesheetLoaded(){return L.waitForStylesheet(L.latestStylesheet)}markCoexistingWidgets(){const e=this.data.html,t=document.querySelector(".hellotext--whatsapp-widget");e&&t&&(e.classList.add("hellotext--with-whatsapp-widget"),t.classList.add("hellotext--with-webchat"))}}class ut{static async load(e){const t=new ut({id:e,html:await M.whatsappWidgets.get(e)});return t.rendered=t.render(),t}constructor(e){this.data=e,this.mounted=!1,this.rendered=Promise.resolve(!1)}async render(){if(!this.data.html)return!1;const e=this.containerToAppendTo;return e?await this.stylesheetLoaded?(e.appendChild(this.data.html),this.markCoexistingWidgets(),this.mounted=!0,!0):(console.warn("Hellotext WhatsApp widget was not mounted because its stylesheet failed to load."),!1):(console.warn(`Hellotext WhatsApp widget was not mounted because the container ${g.whatsapp.container} was not found.`),!1)}get containerToAppendTo(){try{return document.querySelector(g.whatsapp.container)}catch(e){return null}}get stylesheetLoaded(){return L.waitForStylesheet(L.latestStylesheet)}markCoexistingWidgets(){const e=document.querySelector(".hellotext--webchat:not(.hellotext--whatsapp-widget)"),t=this.data.html;e&&t&&(e.classList.add("hellotext--with-whatsapp-widget"),t.classList.add("hellotext--with-webchat"))}}class dt{static get id(){return _.get("hello_user_id")}static get source(){return _.get("hello_user_source")}static get fingerprint(){return _.get("hello_user_identification_hash")}static remember(e,t,s){t&&_.set("hello_user_source",t),s&&_.set("hello_user_identification_hash",s),_.set("hello_user_id",e)}static forget(){_.delete("hello_user_id"),_.delete("hello_user_source"),_.delete("hello_user_identification_hash")}static get identificationData(){return this.id?{id:this.id,source:this.source}:{}}}function pt(e){if(null!=e){if("string"==typeof e){const t=e.trim();return""===t?void 0:t}if(Array.isArray(e))return e.map(e=>pt(e)).filter(e=>void 0!==e);if(e instanceof Date)return e.toISOString();if("object"==typeof e){const t=Object.keys(e).sort((e,t)=>e.localeCompare(t)).reduce((t,s)=>{const i=pt(e[s]);return void 0!==i&&(t[s]=i),t},{});return Object.keys(t).length>0?t:void 0}return"number"==typeof e||"boolean"==typeof e?e:void 0}}function mt(e,t,s={}){const i=pt({session:e,user_id:t,...s})||{};return JSON.stringify(i)}class gt{static matches(e,t){return!!e&&e===t}static async generate(e,t,s={}){return await async function(e){if(!globalThis.crypto?.subtle||"undefined"==typeof TextEncoder)return function(e){let t=5381;for(let s=0;s>>0).toString(16)}`}(e);const t=await globalThis.crypto.subtle.digest("SHA-256",(new TextEncoder).encode(e));return`v1:${Array.from(new Uint8Array(t)).map(e=>e.toString(16).padStart(2,"0")).join("")}`}(mt(e,t,s))}}class ft{static eventEmitter=new r;static forms;static business;static webchat;static whatsapp;static push;static alert;static async initialize(e,t={}){this.alert?.dispose(),this.alert=null,this.push?.dispose(),this.push=null;const s=new L(e);this.business=s,this.page=new P,g.assign({push:{},...t}),F.initialize(this.page),this.forms=new ot,this.query=new b;const i=await s.hydrate();if(this.business!==s)return;!1!==t.push&&i?.push?.public_key&&ct.supported&&(this.push=new ct(i.push),this.push.initialize().catch(e=>{console.warn("Hellotext Push initialization failed:",e)}),i.alert?.html&&(this.alert=new lt(i.alert,s,this.push)));const n=!1!==t.webchat&&this.mergeWebchatConfig(i&&i.webchat||{},t.webchat||{}),r=!1!==t.whatsappWidget&&this.mergeWhatsAppConfig(i&&i.whatsapp||{},t.whatsappWidget||{}),a=t.webchat&&!1!==t.webchat&&Object.prototype.hasOwnProperty.call(t.webchat,"behaviour");g.webchat.behaviourOverride=a,n&&n.id&&(g.webchat.assign(n),this.webchat=await ht.load(n.id)),r&&r.id&&(g.whatsapp.assign(r),this.whatsapp=await ut.load(r.id)),"undefined"!=typeof MutationObserver&&this.forms.collectExistingFormsOnPage()}static mergeWebchatConfig(e,t){return this.deepMergePlainObjects(e,t)}static mergeWhatsAppConfig(e,t){return this.deepMergePlainObjects(e,t)}static deepMergePlainObjects(e,t){const s={...e};return Object.entries(t).forEach(([e,t])=>{this.isPlainObject(t)&&this.isPlainObject(s[e])?s[e]=this.deepMergePlainObjects(s[e],t):s[e]=t}),s}static isPlainObject(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}static async track(e,t={}){if(this.notInitialized)throw new at;const s={...t&&t.headers||{},...this.headers},i={...dt.identificationData,...t.user_parameters||{}},n=t&&t.url?new P(t.url):this.page,r={session:this.session,user_parameters:i,action:e,...t,...n.trackingData};return delete r.headers,await M.events.create({headers:s,body:r,keepalive:x(r)})}static async identify(e,t={}){const s=await gt.generate(this.session,e,t);if(gt.matches(dt.fingerprint,s))return new y(!0,{json:async()=>({already_identified:!0})});const i=await M.identifications.create({user_id:e,...t});return i.succeeded&&dt.remember(e,t.source,s),i}static forget(){dt.forget()}static on(e,t){this.eventEmitter.addSubscriber(e,t)}static removeEventListener(e,t){this.eventEmitter.removeSubscriber(e,t)}static get session(){return F.session}static get isInitialized(){return void 0!==F.session}static get notInitialized(){return!this.business||void 0===this.business.id}static get headers(){if(this.notInitialized)throw new at;return{Authorization:`Bearer ${this.business.id}`,Accept:"application/json","Content-Type":"application/json"}}}const bt=ft,yt=new Map,vt=class extends i.xI{static values={sections:Array};static targets=["title","description","primaryAction","secondaryAction"];initialize(){this.showRequest=0,this.submitting=!1,this.onStorage=this.onStorage.bind(this)}connect(){this.dispatch("connected",{detail:{controller:this}}),window.addEventListener("storage",this.onStorage)}disconnect(){this.close(),window.removeEventListener("storage",this.onStorage)}onStorage(e){e.key===this.storageKey&&this.dismissal.dismissedUntil>Date.now()&&this.close()}async show(e,{force:t=!1,title:s,description:i,primaryAction:n,secondaryAction:r}={}){const a=++this.showRequest,o=this.sectionsValue.find(t=>t.kind===e);return o?(await(this.alert.push.ready?.catch(()=>{})),!(a!==this.showRequest||this.alert.disposed||!this.element.isConnected||(this.unavailable||!t&&this.dismissal.dismissedUntil>Date.now()?(this.close(),1):(this.titleTarget.textContent=s??o.title,this.descriptionTarget.textContent=i??o.description,this.primaryActionTarget.textContent=n??o.primary_action,this.secondaryActionTarget.textContent=r??o.secondary_action,this.kind=e,this.element.hidden=!1,this.record("shown"),bt.eventEmitter.dispatch("alert:shown",{kind:e}),0)))):(this.close(),!1)}hide(){if(this.element.hidden||this.submitting)return;const e=this.dismissal.dismissals+1,t={dismissals:e,dismissedUntil:Date.now()+864e5*(1===e?7:30)};yt.set(this.storageKey,t);try{localStorage.setItem(this.storageKey,JSON.stringify(t))}catch(e){}this.close(),this.record("dismissed"),bt.eventEmitter.dispatch("alert:dismissed",{kind:this.kind})}close(){this.showRequest+=1,this.element.hidden=!0}async subscribe(){if(!this.submitting&&!this.element.hidden){if(this.unavailable)return this.close();this.submitting=!0,this.primaryActionTarget.disabled=!0,this.secondaryActionTarget.disabled=!0,this.element.setAttribute("aria-busy","true");try{this.record("accepted"),bt.eventEmitter.dispatch("alert:accepted",{kind:this.kind});const e=await this.alert.push.subscribe();return this.unavailable&&this.close(),e?.failed&&this.dispatch("error",{detail:{response:e}}),e}catch(e){this.unavailable&&this.close(),this.dispatch("error",{detail:{error:e}})}finally{this.submitting=!1,this.primaryActionTarget.disabled=!1,this.secondaryActionTarget.disabled=!1,this.element.removeAttribute("aria-busy")}}}async record(e){try{const t=await M.pushAlerts.create({section:this.kind,kind:e});t.failed&&console.warn("Hellotext Smart Alert submission failed:",t)}catch(e){console.warn("Hellotext Smart Alert submission failed:",e)}}get unavailable(){return this.alert.push.disposed||this.alert.push.subscribed||"undefined"==typeof Notification||"denied"===Notification.permission}get storageKey(){return`hellotext:alert:${this.alert.business.id}`}get dismissal(){try{const e=JSON.parse(localStorage.getItem(this.storageKey));Number.isSafeInteger(e?.dismissals)&&e.dismissals>0&&Number.isFinite(e.dismissedUntil)&&e.dismissedUntil>=0&&yt.set(this.storageKey,e)}catch(e){}return yt.get(this.storageKey)||{dismissals:0,dismissedUntil:0}}},wt=class extends i.xI{static values={data:Object,step:{type:Number,default:1}};static targets=["inputContainer","input","button","otpContainer"];initialize(){this.form=new rt(this.dataValue,this.element)}connect(){super.connect(),this.element.addEventListener("submit",this.submit.bind(this)),"INPUT"!==document.activeElement.tagName&&this.inputTargets[0].focus()}async submit(e){if(e.preventDefault(),this.invalid)return this.showErrorMessages();this.clearErrorMessages(),this.formData=Object.fromEntries(new FormData(this.element)),this.buttonTarget.disabled=!0;const t=await w.submit(this.form.id,this.formData);this.buttonTarget.disabled=!1;const s=await t.json();if(t.failed)return s.errors.forEach(e=>{const{type:t,parameter:s}=e,i=this.inputTargets.find(e=>e.name===s);i.setCustomValidity(bt.business.locale.errors[t]),i.reportValidity(),i.addEventListener("input",()=>{i.setCustomValidity(""),i.reportValidity()})}),this.showErrorMessages();this.buttonTarget.style.display="none",this.element.querySelectorAll("input").forEach(e=>e.disabled=!0),this.completed()}completed(){if(this.form.markAsCompleted(this.formData),!g.forms.shouldShowSuccessMessage)return this.element.remove();"string"==typeof g.forms.successMessage?this.element.innerHTML=g.forms.successMessage:this.element.innerHTML=bt.business.locale.forms[this.form.localeAuthKey]}showErrorMessages(){this.inputTargets.forEach(e=>{const t=e.closest("article").querySelector("[data-error-container]");e.validity.valid?t.innerText="":t.innerText=e.validationMessage})}clearErrorMessages(){this.inputTargets.forEach(e=>{e.setCustomValidity(""),e.closest("article").querySelector("[data-error-container]").innerText=""})}inputTargetConnected(e){e.getAttribute("data-default-value")&&(e.value=e.getAttribute("data-default-value"))}get requiredInputs(){return this.inputTargets.filter(e=>e.required)}get invalid(){return!this.element.checkValidity()}},Tt=class extends i.xI{static values={fadeDistance:{type:Number,default:64},id:String,kind:String,pageStartOffset:{type:Number,default:0},utm:Object};static targets=["carouselContainer","leftFade","rightFade","carouselCard"];connect(){this.updateFades(),this.observeContainerSize()}disconnect(){this.resizeObserver?.disconnect()}setId({detail:e}){this.idValue=e,this.element.id=e}onScroll(){this.updateFades()}quickReply({currentTarget:e}){const t=e.closest('[data-hellotext--message-target="carouselCard"]'),s=e.closest('[data-controller~="hellotext--message"]'),i=e.dataset.text||e.textContent.trim();this.dispatch("quickReply",{detail:{id:this.idValue,product:t?.dataset.id,buttonId:e.dataset.id,body:i,cardElement:t||s||e}})}addToCart({currentTarget:e}){const t=e.closest('[data-hellotext--message-target="carouselCard"]'),{id:s,reference:i,source:n}=t.dataset,r={product:s,quantity:1};this.hasUtmValue&&bt.page.utm.save(this.utmValue),bt.eventEmitter.dispatch("cart.added",{object_parameters:{items:[{...r,...i&&{reference:i},...n&&{source:n}}]},source:{kind:this.kindValue,message_id:this.idValue,button_id:e.dataset.id}})}moveToLeft(){if(!this.hasCarouselContainerTarget)return;const e=this.getPreviousPageScrollLeft(),t=this.carouselContainerTarget.scrollLeft-e;t<1||this.carouselContainerTarget.scrollBy({left:-t,behavior:"smooth"})}moveToRight(){if(!this.hasCarouselContainerTarget)return;const e=this.getNextPageScrollLeft()-this.carouselContainerTarget.scrollLeft;e<1||this.carouselContainerTarget.scrollBy({left:e,behavior:"smooth"})}getScrollAmount(){return this.getCardScrollAmount()}getCardScrollAmount(){const e=this.carouselContainerTarget.querySelector(".message__carousel_card");return e?e.offsetWidth+this.getGap():280}getPageScrollAmount(){const e=this.carouselContainerTarget.clientWidth-this.getGap();return e>0?e:this.getCardScrollAmount()}getNextPageScrollLeft(){const e=this.getCurrentScrollLeft(),t=e+this.carouselContainerTarget.clientWidth,s=this.getCardMetrics().find(e=>e.end>t+1),i=s?this.getPageAlignedScrollLeft(s.start):e+this.getPageScrollAmount(),n=e+this.getPageScrollAmount();return this.clampScrollLeft(i>e+1?i:n)}getPreviousPageScrollLeft(){const e=this.getCurrentScrollLeft();if(e<=1)return 0;const t=Math.max(e-this.getPageScrollAmount(),0);if(t<=1)return 0;const s=this.getCardMetrics(),i=s.find(s=>s.start>=t-1&&s.startt.start{const t=this.getCardScrollLeft(e);return{start:t,end:t+e.offsetWidth}})}getCardScrollLeft(e){const t=e.getBoundingClientRect(),s=this.carouselContainerTarget.getBoundingClientRect();return t.left||t.width||s.left||s.width?t.left-s.left+this.carouselContainerTarget.scrollLeft:e.offsetLeft||0}getCurrentScrollLeft(){return this.clampScrollLeft(this.carouselContainerTarget.scrollLeft)}clampScrollLeft(e){const t=Math.max(this.carouselContainerTarget.scrollWidth-this.carouselContainerTarget.clientWidth,0);return Math.min(Math.max(e,0),t)}getGap(){const e=window.getComputedStyle(this.carouselContainerTarget),t=Number.parseFloat(e.columnGap||e.gap);return Number.isFinite(t)?t:16}getFadeDistance(){return Number.isFinite(this.fadeDistanceValue)?this.fadeDistanceValue:64}getPageStartOffset(){return Number.isFinite(this.pageStartOffsetValue)?this.pageStartOffsetValue:0}observeContainerSize(){this.hasCarouselContainerTarget&&window.ResizeObserver&&(this.resizeObserver=new ResizeObserver(()=>this.updateFades()),this.resizeObserver.observe(this.carouselContainerTarget))}updateFades(){if(!this.hasCarouselContainerTarget)return;const e=Math.max(this.carouselContainerTarget.scrollWidth-this.carouselContainerTarget.clientWidth,0);if(e<=1)return this.hideFade(this.leftFadeTarget),void this.hideFade(this.rightFadeTarget);const t=Math.min(Math.max(this.carouselContainerTarget.scrollLeft,0),e),s=this.getFadeDistance();this.setFadeOpacity(this.leftFadeTarget,t/s),this.setFadeOpacity(this.rightFadeTarget,(e-t)/s)}setFadeOpacity(e,t){const s=Math.min(Math.max(t,0),1);s<=.05?this.hideFade(e):(e.classList.remove("hidden"),e.removeAttribute("disabled"),e.removeAttribute("tabindex"),e.setAttribute("aria-hidden","false"),e.style.opacity=s.toFixed(3),e.style.pointerEvents="auto")}hideFade(e){e.style.opacity="0",e.style.pointerEvents="none",e.setAttribute("aria-hidden","true"),e.setAttribute("tabindex","-1"),"disabled"in e&&(e.disabled=!0),e.classList.add("hidden")}},St=["start","end"],Ct=["top","right","bottom","left"].reduce((e,t)=>e.concat(t,t+"-"+St[0],t+"-"+St[1]),[]),Ot=Math.min,At=Math.max,Et=Math.round,xt=Math.floor,Mt=e=>({x:e,y:e}),kt={left:"right",right:"left",bottom:"top",top:"bottom"},It={start:"end",end:"start"};function Lt(e,t,s){return At(e,Ot(t,s))}function _t(e,t){return"function"==typeof e?e(t):e}function Nt(e){return e.split("-")[0]}function Pt(e){return e.split("-")[1]}function Ft(e){return"x"===e?"y":"x"}function Rt(e){return"y"===e?"height":"width"}const Dt=new Set(["top","bottom"]);function jt(e){return Dt.has(Nt(e))?"y":"x"}function Bt(e){return Ft(jt(e))}function $t(e,t,s){void 0===s&&(s=!1);const i=Pt(e),n=Bt(e),r=Rt(n);let a="x"===n?i===(s?"end":"start")?"right":"left":"start"===i?"bottom":"top";return t.reference[r]>t.floating[r]&&(a=Ht(a)),[a,Ht(a)]}function Vt(e){return e.replace(/start|end/g,e=>It[e])}const qt=["left","right"],Ut=["right","left"],zt=["top","bottom"],Wt=["bottom","top"];function Ht(e){return e.replace(/left|right|bottom|top/g,e=>kt[e])}function Kt(e){const{x:t,y:s,width:i,height:n}=e;return{width:i,height:n,top:s,left:t,right:t+i,bottom:s+n,x:t,y:s}}function Gt(e,t,s){let{reference:i,floating:n}=e;const r=jt(t),a=Bt(t),o=Rt(a),c=Nt(t),l="y"===r,h=i.x+i.width/2-n.width/2,u=i.y+i.height/2-n.height/2,d=i[o]/2-n[o]/2;let p;switch(c){case"top":p={x:h,y:i.y-n.height};break;case"bottom":p={x:h,y:i.y+i.height};break;case"right":p={x:i.x+i.width,y:u};break;case"left":p={x:i.x-n.width,y:u};break;default:p={x:i.x,y:i.y}}switch(Pt(t)){case"start":p[a]-=d*(s&&l?-1:1);break;case"end":p[a]+=d*(s&&l?-1:1)}return p}async function Jt(e,t){var s;void 0===t&&(t={});const{x:i,y:n,platform:r,rects:a,elements:o,strategy:c}=e,{boundary:l="clippingAncestors",rootBoundary:h="viewport",elementContext:u="floating",altBoundary:d=!1,padding:p=0}=_t(t,e),m=function(e){return"number"!=typeof e?function(e){return{top:0,right:0,bottom:0,left:0,...e}}(e):{top:e,right:e,bottom:e,left:e}}(p),g=o[d?"floating"===u?"reference":"floating":u],f=Kt(await r.getClippingRect({element:null==(s=await(null==r.isElement?void 0:r.isElement(g)))||s?g:g.contextElement||await(null==r.getDocumentElement?void 0:r.getDocumentElement(o.floating)),boundary:l,rootBoundary:h,strategy:c})),b="floating"===u?{x:i,y:n,width:a.floating.width,height:a.floating.height}:a.reference,y=await(null==r.getOffsetParent?void 0:r.getOffsetParent(o.floating)),v=await(null==r.isElement?void 0:r.isElement(y))&&await(null==r.getScale?void 0:r.getScale(y))||{x:1,y:1},w=Kt(r.convertOffsetParentRelativeRectToViewportRelativeRect?await r.convertOffsetParentRelativeRectToViewportRelativeRect({elements:o,rect:b,offsetParent:y,strategy:c}):b);return{top:(f.top-w.top+m.top)/v.y,bottom:(w.bottom-f.bottom+m.bottom)/v.y,left:(f.left-w.left+m.left)/v.x,right:(w.right-f.right+m.right)/v.x}}const Yt=new Set(["left","top"]);function Zt(){return"undefined"!=typeof window}function Xt(e){return ts(e)?(e.nodeName||"").toLowerCase():"#document"}function Qt(e){var t;return(null==e||null==(t=e.ownerDocument)?void 0:t.defaultView)||window}function es(e){var t;return null==(t=(ts(e)?e.ownerDocument:e.document)||window.document)?void 0:t.documentElement}function ts(e){return!!Zt()&&(e instanceof Node||e instanceof Qt(e).Node)}function ss(e){return!!Zt()&&(e instanceof Element||e instanceof Qt(e).Element)}function is(e){return!!Zt()&&(e instanceof HTMLElement||e instanceof Qt(e).HTMLElement)}function ns(e){return!(!Zt()||"undefined"==typeof ShadowRoot)&&(e instanceof ShadowRoot||e instanceof Qt(e).ShadowRoot)}const rs=new Set(["inline","contents"]);function as(e){const{overflow:t,overflowX:s,overflowY:i,display:n}=ys(e);return/auto|scroll|overlay|hidden|clip/.test(t+i+s)&&!rs.has(n)}const os=new Set(["table","td","th"]);function cs(e){return os.has(Xt(e))}const ls=[":popover-open",":modal"];function hs(e){return ls.some(t=>{try{return e.matches(t)}catch(e){return!1}})}const us=["transform","translate","scale","rotate","perspective"],ds=["transform","translate","scale","rotate","perspective","filter"],ps=["paint","layout","strict","content"];function ms(e){const t=gs(),s=ss(e)?ys(e):e;return us.some(e=>!!s[e]&&"none"!==s[e])||!!s.containerType&&"normal"!==s.containerType||!t&&!!s.backdropFilter&&"none"!==s.backdropFilter||!t&&!!s.filter&&"none"!==s.filter||ds.some(e=>(s.willChange||"").includes(e))||ps.some(e=>(s.contain||"").includes(e))}function gs(){return!("undefined"==typeof CSS||!CSS.supports)&&CSS.supports("-webkit-backdrop-filter","none")}const fs=new Set(["html","body","#document"]);function bs(e){return fs.has(Xt(e))}function ys(e){return Qt(e).getComputedStyle(e)}function vs(e){return ss(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function ws(e){if("html"===Xt(e))return e;const t=e.assignedSlot||e.parentNode||ns(e)&&e.host||es(e);return ns(t)?t.host:t}function Ts(e){const t=ws(e);return bs(t)?e.ownerDocument?e.ownerDocument.body:e.body:is(t)&&as(t)?t:Ts(t)}function Ss(e,t,s){var i;void 0===t&&(t=[]),void 0===s&&(s=!0);const n=Ts(e),r=n===(null==(i=e.ownerDocument)?void 0:i.body),a=Qt(n);if(r){const e=Cs(a);return t.concat(a,a.visualViewport||[],as(n)?n:[],e&&s?Ss(e):[])}return t.concat(n,Ss(n,[],s))}function Cs(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}function Os(e){const t=ys(e);let s=parseFloat(t.width)||0,i=parseFloat(t.height)||0;const n=is(e),r=n?e.offsetWidth:s,a=n?e.offsetHeight:i,o=Et(s)!==r||Et(i)!==a;return o&&(s=r,i=a),{width:s,height:i,$:o}}function As(e){return ss(e)?e:e.contextElement}function Es(e){const t=As(e);if(!is(t))return Mt(1);const s=t.getBoundingClientRect(),{width:i,height:n,$:r}=Os(t);let a=(r?Et(s.width):s.width)/i,o=(r?Et(s.height):s.height)/n;return a&&Number.isFinite(a)||(a=1),o&&Number.isFinite(o)||(o=1),{x:a,y:o}}const xs=Mt(0);function Ms(e){const t=Qt(e);return gs()&&t.visualViewport?{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}:xs}function ks(e,t,s,i){void 0===t&&(t=!1),void 0===s&&(s=!1);const n=e.getBoundingClientRect(),r=As(e);let a=Mt(1);t&&(i?ss(i)&&(a=Es(i)):a=Es(e));const o=function(e,t,s){return void 0===t&&(t=!1),!(!s||t&&s!==Qt(e))&&t}(r,s,i)?Ms(r):Mt(0);let c=(n.left+o.x)/a.x,l=(n.top+o.y)/a.y,h=n.width/a.x,u=n.height/a.y;if(r){const e=Qt(r),t=i&&ss(i)?Qt(i):i;let s=e,n=Cs(s);for(;n&&i&&t!==s;){const e=Es(n),t=n.getBoundingClientRect(),i=ys(n),r=t.left+(n.clientLeft+parseFloat(i.paddingLeft))*e.x,a=t.top+(n.clientTop+parseFloat(i.paddingTop))*e.y;c*=e.x,l*=e.y,h*=e.x,u*=e.y,c+=r,l+=a,s=Qt(n),n=Cs(s)}}return Kt({width:h,height:u,x:c,y:l})}function Is(e,t){const s=vs(e).scrollLeft;return t?t.left+s:ks(es(e)).left+s}function Ls(e,t,s){void 0===s&&(s=!1);const i=e.getBoundingClientRect();return{x:i.left+t.scrollLeft-(s?0:Is(e,i)),y:i.top+t.scrollTop}}const _s=new Set(["absolute","fixed"]);function Ns(e,t,s){let i;if("viewport"===t)i=function(e,t){const s=Qt(e),i=es(e),n=s.visualViewport;let r=i.clientWidth,a=i.clientHeight,o=0,c=0;if(n){r=n.width,a=n.height;const e=gs();(!e||e&&"fixed"===t)&&(o=n.offsetLeft,c=n.offsetTop)}return{width:r,height:a,x:o,y:c}}(e,s);else if("document"===t)i=function(e){const t=es(e),s=vs(e),i=e.ownerDocument.body,n=At(t.scrollWidth,t.clientWidth,i.scrollWidth,i.clientWidth),r=At(t.scrollHeight,t.clientHeight,i.scrollHeight,i.clientHeight);let a=-s.scrollLeft+Is(e);const o=-s.scrollTop;return"rtl"===ys(i).direction&&(a+=At(t.clientWidth,i.clientWidth)-n),{width:n,height:r,x:a,y:o}}(es(e));else if(ss(t))i=function(e,t){const s=ks(e,!0,"fixed"===t),i=s.top+e.clientTop,n=s.left+e.clientLeft,r=is(e)?Es(e):Mt(1);return{width:e.clientWidth*r.x,height:e.clientHeight*r.y,x:n*r.x,y:i*r.y}}(t,s);else{const s=Ms(e);i={x:t.x-s.x,y:t.y-s.y,width:t.width,height:t.height}}return Kt(i)}function Ps(e,t){const s=ws(e);return!(s===t||!ss(s)||bs(s))&&("fixed"===ys(s).position||Ps(s,t))}function Fs(e,t,s){const i=is(t),n=es(t),r="fixed"===s,a=ks(e,!0,r,t);let o={scrollLeft:0,scrollTop:0};const c=Mt(0);function l(){c.x=Is(n)}if(i||!i&&!r)if(("body"!==Xt(t)||as(n))&&(o=vs(t)),i){const e=ks(t,!0,r,t);c.x=e.x+t.clientLeft,c.y=e.y+t.clientTop}else n&&l();r&&!i&&n&&l();const h=!n||i||r?Mt(0):Ls(n,o);return{x:a.left+o.scrollLeft-c.x-h.x,y:a.top+o.scrollTop-c.y-h.y,width:a.width,height:a.height}}function Rs(e){return"static"===ys(e).position}function Ds(e,t){if(!is(e)||"fixed"===ys(e).position)return null;if(t)return t(e);let s=e.offsetParent;return es(e)===s&&(s=s.ownerDocument.body),s}function js(e,t){const s=Qt(e);if(hs(e))return s;if(!is(e)){let t=ws(e);for(;t&&!bs(t);){if(ss(t)&&!Rs(t))return t;t=ws(t)}return s}let i=Ds(e,t);for(;i&&cs(i)&&Rs(i);)i=Ds(i,t);return i&&bs(i)&&Rs(i)&&!ms(i)?s:i||function(e){let t=ws(e);for(;is(t)&&!bs(t);){if(ms(t))return t;if(hs(t))return null;t=ws(t)}return null}(e)||s}const Bs={convertOffsetParentRelativeRectToViewportRelativeRect:function(e){let{elements:t,rect:s,offsetParent:i,strategy:n}=e;const r="fixed"===n,a=es(i),o=!!t&&hs(t.floating);if(i===a||o&&r)return s;let c={scrollLeft:0,scrollTop:0},l=Mt(1);const h=Mt(0),u=is(i);if((u||!u&&!r)&&(("body"!==Xt(i)||as(a))&&(c=vs(i)),is(i))){const e=ks(i);l=Es(i),h.x=e.x+i.clientLeft,h.y=e.y+i.clientTop}const d=!a||u||r?Mt(0):Ls(a,c,!0);return{width:s.width*l.x,height:s.height*l.y,x:s.x*l.x-c.scrollLeft*l.x+h.x+d.x,y:s.y*l.y-c.scrollTop*l.y+h.y+d.y}},getDocumentElement:es,getClippingRect:function(e){let{element:t,boundary:s,rootBoundary:i,strategy:n}=e;const r=[..."clippingAncestors"===s?hs(t)?[]:function(e,t){const s=t.get(e);if(s)return s;let i=Ss(e,[],!1).filter(e=>ss(e)&&"body"!==Xt(e)),n=null;const r="fixed"===ys(e).position;let a=r?ws(e):e;for(;ss(a)&&!bs(a);){const t=ys(a),s=ms(a);s||"fixed"!==t.position||(n=null),(r?!s&&!n:!s&&"static"===t.position&&n&&_s.has(n.position)||as(a)&&!s&&Ps(e,a))?i=i.filter(e=>e!==a):n=t,a=ws(a)}return t.set(e,i),i}(t,this._c):[].concat(s),i],a=r[0],o=r.reduce((e,s)=>{const i=Ns(t,s,n);return e.top=At(i.top,e.top),e.right=Ot(i.right,e.right),e.bottom=Ot(i.bottom,e.bottom),e.left=At(i.left,e.left),e},Ns(t,a,n));return{width:o.right-o.left,height:o.bottom-o.top,x:o.left,y:o.top}},getOffsetParent:js,getElementRects:async function(e){const t=this.getOffsetParent||js,s=this.getDimensions,i=await s(e.floating);return{reference:Fs(e.reference,await t(e.floating),e.strategy),floating:{x:0,y:0,width:i.width,height:i.height}}},getClientRects:function(e){return Array.from(e.getClientRects())},getDimensions:function(e){const{width:t,height:s}=Os(e);return{width:t,height:s}},getScale:Es,isElement:ss,isRTL:function(e){return"rtl"===ys(e).direction}};function $s(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}const Vs=function(e){return void 0===e&&(e=0),{name:"offset",options:e,async fn(t){var s,i;const{x:n,y:r,placement:a,middlewareData:o}=t,c=await async function(e,t){const{placement:s,platform:i,elements:n}=e,r=await(null==i.isRTL?void 0:i.isRTL(n.floating)),a=Nt(s),o=Pt(s),c="y"===jt(s),l=Yt.has(a)?-1:1,h=r&&c?-1:1,u=_t(t,e);let{mainAxis:d,crossAxis:p,alignmentAxis:m}="number"==typeof u?{mainAxis:u,crossAxis:0,alignmentAxis:null}:{mainAxis:u.mainAxis||0,crossAxis:u.crossAxis||0,alignmentAxis:u.alignmentAxis};return o&&"number"==typeof m&&(p="end"===o?-1*m:m),c?{x:p*h,y:d*l}:{x:d*l,y:p*h}}(t,e);return a===(null==(s=o.offset)?void 0:s.placement)&&null!=(i=o.arrow)&&i.alignmentOffset?{}:{x:n+c.x,y:r+c.y,data:{...c,placement:a}}}}},qs=function(e){return void 0===e&&(e={}),{name:"shift",options:e,async fn(t){const{x:s,y:i,placement:n}=t,{mainAxis:r=!0,crossAxis:a=!1,limiter:o={fn:e=>{let{x:t,y:s}=e;return{x:t,y:s}}},...c}=_t(e,t),l={x:s,y:i},h=await Jt(t,c),u=jt(Nt(n)),d=Ft(u);let p=l[d],m=l[u];if(r){const e="y"===d?"bottom":"right";p=Lt(p+h["y"===d?"top":"left"],p,p-h[e])}if(a){const e="y"===u?"bottom":"right";m=Lt(m+h["y"===u?"top":"left"],m,m-h[e])}const g=o.fn({...t,[d]:p,[u]:m});return{...g,data:{x:g.x-s,y:g.y-i,enabled:{[d]:r,[u]:a}}}}}},Us=function(e){return void 0===e&&(e={}),{name:"flip",options:e,async fn(t){var s,i;const{placement:n,middlewareData:r,rects:a,initialPlacement:o,platform:c,elements:l}=t,{mainAxis:h=!0,crossAxis:u=!0,fallbackPlacements:d,fallbackStrategy:p="bestFit",fallbackAxisSideDirection:m="none",flipAlignment:g=!0,...f}=_t(e,t);if(null!=(s=r.arrow)&&s.alignmentOffset)return{};const b=Nt(n),y=jt(o),v=Nt(o)===o,w=await(null==c.isRTL?void 0:c.isRTL(l.floating)),T=d||(v||!g?[Ht(o)]:function(e){const t=Ht(e);return[Vt(e),t,Vt(t)]}(o)),S="none"!==m;!d&&S&&T.push(...function(e,t,s,i){const n=Pt(e);let r=function(e,t,s){switch(e){case"top":case"bottom":return s?t?Ut:qt:t?qt:Ut;case"left":case"right":return t?zt:Wt;default:return[]}}(Nt(e),"start"===s,i);return n&&(r=r.map(e=>e+"-"+n),t&&(r=r.concat(r.map(Vt)))),r}(o,g,m,w));const C=[o,...T],O=await Jt(t,f),A=[];let E=(null==(i=r.flip)?void 0:i.overflows)||[];if(h&&A.push(O[b]),u){const e=$t(n,a,w);A.push(O[e[0]],O[e[1]])}if(E=[...E,{placement:n,overflows:A}],!A.every(e=>e<=0)){var x,M;const e=((null==(x=r.flip)?void 0:x.index)||0)+1,t=C[e];if(t&&("alignment"!==u||y===jt(t)||E.every(e=>jt(e.placement)!==y||e.overflows[0]>0)))return{data:{index:e,overflows:E},reset:{placement:t}};let s=null==(M=E.filter(e=>e.overflows[0]<=0).sort((e,t)=>e.overflows[1]-t.overflows[1])[0])?void 0:M.placement;if(!s)switch(p){case"bestFit":{var k;const e=null==(k=E.filter(e=>{if(S){const t=jt(e.placement);return t===y||"y"===t}return!0}).map(e=>[e.placement,e.overflows.filter(e=>e>0).reduce((e,t)=>e+t,0)]).sort((e,t)=>e[1]-t[1])[0])?void 0:k[0];e&&(s=e);break}case"initialPlacement":s=o}if(n!==s)return{reset:{placement:s}}}return{}}}},zs=e=>{Object.assign(e,{show(){this.cancelBehaviourOpen?.(),this.openValue=!0},hide(){this.openValue=!1},toggle(){this.cancelBehaviourOpen?.(),this.openValue=!this.openValue},setupFloatingUI({trigger:e,popover:t,strategy:s}){this.floatingUICleanup=function(e,t,s,i){void 0===i&&(i={});const{ancestorScroll:n=!0,ancestorResize:r=!0,elementResize:a="function"==typeof ResizeObserver,layoutShift:o="function"==typeof IntersectionObserver,animationFrame:c=!1}=i,l=As(e),h=n||r?[...l?Ss(l):[],...Ss(t)]:[];h.forEach(e=>{n&&e.addEventListener("scroll",s,{passive:!0}),r&&e.addEventListener("resize",s)});const u=l&&o?function(e,t){let s,i=null;const n=es(e);function r(){var e;clearTimeout(s),null==(e=i)||e.disconnect(),i=null}return function a(o,c){void 0===o&&(o=!1),void 0===c&&(c=1),r();const l=e.getBoundingClientRect(),{left:h,top:u,width:d,height:p}=l;if(o||t(),!d||!p)return;const m={rootMargin:-xt(u)+"px "+-xt(n.clientWidth-(h+d))+"px "+-xt(n.clientHeight-(u+p))+"px "+-xt(h)+"px",threshold:At(0,Ot(1,c))||1};let g=!0;function f(t){const i=t[0].intersectionRatio;if(i!==c){if(!g)return a();i?a(!1,i):s=setTimeout(()=>{a(!1,1e-7)},1e3)}1!==i||$s(l,e.getBoundingClientRect())||a(),g=!1}try{i=new IntersectionObserver(f,{...m,root:n.ownerDocument})}catch(e){i=new IntersectionObserver(f,m)}i.observe(e)}(!0),r}(l,s):null;let d,p=-1,m=null;a&&(m=new ResizeObserver(e=>{let[i]=e;i&&i.target===l&&m&&(m.unobserve(t),cancelAnimationFrame(p),p=requestAnimationFrame(()=>{var e;null==(e=m)||e.observe(t)})),s()}),l&&!c&&m.observe(l),m.observe(t));let g=c?ks(e):null;return c&&function t(){const i=ks(e);g&&!$s(g,i)&&s(),g=i,d=requestAnimationFrame(t)}(),s(),()=>{var e;h.forEach(e=>{n&&e.removeEventListener("scroll",s),r&&e.removeEventListener("resize",s)}),null==u||u(),null==(e=m)||e.disconnect(),m=null,c&&cancelAnimationFrame(d)}}(e,t,()=>{((e,t,s)=>{const i=new Map,n={platform:Bs,...s},r={...n.platform,_c:i};return(async(e,t,s)=>{const{placement:i="bottom",strategy:n="absolute",middleware:r=[],platform:a}=s,o=r.filter(Boolean),c=await(null==a.isRTL?void 0:a.isRTL(t));let l=await a.getElementRects({reference:e,floating:t,strategy:n}),{x:h,y:u}=Gt(l,i,c),d=i,p={},m=0;for(let s=0;s{const n={left:`${e}px`,top:`${s}px`,position:i};Object.assign(t.style,n)})})},openValueChanged(){this.disabledValue||(this.openValue?(this.preparePopoverOpenAnimation?.(),this.popoverTarget.showPopover(),this.popoverTarget.setAttribute("aria-expanded","true"),this.onPopoverOpened&&this.onPopoverOpened()):(this.popoverTarget.hidePopover(),this.popoverTarget.removeAttribute("aria-expanded"),this.onPopoverClosed&&this.onPopoverClosed()))}})},Ws=class extends i.xI{static targets=["button","popover"];static values={placement:{type:String,default:"bottom-end"},open:{type:Boolean,default:!1},autoPlacement:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},size:{type:Number,default:24},perLine:{type:Number,default:9}};initialize(){this.onEmojiSelect=this.onEmojiSelect.bind(this),this.pickerLoaded=!1,this.pickerLoadPromise=null,this.connected=!1,super.initialize()}connect(){this.connected=!0,zs(this),this.setupFloatingUI({trigger:this.buttonTarget,popover:this.popoverTarget,strategy:"absolute"}),super.connect()}disconnect(){this.connected=!1,this.pickerLoadPromise=null,this.floatingUICleanup(),super.disconnect()}onEmojiSelect(e){this.dispatch("selected",{detail:e.native}),this.hide()}onClickOutside(e){this.openValue&&e.target.nodeType&&!1===this.element.contains(e.target)&&(this.openValue=!1)}async onPopoverOpened(){await this.loadPicker()}async loadPicker(){if(this.pickerLoaded)return;this.pickerLoadPromise||=this.loadPickerDependencies();const{Picker:e,i18n:t}=await this.pickerLoadPromise;this.connected&&!this.pickerLoaded&&(this.popoverTarget.appendChild(this.buildPicker(e,t)),this.pickerLoaded=!0)}async loadPickerDependencies(){const[e,t]=await Promise.all([s.e(160).then(s.bind(s,405)),this.loadI18n()]);return{Picker:e.Picker,i18n:t.default||t}}loadI18n(){return"es"===Hellotext.business.locale?s.e(437).then(s.t.bind(s,9,19)):s.e(200).then(s.t.bind(s,714,19))}buildPicker(e,t){return new e({onEmojiSelect:this.onEmojiSelect,theme:"light",dynamicWidth:!0,previewPosition:"none",skinTonePosition:"none",emojiSize:this.sizeValue,perLine:this.perLineValue,i18n:t})}get middlewares(){return[Vs(5),qs({padding:24}),(e={allowedPlacements:["top","bottom"]},void 0===e&&(e={}),{name:"autoPlacement",options:e,async fn(t){var s,i,n;const{rects:r,middlewareData:a,placement:o,platform:c,elements:l}=t,{crossAxis:h=!1,alignment:u,allowedPlacements:d=Ct,autoAlignment:p=!0,...m}=_t(e,t),g=void 0!==u||d===Ct?function(e,t,s){return(e?[...s.filter(t=>Pt(t)===e),...s.filter(t=>Pt(t)!==e)]:s.filter(e=>Nt(e)===e)).filter(s=>!e||Pt(s)===e||!!t&&Vt(s)!==s)}(u||null,p,d):d,f=await Jt(t,m),b=(null==(s=a.autoPlacement)?void 0:s.index)||0,y=g[b];if(null==y)return{};const v=$t(y,r,await(null==c.isRTL?void 0:c.isRTL(l.floating)));if(o!==y)return{reset:{placement:g[0]}};const w=[f[Nt(y)],f[v[0]],f[v[1]]],T=[...(null==(i=a.autoPlacement)?void 0:i.overflows)||[],{placement:y,overflows:w}],S=g[b+1];if(S)return{data:{index:b+1,overflows:T},reset:{placement:S}};const C=T.map(e=>{const t=Pt(e.placement);return[e.placement,t&&h?e.overflows.slice(0,2).reduce((e,t)=>e+t,0):e.overflows[0],e.overflows]}).sort((e,t)=>e[1]-t[1]),O=(null==(n=C.filter(e=>e[2].slice(0,Pt(e[0])?2:3).every(e=>e<=0))[0])?void 0:n[0])||C[0][0];return O!==o?{data:{index:b+1,overflows:T},reset:{placement:O}}:{}}})];var e}};class Hs{static get endpoint(){return g.endpoint("public/webchats/:id/messages")}constructor(e){this.webchatId=e}async index(e){const t=new URL(this.url);return Object.entries(e).forEach(([e,s])=>{t.searchParams.append(e,s)}),await fetch(t,{method:"GET",headers:bt.headers})}catchUp(e){return this.index({after_id:e,session:bt.session})}async create(e){const t=await fetch(this.url,{method:"POST",headers:{Authorization:`Bearer ${bt.business.id}`},body:e});return new y(t.ok,t)}markAsSeen(e=null){const t=e?this.url+`/${e}`:this.url+"/seen";fetch(t,{method:"PATCH",headers:bt.headers,body:JSON.stringify({session:bt.session})})}get url(){return Hs.endpoint.replace(":id",this.webchatId)}}const Ks=Hs;class Gs{static webSocket;static channels=new Set;static messageHandlers=new Set;static disconnectHandlers=new Set;static subscriptionConfirmHandlers=new Set;static reconnectTimeout=null;static reconnectAttempts=0;static reconnectBaseDelay=500;static reconnectMaxDelay=1e4;static reconnectJitter=.3;static needsResubscribe=!1;constructor(){Gs.channels.add(this)}send({command:e,identifier:t,data:s}){const i={command:e,identifier:JSON.stringify(t),data:JSON.stringify(s||{})},n=Gs.ensureWebSocket(),r=JSON.stringify(i);n.readyState===WebSocket.OPEN?n.send(r):n.addEventListener("open",()=>{n.send(r)})}onMessage(e){const t=t=>{const s=JSON.parse(t.data),{type:i,message:n}=s;this.ignoredEvents.includes(i)||e(n)};Gs.messageHandlers.add(t),Gs.ensureWebSocket().addEventListener("message",t)}onDisconnect(e){Gs.disconnectHandlers.add(e)}onSubscriptionConfirmed(e){Gs.subscriptionConfirmHandlers.add(e)}get webSocket(){return Gs.ensureWebSocket()}static ensureWebSocket(){return this.webSocket&&!this.closedWebSocket(this.webSocket)?this.webSocket:(this.webSocket&&(this.needsResubscribe=!0),this.openWebSocket())}static openWebSocket(){this.clearReconnectTimeout();const e=new WebSocket(g.actionCableUrl);return this.webSocket=e,this.installWebSocketHandlers(e),e}static installWebSocketHandlers(e){e.addEventListener("open",()=>this.handleOpen(e)),e.addEventListener("close",()=>this.handleDisconnect(e)),e.addEventListener("error",()=>this.handleDisconnect(e)),e.addEventListener("message",e=>this.handleControlMessage(e)),this.messageHandlers.forEach(t=>{e.addEventListener("message",t)})}static handleOpen(e){e===this.webSocket&&(this.reconnectAttempts=0,this.needsResubscribe&&(this.needsResubscribe=!1,this.resubscribeChannels()))}static handleControlMessage(e){let t;try{t=JSON.parse(e.data)}catch{return}"confirm_subscription"===t.type&&this.subscriptionConfirmHandlers.forEach(e=>e(t.identifier))}static handleDisconnect(e){e===this.webSocket&&(this.disconnectHandlers.forEach(e=>e()),this.webSocket=null,this.needsResubscribe=!0,this.scheduleReconnect())}static scheduleReconnect(){this.reconnectTimeout||(this.reconnectTimeout=setTimeout(()=>{this.reconnectTimeout=null,this.reconnectAttempts+=1,this.openWebSocket()},this.reconnectDelay))}static clearReconnectTimeout(){this.reconnectTimeout&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=null)}static resubscribeChannels(){this.channels.forEach(e=>{const t=e.resubscribe||e.subscribe;"function"==typeof t&&t.call(e)})}static closedWebSocket(e){return e.readyState===WebSocket.CLOSED||e.readyState===WebSocket.CLOSING}static get reconnectDelay(){const e=Math.min(this.reconnectMaxDelay,this.reconnectBaseDelay*2**this.reconnectAttempts);return e+Math.round(e*this.reconnectJitter*Math.random())}get ignoredEvents(){return["ping","confirm_subscription","welcome"]}}const Js=Gs,Ys=class extends Js{constructor(e,t,s){super(),this.id=e,this.session=t,this.conversation=s,this.subscribed=!1,this.awaitingReconnectConfirmation=!1,this.reconnectCallbacks=new Set,this.onSubscriptionConfirmed(e=>this.handleSubscriptionConfirmed(e)),this.subscribe()}subscribe(){this.subscribed=!0;const e={channel:"WebchatChannel",id:this.id,session:this.session,conversation:this.conversation};this.send({command:"subscribe",identifier:e})}unsubscribe(){this.subscribed=!1;const e={channel:"WebchatChannel",id:this.id,session:this.session,conversation:this.conversation};this.send({command:"unsubscribe",identifier:e})}resubscribe(){!1!==this.subscribed&&(this.awaitingReconnectConfirmation=!0,this.subscribe())}onReconnect(e){this.reconnectCallbacks.add(e)}handleSubscriptionConfirmed(e){this.awaitingReconnectConfirmation&&this.matchesIdentifier(e)&&(this.awaitingReconnectConfirmation=!1,this.reconnectCallbacks.forEach(e=>e()))}matchesIdentifier(e){let t;try{t="string"==typeof e?JSON.parse(e):e}catch{return!1}return"WebchatChannel"===t.channel&&t.id===this.id&&t.session===this.session&&t.conversation===this.conversation}startTypingIndicator(){const e={channel:"WebchatChannel",id:this.id,session:this.session,conversation:this.conversation};this.send({command:"message",identifier:e,data:{action:"started_typing"}})}stopTypingIndicator(){const e={channel:"WebchatChannel",id:this.id,session:this.session,conversation:this.conversation};this.send({command:"typing:stop",identifier:e,data:{action:"stopped_typing"}})}onMessage(e){super.onMessage(t=>{"message"===t.type&&e(t)})}onReaction(e){super.onMessage(t=>{"reaction.create"!==t.type&&"reaction.destroy"!==t.type||e(t)})}onTypingStart(e){super.onMessage(t=>{"started_typing"===t.type&&e(t)})}updateSubscriptionWith(e){this.unsubscribe(),setTimeout(()=>{this.conversation=e,this.subscribe()},1e3)}},Zs=e=>{Object.assign(e,{scheduleBehaviourOpen(){if(!this.shouldAutoOpenFromBehaviour())return;const e=1e3*Number(this.behaviourValue.delay_seconds||0);this.behaviourOpenTimeout=window.setTimeout(()=>{this.behaviourOpenTimeout=null,this.openValue||(this.openValue=!0,this.markBehaviourAutoOpened())},e)},cancelBehaviourOpen(){window.clearTimeout(this.behaviourOpenTimeout),this.behaviourOpenTimeout=null},shouldAutoOpenFromBehaviour(){const e=this.behaviourValue;return!(!e||"on_load"!==e.trigger||e.first_visit_only&&localStorage.getItem(this.firstVisitKey())||e.once_per_session&&sessionStorage.getItem(this.sessionKey()))},markBehaviourAutoOpened(){this.behaviourValue.first_visit_only&&localStorage.setItem(this.firstVisitKey(),"1"),this.behaviourValue.once_per_session&&sessionStorage.setItem(this.sessionKey(),"1")},firstVisitKey(){return`hellotext--webchat--${this.idValue}--auto-opened`},sessionKey(){return`hellotext--webchat--${this.idValue}--auto-opened-session`}})},Xs=e=>{Object.assign(e,{setupOpeningSequence(){this.openingSequenceStarted=!1,this.openingSequenceCancelled=!1,this.openingSequenceTimeout=null,this.openingSequenceMessages=[],this.revealedOpeningSequenceMessageIds=[]},teardownOpeningSequence(){this.cancelOpeningSequence()},startOpeningSequence(){this.openingSequenceMessages=Array.from(this.openingSequenceMessageTargets||[]),this.openingSequenceCanStart()&&(this.openingSequenceStarted=!0,this.openingSequenceCancelled=!1,this.revealedOpeningSequenceMessageIds=[],this.playOpeningSequenceMessageAt(0))},openingSequenceCanStart(){return!this.conversationIdValue&&this.hasOpeningSequenceTarget&&this.openingSequenceMessages.length>0&&!this.openingSequenceStarted},playOpeningSequenceMessageAt(e){const t=this.openingSequenceMessages[e];if(!t)return;const s=1e3*this.openingSequenceMessageDelay(t);this.openingSequenceTimeout=window.setTimeout(()=>{this.openingSequenceTimeout=null,this.openingSequenceCancelled||(this.revealOpeningSequenceMessage(t),this.playOpeningSequenceMessageAt(e+1))},s)},revealOpeningSequenceMessage(e){this.messagesContainerTarget.insertBefore(e,this.messageTemplateTarget),e.hidden=!1,this.recordOpeningSequenceMessage(e),this.scrollOpeningSequenceToBottom()},recordOpeningSequenceMessage(e){const t=e.dataset.openingSequenceMessageId;t&&!this.revealedOpeningSequenceMessageIds.includes(t)&&this.revealedOpeningSequenceMessageIds.push(t)},openingSequenceMessageDelay(e){const t=Number(e.dataset.delaySeconds||0);return Number.isFinite(t)?t:0},scrollOpeningSequenceToBottom(){this.messagesContainerTarget.scroll&&this.messagesContainerTarget.scroll({top:this.messagesContainerTarget.scrollHeight,behavior:"smooth"})},cancelOpeningSequence(){this.openingSequenceCancelled=!0,null!==this.openingSequenceTimeout&&void 0!==this.openingSequenceTimeout&&(window.clearTimeout(this.openingSequenceTimeout),this.openingSequenceTimeout=null)},appendOpeningSequenceMessageIds(e){this.cancelOpeningSequence(),(this.revealedOpeningSequenceMessageIds||[]).forEach(t=>{e.append("message[opening_sequence_message_ids][]",t)})},clearRevealedOpeningSequenceMessageIds(){this.revealedOpeningSequenceMessageIds=[]}})},Qs=e=>{Object.assign(e,{setupTeaser(){this.teaserCycleTimeout=null,this.teaserMessages=[],this.boundOnTeaserClick=this.boundOnTeaserClick||this.onTeaserClick.bind(this),this.hasTeaserTarget&&(this.teaserTarget.addEventListener("click",this.boundOnTeaserClick),this.startTeaserPresentation())},teardownTeaser(){this.stopTeaserCycle(),this.hasTeaserTarget&&this.boundOnTeaserClick&&this.teaserTarget.removeEventListener("click",this.boundOnTeaserClick)},collectTeaserMessages(){return this.hasTeaserTarget?Array.from(this.teaserTarget.querySelectorAll("[data-teaser-message]")):[]},startTeaserPresentation(){this.stopTeaserCycle(),this.teaserMessages=this.collectTeaserMessages(),this.hasTeaserTarget&&(0!==this.teaserMessages.length?this.openValue||this.conversationIdValue||this.hasRenderedConversationMessages()?this.dismissTeaserForSession():this.teaserSeenForSession()?this.hideTeaser():(this.teaserTarget.classList.remove("invisible"),this.showTeaserMessage(0),this.teaserMessages.length<2||this.scheduleNextTeaserMessage(0)):this.hideTeaser())},scheduleNextTeaserMessage(e){const t=e+1;if(t>=this.teaserMessages.length)return;const s=this.teaserMessages[e],i=this.teaserPresentationDelay(s);this.teaserCycleTimeout=window.setTimeout(()=>{this.teaserCycleTimeout=null,this.showTeaserMessage(t),this.scheduleNextTeaserMessage(t)},i)},showTeaserMessage(e){this.teaserMessages.forEach((t,s)=>{t.classList.toggle("hidden",s!==e)})},stopTeaserCycle(){null!==this.teaserCycleTimeout&&void 0!==this.teaserCycleTimeout&&(window.clearTimeout(this.teaserCycleTimeout),this.teaserCycleTimeout=null)},teaserMessageDelay(e){const t=Number(e.dataset.delaySeconds||0);return Number.isFinite(t)?t:0},teaserPresentationDelay(e){return Math.max(1e3*this.teaserMessageDelay(e),250)},hasRenderedConversationMessages(){let e=[];try{e=Array.from(this.messageTargets||[])}catch(t){e=[]}return e.some(e=>e!==this.messageTemplateTarget)},teaserSeenKey(){const e=this.hasTeaserTarget?this.teaserTarget.dataset.teaserVersion:"",t=e?`:${e}`:"";return`hellotext:webchat:${this.idValue||this.element.id}:teaser-seen${t}`},teaserSeenForSession(){try{return"true"===window.sessionStorage.getItem(this.teaserSeenKey())}catch(e){return!1}},markTeaserSeenForSession(){try{window.sessionStorage.setItem(this.teaserSeenKey(),"true")}catch(e){}},dismissTeaserForSession(){this.markTeaserSeenForSession(),this.hideTeaser()},hideTeaser(){this.stopTeaserCycle(),this.hasTeaserTarget&&this.teaserTarget.classList.add("invisible")},onTeaserClick(e){e.target.closest("a")||(this.dismissTeaserForSession(),this.show())}})},ei={hour:"numeric",minute:"2-digit"},ti=/Android|iPhone|iPad|iPod/i,si={capture:!0,passive:!0},ii=class extends i.xI{static messageTimestampFormatters={};static values={id:String,conversationId:String,media:Object,fileSizeErrorMessage:String,placement:{type:String,default:"bottom-end"},open:{type:Boolean,default:!1},autoPlacement:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},nextPage:{type:Number,default:void 0},fullScreenThreshold:{type:Number,default:1024},typingIndicatorKeepAlive:{type:Number,default:3e4},offset:{type:Number,default:24},padding:{type:Number,default:24},optimisticTypingIndicatorWait:{type:Number,default:1e3},teaser:Object,messageTeaser:String,behaviour:Object};static classes=["fadeOut"];static targets=["trigger","popover","input","attachmentInput","attachmentButton","errorMessageContainer","attachmentTemplate","attachmentContainer","attachment","messageTemplate","messagesContainer","title","attachmentImage","footer","toolbar","message","unreadCounter","typingIndicator","typingIndicatorTemplate","teaser","teaserMessage","inboundMessageTeaser","inboundMessageTeaserBody","openingSequence","openingSequenceMessage"];initialize(){this.messagesAPI=new Ks(this.idValue),this.webChatChannel=new Ys(this.idValue,bt.session,this.conversationIdValue),this.files=[],this.messageIds=new Set,this.catchUpAfterMessageId=null,this.fetchingCatchUpMessages=!1,this.onMessageReceived=this.onMessageReceived.bind(this),this.onMessageReaction=this.onMessageReaction.bind(this),this.onTypingStart=this.onTypingStart.bind(this),this.captureCatchUpCursor=this.captureCatchUpCursor.bind(this),this.catchUpMessages=this.catchUpMessages.bind(this),this.onScroll=this.onScroll.bind(this),this.onOutboundMessageSent=this.onOutboundMessageSent.bind(this),this.closePopoverOnEscape=this.closePopoverOnEscape.bind(this),this.broadcastChannel=new BroadcastChannel(`hellotext--webchat--${this.idValue}`),this.webChatChannel.onDisconnect(this.captureCatchUpCursor),this.webChatChannel.onReconnect(this.catchUpMessages),super.initialize()}connect(){Zs(this),zs(this),Xs(this),Qs(this),this.setupFloatingUI({trigger:this.triggerTarget,popover:this.popoverTarget}),this.hasTeaserTarget&&this.setupFloatingUI({trigger:this.triggerTarget,popover:this.teaserTarget,strategy:"absolute"}),this.setupTeaser(),this.setupOpeningSequence(),this.localizeMessageTimestamps(),this.webChatChannel.onMessage(this.onMessageReceived),this.webChatChannel.onTypingStart(this.onTypingStart),this.webChatChannel.onReaction(this.onMessageReaction),this.setupMessagesContainerScrollIsolation(),this.messagesContainerTarget.addEventListener("scroll",this.onScroll),this.messagesContainerTarget.addEventListener("wheel",this.stopHostScrollPropagation,si),this.messagesContainerTarget.addEventListener("touchmove",this.stopHostScrollPropagation,si),this.shouldOpenOnMount&&(this.openValue=!0),bt.eventEmitter.dispatch("webchat:mounted"),this.broadcastChannel.addEventListener("message",this.onOutboundMessageSent),window.addEventListener("keydown",this.closePopoverOnEscape,!0),this.scheduleBehaviourOpen(),super.connect()}disconnect(){this.cancelBehaviourOpen(),this.clearPopoverOpenAnimation(),this.teardownTeaser(),this.teardownOpeningSequence(),this.broadcastChannel.removeEventListener("message",this.onOutboundMessageSent),this.messagesContainerTarget.removeEventListener("scroll",this.onScroll),this.messagesContainerTarget.removeEventListener("wheel",this.stopHostScrollPropagation,si),this.messagesContainerTarget.removeEventListener("touchmove",this.stopHostScrollPropagation,si),window.removeEventListener("keydown",this.closePopoverOnEscape,!0),this.clearTypingIndicator(),this.broadcastChannel.close(),this.floatingUICleanup(),super.disconnect()}setupMessagesContainerScrollIsolation(){this.messagesContainerTarget.style.overscrollBehavior="contain",this.messagesContainerTarget.style.webkitOverflowScrolling="touch",this.messagesContainerTarget.style.touchAction="pan-y",this.messagesContainerTarget.setAttribute("data-lenis-prevent",""),this.messagesContainerTarget.setAttribute("data-lenis-prevent-wheel",""),this.messagesContainerTarget.setAttribute("data-lenis-prevent-touch","")}stopHostScrollPropagation(e){e.stopPropagation()}onTypingStart(){if(this.typingIndicatorVisible)return this.resetTypingIndicatorTimer();this.showTypingIndicator()}showOptimisticTypingIndicator(){this.typingIndicatorVisible||this.showTypingIndicator()}showTypingIndicator(){this.clearTypingIndicator(),this.typingIndicatorVisible=!0;const e=this.typingIndicatorTemplateTarget.cloneNode(!0);e.setAttribute("data-hellotext--webchat-target","typingIndicator"),e.style.display="flex",this.messagesContainerTarget.appendChild(e),requestAnimationFrame(()=>{this.messagesContainerTarget.scroll({top:this.messagesContainerTarget.scrollHeight,behavior:"instant"})});const t=this.typingIndicatorKeepAliveValue;this.incomingTypingIndicatorTimeout=setTimeout(()=>{this.clearTypingIndicator()},t)}resetTypingIndicatorTimer(){if(!this.typingIndicatorVisible)return;clearTimeout(this.incomingTypingIndicatorTimeout),clearTimeout(this.optimisticTypingTimeout);const e=this.typingIndicatorKeepAliveValue;this.incomingTypingIndicatorTimeout=setTimeout(()=>{this.clearTypingIndicator()},e)}clearTypingIndicator(){this.hasTypingIndicatorTarget&&this.typingIndicatorTarget.remove(),this.typingIndicatorVisible=!1,clearTimeout(this.incomingTypingIndicatorTimeout),clearTimeout(this.optimisticTypingTimeout)}onMessageInputChange(){this.resizeInput(),clearTimeout(this.typingIndicatorTimeout),this.hasSentTypingIndicator||(this.webChatChannel.startTypingIndicator(),this.hasSentTypingIndicator=!0),this.typingIndicatorTimeout=setTimeout(()=>{this.hasSentTypingIndicator=!1},3e3)}onOutboundMessageSent(e){const{data:t}=e,s={"message:sent":e=>{const t=(new DOMParser).parseFromString(e.element,"text/html").body.firstElementChild;this.localizeMessageTimestamps(t),this.typingIndicatorVisible&&this.hasTypingIndicatorTarget?this.messagesContainerTarget.insertBefore(t,this.typingIndicatorTarget):this.messagesContainerTarget.appendChild(t),t.scrollIntoView({behavior:"instant"})},"message:failed":e=>{const t=this.messagesContainerTarget.querySelector(`#${e.id}`);this.markMessageFailed(t,e.reason)}};s[t.type]?s[t.type](t):console.log(`Unhandled message event: ${t.type}`)}async onScroll(){if(this.messagesContainerTarget.scrollTop>300||!this.nextPageValue||this.fetchingNextPage)return;this.fetchingNextPage=!0;const e=await this.messagesAPI.index({page:this.nextPageValue,session:bt.session}),{next:t,messages:s}=await e.json();this.nextPageValue=t,this.oldScrollHeight=this.messagesContainerTarget.scrollHeight,s.forEach(e=>{const{body:t,attachments:s}=e,i=e.created_at||e.createdAt,n=this.messageTemplateTarget.cloneNode(!0);n.classList.add("hellotext--webchat-message"),n.setAttribute("data-hellotext--webchat-target","message"),n.setAttribute("data-id",e.id),i&&n.setAttribute("data-created-at",i),n.style.removeProperty("display"),nt(n.querySelector("[data-body]"),t),"received"===e.state?n.classList.add("received"):n.classList.remove("received"),s&&s.forEach(e=>{const t=this.attachmentImageTarget.cloneNode(!0);t.removeAttribute("data-hellotext--webchat-target"),t.src=e,t.style.display="block",this.messageAttachmentsContainer(n)?.appendChild(t)}),n.setAttribute("data-body",t),this.localizeMessageTimestamp(n.querySelector("[data-message-timestamp]"),i),this.messagesContainerTarget.prepend(n)}),this.messagesContainerTarget.scroll({top:this.messagesContainerTarget.scrollHeight-this.oldScrollHeight,behavior:"instant"}),this.fetchingNextPage=!1}onClickOutside(e){u.mode===h.POPOVER&&this.openValue&&e.target.nodeType&&!1===this.element.contains(e.target)&&(this.openValue=!1)}closePopover(){this.clearPopoverOpenAnimation(),this.popoverTarget.classList.remove(...this.fadeOutClasses),this.openValue=!1}preparePopoverOpenAnimation(){this.clearPopoverOpenAnimation(),this.popoverTarget.classList.remove(...this.fadeOutClasses),this.popoverTarget.classList.add("hellotext--webchat-popover-opening"),this.popoverOpenAnimationTimeout=setTimeout(()=>{this.popoverTarget.classList.remove("hellotext--webchat-popover-opening"),this.popoverOpenAnimationTimeout=null},120)}clearPopoverOpenAnimation(){this.popoverOpenAnimationTimeout&&(clearTimeout(this.popoverOpenAnimationTimeout),this.popoverOpenAnimationTimeout=null),this.popoverTarget?.classList.remove("hellotext--webchat-popover-opening")}onPopoverOpened(){this.popoverTarget.classList.remove(...this.fadeOutClasses),this.dismissTeaserForSession?.(),this.onMobile||this.focusComposeInput(),this.scrolled||(requestAnimationFrame(()=>{this.messagesContainerTarget.scroll({top:this.messagesContainerTarget.scrollHeight,behavior:"instant"})}),this.scrolled=!0),bt.eventEmitter.dispatch("webchat:opened"),localStorage.setItem(`hellotext--webchat--${this.idValue}`,"opened"),this.messageTeaserValue&&(this.messageTeaserValue=null),this.startOpeningSequence(),"none"!==this.unreadCounterTarget.style.display&&(this.unreadCounterTarget.style.display="none",this.unreadCounterTarget.innerText="0",this.messagesAPI.markAsSeen())}onPopoverClosed(){this.clearPopoverOpenAnimation(),bt.eventEmitter.dispatch("webchat:closed"),localStorage.setItem(`hellotext--webchat--${this.idValue}`,"closed")}onMessageReaction(e){const{message:t,reaction:s,type:i}=e,n=this.messageTargets.find(e=>e.dataset.id===t).querySelector("[data-reactions]");if("reaction.destroy"===i)return n.querySelector(`[data-id="${s.id}"]`).remove();if(n.querySelector(`[data-id="${s.id}"]`))n.querySelector(`[data-id="${s.id}"]`).innerText=s.emoji;else{const e=document.createElement("span");e.innerText=s.emoji,e.setAttribute("data-id",s.id),n.appendChild(e)}}onMessageReceived(e,t={}){const{id:s,body:i,attachments:n,teaser:r}=e,a=e.created_at||e.createdAt;if(!this.claimMessageId(s))return;if(this.hideTeaser?.(),e.carousel)return this.insertCarouselMessage(e,t);const o=this.messageTemplateTarget.cloneNode(!0);o.classList.add("hellotext--webchat-message"),o.style.display="flex",nt(o.querySelector("[data-body]"),i),o.setAttribute("data-id",s),o.setAttribute("data-hellotext--webchat-target","message"),this.setMessageCreatedAt(o,a),this.localizeMessageTimestamp(o.querySelector("[data-message-timestamp]"),a),n&&n.forEach(e=>{const t=this.attachmentImageTarget.cloneNode(!0);t.src=e,t.style.display="block",this.messageAttachmentsContainer(o)?.appendChild(t)}),this.clearTypingIndicator(),this.insertMessageElement(o),bt.eventEmitter.dispatch("webchat:message:received",{...e,body:o.querySelector("[data-body]").innerText}),!1!==t.scroll&&o.scrollIntoView({behavior:"smooth"}),this.updateMessageTeaser(r),this.openValue?this.messagesAPI.markAsSeen(s):this.incrementUnreadCounter()}claimMessageId(e){const t=this.messageTargets||[];return!this.messageIds.has(e)&&(this.messageIds.add(e),!t.some(t=>t.dataset.id===e))}captureCatchUpCursor(){this.catchUpAfterMessageId=this.lastRenderedMessageId}async catchUpMessages(){const e=this.catchUpAfterMessageId;if(e&&!this.fetchingCatchUpMessages){this.fetchingCatchUpMessages=!0;try{const t=await this.messagesAPI.catchUp(e),{messages:s=[]}=await t.json();s.forEach(e=>this.onMessageReceived(e,{scroll:!1})),this.catchUpAfterMessageId=this.lastRenderedMessageId}finally{this.fetchingCatchUpMessages=!1}}}get lastRenderedMessageId(){const e=this.persistedMessageElements;return e[e.length-1]?.dataset.id||null}get persistedMessageElements(){return Array.from(this.messagesContainerTarget.querySelectorAll(".hellotext--webchat-message[data-id]"))}setMessageCreatedAt(e,t){t&&e.setAttribute("data-created-at",t)}insertMessageElement(e){const t=this.nextMessageElementFor(e);t?this.messagesContainerTarget.insertBefore(e,t):this.messagesContainerTarget.appendChild(e)}nextMessageElementFor(e){const t=Date.parse(e.dataset.createdAt);return Number.isNaN(t)?null:this.persistedMessageElements.find(s=>{if(s===e)return!1;const i=Date.parse(s.dataset.createdAt);return!Number.isNaN(i)&&i>t})}updateMessageTeaser(e){this.messageTeaserValue=e,this.messageTeaserValue&&this.hasTeaserTarget&&this.hasInboundMessageTeaserTarget&&this.hasInboundMessageTeaserBodyTarget&&(this.teaserMessageTargets.forEach(e=>e.classList.add("hidden")),this.inboundMessageTeaserBodyTarget.textContent=this.messageTeaserValue,this.inboundMessageTeaserTarget.classList.remove("hidden"),this.teaserTarget.classList.toggle("invisible",this.openValue))}insertCarouselMessage(e,t={}){const s=e.html,i=e.created_at||e.createdAt,n=function(e){return it(e,st)}(s).firstElementChild;n.classList.add("hellotext--webchat-message"),n.setAttribute("data-id",e.id),n.setAttribute("data-hellotext--webchat-target","message"),this.setMessageCreatedAt(n,i),this.localizeMessageTimestamps(n),this.clearTypingIndicator(),this.insertMessageElement(n),!1!==t.scroll&&n.scrollIntoView({behavior:"smooth"}),bt.eventEmitter.dispatch("webchat:message:received",{...e,body:n.querySelector("[data-body]")?.innerText||""}),this.updateMessageTeaser(e.teaser),this.openValue?this.messagesAPI.markAsSeen(e.id):this.incrementUnreadCounter()}resizeInput(){this.inputTarget.style.height="auto";const e=this.inputTarget.scrollHeight;this.inputTarget.style.height=`${Math.min(e,96)}px`}async sendQuickReplyMessage({detail:{id:e,product:t,buttonId:s,body:i,cardElement:n}}){this.dismissTeaserForSession?.();const r=new FormData;r.append("message[body]",i),e&&r.append("message[replied_to]",e),t&&r.append("message[product]",t),s&&r.append("message[button]",s),r.append("session",bt.session),r.append("locale",o.toString()),this.appendOpeningSequenceMessageIds(r);const a=this.buildMessageElement(),c=n?.querySelector("img")?.cloneNode(!0);a.querySelector("[data-body]").innerText=i,c&&(c.removeAttribute("width"),c.removeAttribute("height"),this.messageAttachmentsContainer(a)?.appendChild(c)),this.typingIndicatorVisible&&this.hasTypingIndicatorTarget?this.messagesContainerTarget.insertBefore(a,this.typingIndicatorTarget):this.messagesContainerTarget.appendChild(a),a.scrollIntoView({behavior:"smooth"}),this.broadcastChannel.postMessage({type:"message:sent",element:a.outerHTML});const l=await this.messagesAPI.create(r);if(l.failed)return clearTimeout(this.optimisticTypingTimeout),this.markMessageFailedFromResponse(l,a);const h=await l.json();this.dispatch("set:id",{target:a,detail:h.id}),this.localizeMessageTimestamp(a.querySelector("[data-message-timestamp]"),h.created_at||h.createdAt),this.clearRevealedOpeningSequenceMessageIds();const u={id:h.id,body:i,attachments:c?[c.src]:[],replied_to:e,product:t,button:s,type:"quick_reply"};bt.eventEmitter.dispatch("webchat:message:sent",u)}async sendTeaserQuickReply(e){e.preventDefault(),e.stopPropagation();const t=e.currentTarget,s=(t.dataset.value||"").trim(),i=[t.dataset.text,t.textContent].map(e=>(e||"").trim()).find(e=>e.length>0),n=s||i;if(!n)return;this.dismissTeaserForSession?.(),this.show();const r=(t.dataset.type||"").trim()||"quick_reply",a=new FormData;a.append("message[body]",n),a.append("session",bt.session),a.append("locale",o.toString()),this.appendOpeningSequenceMessageIds(a);const c=this.buildMessageElement();c.querySelector("[data-body]").innerText=n,this.typingIndicatorVisible&&this.hasTypingIndicatorTarget?this.messagesContainerTarget.insertBefore(c,this.typingIndicatorTarget):this.messagesContainerTarget.appendChild(c),c.scrollIntoView({behavior:"smooth"}),this.broadcastChannel.postMessage({type:"message:sent",element:c.outerHTML}),this.typingIndicatorVisible||(clearTimeout(this.optimisticTypingTimeout),this.optimisticTypingTimeout=setTimeout(()=>{this.showOptimisticTypingIndicator()},this.optimisticTypingIndicatorWaitValue));const l=await this.messagesAPI.create(a);if(l.failed)return clearTimeout(this.optimisticTypingTimeout),this.markMessageFailedFromResponse(l,c);const h=await l.json();c.setAttribute("data-id",h.id),this.localizeMessageTimestamp(c.querySelector("[data-message-timestamp]"),h.created_at||h.createdAt),this.clearRevealedOpeningSequenceMessageIds(),bt.eventEmitter.dispatch("webchat:message:sent",{id:h.id,body:n,attachments:[],type:"quick_reply",teaser:{text:i||n,value:s||n,type:r}}),h.conversation&&h.conversation!==this.conversationIdValue&&(this.conversationIdValue=h.conversation,this.webChatChannel.updateSubscriptionWith(this.conversationIdValue)),this.typingIndicatorVisible&&this.resetTypingIndicatorTimer()}async sendMessage(e){const t={body:this.inputTarget.value,attachments:this.files};if(0===this.inputTarget.value.trim().length&&0===this.files.length)return void(e&&e.target&&e.preventDefault());this.dismissTeaserForSession?.();const s=new FormData;this.inputTarget.value.trim().length>0?s.append("message[body]",this.inputTarget.value):delete t.body,this.files.forEach(e=>{s.append("message[attachments][]",e)}),s.append("session",bt.session),s.append("locale",o.toString()),this.appendOpeningSequenceMessageIds(s);const i=this.buildMessageElement();this.inputTarget.value.trim().length>0?i.querySelector("[data-body]").innerText=this.inputTarget.value:i.querySelector("[data-message-bubble]").remove();const n=this.attachmentContainerTarget.querySelectorAll("img");n.length>0&&n.forEach(e=>{this.messageAttachmentsContainer(i)?.appendChild(e.cloneNode(!0))}),this.typingIndicatorVisible&&this.hasTypingIndicatorTarget?this.messagesContainerTarget.insertBefore(i,this.typingIndicatorTarget):this.messagesContainerTarget.appendChild(i),i.scrollIntoView({behavior:"smooth"}),this.broadcastChannel.postMessage({type:"message:sent",element:i.outerHTML}),this.inputTarget.value="",this.resizeInput(),this.files=[],this.attachmentInputTarget.value="",this.attachmentContainerTarget.innerHTML="",this.attachmentContainerTarget.style.display="none",this.errorMessageContainerTarget.style.display="none",this.focusComposeInput(),this.typingIndicatorVisible||(clearTimeout(this.optimisticTypingTimeout),this.optimisticTypingTimeout=setTimeout(()=>{this.showOptimisticTypingIndicator()},this.optimisticTypingIndicatorWaitValue));const r=await this.messagesAPI.create(s);if(r.failed)return clearTimeout(this.optimisticTypingTimeout),this.markMessageFailedFromResponse(r,i);const a=await r.json();i.setAttribute("data-id",a.id),t.id=a.id,this.localizeMessageTimestamp(i.querySelector("[data-message-timestamp]"),a.created_at||a.createdAt),this.clearRevealedOpeningSequenceMessageIds(),bt.eventEmitter.dispatch("webchat:message:sent",t),a.conversation!==this.conversationIdValue&&(this.conversationIdValue=a.conversation,this.webChatChannel.updateSubscriptionWith(this.conversationIdValue)),this.typingIndicatorVisible&&this.resetTypingIndicatorTimer(),this.attachmentContainerTarget.style.display=""}buildMessageElement(){const e=this.messageTemplateTarget.cloneNode(!0);return e.id=`hellotext--webchat--${this.idValue}--message--${Date.now()}`,e.classList.add("received"),e.style.removeProperty("display"),e.setAttribute("data-controller","hellotext--message"),e.setAttribute("data-hellotext--webchat-target","message"),this.localizeMessageTimestamp(e.querySelector("[data-message-timestamp]"),new Date),e}focusCompose(e){const{target:t}=e,s=["button","a","input","textarea","select","label",'[role="button"]',"em-emoji-picker",'[data-hellotext--webchat--emoji-target~="popover"]','[data-controller~="hellotext--webchat--emoji"]'].join(", ");this.hasInputTarget&&!t.closest(s)&&this.focusComposeInput({moveCursorToEnd:!0})&&e.preventDefault()}closePopoverFromHeader(e){const{target:t}=e;t.closest(".hellotext--webchat-header-channel-button, .hellotext--webchat-close-button")||(e.preventDefault(),this.closePopover())}closePopoverOnEscape(e){"Escape"===e.key&&this.openValue&&(e.preventDefault(),e.stopPropagation(),this.closePopover(),this.triggerTarget?.focus?.())}async markMessageFailedFromResponse(e,t){const s=await this.messageFailureReason(e);this.markMessageFailed(t,s),this.broadcastChannel.postMessage({type:"message:failed",id:t.id,reason:s})}markMessageFailed(e,t){if(!e)return;if(e.classList.add("failed"),!t)return;const s=e.querySelector("[data-message-timestamp]");s&&(s.textContent=t)}localizeMessageTimestamps(e=this.element){e&&(e.matches?.("time[datetime][data-message-timestamp]")?[e]:Array.from(e.querySelectorAll?.("time[datetime][data-message-timestamp]")||[])).forEach(e=>this.localizeMessageTimestamp(e))}localizeMessageTimestamp(e,t=e?.getAttribute("datetime")){if(!e||!t)return;const s=t instanceof Date?t:new Date(t);Number.isNaN(s.getTime())||(e.setAttribute("datetime",s.toISOString()),e.textContent=this.formatMessageTimestamp(s))}formatMessageTimestamp(e){return this.constructor.messageTimestampFormatterFor(o.toString()).format(e)}static messageTimestampFormatterFor(e){const t=e||"default";return this.messageTimestampFormatters[t]||(this.messageTimestampFormatters[t]=this.buildMessageTimestampFormatter(e)),this.messageTimestampFormatters[t]}static buildMessageTimestampFormatter(e){try{return new Intl.DateTimeFormat(e||void 0,ei)}catch(e){return new Intl.DateTimeFormat(void 0,ei)}}async messageFailureReason(e){const t=e?.data||e?.response,s=t?.statusText||"Message failed";try{const e=t?.clone?t.clone():t,s=await(e?.json?.()),i=this.messageFailureReasonFromPayload(s);if(i)return i}catch(e){}try{const e=t?.clone?t.clone():t,i=await(e?.text?.());return this.messageFailureReasonFromText(i)||s}catch(e){return s}}messageFailureReasonFromText(e){if("string"!=typeof e)return null;const t=e.trim();if(!t||t.startsWith("<"))return null;try{return this.messageFailureReasonFromPayload(JSON.parse(t))||t}catch(e){return t}}messageFailureReasonFromPayload(e){return e?[e.error?.message,e.message,e.errors?.message,e.errors?.[0]?.message,e.errors?.[0]?.description].find(e=>"string"==typeof e&&e.trim().length>0):null}messageAttachmentsContainer(e){return e.querySelector("[data-attachments-container], [data-attachment-container]")}incrementUnreadCounter(){this.unreadCounterTarget.style.display="flex";const e=(parseInt(this.unreadCounterTarget.innerText)||0)+1;this.unreadCounterTarget.innerText=Math.min(e,9)}openAttachment(){this.attachmentInputTarget.click()}onFileInputChange(){this.errorMessageContainerTarget.style.display="none";const e=Array.from(this.attachmentInputTarget.files);this.attachmentInputTarget.value="";const t=e.find(e=>{const t=e.type.split("/")[0];return["image","video","audio"].includes(t)?this.mediaValue[t].max_sizethis.createAttachmentElement(e)),this.focusComposeInput()}createAttachmentElement(e){const t=this.attachmentElement();if(this.attachmentContainerTarget.style.display="",t.setAttribute("data-name",e.name),e.type.startsWith("image/")){const s=this.attachmentImageTarget.cloneNode(!0);s.src=URL.createObjectURL(e),s.style.display="block",t.appendChild(s),this.attachmentContainerTarget.appendChild(t),this.attachmentContainerTarget.style.display="flex"}else{const s=t.querySelector("main");s.style.height="5rem",s.style.borderRadius="0.375rem",s.style.backgroundColor="#e5e7eb",s.style.padding="0.25rem",t.querySelector("p[data-attachment-name]").innerText=e.name,this.attachmentContainerTarget.appendChild(t),this.attachmentContainerTarget.style.display="flex"}}removeAttachment({currentTarget:e}){const t=e.closest("[data-hellotext--webchat-target='attachment']");this.files=this.files.filter(e=>e.name!==t.dataset.name),this.attachmentInputTarget.value="",t.remove(),this.focusComposeInput()}attachmentTargetDisconnected(){0===this.attachmentTargets.length&&(this.attachmentContainerTarget.innerHTML="",this.attachmentContainerTarget.style.display="none")}attachmentElement(){const e=this.attachmentTemplateTarget.cloneNode(!0);return e.removeAttribute("hidden"),e.style.display="flex",e.setAttribute("data-hellotext--webchat-target","attachment"),e}onEmojiSelect({detail:e}){const t=this.inputTarget.value,s=this.inputTarget.selectionStart,i=this.inputTarget.selectionEnd;this.inputTarget.value=t.slice(0,s)+e+t.slice(i),this.inputTarget.selectionStart=this.inputTarget.selectionEnd=s+e.length,this.focusComposeInput()}focusComposeInput({moveCursorToEnd:e=!1}={}){if(!this.shouldAutofocusCompose)return!1;if(!1===this.hasInputTarget)return!1;if(void 0===this.hasInputTarget&&!this.inputTarget)return!1;if(this.inputTarget.focus(),e&&"number"==typeof this.inputTarget.selectionStart){const e=this.inputTarget.value.length;this.inputTarget.setSelectionRange(e,e)}return!0}byteToMegabyte(e){return Math.ceil(e/1024/1024)}get middlewares(){return[Vs(this.offsetValue),qs({padding:this.paddingValue}),Us()]}get shouldOpenOnMount(){return"opened"===localStorage.getItem(`hellotext--webchat--${this.idValue}`)&&!this.onMobile}get shouldAutofocusCompose(){return!this.usesVirtualKeyboard}get usesVirtualKeyboard(){if("undefined"==typeof navigator)return!1;const e=navigator.userAgent||"",t="MacIntel"===navigator.platform&&navigator.maxTouchPoints>1,s=ti.test(e),i=!0===navigator.userAgentData?.mobile;return s||t||i||this.hasTouchOnlyPointer}get hasTouchOnlyPointer(){return"undefined"!=typeof window&&"function"==typeof window.matchMedia&&window.matchMedia("(pointer: coarse)").matches&&window.matchMedia("(hover: none)").matches}get onMobile(){return"undefined"!=typeof window&&"function"==typeof window.matchMedia&&window.matchMedia(`(max-width: ${this.fullScreenThresholdValue}px)`).matches}},ni=i.lg.start();ni.register("hellotext--alert",vt),ni.register("hellotext--form",wt),ni.register("hellotext--webchat",ii),ni.register("hellotext--webchat--emoji",Ws),ni.register("hellotext--message",Tt),window.Hellotext=bt;const ri=bt}};const t={};function s(i){const n=t[i];if(void 0!==n)return n.exports;const r=t[i]={exports:{}};return e[i](r,r.exports,s),r.exports}s.m=e,(()=>{const e=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;let t;s.t=function(i,n){if(1&n&&(i=this(i)),8&n)return i;if("object"==typeof i&&i){if(4&n&&i.__esModule)return i;if(16&n&&"function"==typeof i.then)return i}const r=Object.create(null);s.r(r);const a={};t=t||[null,e({}),e([]),e(e)];for(var o=2&n&&i;("object"==typeof o||"function"==typeof o)&&!~t.indexOf(o);o=e(o))Object.getOwnPropertyNames(o).forEach(e=>a[e]=()=>i[e]);return a.default=()=>i,s.d(r,a),r}})(),s.d=(e,t)=>{if(Array.isArray(t))for(var i=0;iPromise.all(Object.keys(s.f).reduce((t,i)=>(s.f[i](e,t),t),[])),s.u=e=>({160:"webchat-emoji",200:"webchat-emoji-en",437:"webchat-emoji-es"}[e]+".js"),s.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),s.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{const e={},t="Hellotext:";s.l=(i,n,r,a)=>{if(e[i])return void e[i].push(n);let o,c;if(void 0!==r){const e=document.getElementsByTagName("script");for(var l=0;l{o.onerror=o.onload=null,clearTimeout(u);const n=e[i];if(delete e[i],o.parentNode?.removeChild(o),n?.forEach(e=>e(s)),t)return t(s)},u=setTimeout(h.bind(null,void 0,{type:"timeout",target:o}),12e4);o.onerror=h.bind(null,o.onerror),o.onload=h.bind(null,o.onload),c&&document.head.appendChild(o)}})(),s.r=e=>{Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{let e;s.g.importScripts&&(e=s.g.location+"");const t=s.g.document;if(!e&&t&&("SCRIPT"===t.currentScript?.tagName.toUpperCase()&&(e=t.currentScript.src),!e)){const s=t.getElementsByTagName("script");if(s.length){let t=s.length-1;for(;t>-1&&(!e||!/^http(s?):/.test(e));)e=s[t--].src}}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),s.p=e})(),(()=>{const e={792:0};s.f.j=(t,i)=>{let n=s.o(e,t)?e[t]:void 0;if(0!==n)if(n)i.push(n[2]);else{const r=new Promise((s,i)=>n=e[t]=[s,i]);i.push(n[2]=r);const a=s.p+s.u(t),o=new Error,c=i=>{if(s.o(e,t)&&(n=e[t],0!==n&&(e[t]=void 0),n)){const e=i&&("load"===i.type?"missing":i.type),s=i&&i.target&&i.target.src;o.message="Loading chunk "+t+" failed.\n("+e+": "+s+")",o.name="ChunkLoadError",o.type=e,o.request=s,n[1](o)}};s.l(a,c,"chunk-"+t,t)}};const t=(t,i)=>{let[n,r,a]=i;var o,c,l=0;if(n.some(t=>0!==e[t])){for(o in r)s.o(r,o)&&(s.m[o]=r[o]);a&&a(s)}for(t&&t(i);l(()=>{"use strict";var e={891(e,t,s){s.d(t,{lg:()=>G,xI:()=>ne});class i{constructor(e,t,s){this.eventTarget=e,this.eventName=t,this.eventOptions=s,this.unorderedBindings=new Set}connect(){this.eventTarget.addEventListener(this.eventName,this,this.eventOptions)}disconnect(){this.eventTarget.removeEventListener(this.eventName,this,this.eventOptions)}bindingConnected(e){this.unorderedBindings.add(e)}bindingDisconnected(e){this.unorderedBindings.delete(e)}handleEvent(e){const t=function(e){if("immediatePropagationStopped"in e)return e;{const{stopImmediatePropagation:t}=e;return Object.assign(e,{immediatePropagationStopped:!1,stopImmediatePropagation(){this.immediatePropagationStopped=!0,t.call(this)}})}}(e);for(const e of this.bindings){if(t.immediatePropagationStopped)break;e.handleEvent(t)}}hasBindings(){return this.unorderedBindings.size>0}get bindings(){return Array.from(this.unorderedBindings).sort((e,t)=>{const s=e.index,i=t.index;return si?1:0})}}class n{constructor(e){this.application=e,this.eventListenerMaps=new Map,this.started=!1}start(){this.started||(this.started=!0,this.eventListeners.forEach(e=>e.connect()))}stop(){this.started&&(this.started=!1,this.eventListeners.forEach(e=>e.disconnect()))}get eventListeners(){return Array.from(this.eventListenerMaps.values()).reduce((e,t)=>e.concat(Array.from(t.values())),[])}bindingConnected(e){this.fetchEventListenerForBinding(e).bindingConnected(e)}bindingDisconnected(e,t=!1){this.fetchEventListenerForBinding(e).bindingDisconnected(e),t&&this.clearEventListenersForBinding(e)}handleError(e,t,s={}){this.application.handleError(e,`Error ${t}`,s)}clearEventListenersForBinding(e){const t=this.fetchEventListenerForBinding(e);t.hasBindings()||(t.disconnect(),this.removeMappedEventListenerFor(e))}removeMappedEventListenerFor(e){const{eventTarget:t,eventName:s,eventOptions:i}=e,n=this.fetchEventListenerMapForEventTarget(t),r=this.cacheKey(s,i);n.delete(r),0==n.size&&this.eventListenerMaps.delete(t)}fetchEventListenerForBinding(e){const{eventTarget:t,eventName:s,eventOptions:i}=e;return this.fetchEventListener(t,s,i)}fetchEventListener(e,t,s){const i=this.fetchEventListenerMapForEventTarget(e),n=this.cacheKey(t,s);let r=i.get(n);return r||(r=this.createEventListener(e,t,s),i.set(n,r)),r}createEventListener(e,t,s){const n=new i(e,t,s);return this.started&&n.connect(),n}fetchEventListenerMapForEventTarget(e){let t=this.eventListenerMaps.get(e);return t||(t=new Map,this.eventListenerMaps.set(e,t)),t}cacheKey(e,t){const s=[e];return Object.keys(t).sort().forEach(e=>{s.push(`${t[e]?"":"!"}${e}`)}),s.join(":")}}const r={stop:({event:e,value:t})=>(t&&e.stopPropagation(),!0),prevent:({event:e,value:t})=>(t&&e.preventDefault(),!0),self:({event:e,value:t,element:s})=>!t||s===e.target},a=/^(?:(?:([^.]+?)\+)?(.+?)(?:\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;function o(e){return e.replace(/(?:[_-])([a-z0-9])/g,(e,t)=>t.toUpperCase())}function c(e){return o(e.replace(/--/g,"-").replace(/__/g,"_"))}function l(e){return e.charAt(0).toUpperCase()+e.slice(1)}function h(e){return e.replace(/([A-Z])/g,(e,t)=>`-${t.toLowerCase()}`)}function u(e){return null!=e}function d(e,t){return Object.prototype.hasOwnProperty.call(e,t)}const p=["meta","ctrl","alt","shift"];class m{constructor(e,t,s,i){this.element=e,this.index=t,this.eventTarget=s.eventTarget||e,this.eventName=s.eventName||function(e){const t=e.tagName.toLowerCase();if(t in g)return g[t](e)}(e)||f("missing event name"),this.eventOptions=s.eventOptions||{},this.identifier=s.identifier||f("missing identifier"),this.methodName=s.methodName||f("missing method name"),this.keyFilter=s.keyFilter||"",this.schema=i}static forToken(e,t){return new this(e.element,e.index,function(e){const t=e.trim().match(a)||[];let s=t[2],i=t[3];return i&&!["keydown","keyup","keypress"].includes(s)&&(s+=`.${i}`,i=""),{eventTarget:(n=t[4],"window"==n?window:"document"==n?document:void 0),eventName:s,eventOptions:t[7]?(r=t[7],r.split(":").reduce((e,t)=>Object.assign(e,{[t.replace(/^!/,"")]:!/^!/.test(t)}),{})):{},identifier:t[5],methodName:t[6],keyFilter:t[1]||i};var n,r}(e.content),t)}toString(){const e=this.keyFilter?`.${this.keyFilter}`:"",t=this.eventTargetName?`@${this.eventTargetName}`:"";return`${this.eventName}${e}${t}->${this.identifier}#${this.methodName}`}shouldIgnoreKeyboardEvent(e){if(!this.keyFilter)return!1;const t=this.keyFilter.split("+");if(this.keyFilterDissatisfied(e,t))return!0;const s=t.filter(e=>!p.includes(e))[0];return!!s&&(d(this.keyMappings,s)||f(`contains unknown key filter: ${this.keyFilter}`),this.keyMappings[s].toLowerCase()!==e.key.toLowerCase())}shouldIgnoreMouseEvent(e){if(!this.keyFilter)return!1;const t=[this.keyFilter];return!!this.keyFilterDissatisfied(e,t)}get params(){const e={},t=new RegExp(`^data-${this.identifier}-(.+)-param$`,"i");for(const{name:s,value:i}of Array.from(this.element.attributes)){const n=s.match(t),r=n&&n[1];r&&(e[o(r)]=b(i))}return e}get eventTargetName(){return(e=this.eventTarget)==window?"window":e==document?"document":void 0;var e}get keyMappings(){return this.schema.keyMappings}keyFilterDissatisfied(e,t){const[s,i,n,r]=p.map(e=>t.includes(e));return e.metaKey!==s||e.ctrlKey!==i||e.altKey!==n||e.shiftKey!==r}}const g={a:()=>"click",button:()=>"click",form:()=>"submit",details:()=>"toggle",input:e=>"submit"==e.getAttribute("type")?"click":"input",select:()=>"change",textarea:()=>"input"};function f(e){throw new Error(e)}function b(e){try{return JSON.parse(e)}catch(t){return e}}class y{constructor(e,t){this.context=e,this.action=t}get index(){return this.action.index}get eventTarget(){return this.action.eventTarget}get eventOptions(){return this.action.eventOptions}get identifier(){return this.context.identifier}handleEvent(e){const t=this.prepareActionEvent(e);this.willBeInvokedByEvent(e)&&this.applyEventModifiers(t)&&this.invokeWithEvent(t)}get eventName(){return this.action.eventName}get method(){const e=this.controller[this.methodName];if("function"==typeof e)return e;throw new Error(`Action "${this.action}" references undefined method "${this.methodName}"`)}applyEventModifiers(e){const{element:t}=this.action,{actionDescriptorFilters:s}=this.context.application,{controller:i}=this.context;let n=!0;for(const[r,a]of Object.entries(this.eventOptions))if(r in s){const o=s[r];n=n&&o({name:r,value:a,event:e,element:t,controller:i})}return n}prepareActionEvent(e){return Object.assign(e,{params:this.action.params})}invokeWithEvent(e){const{target:t,currentTarget:s}=e;try{this.method.call(this.controller,e),this.context.logDebugActivity(this.methodName,{event:e,target:t,currentTarget:s,action:this.methodName})}catch(t){const{identifier:s,controller:i,element:n,index:r}=this,a={identifier:s,controller:i,element:n,index:r,event:e};this.context.handleError(t,`invoking action "${this.action}"`,a)}}willBeInvokedByEvent(e){const t=e.target;return!(e instanceof KeyboardEvent&&this.action.shouldIgnoreKeyboardEvent(e))&&!(e instanceof MouseEvent&&this.action.shouldIgnoreMouseEvent(e))&&(this.element===t||(t instanceof Element&&this.element.contains(t)?this.scope.containsElement(t):this.scope.containsElement(this.action.element)))}get controller(){return this.context.controller}get methodName(){return this.action.methodName}get element(){return this.scope.element}get scope(){return this.context.scope}}class v{constructor(e,t){this.mutationObserverInit={attributes:!0,childList:!0,subtree:!0},this.element=e,this.started=!1,this.delegate=t,this.elements=new Set,this.mutationObserver=new MutationObserver(e=>this.processMutations(e))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,this.mutationObserverInit),this.refresh())}pause(e){this.started&&(this.mutationObserver.disconnect(),this.started=!1),e(),this.started||(this.mutationObserver.observe(this.element,this.mutationObserverInit),this.started=!0)}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started){const e=new Set(this.matchElementsInTree());for(const t of Array.from(this.elements))e.has(t)||this.removeElement(t);for(const t of Array.from(e))this.addElement(t)}}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){"attributes"==e.type?this.processAttributeChange(e.target,e.attributeName):"childList"==e.type&&(this.processRemovedNodes(e.removedNodes),this.processAddedNodes(e.addedNodes))}processAttributeChange(e,t){this.elements.has(e)?this.delegate.elementAttributeChanged&&this.matchElement(e)?this.delegate.elementAttributeChanged(e,t):this.removeElement(e):this.matchElement(e)&&this.addElement(e)}processRemovedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.processTree(e,this.removeElement)}}processAddedNodes(e){for(const t of Array.from(e)){const e=this.elementFromNode(t);e&&this.elementIsActive(e)&&this.processTree(e,this.addElement)}}matchElement(e){return this.delegate.matchElement(e)}matchElementsInTree(e=this.element){return this.delegate.matchElementsInTree(e)}processTree(e,t){for(const s of this.matchElementsInTree(e))t.call(this,s)}elementFromNode(e){if(e.nodeType==Node.ELEMENT_NODE)return e}elementIsActive(e){return e.isConnected==this.element.isConnected&&this.element.contains(e)}addElement(e){this.elements.has(e)||this.elementIsActive(e)&&(this.elements.add(e),this.delegate.elementMatched&&this.delegate.elementMatched(e))}removeElement(e){this.elements.has(e)&&(this.elements.delete(e),this.delegate.elementUnmatched&&this.delegate.elementUnmatched(e))}}class w{constructor(e,t,s){this.attributeName=t,this.delegate=s,this.elementObserver=new v(e,this)}get element(){return this.elementObserver.element}get selector(){return`[${this.attributeName}]`}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get started(){return this.elementObserver.started}matchElement(e){return e.hasAttribute(this.attributeName)}matchElementsInTree(e){const t=this.matchElement(e)?[e]:[],s=Array.from(e.querySelectorAll(this.selector));return t.concat(s)}elementMatched(e){this.delegate.elementMatchedAttribute&&this.delegate.elementMatchedAttribute(e,this.attributeName)}elementUnmatched(e){this.delegate.elementUnmatchedAttribute&&this.delegate.elementUnmatchedAttribute(e,this.attributeName)}elementAttributeChanged(e,t){this.delegate.elementAttributeValueChanged&&this.attributeName==t&&this.delegate.elementAttributeValueChanged(e,t)}}function T(e,t){let s=e.get(t);return s||(s=new Set,e.set(t,s)),s}class S{constructor(){this.valuesByKey=new Map}get keys(){return Array.from(this.valuesByKey.keys())}get values(){return Array.from(this.valuesByKey.values()).reduce((e,t)=>e.concat(Array.from(t)),[])}get size(){return Array.from(this.valuesByKey.values()).reduce((e,t)=>e+t.size,0)}add(e,t){!function(e,t,s){T(e,t).add(s)}(this.valuesByKey,e,t)}delete(e,t){!function(e,t,s){T(e,t).delete(s),function(e,t){const s=e.get(t);null!=s&&0==s.size&&e.delete(t)}(e,t)}(this.valuesByKey,e,t)}has(e,t){const s=this.valuesByKey.get(e);return null!=s&&s.has(t)}hasKey(e){return this.valuesByKey.has(e)}hasValue(e){return Array.from(this.valuesByKey.values()).some(t=>t.has(e))}getValuesForKey(e){const t=this.valuesByKey.get(e);return t?Array.from(t):[]}getKeysForValue(e){return Array.from(this.valuesByKey).filter(([t,s])=>s.has(e)).map(([e,t])=>e)}}class C{constructor(e,t,s,i){this._selector=t,this.details=i,this.elementObserver=new v(e,this),this.delegate=s,this.matchesByElement=new S}get started(){return this.elementObserver.started}get selector(){return this._selector}set selector(e){this._selector=e,this.refresh()}start(){this.elementObserver.start()}pause(e){this.elementObserver.pause(e)}stop(){this.elementObserver.stop()}refresh(){this.elementObserver.refresh()}get element(){return this.elementObserver.element}matchElement(e){const{selector:t}=this;if(t){const s=e.matches(t);return this.delegate.selectorMatchElement?s&&this.delegate.selectorMatchElement(e,this.details):s}return!1}matchElementsInTree(e){const{selector:t}=this;if(t){const s=this.matchElement(e)?[e]:[],i=Array.from(e.querySelectorAll(t)).filter(e=>this.matchElement(e));return s.concat(i)}return[]}elementMatched(e){const{selector:t}=this;t&&this.selectorMatched(e,t)}elementUnmatched(e){const t=this.matchesByElement.getKeysForValue(e);for(const s of t)this.selectorUnmatched(e,s)}elementAttributeChanged(e,t){const{selector:s}=this;if(s){const t=this.matchElement(e),i=this.matchesByElement.has(s,e);t&&!i?this.selectorMatched(e,s):!t&&i&&this.selectorUnmatched(e,s)}}selectorMatched(e,t){this.delegate.selectorMatched(e,t,this.details),this.matchesByElement.add(t,e)}selectorUnmatched(e,t){this.delegate.selectorUnmatched(e,t,this.details),this.matchesByElement.delete(t,e)}}class O{constructor(e,t){this.element=e,this.delegate=t,this.started=!1,this.stringMap=new Map,this.mutationObserver=new MutationObserver(e=>this.processMutations(e))}start(){this.started||(this.started=!0,this.mutationObserver.observe(this.element,{attributes:!0,attributeOldValue:!0}),this.refresh())}stop(){this.started&&(this.mutationObserver.takeRecords(),this.mutationObserver.disconnect(),this.started=!1)}refresh(){if(this.started)for(const e of this.knownAttributeNames)this.refreshAttribute(e,null)}processMutations(e){if(this.started)for(const t of e)this.processMutation(t)}processMutation(e){const t=e.attributeName;t&&this.refreshAttribute(t,e.oldValue)}refreshAttribute(e,t){const s=this.delegate.getStringMapKeyForAttribute(e);if(null!=s){this.stringMap.has(e)||this.stringMapKeyAdded(s,e);const i=this.element.getAttribute(e);if(this.stringMap.get(e)!=i&&this.stringMapValueChanged(i,s,t),null==i){const t=this.stringMap.get(e);this.stringMap.delete(e),t&&this.stringMapKeyRemoved(s,e,t)}else this.stringMap.set(e,i)}}stringMapKeyAdded(e,t){this.delegate.stringMapKeyAdded&&this.delegate.stringMapKeyAdded(e,t)}stringMapValueChanged(e,t,s){this.delegate.stringMapValueChanged&&this.delegate.stringMapValueChanged(e,t,s)}stringMapKeyRemoved(e,t,s){this.delegate.stringMapKeyRemoved&&this.delegate.stringMapKeyRemoved(e,t,s)}get knownAttributeNames(){return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)))}get currentAttributeNames(){return Array.from(this.element.attributes).map(e=>e.name)}get recordedAttributeNames(){return Array.from(this.stringMap.keys())}}class A{constructor(e,t,s){this.attributeObserver=new w(e,t,this),this.delegate=s,this.tokensByElement=new S}get started(){return this.attributeObserver.started}start(){this.attributeObserver.start()}pause(e){this.attributeObserver.pause(e)}stop(){this.attributeObserver.stop()}refresh(){this.attributeObserver.refresh()}get element(){return this.attributeObserver.element}get attributeName(){return this.attributeObserver.attributeName}elementMatchedAttribute(e){this.tokensMatched(this.readTokensForElement(e))}elementAttributeValueChanged(e){const[t,s]=this.refreshTokensForElement(e);this.tokensUnmatched(t),this.tokensMatched(s)}elementUnmatchedAttribute(e){this.tokensUnmatched(this.tokensByElement.getValuesForKey(e))}tokensMatched(e){e.forEach(e=>this.tokenMatched(e))}tokensUnmatched(e){e.forEach(e=>this.tokenUnmatched(e))}tokenMatched(e){this.delegate.tokenMatched(e),this.tokensByElement.add(e.element,e)}tokenUnmatched(e){this.delegate.tokenUnmatched(e),this.tokensByElement.delete(e.element,e)}refreshTokensForElement(e){const t=this.tokensByElement.getValuesForKey(e),s=this.readTokensForElement(e),i=function(e,t){const s=Math.max(e.length,t.length);return Array.from({length:s},(s,i)=>[e[i],t[i]])}(t,s).findIndex(([e,t])=>{return i=t,!((s=e)&&i&&s.index==i.index&&s.content==i.content);var s,i});return-1==i?[[],[]]:[t.slice(i),s.slice(i)]}readTokensForElement(e){const t=this.attributeName;return function(e,t,s){return e.trim().split(/\s+/).filter(e=>e.length).map((e,i)=>({element:t,attributeName:s,content:e,index:i}))}(e.getAttribute(t)||"",e,t)}}class E{constructor(e,t,s){this.tokenListObserver=new A(e,t,this),this.delegate=s,this.parseResultsByToken=new WeakMap,this.valuesByTokenByElement=new WeakMap}get started(){return this.tokenListObserver.started}start(){this.tokenListObserver.start()}stop(){this.tokenListObserver.stop()}refresh(){this.tokenListObserver.refresh()}get element(){return this.tokenListObserver.element}get attributeName(){return this.tokenListObserver.attributeName}tokenMatched(e){const{element:t}=e,{value:s}=this.fetchParseResultForToken(e);s&&(this.fetchValuesByTokenForElement(t).set(e,s),this.delegate.elementMatchedValue(t,s))}tokenUnmatched(e){const{element:t}=e,{value:s}=this.fetchParseResultForToken(e);s&&(this.fetchValuesByTokenForElement(t).delete(e),this.delegate.elementUnmatchedValue(t,s))}fetchParseResultForToken(e){let t=this.parseResultsByToken.get(e);return t||(t=this.parseToken(e),this.parseResultsByToken.set(e,t)),t}fetchValuesByTokenForElement(e){let t=this.valuesByTokenByElement.get(e);return t||(t=new Map,this.valuesByTokenByElement.set(e,t)),t}parseToken(e){try{return{value:this.delegate.parseValueForToken(e)}}catch(e){return{error:e}}}}class x{constructor(e,t){this.context=e,this.delegate=t,this.bindingsByAction=new Map}start(){this.valueListObserver||(this.valueListObserver=new E(this.element,this.actionAttribute,this),this.valueListObserver.start())}stop(){this.valueListObserver&&(this.valueListObserver.stop(),delete this.valueListObserver,this.disconnectAllActions())}get element(){return this.context.element}get identifier(){return this.context.identifier}get actionAttribute(){return this.schema.actionAttribute}get schema(){return this.context.schema}get bindings(){return Array.from(this.bindingsByAction.values())}connectAction(e){const t=new y(this.context,e);this.bindingsByAction.set(e,t),this.delegate.bindingConnected(t)}disconnectAction(e){const t=this.bindingsByAction.get(e);t&&(this.bindingsByAction.delete(e),this.delegate.bindingDisconnected(t))}disconnectAllActions(){this.bindings.forEach(e=>this.delegate.bindingDisconnected(e,!0)),this.bindingsByAction.clear()}parseValueForToken(e){const t=m.forToken(e,this.schema);if(t.identifier==this.identifier)return t}elementMatchedValue(e,t){this.connectAction(t)}elementUnmatchedValue(e,t){this.disconnectAction(t)}}class M{constructor(e,t){this.context=e,this.receiver=t,this.stringMapObserver=new O(this.element,this),this.valueDescriptorMap=this.controller.valueDescriptorMap}start(){this.stringMapObserver.start(),this.invokeChangedCallbacksForDefaultValues()}stop(){this.stringMapObserver.stop()}get element(){return this.context.element}get controller(){return this.context.controller}getStringMapKeyForAttribute(e){if(e in this.valueDescriptorMap)return this.valueDescriptorMap[e].name}stringMapKeyAdded(e,t){const s=this.valueDescriptorMap[t];this.hasValue(e)||this.invokeChangedCallback(e,s.writer(this.receiver[e]),s.writer(s.defaultValue))}stringMapValueChanged(e,t,s){const i=this.valueDescriptorNameMap[t];null!==e&&(null===s&&(s=i.writer(i.defaultValue)),this.invokeChangedCallback(t,e,s))}stringMapKeyRemoved(e,t,s){const i=this.valueDescriptorNameMap[e];this.hasValue(e)?this.invokeChangedCallback(e,i.writer(this.receiver[e]),s):this.invokeChangedCallback(e,i.writer(i.defaultValue),s)}invokeChangedCallbacksForDefaultValues(){for(const{key:e,name:t,defaultValue:s,writer:i}of this.valueDescriptors)null==s||this.controller.data.has(e)||this.invokeChangedCallback(t,i(s),void 0)}invokeChangedCallback(e,t,s){const i=`${e}Changed`,n=this.receiver[i];if("function"==typeof n){const i=this.valueDescriptorNameMap[e];try{const e=i.reader(t);let r=s;s&&(r=i.reader(s)),n.call(this.receiver,e,r)}catch(e){throw e instanceof TypeError&&(e.message=`Stimulus Value "${this.context.identifier}.${i.name}" - ${e.message}`),e}}}get valueDescriptors(){const{valueDescriptorMap:e}=this;return Object.keys(e).map(t=>e[t])}get valueDescriptorNameMap(){const e={};return Object.keys(this.valueDescriptorMap).forEach(t=>{const s=this.valueDescriptorMap[t];e[s.name]=s}),e}hasValue(e){const t=`has${l(this.valueDescriptorNameMap[e].name)}`;return this.receiver[t]}}class k{constructor(e,t){this.context=e,this.delegate=t,this.targetsByName=new S}start(){this.tokenListObserver||(this.tokenListObserver=new A(this.element,this.attributeName,this),this.tokenListObserver.start())}stop(){this.tokenListObserver&&(this.disconnectAllTargets(),this.tokenListObserver.stop(),delete this.tokenListObserver)}tokenMatched({element:e,content:t}){this.scope.containsElement(e)&&this.connectTarget(e,t)}tokenUnmatched({element:e,content:t}){this.disconnectTarget(e,t)}connectTarget(e,t){var s;this.targetsByName.has(t,e)||(this.targetsByName.add(t,e),null===(s=this.tokenListObserver)||void 0===s||s.pause(()=>this.delegate.targetConnected(e,t)))}disconnectTarget(e,t){var s;this.targetsByName.has(t,e)&&(this.targetsByName.delete(t,e),null===(s=this.tokenListObserver)||void 0===s||s.pause(()=>this.delegate.targetDisconnected(e,t)))}disconnectAllTargets(){for(const e of this.targetsByName.keys)for(const t of this.targetsByName.getValuesForKey(e))this.disconnectTarget(t,e)}get attributeName(){return`data-${this.context.identifier}-target`}get element(){return this.context.element}get scope(){return this.context.scope}}function I(e,t){const s=L(e);return Array.from(s.reduce((e,s)=>(function(e,t){const s=e[t];return Array.isArray(s)?s:[]}(s,t).forEach(t=>e.add(t)),e),new Set))}function L(e){const t=[];for(;e;)t.push(e),e=Object.getPrototypeOf(e);return t.reverse()}class _{constructor(e,t){this.started=!1,this.context=e,this.delegate=t,this.outletsByName=new S,this.outletElementsByName=new S,this.selectorObserverMap=new Map,this.attributeObserverMap=new Map}start(){this.started||(this.outletDefinitions.forEach(e=>{this.setupSelectorObserverForOutlet(e),this.setupAttributeObserverForOutlet(e)}),this.started=!0,this.dependentContexts.forEach(e=>e.refresh()))}refresh(){this.selectorObserverMap.forEach(e=>e.refresh()),this.attributeObserverMap.forEach(e=>e.refresh())}stop(){this.started&&(this.started=!1,this.disconnectAllOutlets(),this.stopSelectorObservers(),this.stopAttributeObservers())}stopSelectorObservers(){this.selectorObserverMap.size>0&&(this.selectorObserverMap.forEach(e=>e.stop()),this.selectorObserverMap.clear())}stopAttributeObservers(){this.attributeObserverMap.size>0&&(this.attributeObserverMap.forEach(e=>e.stop()),this.attributeObserverMap.clear())}selectorMatched(e,t,{outletName:s}){const i=this.getOutlet(e,s);i&&this.connectOutlet(i,e,s)}selectorUnmatched(e,t,{outletName:s}){const i=this.getOutletFromMap(e,s);i&&this.disconnectOutlet(i,e,s)}selectorMatchElement(e,{outletName:t}){const s=this.selector(t),i=this.hasOutlet(e,t),n=e.matches(`[${this.schema.controllerAttribute}~=${t}]`);return!!s&&i&&n&&e.matches(s)}elementMatchedAttribute(e,t){const s=this.getOutletNameFromOutletAttributeName(t);s&&this.updateSelectorObserverForOutlet(s)}elementAttributeValueChanged(e,t){const s=this.getOutletNameFromOutletAttributeName(t);s&&this.updateSelectorObserverForOutlet(s)}elementUnmatchedAttribute(e,t){const s=this.getOutletNameFromOutletAttributeName(t);s&&this.updateSelectorObserverForOutlet(s)}connectOutlet(e,t,s){var i;this.outletElementsByName.has(s,t)||(this.outletsByName.add(s,e),this.outletElementsByName.add(s,t),null===(i=this.selectorObserverMap.get(s))||void 0===i||i.pause(()=>this.delegate.outletConnected(e,t,s)))}disconnectOutlet(e,t,s){var i;this.outletElementsByName.has(s,t)&&(this.outletsByName.delete(s,e),this.outletElementsByName.delete(s,t),null===(i=this.selectorObserverMap.get(s))||void 0===i||i.pause(()=>this.delegate.outletDisconnected(e,t,s)))}disconnectAllOutlets(){for(const e of this.outletElementsByName.keys)for(const t of this.outletElementsByName.getValuesForKey(e))for(const s of this.outletsByName.getValuesForKey(e))this.disconnectOutlet(s,t,e)}updateSelectorObserverForOutlet(e){const t=this.selectorObserverMap.get(e);t&&(t.selector=this.selector(e))}setupSelectorObserverForOutlet(e){const t=this.selector(e),s=new C(document.body,t,this,{outletName:e});this.selectorObserverMap.set(e,s),s.start()}setupAttributeObserverForOutlet(e){const t=this.attributeNameForOutletName(e),s=new w(this.scope.element,t,this);this.attributeObserverMap.set(e,s),s.start()}selector(e){return this.scope.outlets.getSelectorForOutletName(e)}attributeNameForOutletName(e){return this.scope.schema.outletAttributeForScope(this.identifier,e)}getOutletNameFromOutletAttributeName(e){return this.outletDefinitions.find(t=>this.attributeNameForOutletName(t)===e)}get outletDependencies(){const e=new S;return this.router.modules.forEach(t=>{I(t.definition.controllerConstructor,"outlets").forEach(s=>e.add(s,t.identifier))}),e}get outletDefinitions(){return this.outletDependencies.getKeysForValue(this.identifier)}get dependentControllerIdentifiers(){return this.outletDependencies.getValuesForKey(this.identifier)}get dependentContexts(){const e=this.dependentControllerIdentifiers;return this.router.contexts.filter(t=>e.includes(t.identifier))}hasOutlet(e,t){return!!this.getOutlet(e,t)||!!this.getOutletFromMap(e,t)}getOutlet(e,t){return this.application.getControllerForElementAndIdentifier(e,t)}getOutletFromMap(e,t){return this.outletsByName.getValuesForKey(t).find(t=>t.element===e)}get scope(){return this.context.scope}get schema(){return this.context.schema}get identifier(){return this.context.identifier}get application(){return this.context.application}get router(){return this.application.router}}class N{constructor(e,t){this.logDebugActivity=(e,t={})=>{const{identifier:s,controller:i,element:n}=this;t=Object.assign({identifier:s,controller:i,element:n},t),this.application.logDebugActivity(this.identifier,e,t)},this.module=e,this.scope=t,this.controller=new e.controllerConstructor(this),this.bindingObserver=new x(this,this.dispatcher),this.valueObserver=new M(this,this.controller),this.targetObserver=new k(this,this),this.outletObserver=new _(this,this);try{this.controller.initialize(),this.logDebugActivity("initialize")}catch(e){this.handleError(e,"initializing controller")}}connect(){this.bindingObserver.start(),this.valueObserver.start(),this.targetObserver.start(),this.outletObserver.start();try{this.controller.connect(),this.logDebugActivity("connect")}catch(e){this.handleError(e,"connecting controller")}}refresh(){this.outletObserver.refresh()}disconnect(){try{this.controller.disconnect(),this.logDebugActivity("disconnect")}catch(e){this.handleError(e,"disconnecting controller")}this.outletObserver.stop(),this.targetObserver.stop(),this.valueObserver.stop(),this.bindingObserver.stop()}get application(){return this.module.application}get identifier(){return this.module.identifier}get schema(){return this.application.schema}get dispatcher(){return this.application.dispatcher}get element(){return this.scope.element}get parentElement(){return this.element.parentElement}handleError(e,t,s={}){const{identifier:i,controller:n,element:r}=this;s=Object.assign({identifier:i,controller:n,element:r},s),this.application.handleError(e,`Error ${t}`,s)}targetConnected(e,t){this.invokeControllerMethod(`${t}TargetConnected`,e)}targetDisconnected(e,t){this.invokeControllerMethod(`${t}TargetDisconnected`,e)}outletConnected(e,t,s){this.invokeControllerMethod(`${c(s)}OutletConnected`,e,t)}outletDisconnected(e,t,s){this.invokeControllerMethod(`${c(s)}OutletDisconnected`,e,t)}invokeControllerMethod(e,...t){const s=this.controller;"function"==typeof s[e]&&s[e](...t)}}const P="function"==typeof Object.getOwnPropertySymbols?e=>[...Object.getOwnPropertyNames(e),...Object.getOwnPropertySymbols(e)]:Object.getOwnPropertyNames,F=(()=>{function e(e){function t(){return Reflect.construct(e,arguments,new.target)}return t.prototype=Object.create(e.prototype,{constructor:{value:t}}),Reflect.setPrototypeOf(t,e),t}try{return function(){const t=e(function(){this.a.call(this)});t.prototype.a=function(){},new t}(),e}catch(e){return e=>class extends e{}}})();class R{constructor(e,t){this.application=e,this.definition=function(e){return{identifier:e.identifier,controllerConstructor:(t=e.controllerConstructor,function(e,t){const s=F(e),i=function(e,t){return P(t).reduce((s,i)=>{const n=function(e,t,s){const i=Object.getOwnPropertyDescriptor(e,s);if(!i||!("value"in i)){const e=Object.getOwnPropertyDescriptor(t,s).value;return i&&(e.get=i.get||e.get,e.set=i.set||e.set),e}}(e,t,i);return n&&Object.assign(s,{[i]:n}),s},{})}(e.prototype,t);return Object.defineProperties(s.prototype,i),s}(t,function(e){return I(e,"blessings").reduce((t,s)=>{const i=s(e);for(const e in i){const s=t[e]||{};t[e]=Object.assign(s,i[e])}return t},{})}(t)))};var t}(t),this.contextsByScope=new WeakMap,this.connectedContexts=new Set}get identifier(){return this.definition.identifier}get controllerConstructor(){return this.definition.controllerConstructor}get contexts(){return Array.from(this.connectedContexts)}connectContextForScope(e){const t=this.fetchContextForScope(e);this.connectedContexts.add(t),t.connect()}disconnectContextForScope(e){const t=this.contextsByScope.get(e);t&&(this.connectedContexts.delete(t),t.disconnect())}fetchContextForScope(e){let t=this.contextsByScope.get(e);return t||(t=new N(this,e),this.contextsByScope.set(e,t)),t}}class D{constructor(e){this.scope=e}has(e){return this.data.has(this.getDataKey(e))}get(e){return this.getAll(e)[0]}getAll(e){return(this.data.get(this.getDataKey(e))||"").match(/[^\s]+/g)||[]}getAttributeName(e){return this.data.getAttributeNameForKey(this.getDataKey(e))}getDataKey(e){return`${e}-class`}get data(){return this.scope.data}}class j{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get(e){const t=this.getAttributeNameForKey(e);return this.element.getAttribute(t)}set(e,t){const s=this.getAttributeNameForKey(e);return this.element.setAttribute(s,t),this.get(e)}has(e){const t=this.getAttributeNameForKey(e);return this.element.hasAttribute(t)}delete(e){if(this.has(e)){const t=this.getAttributeNameForKey(e);return this.element.removeAttribute(t),!0}return!1}getAttributeNameForKey(e){return`data-${this.identifier}-${h(e)}`}}class B{constructor(e){this.warnedKeysByObject=new WeakMap,this.logger=e}warn(e,t,s){let i=this.warnedKeysByObject.get(e);i||(i=new Set,this.warnedKeysByObject.set(e,i)),i.has(t)||(i.add(t),this.logger.warn(s,e))}}function $(e,t){return`[${e}~="${t}"]`}class V{constructor(e){this.scope=e}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce((e,t)=>e||this.findTarget(t)||this.findLegacyTarget(t),void 0)}findAll(...e){return e.reduce((e,t)=>[...e,...this.findAllTargets(t),...this.findAllLegacyTargets(t)],[])}findTarget(e){const t=this.getSelectorForTargetName(e);return this.scope.findElement(t)}findAllTargets(e){const t=this.getSelectorForTargetName(e);return this.scope.findAllElements(t)}getSelectorForTargetName(e){return $(this.schema.targetAttributeForScope(this.identifier),e)}findLegacyTarget(e){const t=this.getLegacySelectorForTargetName(e);return this.deprecate(this.scope.findElement(t),e)}findAllLegacyTargets(e){const t=this.getLegacySelectorForTargetName(e);return this.scope.findAllElements(t).map(t=>this.deprecate(t,e))}getLegacySelectorForTargetName(e){const t=`${this.identifier}.${e}`;return $(this.schema.targetAttribute,t)}deprecate(e,t){if(e){const{identifier:s}=this,i=this.schema.targetAttribute,n=this.schema.targetAttributeForScope(s);this.guide.warn(e,`target:${t}`,`Please replace ${i}="${s}.${t}" with ${n}="${t}". The ${i} attribute is deprecated and will be removed in a future version of Stimulus.`)}return e}get guide(){return this.scope.guide}}class q{constructor(e,t){this.scope=e,this.controllerElement=t}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get schema(){return this.scope.schema}has(e){return null!=this.find(e)}find(...e){return e.reduce((e,t)=>e||this.findOutlet(t),void 0)}findAll(...e){return e.reduce((e,t)=>[...e,...this.findAllOutlets(t)],[])}getSelectorForOutletName(e){const t=this.schema.outletAttributeForScope(this.identifier,e);return this.controllerElement.getAttribute(t)}findOutlet(e){const t=this.getSelectorForOutletName(e);if(t)return this.findElement(t,e)}findAllOutlets(e){const t=this.getSelectorForOutletName(e);return t?this.findAllElements(t,e):[]}findElement(e,t){return this.scope.queryElements(e).filter(s=>this.matchesElement(s,e,t))[0]}findAllElements(e,t){return this.scope.queryElements(e).filter(s=>this.matchesElement(s,e,t))}matchesElement(e,t,s){const i=e.getAttribute(this.scope.schema.controllerAttribute)||"";return e.matches(t)&&i.split(" ").includes(s)}}class U{constructor(e,t,s,i){this.targets=new V(this),this.classes=new D(this),this.data=new j(this),this.containsElement=e=>e.closest(this.controllerSelector)===this.element,this.schema=e,this.element=t,this.identifier=s,this.guide=new B(i),this.outlets=new q(this.documentScope,t)}findElement(e){return this.element.matches(e)?this.element:this.queryElements(e).find(this.containsElement)}findAllElements(e){return[...this.element.matches(e)?[this.element]:[],...this.queryElements(e).filter(this.containsElement)]}queryElements(e){return Array.from(this.element.querySelectorAll(e))}get controllerSelector(){return $(this.schema.controllerAttribute,this.identifier)}get isDocumentScope(){return this.element===document.documentElement}get documentScope(){return this.isDocumentScope?this:new U(this.schema,document.documentElement,this.identifier,this.guide.logger)}}class z{constructor(e,t,s){this.element=e,this.schema=t,this.delegate=s,this.valueListObserver=new E(this.element,this.controllerAttribute,this),this.scopesByIdentifierByElement=new WeakMap,this.scopeReferenceCounts=new WeakMap}start(){this.valueListObserver.start()}stop(){this.valueListObserver.stop()}get controllerAttribute(){return this.schema.controllerAttribute}parseValueForToken(e){const{element:t,content:s}=e;return this.parseValueForElementAndIdentifier(t,s)}parseValueForElementAndIdentifier(e,t){const s=this.fetchScopesByIdentifierForElement(e);let i=s.get(t);return i||(i=this.delegate.createScopeForElementAndIdentifier(e,t),s.set(t,i)),i}elementMatchedValue(e,t){const s=(this.scopeReferenceCounts.get(t)||0)+1;this.scopeReferenceCounts.set(t,s),1==s&&this.delegate.scopeConnected(t)}elementUnmatchedValue(e,t){const s=this.scopeReferenceCounts.get(t);s&&(this.scopeReferenceCounts.set(t,s-1),1==s&&this.delegate.scopeDisconnected(t))}fetchScopesByIdentifierForElement(e){let t=this.scopesByIdentifierByElement.get(e);return t||(t=new Map,this.scopesByIdentifierByElement.set(e,t)),t}}class W{constructor(e){this.application=e,this.scopeObserver=new z(this.element,this.schema,this),this.scopesByIdentifier=new S,this.modulesByIdentifier=new Map}get element(){return this.application.element}get schema(){return this.application.schema}get logger(){return this.application.logger}get controllerAttribute(){return this.schema.controllerAttribute}get modules(){return Array.from(this.modulesByIdentifier.values())}get contexts(){return this.modules.reduce((e,t)=>e.concat(t.contexts),[])}start(){this.scopeObserver.start()}stop(){this.scopeObserver.stop()}loadDefinition(e){this.unloadIdentifier(e.identifier);const t=new R(this.application,e);this.connectModule(t);const s=e.controllerConstructor.afterLoad;s&&s.call(e.controllerConstructor,e.identifier,this.application)}unloadIdentifier(e){const t=this.modulesByIdentifier.get(e);t&&this.disconnectModule(t)}getContextForElementAndIdentifier(e,t){const s=this.modulesByIdentifier.get(t);if(s)return s.contexts.find(t=>t.element==e)}proposeToConnectScopeForElementAndIdentifier(e,t){const s=this.scopeObserver.parseValueForElementAndIdentifier(e,t);s?this.scopeObserver.elementMatchedValue(s.element,s):console.error(`Couldn't find or create scope for identifier: "${t}" and element:`,e)}handleError(e,t,s){this.application.handleError(e,t,s)}createScopeForElementAndIdentifier(e,t){return new U(this.schema,e,t,this.logger)}scopeConnected(e){this.scopesByIdentifier.add(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.connectContextForScope(e)}scopeDisconnected(e){this.scopesByIdentifier.delete(e.identifier,e);const t=this.modulesByIdentifier.get(e.identifier);t&&t.disconnectContextForScope(e)}connectModule(e){this.modulesByIdentifier.set(e.identifier,e),this.scopesByIdentifier.getValuesForKey(e.identifier).forEach(t=>e.connectContextForScope(t))}disconnectModule(e){this.modulesByIdentifier.delete(e.identifier),this.scopesByIdentifier.getValuesForKey(e.identifier).forEach(t=>e.disconnectContextForScope(t))}}const H={controllerAttribute:"data-controller",actionAttribute:"data-action",targetAttribute:"data-target",targetAttributeForScope:e=>`data-${e}-target`,outletAttributeForScope:(e,t)=>`data-${e}-${t}-outlet`,keyMappings:Object.assign(Object.assign({enter:"Enter",tab:"Tab",esc:"Escape",space:" ",up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",home:"Home",end:"End",page_up:"PageUp",page_down:"PageDown"},K("abcdefghijklmnopqrstuvwxyz".split("").map(e=>[e,e]))),K("0123456789".split("").map(e=>[e,e])))};function K(e){return e.reduce((e,[t,s])=>Object.assign(Object.assign({},e),{[t]:s}),{})}class G{constructor(e=document.documentElement,t=H){this.logger=console,this.debug=!1,this.logDebugActivity=(e,t,s={})=>{this.debug&&this.logFormattedMessage(e,t,s)},this.element=e,this.schema=t,this.dispatcher=new n(this),this.router=new W(this),this.actionDescriptorFilters=Object.assign({},r)}static start(e,t){const s=new this(e,t);return s.start(),s}async start(){await new Promise(e=>{"loading"==document.readyState?document.addEventListener("DOMContentLoaded",()=>e()):e()}),this.logDebugActivity("application","starting"),this.dispatcher.start(),this.router.start(),this.logDebugActivity("application","start")}stop(){this.logDebugActivity("application","stopping"),this.dispatcher.stop(),this.router.stop(),this.logDebugActivity("application","stop")}register(e,t){this.load({identifier:e,controllerConstructor:t})}registerActionOption(e,t){this.actionDescriptorFilters[e]=t}load(e,...t){(Array.isArray(e)?e:[e,...t]).forEach(e=>{e.controllerConstructor.shouldLoad&&this.router.loadDefinition(e)})}unload(e,...t){(Array.isArray(e)?e:[e,...t]).forEach(e=>this.router.unloadIdentifier(e))}get controllers(){return this.router.contexts.map(e=>e.controller)}getControllerForElementAndIdentifier(e,t){const s=this.router.getContextForElementAndIdentifier(e,t);return s?s.controller:null}handleError(e,t,s){var i;this.logger.error("%s\n\n%o\n\n%o",t,e,s),null===(i=window.onerror)||void 0===i||i.call(window,t,"",0,0,e)}logFormattedMessage(e,t,s={}){s=Object.assign({application:this},s),this.logger.groupCollapsed(`${e} #${t}`),this.logger.log("details:",Object.assign({},s)),this.logger.groupEnd()}}function J(e,t,s){return e.application.getControllerForElementAndIdentifier(t,s)}function Y(e,t,s){let i=J(e,t,s);return i||(e.application.router.proposeToConnectScopeForElementAndIdentifier(t,s),i=J(e,t,s),i||void 0)}function Z([e,t],s){return function(e){const{token:t,typeDefinition:s}=e,i=`${h(t)}-value`,n=function(e){const{controller:t,token:s,typeDefinition:i}=e,n=function(e){const{controller:t,token:s,typeObject:i}=e,n=u(i.type),r=u(i.default),a=n&&r,o=n&&!r,c=!n&&r,l=X(i.type),h=Q(e.typeObject.default);if(o)return l;if(c)return h;if(l!==h)throw new Error(`The specified default value for the Stimulus Value "${t?`${t}.${s}`:s}" must match the defined type "${l}". The provided default value of "${i.default}" is of type "${h}".`);return a?l:void 0}({controller:t,token:s,typeObject:i}),r=Q(i),a=X(i),o=n||r||a;if(o)return o;throw new Error(`Unknown value type "${t?`${t}.${i}`:s}" for "${s}" value`)}(e);return{type:n,key:i,name:o(i),get defaultValue(){return function(e){const t=X(e);if(t)return ee[t];const s=d(e,"default"),i=d(e,"type"),n=e;if(s)return n.default;if(i){const{type:e}=n,t=X(e);if(t)return ee[t]}return e}(s)},get hasCustomDefaultValue(){return void 0!==Q(s)},reader:te[n],writer:se[n]||se.default}}({controller:s,token:e,typeDefinition:t})}function X(e){switch(e){case Array:return"array";case Boolean:return"boolean";case Number:return"number";case Object:return"object";case String:return"string"}}function Q(e){switch(typeof e){case"boolean":return"boolean";case"number":return"number";case"string":return"string"}return Array.isArray(e)?"array":"[object Object]"===Object.prototype.toString.call(e)?"object":void 0}const ee={get array(){return[]},boolean:!1,number:0,get object(){return{}},string:""},te={array(e){const t=JSON.parse(e);if(!Array.isArray(t))throw new TypeError(`expected value of type "array" but instead got value "${e}" of type "${Q(t)}"`);return t},boolean:e=>!("0"==e||"false"==String(e).toLowerCase()),number:e=>Number(e.replace(/_/g,"")),object(e){const t=JSON.parse(e);if(null===t||"object"!=typeof t||Array.isArray(t))throw new TypeError(`expected value of type "object" but instead got value "${e}" of type "${Q(t)}"`);return t},string:e=>e},se={default:function(e){return`${e}`},array:ie,object:ie};function ie(e){return JSON.stringify(e)}class ne{constructor(e){this.context=e}static get shouldLoad(){return!0}static afterLoad(e,t){}get application(){return this.context.application}get scope(){return this.context.scope}get element(){return this.scope.element}get identifier(){return this.scope.identifier}get targets(){return this.scope.targets}get outlets(){return this.scope.outlets}get classes(){return this.scope.classes}get data(){return this.scope.data}initialize(){}connect(){}disconnect(){}dispatch(e,{target:t=this.element,detail:s={},prefix:i=this.identifier,bubbles:n=!0,cancelable:r=!0}={}){const a=new CustomEvent(i?`${i}:${e}`:e,{detail:s,bubbles:n,cancelable:r});return t.dispatchEvent(a),a}}ne.blessings=[function(e){return I(e,"classes").reduce((e,t)=>{return Object.assign(e,(s=t,{[`${s}Class`]:{get(){const{classes:e}=this;if(e.has(s))return e.get(s);{const t=e.getAttributeName(s);throw new Error(`Missing attribute "${t}"`)}}},[`${s}Classes`]:{get(){return this.classes.getAll(s)}},[`has${l(s)}Class`]:{get(){return this.classes.has(s)}}}));var s},{})},function(e){return I(e,"targets").reduce((e,t)=>{return Object.assign(e,(s=t,{[`${s}Target`]:{get(){const e=this.targets.find(s);if(e)return e;throw new Error(`Missing target element "${s}" for "${this.identifier}" controller`)}},[`${s}Targets`]:{get(){return this.targets.findAll(s)}},[`has${l(s)}Target`]:{get(){return this.targets.has(s)}}}));var s},{})},function(e){const t=function(e,t){return L(e).reduce((e,s)=>(e.push(...function(e,t){const s=e[t];return s?Object.keys(s).map(e=>[e,s[e]]):[]}(s,t)),e),[])}(e,"values"),s={valueDescriptorMap:{get(){return t.reduce((e,t)=>{const s=Z(t,this.identifier),i=this.data.getAttributeNameForKey(s.key);return Object.assign(e,{[i]:s})},{})}}};return t.reduce((e,t)=>Object.assign(e,function(e){const t=Z(e,void 0),{key:s,name:i,reader:n,writer:r}=t;return{[i]:{get(){const e=this.data.get(s);return null!==e?n(e):t.defaultValue},set(e){void 0===e?this.data.delete(s):this.data.set(s,r(e))}},[`has${l(i)}`]:{get(){return this.data.has(s)||t.hasCustomDefaultValue}}}}(t)),s)},function(e){return I(e,"outlets").reduce((e,t)=>Object.assign(e,function(e){const t=c(e);return{[`${t}Outlet`]:{get(){const t=this.outlets.find(e),s=this.outlets.getSelectorForOutletName(e);if(t){const s=Y(this,t,e);if(s)return s;throw new Error(`The provided outlet element is missing an outlet controller "${e}" instance for host controller "${this.identifier}"`)}throw new Error(`Missing outlet element "${e}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${s}".`)}},[`${t}Outlets`]:{get(){const t=this.outlets.findAll(e);return t.length>0?t.map(t=>{const s=Y(this,t,e);if(s)return s;console.warn(`The provided outlet element is missing an outlet controller "${e}" instance for host controller "${this.identifier}"`,t)}).filter(e=>e):[]}},[`${t}OutletElement`]:{get(){const t=this.outlets.find(e),s=this.outlets.getSelectorForOutletName(e);if(t)return t;throw new Error(`Missing outlet element "${e}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${s}".`)}},[`${t}OutletElements`]:{get(){return this.outlets.findAll(e)}},[`has${l(t)}Outlet`]:{get(){return this.outlets.has(e)}}}}(t)),{})}],ne.targets=[],ne.outlets=[],ne.values={}},434(e,t,s){s.d(t,{default:()=>ri});var i=s(891);class n extends Error{constructor(e){super(`${e} is not valid. Please provide a valid event name`),this.name="InvalidEvent"}}class r{static events=["session-set","utm-set","forms:collected","form:completed","alert:shown","alert:dismissed","alert:accepted","webchat:mounted","webchat:opened","webchat:closed","webchat:message:sent","webchat:message:received","cart.added"];static valid(e){return r.exists(e)}static invalid(e){return!this.valid(e)}static exists(e){return void 0!==this.events.find(t=>t===e)}constructor(){this.subscribers={}}addSubscriber(e,t){if(r.invalid(e))throw new n(e);this.subscribers={...this.subscribers,[e]:this.subscribers[e]?[...this.subscribers[e],t]:[t]}}removeSubscriber(e,t){if(r.invalid(e))throw new n(e);this.subscribers[e]&&(this.subscribers[e]=this.subscribers[e].filter(e=>e!==t))}dispatch(e,t){this.subscribers[e]?.forEach(e=>{e(t)})}get listeners(){return 0!==Object.keys(this.subscribers).length}}class a{static autoMount=!0;static successMessage=!0;static assign(e){return e&&Object.entries(e).forEach(([e,t])=>{this[e]=t}),this}static get shouldShowSuccessMessage(){return this.successMessage}}class o{static _identifier;static set identifier(e){this._identifier=e}static get identifier(){return this._identifier?this._identifier:this.#e||this.#t||this.#s||"en"}static toString(){return this.identifier}static get#e(){return document?.documentElement?.lang}static get#t(){return document?.querySelector('meta[name="locale"]')?.content}static get#s(){return navigator?.language?.split("-")[0]}}const c={TOP_LEFT:"top-left",TOP_RIGHT:"top-right",BOTTOM_LEFT:"bottom-left",BOTTOM_RIGHT:"bottom-right"},l={ABSOLUTE:"absolute",FIXED:"fixed"},h={MODAL:"modal",POPOVER:"popover"};class u{static _id;static _container="body";static _placement="bottom-right";static _style={};static _appearance={};static _whatsapp={};static _mode=h.POPOVER;static _behaviour=null;static _hasBehaviourOverride=!1;static _strategy=null;static set container(e){this._container=e}static get container(){return this._container}static set placement(e){if(!Object.values(c).includes(e))throw new Error(`Invalid placement value: ${e}`);this._placement=e}static get placement(){return this._placement}static set id(e){this._id=e}static get id(){return this._id}static get isSet(){return!!this._id}static get style(){return this._style}static set style(e){if("object"!=typeof e)throw new Error("Style must be an object");Object.entries(e).forEach(([e,t])=>{if(!["primaryColor","secondaryColor","typography"].includes(e))throw new Error(`Invalid style property: ${e}`);if("typography"!==e&&!this.isHexOrRgba(t))throw new Error(`Invalid color value: ${t} for ${e}. Colors must be hex or rgb/a.`)}),this._style=e}static get appearance(){return this._appearance}static set appearance(e){if(!this.isPlainObject(e))throw new Error("Appearance must be an object");Object.entries(e).forEach(([e,t])=>{if(!["header","launcher"].includes(e))throw new Error(`Invalid appearance property: ${e}`);if(!this.isPlainObject(t))throw new Error(`Appearance ${e} must be an object`);Object.entries(t).forEach(([t,s])=>{if("header"===e&&"name"!==t)throw new Error(`Invalid appearance header property: ${t}`);if("launcher"===e&&"iconUrl"!==t)throw new Error(`Invalid appearance launcher property: ${t}`);if(null!=s&&"string"!=typeof s)throw new Error(`Invalid appearance ${e}.${t} value: ${s}`)})}),this._appearance=e}static get whatsapp(){return this._whatsapp}static set whatsapp(e){if(!this.isPlainObject(e))throw new Error("WhatsApp must be an object");Object.entries(e).forEach(([e,t])=>{if(!["number","restrictToChannel"].includes(e))throw new Error(`Invalid WhatsApp property: ${e}`);if(null!=t){if("number"===e&&"string"!=typeof t)throw new Error(`Invalid WhatsApp number value: ${t}`);if("restrictToChannel"===e&&"boolean"!=typeof t)throw new Error(`Invalid WhatsApp restrictToChannel value: ${t}`)}}),this._whatsapp=e}static get mode(){return this._mode}static set mode(e){if(!Object.values(h).includes(e))throw new Error(`Invalid mode value: ${e}`);this._mode=e}static get behaviour(){return this._behaviour}static set behaviour(e){if(null!=e){if("object"!=typeof e||Array.isArray(e))throw new Error(`Invalid behaviour value: ${e}`);this._behaviour=e}else this._behaviour=e}static get hasBehaviourOverride(){return this._hasBehaviourOverride}static set behaviourOverride(e){this._hasBehaviourOverride=!!e}static get strategy(){return this._strategy?this._strategy:"body"==this.container?l.FIXED:l.ABSOLUTE}static set strategy(e){if(e&&!Object.values(l).includes(e))throw new Error(`Invalid strategy value: ${e}`);this._strategy=e}static assign(e){return e&&Object.entries(e).forEach(([e,t])=>{this[e]=t}),this}static isHexOrRgba(e){return/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(e)||/^rgba?\(\s*\d{1,3},\s*\d{1,3},\s*\d{1,3},?\s*(0|1|0?\.\d+)?\s*\)$/.test(e)}static isPlainObject(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}}const d={TOP_LEFT:"top-left",TOP_RIGHT:"top-right",BOTTOM_LEFT:"bottom-left",BOTTOM_RIGHT:"bottom-right"};class p{static _id;static _container="body";static _placement="bottom-right";static _appearance={};static _number=null;static _body=null;static set id(e){this._id=e}static get id(){return this._id}static set container(e){this._container=e}static get container(){return this._container}static set placement(e){if(!Object.values(d).includes(e))throw new Error(`Invalid placement value: ${e}`);this._placement=e}static get placement(){return this._placement}static get appearance(){return this._appearance}static set appearance(e){if(!this.isPlainObject(e))throw new Error("Appearance must be an object");Object.entries(e).forEach(([e,t])=>{if("launcher"!==e)throw new Error(`Invalid appearance property: ${e}`);if(!this.isPlainObject(t))throw new Error(`Appearance ${e} must be an object`);Object.entries(t).forEach(([t,s])=>{if("iconUrl"!==t)throw new Error(`Invalid appearance launcher property: ${t}`);if(null!=s&&"string"!=typeof s)throw new Error(`Invalid appearance ${e}.${t} value: ${s}`)})}),this._appearance=e}static get number(){return this._number}static set number(e){if(null!=e&&"string"!=typeof e)throw new Error(`Invalid number value: ${e}`);this._number=e}static get body(){return this._body}static set body(e){if(null!=e&&"string"!=typeof e)throw new Error(`Invalid body value: ${e}`);this._body=e}static assign(e){return e&&Object.entries(e).forEach(([e,t])=>{this[e]=t}),this}static isPlainObject(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}}class m{static serviceWorkerUrl=null;static channelId=null;static assign(e){return this.serviceWorkerUrl=e?.serviceWorkerUrl||null,this.channelId=e?.channelId||null,this}}class g{static apiRoot="https://api.hellotext.com/v1";static actionCableUrl="wss://www.hellotext.com/cable";static autoGenerateSession=!0;static session=null;static forms=a;static webchat=u;static whatsapp=p;static push=m;static assign(e){if(e){const t=Object.prototype.hasOwnProperty.call(e,"apiRoot")&&!Object.prototype.hasOwnProperty.call(e,"actionCableUrl");Object.entries(e).forEach(([e,t])=>{"forms"===e?this.forms=a.assign(t):"webchat"===e?this.webchat=u.assign(t):"whatsappWidget"===e?this.whatsapp=p.assign(t):"push"===e?this.push=m.assign(t):this[e]=t}),t&&(this.actionCableUrl=this.actionCableUrlForApiRoot(this.apiRoot))}return this}static set locale(e){o.identifier=e}static get locale(){return o.toString()}static endpoint(e){return`${this.apiRoot}/${e}`}static actionCableUrlForApiRoot(e){try{const t=new URL(e),s="https:"===t.protocol?"wss:":"ws:";return t.protocol=s,t.pathname="/cable",t.search="",t.hash="",t.toString()}catch(e){return this.actionCableUrl}}}const f=class{static get endpoint(){return g.endpoint("public/businesses")}static async get(e){return fetch(`${this.endpoint}/${e}`,{method:"GET",headers:{Authorization:`Bearer ${e}`,Accept:"application/json","Content-Type":"application/json"}})}};class b{static get inPreviewMode(){return(new this).inPreviewMode}constructor(){this.urlSearchParams=new URLSearchParams(window.location.search)}get(e){return this.urlSearchParams.get(this.toHellotextParam(e))}has(e){return this.urlSearchParams.has(this.toHellotextParam(e))}get inPreviewMode(){return this.has("preview")}get session(){return this.get("session")}toHellotextParam(e){return`hello_${e}`}}class y{#i;constructor(e,t){this.response=t,this.#i=e}get data(){return this.response}async json(){return await this.response.json()}get failed(){return!1===this.#i}get succeeded(){return!0===this.#i}}class v{static get endpoint(){return g.endpoint("track/events")}static async create({headers:e,body:t,keepalive:s=!1}){if(b.inPreviewMode)return new y(!0,{received:!0});const i={method:"POST",headers:e,body:JSON.stringify(t)};s&&(i.keepalive=!0);const n=await fetch(this.endpoint,i);return new y(200===n.status,await n.json())}}class w{static get endpoint(){return g.endpoint("public/forms")}static async get(e){const t=new URL(`${this.endpoint}/${e}`);return t.searchParams.append("session",bt.session),t.searchParams.append("locale",o.toString()),fetch(t,{method:"GET",headers:bt.headers})}static async submit(e,t){const s=await fetch(`${this.endpoint}/${e}/submissions`,{method:"POST",headers:bt.headers,body:JSON.stringify({session:bt.session,...t})});return new y(s.ok,s)}}const T=class{static get endpoint(){return g.endpoint("public/identifications")}static async create(e={}){const t=await fetch(this.endpoint,{method:"POST",headers:bt.headers,body:JSON.stringify({session:bt.session,...e})});return new y(t.ok,t)}},S=class{static get endpoint(){return g.endpoint("public/webchats")}static async get(e){const t=new URL(`${this.endpoint}/${e}`);t.searchParams.append("session",bt.session),t.searchParams.append("locale",o.toString()),Object.entries(g.webchat.style).forEach(([e,s])=>{t.searchParams.append(`style[${e}]`,s)}),this.appendWebchatOverrides(t),t.searchParams.append("placement",g.webchat.placement);const s=await fetch(t,{method:"GET",headers:bt.headers}),i=await s.json();return bt.business.data||(bt.business.setData(i.business),bt.business.setLocale(i.locale)),(new DOMParser).parseFromString(i.html,"text/html").querySelector("article")}static appendWebchatOverrides(e){const{appearance:t,whatsapp:s}=g.webchat;this.appendIfSupplied(e,"webchat[appearance][header][name]",t.header?.name),this.appendIfSupplied(e,"webchat[appearance][launcher][icon_url]",t.launcher?.iconUrl),this.appendIfSupplied(e,"webchat[handoff][identifier]",s.number),this.appendIfSupplied(e,"webchat[handoff][restrict_to_channel]",s.restrictToChannel)}static appendIfSupplied(e,t,s){null!=s&&e.searchParams.append(t,String(s))}},C=class{static get endpoint(){return g.endpoint("public/widgets/whatsapp")}static async get(e){const t=new URL(`${this.endpoint}/${e}`);t.searchParams.append("locale",o.toString()),t.searchParams.append("placement",g.whatsapp.placement),this.appendWhatsAppOverrides(t);const s=await this.fetchWidget(t);if(!s.ok)return null;const i=await this.parseWidgetResponse(s);return i?(bt.business.data||(bt.business.setData(i.business),bt.business.setLocale(i.locale)),(new DOMParser).parseFromString(i.html,"text/html").querySelector("article")):null}static appendWhatsAppOverrides(e){const{appearance:t,body:s,number:i}=g.whatsapp;this.appendIfSupplied(e,"whatsapp[appearance][launcher][icon_url]",t.launcher?.iconUrl),this.appendIfSupplied(e,"whatsapp[number]",i),this.appendIfSupplied(e,"whatsapp[body]",s)}static appendIfSupplied(e,t,s){null!=s&&e.searchParams.append(t,String(s))}static async fetchWidget(e){try{return await fetch(e,{method:"GET",headers:bt.headers})}catch(e){return{ok:!1}}}static async parseWidgetResponse(e){try{return await e.json()}catch(e){return null}}},O=class{static get endpoint(){return g.endpoint("public/acks")}static async send(e={}){const t={...e,session:bt.session,at:(new Date).toISOString()};fetch(this.endpoint,{method:"POST",headers:bt.headers,body:JSON.stringify(t),keepalive:!0})}},A=class{static get endpoint(){return g.endpoint("public/push/identities")}static async create(e={}){const t=await fetch(this.endpoint,{method:"POST",keepalive:!0,headers:bt.headers,body:JSON.stringify({...e,session:bt.session,origin:window.location.origin})});return new y(t.ok,t)}static async destroy(e={}){const t=await fetch(this.endpoint,{method:"DELETE",keepalive:!0,headers:bt.headers,body:JSON.stringify({...e,session:bt.session,origin:window.location.origin})});return new y(t.ok,t)}},E=class{static get endpoint(){return g.endpoint("public/push/alerts")}static async create({section:e,kind:t,page:s}){const i=await fetch(this.endpoint,{method:"POST",keepalive:!0,headers:bt.headers,body:JSON.stringify({session:bt.session,section:e,kind:t,page:s})});return new y(i.ok,i)}};function x(e){const t=JSON.stringify(e);return"undefined"==typeof Blob?t.length<6e4:new Blob([t]).size<6e4}class M{static get businesses(){return f}static get events(){return v}static get forms(){return w}static get webchats(){return S}static get whatsappWidgets(){return C}static get identifications(){return T}static get acks(){return O}static get pushAlerts(){return E}static get pushIdentities(){return A}}const k={en:{white_label:{powered_by:"By"},errors:{parameter_not_unique:"This value is taken.",blank:"This field is required."},forms:{phone:"Click the link sent via SMS to verify your submission.",email:"Click the link sent via email to verify your submission.",phone_and_email:"Click the links sent via SMS and email to verify your submission.",none:"Your submission has been received."}},es:{white_label:{powered_by:"Por"},errors:{parameter_not_unique:"Este valor ya está en uso.",blank:"Este campo es obligatorio."},forms:{phone:"Haga clic en el enlace enviado por SMS para verificar su envío.",email:"Haga clic en el enlace enviado por e-mail para verificar su envío.",phone_and_email:"Haga clic en los enlaces enviados por SMS y e-mail para verificar su envío.",none:"Su envío ha sido recibido."}}},I="data-hellotext-stylesheet";class L{constructor(e){this.id=e,this.data=null,this.stylesheet=null,this.stylesheetLoaded=Promise.resolve(!1)}async hydrate(){try{const e=await f.get(this.id);if(!1===e.ok)return null;const t=await e.json();return t?(this.setData(t),t.locale&&this.setLocale(t.locale),t):null}catch(e){return null}}setData(e){this.data=e,"undefined"!=typeof document&&e.style_url?(this.stylesheet=this.constructor.ensureStylesheet(e.style_url),this.stylesheetLoaded=this.constructor.waitForStylesheet(this.stylesheet)):(this.stylesheet=null,this.stylesheetLoaded=Promise.resolve(!1))}static get stylesheetSelector(){return`link[rel="stylesheet"][${I}]`}static ensureStylesheet(e){const t=this.normalizedStylesheetUrl(e),s=this.stylesheetLinks.find(e=>e.href===t);if(s)return s.setAttribute(I,"true"),s;const i=document.createElement("link");return i.rel="stylesheet",i.href=e,i.setAttribute(I,"true"),this.waitForStylesheet(i),document.head.append(i),i}static get stylesheetLinks(){return"undefined"==typeof document?[]:Array.from(document.querySelectorAll(this.stylesheetSelector))}static get latestStylesheet(){return this.stylesheetLinks[this.stylesheetLinks.length-1]}static normalizedStylesheetUrl(e){try{return new URL(e,document.baseURI).href}catch(t){return e}}static waitForStylesheet(e){return e?this.stylesheetIsLoaded(e)?Promise.resolve(!0):"false"===e.dataset.hellotextStylesheetLoaded?Promise.resolve(!1):(e._hellotextStylesheetLoaded||(e._hellotextStylesheetLoaded=new Promise(t=>{let s;const i=i=>{clearTimeout(s),e.removeEventListener("load",n),e.removeEventListener("error",r),e.dataset.hellotextStylesheetLoaded=i?"true":"false",t(i)},n=()=>i(this.stylesheetIsLoaded(e)),r=()=>i(!1);e.addEventListener("load",n),e.addEventListener("error",r),s=setTimeout(()=>i(this.stylesheetIsLoaded(e)),1e4),s.unref&&s.unref()})),e._hellotextStylesheetLoaded):Promise.resolve(!1)}static stylesheetIsLoaded(e){return"true"===e.dataset.hellotextStylesheetLoaded||!!e.sheet}get subscription(){return this.data.subscription}get country(){return this.data.country}get enabledWhitelist(){return"disabled"!==this.data.whitelist}setLocale(e){if(!k[e])return console.warn(`Locale ${e} not found`);this.data||(this.data={}),this.data.locale=e}get locale(){return k[this.data.locale]}get features(){return this.data.features}}class _{static set(e,t){if("undefined"!=typeof document){const s="https:"===window.location.protocol?"; Secure":"",i=P.getRootDomain(),n=31536e4;document.cookie=i?`${e}=${t}; path=/${s}; domain=${i}; max-age=${n}; SameSite=Lax`:`${e}=${t}; path=/${s}; max-age=${n}; SameSite=Lax`}return"hello_session"===e&&bt.eventEmitter.dispatch("session-set",t),"hello_utm"===e&&bt.eventEmitter.dispatch("utm-set",t),t}static get(e){return"undefined"!=typeof document?document.cookie.match("(^|;)\\s*"+e+"\\s*=\\s*([^;]+)")?.pop():void 0}static delete(e){if("undefined"!=typeof document){const t=P.getRootDomain(),s="https:"===window.location.protocol?"; Secure":"";document.cookie=t?`${e}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT${s}; domain=${t}; SameSite=Lax`:`${e}=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT${s}; SameSite=Lax`}}}class N{constructor(){const e=new URLSearchParams(window.location.search),t={source:e.get("utm_source"),medium:e.get("utm_medium"),campaign:e.get("utm_campaign"),term:e.get("utm_term"),content:e.get("utm_content")};this.save(t)}save(e){if(!e.source||!e.medium)return;const t=Object.fromEntries(Object.entries(e).filter(([e,t])=>t));t.observed_at=(new Date).toISOString(),_.set("hello_utm",JSON.stringify(t))}get current(){try{return JSON.parse(_.get("hello_utm"))||{}}catch(e){return{}}}}class P{constructor(e=null){this.utm=new N,this._url=e}get url(){return null!==this._url&&void 0!==this._url?this._url:window.location.href}get title(){return document.title}get path(){if(this._url)try{return new URL(this._url).pathname}catch(e){return"/"}return window.location.pathname}get utmParams(){return this.utm.current}get trackingData(){return{page:{url:this.url,title:this.title,path:this.path},utm_params:this.utmParams}}get domain(){try{const e=this.url;if(!e)return null;const t=new URL(e).hostname;return P.getRootDomain(t)}catch(e){return null}}static getRootDomain(e=null){try{if(!e){if("undefined"==typeof window||!window.location?.hostname)return null;e=window.location.hostname}const t=e.split(".");if(t.length<=1)return e;const s=["myshopify.com","vtexcommercestable.com.br","myvtex.com","wixsite.com"];for(const e of s){const s=e.split(".");if(t.slice(-s.length).join(".")===e&&t.length>s.length)return`.${t.slice(-(s.length+1)).join(".")}`}const i=t[t.length-1],n=t[t.length-2];return t.length>2&&2===i.length&&n.length<=3?`.${t.slice(-3).join(".")}`:`.${t.slice(-2).join(".")}`}catch(e){return null}}}class F{static#n;static#r;static#a;static get session(){return this.#n}static get ackPayload(){return{utm_params:this.#a?.utmParams||{}}}static set session(e){const t=_.get("hello_session");return this.#n=e,_.set("hello_session",e),t!==e&&_.delete("hello_session_ack_at"),_.get("hello_session_ack_at")||(M.acks.send(this.ackPayload),_.set("hello_session_ack_at",(new Date).toISOString())),this.#n}static initialize(e=new P){this.#a=e,this.#r=new b,this.session=this.#r.session||g.session||_.get("hello_session"),!this.session&&g.autoGenerateSession&&(this.session=crypto.randomUUID())}}class R{static build(e){const t=document.createElement("article"),s=document.createElement("label"),i=document.createElement("input");s.innerText=e.label,i.type=e.type,i.required=e.required,i.placeholder=e.placeholder,["first_name","last_name"].includes(e.kind)?(i.type="text",i.id=i.name=e.kind,s.setAttribute("for",e.kind)):(i.type=e.type,"email"===e.type?(i.id=i.name="email",s.setAttribute("for","email")):"tel"===i.type?(i.id=i.name="phone",s.setAttribute("for","phone"),i.value=`+${bt.business.country.prefix}`,i.setAttribute("data-default-value",`+${bt.business.country.prefix}`)):(i.name=i.id=`property_by_id[${e.property}]`,s.setAttribute("for",`property_by_id[${e.property}]`)));const n=document.createElement("main");n.appendChild(s),n.appendChild(i),t.appendChild(n),t.setAttribute("data-hellotext--form-target","inputContainer"),i.setAttribute("data-hellotext--form-target","input");const r=document.createElement("div");return r.setAttribute("data-error-container",""),t.appendChild(r),t}}class D{static build(){const e=document.createElement("div");return e.innerHTML=this.#o(),e.firstElementChild}static#o(){const e=`https://www.hellotext.com?hello_session=${bt.session}`;return`\n
\n ${bt.business.locale.white_label.powered_by}\n\n \n \n Hellotext\n \n \n \n
\n `}}function j(e,t){(null==t||t>e.length)&&(t=e.length);for(var s=0,i=Array(t);s2?s-2:0),n=2;n1?t-1:0),i=1;i1?s-1:0),n=1;n2&&void 0!==arguments[2]?arguments[2]:ie;if(V&&V(e,null),!se(t))return e;let i=t.length;for(;i--;){let n=t[i];if("string"==typeof n){const e=s(n);e!==n&&(q(t)||(t[i]=e),n=e)}e[n]=!0}return e}function we(e){for(let t=0;t/g),Re=H(/\${[\w\W]*/g),De=H(/^data-[\-\w.\u00B7-\uFFFF]+$/),je=H(/^aria-[\-\w]+$/),Be=H(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),$e=H(/^(?:\w+script|data):/i),Ve=H(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),qe=H(/^html$/i),Ue=H(/^[a-z][.\w]*(-[.\w]+)+$/i),ze=H(/<[/\w!]/g),We=H(/<[/\w]/g),He=H(/<\/no(script|embed|frames)/i),Ke=H(/\/>/i),Ge=["style","script","xmp","iframe","noembed","noframes","plaintext","noscript"],Je=W(ve({},Ge)),Ye=function(){const e={};return Z(Ge,t=>{e[t]=H(new RegExp("])","i"))}),W(e)}(),Ze=function(){return"undefined"==typeof window?null:window},Xe=function(e,t,s,i){return pe(e,t)&&se(e[t])?ve(i.base?Te(i.base):{},e[t],i.transform):s},Qe=function(e,t,s){const i=pe(e,t)?e[t]:void 0;return i&&"object"==typeof i?Te(i):s()};var et=function e(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Ze();const s=t=>e(t);if(s.version="3.4.14",s.removed=[],!t||!t.document||9!==t.document.nodeType||!t.Element)return s.isSupported=!1,s;let i=t.document;const n=i,r=n.currentScript;t.DocumentFragment;const a=t.HTMLTemplateElement,o=t.Node,c=t.Element,l=t.NodeFilter;void 0===t.NamedNodeMap&&(t.NamedNodeMap||t.MozNamedAttrMap),t.HTMLFormElement;const h=t.DOMParser,u=t.trustedTypes,d=c.prototype,p=Se(d,"cloneNode"),m=Se(d,"remove"),g=Se(d,"nextSibling"),f=Se(d,"childNodes"),b=Se(d,"parentNode"),y=Se(d,"shadowRoot"),v=Se(d,"attributes"),w=o&&o.prototype?Se(o.prototype,"nodeType"):null,T=o&&o.prototype?Se(o.prototype,"nodeName"):null,S=o&&o.prototype?Se(o.prototype,"ownerDocument"):null,C=function(e){return w?w(e):e.nodeType},O=function(e){return T?T(e):e.nodeName};if("function"==typeof a){const e=i.createElement("template");e.content&&e.content.ownerDocument&&(i=e.content.ownerDocument)}let A,E,x="",M=!1,k=0;const I=function(){if(k>0)throw fe('A configured TRUSTED_TYPES_POLICY callback (createHTML or createScriptURL) must not call DOMPurify.sanitize, as that causes infinite recursion. Do not pass a policy whose callbacks wrap DOMPurify as TRUSTED_TYPES_POLICY; see the "DOMPurify and Trusted Types" section of the README.')},L=function(e){I(),k++;try{return A.createHTML(e)}finally{k--}},_=i,N=_.implementation,P=_.createNodeIterator,F=_.createDocumentFragment,R=_.getElementsByTagName,D=n.importNode;let j={afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]};s.isSupported="function"==typeof $&&"function"==typeof b&&N&&void 0!==N.createHTMLDocument;const B=Pe,V=Fe,q=Re,U=De,z=je,G=$e,J=Ve,Y=Ue;let be=Be,ye=null;const we=ve({},[...Ce,...Oe,...Ae,...xe,...ke]);let Ge=null;const et=ve({},[...Ie,...Le,..._e,...Ne]);let tt=Object.seal(K(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),st=null,it=null;const nt=Object.seal(K(null,{tagCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeCheck:{writable:!0,configurable:!1,enumerable:!0,value:null}}));let rt=!0,at=!0,ot=!1,ct=!0,lt=!1,ht=!0,ut=!1,dt=!1,pt=null,mt=null,gt=!1,ft=!1,bt=!1,yt=!1,vt=!0,wt=!1;const Tt="user-content-";let St=!0,Ct=!1,Ot={},At=null;const Et=ve({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","selectedcontent","style","svg","template","thead","title","video","xmp"]);let xt=null;const Mt=ve({},["audio","video","img","source","image","track"]);let kt=null;const It=ve({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Lt="http://www.w3.org/1998/Math/MathML",_t="http://www.w3.org/2000/svg",Nt="http://www.w3.org/1999/xhtml";let Pt=Nt,Ft=!1,Rt=null;const Dt=ve({},[Lt,_t,Nt],ne),jt=W(["mi","mo","mn","ms","mtext"]);let Bt=ve({},jt);const $t=W(["annotation-xml"]);let Vt=ve({},$t);const qt=ve({},["title","style","font","a","script"]);let Ut=null;const zt=["application/xhtml+xml","text/html"];let Wt=null,Ht=null;const Kt=i.createElement("form"),Gt=function(e){return e instanceof RegExp||e instanceof Function},Jt=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(Ht&&Ht===e)return;e&&"object"==typeof e||(e={}),e=Te(e),Ut=-1===zt.indexOf(e.PARSER_MEDIA_TYPE)?"text/html":e.PARSER_MEDIA_TYPE,Wt="application/xhtml+xml"===Ut?ne:ie,ye=Xe(e,"ALLOWED_TAGS",we,{transform:Wt}),Ge=Xe(e,"ALLOWED_ATTR",et,{transform:Wt}),Rt=Xe(e,"ALLOWED_NAMESPACES",Dt,{transform:ne}),kt=Xe(e,"ADD_URI_SAFE_ATTR",It,{transform:Wt,base:It}),xt=Xe(e,"ADD_DATA_URI_TAGS",Mt,{transform:Wt,base:Mt}),At=Xe(e,"FORBID_CONTENTS",Et,{transform:Wt}),st=Xe(e,"FORBID_TAGS",Te({}),{transform:Wt}),it=Xe(e,"FORBID_ATTR",Te({}),{transform:Wt}),Ot=!!pe(e,"USE_PROFILES")&&(e.USE_PROFILES&&"object"==typeof e.USE_PROFILES?Te(e.USE_PROFILES):e.USE_PROFILES),rt=!1!==e.ALLOW_ARIA_ATTR,at=!1!==e.ALLOW_DATA_ATTR,ot=e.ALLOW_UNKNOWN_PROTOCOLS||!1,ct=!1!==e.ALLOW_SELF_CLOSE_IN_ATTR,lt=e.SAFE_FOR_TEMPLATES||!1,ht=!1!==e.SAFE_FOR_XML,ut=e.WHOLE_DOCUMENT||!1,ft=e.RETURN_DOM||!1,bt=e.RETURN_DOM_FRAGMENT||!1,yt=e.RETURN_TRUSTED_TYPE||!1,gt=e.FORCE_BODY||!1,vt=!1!==e.SANITIZE_DOM,wt=e.SANITIZE_NAMED_PROPS||!1,St=!1!==e.KEEP_CONTENT,Ct=e.IN_PLACE||!1,be=function(e){try{return ge(e,""),!0}catch(e){return!1}}(e.ALLOWED_URI_REGEXP)?e.ALLOWED_URI_REGEXP:Be,Pt="string"==typeof e.NAMESPACE?e.NAMESPACE:Nt,Bt=Qe(e,"MATHML_TEXT_INTEGRATION_POINTS",()=>ve({},jt)),Vt=Qe(e,"HTML_INTEGRATION_POINTS",()=>ve({},$t));const t=Qe(e,"CUSTOM_ELEMENT_HANDLING",()=>K(null));if(tt=K(null),pe(t,"tagNameCheck")&&Gt(t.tagNameCheck)&&(tt.tagNameCheck=t.tagNameCheck),pe(t,"attributeNameCheck")&&Gt(t.attributeNameCheck)&&(tt.attributeNameCheck=t.attributeNameCheck),pe(t,"allowCustomizedBuiltInElements")&&"boolean"==typeof t.allowCustomizedBuiltInElements&&(tt.allowCustomizedBuiltInElements=t.allowCustomizedBuiltInElements),H(tt),lt&&(at=!1),bt&&(ft=!0),Ot&&(ye=ve({},ke),Ge=K(null),!0===Ot.html&&(ve(ye,Ce),ve(Ge,Ie)),!0===Ot.svg&&(ve(ye,Oe),ve(Ge,Le),ve(Ge,Ne)),!0===Ot.svgFilters&&(ve(ye,Ae),ve(Ge,Le),ve(Ge,Ne)),!0===Ot.mathMl&&(ve(ye,xe),ve(Ge,_e),ve(Ge,Ne))),nt.tagCheck=null,nt.attributeCheck=null,pe(e,"ADD_TAGS")&&("function"==typeof e.ADD_TAGS?nt.tagCheck=e.ADD_TAGS:se(e.ADD_TAGS)&&(ye===we&&(ye=Te(ye)),ve(ye,e.ADD_TAGS,Wt))),pe(e,"ADD_ATTR")&&("function"==typeof e.ADD_ATTR?nt.attributeCheck=e.ADD_ATTR:se(e.ADD_ATTR)&&(Ge===et&&(Ge=Te(Ge)),ve(Ge,e.ADD_ATTR,Wt))),pe(e,"ADD_FORBID_CONTENTS")&&se(e.ADD_FORBID_CONTENTS)&&(At===Et&&(At=Te(At)),ve(At,e.ADD_FORBID_CONTENTS,Wt)),St&&(ye["#text"]=!0),ut&&ve(ye,["html","head","body"]),ye.table&&(ve(ye,["tbody"]),delete st.tbody),e.TRUSTED_TYPES_POLICY){if("function"!=typeof e.TRUSTED_TYPES_POLICY.createHTML)throw fe('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof e.TRUSTED_TYPES_POLICY.createScriptURL)throw fe('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');const t=A;A=e.TRUSTED_TYPES_POLICY;try{x=L("")}catch(e){throw A=t,e}}else null===e.TRUSTED_TYPES_POLICY?(A=void 0,x=""):(void 0===A&&(M||(E=function(e,t){if("object"!=typeof e||"function"!=typeof e.createPolicy)return null;let s=null;const i="data-tt-policy-suffix";t&&t.hasAttribute(i)&&(s=t.getAttribute(i));const n="dompurify"+(s?"#"+s:"");try{return e.createPolicy(n,{createHTML:e=>e,createScriptURL:e=>e})}catch(e){return console.warn("TrustedTypes policy "+n+" could not be created."),null}}(u,r),M=!0),A=E),A&&"string"==typeof x&&(x=L("")));W&&W(e),Ht=e},Yt=ve({},[...Oe,...Ae,...Ee]),Zt=ve({},[...xe,...Me]),Xt=function(e){ee(s.removed,{element:e});try{b(e).removeChild(e)}catch(t){if(m(e),!b(e))throw fe("a node selected for removal could not be detached from its tree and cannot be safely returned; refusing to sanitize in place")}},Qt=function(e,t,s){try{e.removeAttributeNode(t)}catch(t){try{e.removeAttribute(s)}catch(e){}}},es=function(e){is(e);const t=f(e);if(t){const e=[];Z(t,t=>{ee(e,t)}),Z(e,e=>{try{m(e)}catch(e){}})}const s=v(e);if(s)for(let t=s.length-1;t>=0;--t){const i=s[t],n=i&&i.name;"string"==typeof n&&Qt(e,i,n)}},ts=function(e,t,i){if(!i)try{i=t.getAttributeNode(e)}catch(e){i=null}ee(s.removed,{attribute:i||null,from:t});try{i?t.removeAttributeNode(i):t.removeAttribute(e)}catch(s){try{t.removeAttribute(e)}catch(e){}}if("is"===e)if(ft||bt)try{Xt(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},ss=function(e){const t=v(e);if(t)for(let s=t.length-1;s>=0;--s){const i=t[s],n=i&&i.name;"string"!=typeof n||Ge[Wt(n)]||Qt(e,i,n)}},is=function(e){const t=[e];for(;t.length>0;){const e=t.pop();1===C(e)&&ss(e);const s=f(e);if(s)for(let e=s.length-1;e>=0;--e)t.push(s[e])}},ns=function(e,t){return!!ht&&("patchsrc"===e||"for"===e&&"label"!==t&&"output"!==t)},rs=function(e){let t=null,s=null;if(gt)e=""+e;else{const t=re(e,/^[\r\n\t ]+/);s=t&&t[0]}"application/xhtml+xml"===Ut&&Pt===Nt&&(e=''+e+"");const n=A?L(e):e;if(Pt===Nt)try{t=(new h).parseFromString(n,Ut)}catch(e){}if(!t||!t.documentElement){t=N.createDocument(Pt,"template",null);try{t.documentElement.innerHTML=Ft?x:n}catch(e){}}const r=t.body||t.documentElement;return e&&s&&r.insertBefore(i.createTextNode(s),r.childNodes[0]||null),Pt===Nt?R.call(t,ut?"html":"body")[0]:ut?t.documentElement:r},as=function(e){const t=S?S(e):e.ownerDocument;return P.call(t||e,e,l.SHOW_ELEMENT|l.SHOW_COMMENT|l.SHOW_TEXT|l.SHOW_PROCESSING_INSTRUCTION|l.SHOW_CDATA_SECTION,null)},os=function(e){return e=ae(e,B," "),e=ae(e,V," "),ae(e,q," ")},cs=function(e){var t;e.normalize();const s=S?S(e):e.ownerDocument,i=P.call(s||e,e,l.SHOW_TEXT|l.SHOW_COMMENT|l.SHOW_CDATA_SECTION|l.SHOW_PROCESSING_INSTRUCTION,null);let n=i.nextNode();for(;n;)n.data=os(n.data),n=i.nextNode();const r=null===(t=e.querySelectorAll)||void 0===t?void 0:t.call(e,"template");r&&Z(r,e=>{hs(e.content)&&cs(e.content)})},ls=function(e){const t=T?T(e):null;return"string"==typeof t&&"form"===Wt(t)&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||e.attributes!==v(e)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore||"function"!=typeof e.hasChildNodes||e.nodeType!==w(e)||e.childNodes!==f(e))},hs=function(e){if(!w||"object"!=typeof e||null===e)return!1;try{return 11===w(e)}catch(e){return!1}},us=function(e){if(!w||"object"!=typeof e||null===e)return!1;try{return"number"==typeof w(e)}catch(e){return!1}};function ds(e,t,i){0!==e.length&&Z(e,e=>{e.call(s,t,i,Ht)})}const ps=function(e,t){if(e instanceof RegExp)return ge(e,t);if(e instanceof Function){for(var s=arguments.length,i=new Array(s>2?s-2:0),n=2;n=0;--n){const r=e===s?p(i[n],!0):i[n];t.insertBefore(r,g(e))}}return Xt(e),!0}(e,i,t);return!1===s&&ds(j.afterSanitizeElements,e,null),s}if(1===C(e)&&!function(e){let t=b(e);t&&t.tagName||(t={namespaceURI:Pt,tagName:"template"});const s=ie(e.tagName),i=ie(t.tagName);return!!Rt[e.namespaceURI]&&(e.namespaceURI===_t?function(e,t,s){return t.namespaceURI===Nt?"svg"===e:t.namespaceURI===Lt?"svg"===e&&("annotation-xml"===s||Bt[s]):Boolean(Yt[e])}(s,t,i):e.namespaceURI===Lt?function(e,t,s){return t.namespaceURI===Nt?"math"===e:t.namespaceURI===_t?"math"===e&&Vt[s]:Boolean(Zt[e])}(s,t,i):e.namespaceURI===Nt?function(e,t,s){return!(t.namespaceURI===_t&&!Vt[s])&&!(t.namespaceURI===Lt&&!Bt[s])&&!Zt[e]&&(qt[e]||!Yt[e])}(s,t,i):!("application/xhtml+xml"!==Ut||!Rt[e.namespaceURI]))}(e))return Xt(e),!0;if(("noscript"===i||"noembed"===i||"noframes"===i)&&ge(He,e.innerHTML))return Xt(e),!0;if(lt&&3===e.nodeType){const t=os(e.textContent);e.textContent!==t&&(ee(s.removed,{element:e.cloneNode()}),e.textContent=t)}return ds(j.afterSanitizeElements,e,null),!1},bs=function(e,t,s){if(it[t])return!1;if(ns(t,e))return!1;if(vt&&("id"===t||"name"===t)&&(s in i||s in Kt))return!1;const n=Ge[t]||nt.attributeCheck instanceof Function&&nt.attributeCheck(t,e);return!(!at||!ge(U,t))||!(!rt||!ge(z,t))||(n?!(!kt[t]&&!ge(be,ae(s,J,""))&&("src"!==t&&"xlink:href"!==t&&"href"!==t||"script"===e||0!==oe(s,"data:")||!xt[e])&&(!ot||ge(G,ae(s,J,"")))&&s):vs(e)&&ps(tt.tagNameCheck,e)&&ps(tt.attributeNameCheck,t,e)||"is"===t&&tt.allowCustomizedBuiltInElements&&ps(tt.tagNameCheck,s))},ys=ve({},["annotation-xml","color-profile","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","missing-glyph"]),vs=function(e){return!ys[ie(e)]&&ge(Y,e)},ws=function(e,t,s,i){if(A&&"object"==typeof u&&"function"==typeof u.getAttributeType&&!s)switch(u.getAttributeType(e,t)){case"TrustedHTML":return L(i);case"TrustedScriptURL":return function(e){I(),k++;try{return A.createScriptURL(e)}finally{k--}}(i)}return i},Ts=function(e,t,i,n){try{i?e.setAttributeNS(i,t,n):e.setAttribute(t,n),ls(e)?Xt(e):Q(s.removed)}catch(s){ts(t,e)}},Ss=function(e){ds(j.beforeSanitizeAttributes,e,null);const t=e.attributes;if(!t||ls(e))return;Ge=ms(j.uponSanitizeAttribute,Ge,et,mt);const s={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:Ge,forceKeepAttr:void 0};let i=t.length;const n=Wt(e.nodeName);for(;i--;){const r=t[i],a=r.name,o=r.namespaceURI,c=r.value,l=Wt(a),h=c;let u="value"===a?h:ce(h);s.attrName=l,s.attrValue=u,s.keepAttr=!0,s.forceKeepAttr=void 0,ds(j.uponSanitizeAttribute,e,s),u=s.attrValue,!wt||"id"!==l&&"name"!==l||0===oe(u,Tt)||(ts(a,e,r),u=Tt+u),ht&&ge(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i,u)||"attributename"===l&&re(u,"href")?ts(a,e,r):s.forceKeepAttr||(!s.keepAttr||!ct&&ge(Ke,u)?ts(a,e,r):(lt&&(u=os(u)),bs(n,l,u)?(u=ws(n,l,o,u),u!==h&&Ts(e,a,o,u)):ts(a,e,r)))}ds(j.afterSanitizeAttributes,e,null)},Cs=function(e){let t=null;const s=as(e);for(ds(j.beforeSanitizeShadowDOM,e,null);t=s.nextNode();)if(ds(j.uponSanitizeShadowNode,t,null),fs(t,e),Ss(t),hs(t.content)&&Cs(t.content),1===C(t)){const e=y(t);hs(e)&&(Os(e),Cs(e))}ds(j.afterSanitizeShadowDOM,e,null)},Os=function(e){const t=[{node:e,shadow:null}];for(;t.length>0;){const e=t.pop();if(e.shadow){Cs(e.shadow);continue}const s=e.node,i=1===C(s),n=f(s);if(n)for(let e=n.length-1;e>=0;--e)t.push({node:n[e],shadow:null});if(i){const e=T?T(s):null;if("string"==typeof e&&"template"===Wt(e)){const e=s.content;hs(e)&&t.push({node:e,shadow:null})}}if(i){const e=y(s);hs(e)&&t.push({node:null,shadow:e},{node:e,shadow:null})}}};return s.sanitize=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=null,r=null,a=null,o=null;if(Ft=!e,Ft&&(e="\x3c!--\x3e"),"string"!=typeof e&&!us(e)&&"string"!=typeof(e=function(e){switch(typeof e){case"string":return e;case"number":return le(e);case"boolean":return he(e);case"bigint":return ue?ue(e):"0";case"symbol":return de?de(e):"Symbol()";case"undefined":default:return me(e);case"function":case"object":{if(null===e)return me(e);const t=e,s=Se(t,"toString");if("function"==typeof s){const e=s(t);return"string"==typeof e?e:me(e)}return me(e)}}}(e)))throw fe("dirty is not a string, aborting");if(!s.isSupported)return e;dt?(ye=pt,Ge=mt):Jt(t),(j.uponSanitizeElement.length>0||j.uponSanitizeAttribute.length>0)&&(ye=Te(ye)),j.uponSanitizeAttribute.length>0&&(Ge=Te(Ge)),s.removed=[];const c=Ct&&"string"!=typeof e&&us(e);if(c){!function(e){if(!ht)return;const t=[e];for(;t.length>0;){const e=t.pop(),s=C(e);if(7===s||8===s&&ge(We,e.data)){try{m(e)}catch(e){}continue}if(1===s){const t=e,s=Wt(O(e));try{t.hasAttribute&&t.hasAttribute("patchsrc")&&t.removeAttribute("patchsrc"),t.hasAttribute&&t.hasAttribute("for")&&ns("for",s)&&t.removeAttribute("for")}catch(e){}}const i=f(e);if(i)for(let e=i.length-1;e>=0;--e)t.push(i[e])}}(e);const t=O(e);if("string"==typeof t){const s=Wt(t);if(!ye[s]||st[s])throw es(e),fe("root node is forbidden and cannot be sanitized in-place")}if(ls(e))throw es(e),fe("root node is clobbered and cannot be sanitized in-place");try{Os(e)}catch(t){throw es(e),t}}else if(us(e))i=rs("\x3c!----\x3e"),r=i.ownerDocument.importNode(e,!0),1===r.nodeType&&"BODY"===r.nodeName||"HTML"===r.nodeName?i=r:i.appendChild(r),Os(r);else{if(!ft&&!lt&&!ut&&-1===e.indexOf("<"))return A&&yt?L(e):e;if(i=rs(e),!i)return ft?null:yt?x:""}i&>&&Xt(i.firstChild);const l=c?e:i;try{const e=as(l);for(;a=e.nextNode();)fs(a,l),Ss(a),hs(a.content)&&Cs(a.content)}catch(t){throw c&&(es(e),Z(s.removed,e=>{e.element&&is(e.element)})),t}if(c)return Z(s.removed,e=>{e.element&&is(e.element)}),lt&&cs(e),e;if(ft){if(lt&&cs(i),bt)for(o=F.call(i.ownerDocument);i.firstChild;)o.appendChild(i.firstChild);else o=i;return(Ge.shadowroot||Ge.shadowrootmode)&&(o=D.call(n,o,!0)),o}let h=ut?i.outerHTML:i.innerHTML;return ut&&ye["!doctype"]&&i.ownerDocument&&i.ownerDocument.doctype&&i.ownerDocument.doctype.name&&ge(qe,i.ownerDocument.doctype.name)&&(h="\n"+h),lt&&(h=os(h)),A&&yt?L(h):h},s.setConfig=function(){Jt(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),dt=!0,pt=ye,mt=Ge},s.clearConfig=function(){Ht=null,dt=!1,pt=null,mt=null,A=E,x=""},s.isValidAttribute=function(e,t,s){Ht||Jt({});const i=Wt(e),n=Wt(t);return bs(i,n,s)},s.addHook=function(e,t){"function"==typeof t&&pe(j,e)&&ee(j[e],t)},s.removeHook=function(e,t){if(pe(j,e)){if(void 0!==t){const s=X(j[e],t);return-1===s?void 0:te(j[e],s,1)[0]}return Q(j[e])}},s.removeHooks=function(e){pe(j,e)&&(j[e]=[])},s.removeAllHooks=function(){j={afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}},s}();const tt={ADD_ATTR:["target"],ALLOW_DATA_ATTR:!1,RETURN_DOM_FRAGMENT:!0,USE_PROFILES:{html:!0}},st={ADD_ATTR:["target"],ADD_TAGS:["hellotext-icon"],RETURN_DOM_FRAGMENT:!0,USE_PROFILES:{html:!0,svg:!0}};function it(e,t){const s=et.sanitize(e,t);return s.querySelectorAll('a[target="_blank"]').forEach(e=>{const t=new Set(e.rel.split(/\s+/).filter(Boolean));t.add("noopener"),t.add("noreferrer"),e.rel=Array.from(t).join(" ")}),s}function nt(e,t){e.replaceChildren(function(e){return it(e,tt)}(t))}class rt{constructor(e,t=null){this.data=e,this.element=t||document.querySelector(`[data-hello-form="${this.id}"]`)||document.createElement("form")}async mount({ifCompleted:e=!0}={}){if(e&&this.hasBeenCompleted)return this.element?.remove(),bt.eventEmitter.dispatch("form:completed",{id:this.id,...JSON.parse(localStorage.getItem(`hello-form-${this.id}`))});const t=this.data.steps[0];this.buildHeader(t.header),this.buildInputs(t.inputs),this.buildButton(t.button),this.buildFooter(t.footer),this.elementAttributes.forEach(e=>{this.element.setAttribute(e.name,e.value)}),document.contains(this.element)||document.body.appendChild(this.element),bt.business.features.white_label||this.element.prepend(D.build())}buildHeader(e){const t=this.#c("[data-form-header]","header");nt(t,e.content),this.element.querySelector("[data-form-header]")?this.element.querySelector("[data-form-header]").replaceWith(t):this.element.prepend(t)}buildInputs(e){const t=this.#c("[data-form-inputs]","main");e.map(e=>R.build(e)).forEach(e=>t.appendChild(e)),this.element.querySelector("[data-form-inputs]")?this.element.querySelector("[data-form-inputs]").replaceWith(t):this.element.querySelector("[data-form-header]").insertAdjacentHTML("afterend",t.outerHTML)}buildButton(e){const t=this.#c("[data-form-button]","button");t.innerText=e.text,t.setAttribute("data-action","click->hellotext--form#submit"),t.setAttribute("data-hellotext--form-target","button"),this.element.querySelector("[data-form-button]")?this.element.querySelector("[data-form-button]").replaceWith(t):this.element.querySelector("[data-form-inputs]").insertAdjacentHTML("afterend",t.outerHTML)}buildFooter(e){const t=this.#c("[data-form-footer]","footer");nt(t,e.content),this.element.querySelector("[data-form-footer]")?this.element.querySelector("[data-form-footer]").replaceWith(t):this.element.appendChild(t)}markAsCompleted(e){const t={state:"completed",id:this.id,data:e,completedAt:(new Date).getTime()};localStorage.setItem(`hello-form-${this.id}`,JSON.stringify(t)),bt.eventEmitter.dispatch("form:completed",t)}get hasBeenCompleted(){return null!==localStorage.getItem(`hello-form-${this.id}`)}get id(){return this.data.id}get localeAuthKey(){const e=this.data.steps[0];return e.inputs.some(e=>"email"===e.kind)&&e.inputs.some(e=>"phone"===e.kind)?"phone_and_email":e.inputs.some(e=>"email"===e.kind)?"email":e.inputs.some(e=>"phone"===e.kind)?"phone":"none"}get elementAttributes(){return[{name:"data-controller",value:"hellotext--form"},{name:"data-hello-form",value:this.id},{name:"data-hellotext--form-data-value",value:JSON.stringify(this.data)}]}#c(e,t){const s=this.element.querySelector(e);if(s)return s.cloneNode(!0);const i=document.createElement(t);return i.setAttribute(e.replace("[","").replace("]",""),""),i}}class at extends Error{constructor(){super("You need to initialize before tracking events. Call Hellotext.initialize and pass your public business id"),this.name="NotInitializedError"}}class ot{constructor(){this.forms=[],this.includes=this.includes.bind(this),this.excludes=this.excludes.bind(this),this.add=this.add.bind(this),"undefined"!=typeof MutationObserver&&(this.mutationObserver=new MutationObserver(this.formMutationObserver.bind(this)),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0}))}collectExistingFormsOnPage(){Array.from(document.querySelectorAll("[data-hello-form]")).length>0&&this.collect()}formMutationObserver(e){e.find(e=>"childList"===e.type&&e.addedNodes.length>0)&&Array.from(document.querySelectorAll("[data-hello-form]")).length>0&&this.collect()}async collect(){if(bt.notInitialized)throw new at;if(this.fetching)return;if("undefined"==typeof document||!("querySelectorAll"in document))return console.warn("Document is not defined, collection is not possible. Please make sure to initialize the library after the document is loaded.");const e=this.#l;if(0===e.length)return;const t=e.map(e=>w.get(e).then(e=>e.json()));this.fetching=!0,await Promise.all(t).then(e=>e.forEach(this.add)).then(()=>bt.eventEmitter.dispatch("forms:collected",this)).then(()=>this.fetching=!1),g.forms.autoMount&&this.forms.forEach(e=>e.mount())}forEach(e){this.forms.forEach(e)}map(e){return this.forms.map(e)}add(e){this.includes(e.id)||(bt.business.data||(bt.business.setData(e.business),bt.business.setLocale(o.toString())),bt.business.enabledWhitelist||console.warn("No whitelist has been configured. It is advised to whitelist the domain to avoid bots from submitting forms."),this.forms.push(new rt(e)))}getById(e){return this.forms.find(t=>t.id===e)}getByIndex(e){return this.forms[e]}includes(e){return this.forms.some(t=>t.id===e)}excludes(e){return!this.includes(e)}get length(){return this.forms.length}get#l(){return Array.from(document.querySelectorAll("[data-hello-form]")).map(e=>e.dataset.helloForm).filter(this.excludes)}}class ct{constructor(e){this.publicKey=e.public_key,this.serviceWorkerUrl=g.push.serviceWorkerUrl,this.channelId=g.push.channelId,this.ready=null,this.registrationPromise=null,this.subscribePromise=null,this.unsubscribePromise=null,this.syncPromise=null,this.subscription=null,this.retryTimeout=null,this.retryAttempts=0,this.disposed=!1}initialize(){return this.ready=this.restoreSubscription(),this.ready}async restoreSubscription(){const e=await this.getRegistration(),t=await e.pushManager.getSubscription();!this.disposed&&!this.unsubscribePromise&&t&&this.owns(t)&&(this.subscription=t,await this.sync())}subscribe(){if(this.disposed)return Promise.resolve();if(this.unsubscribePromise)return Promise.reject(new Error("Push unsubscribe is in progress"));if(this.subscribePromise)return this.subscribePromise;const e="default"===Notification.permission?Notification.requestPermission():Promise.resolve(Notification.permission);return this.subscribePromise=this.createSubscription(e).finally(()=>{this.subscribePromise=null}),this.subscribePromise}async createSubscription(e){if("granted"!==await e)throw new Error("Push permission was not granted");const t=await this.getRegistration();if(this.disposed)return;let s=await t.pushManager.getSubscription();if(!this.disposed){if(s&&!this.owns(s))throw new Error("The existing Push subscription belongs to a different application");if(s||=await t.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:this.applicationServerKey}),!this.disposed)return this.subscription=s,this.sync()}}unsubscribe(){return this.disposed?Promise.resolve():(this.unsubscribePromise||(this.clearRetryTimeout(),this.unsubscribePromise=this.removeSubscription().finally(()=>{this.unsubscribePromise=null})),this.unsubscribePromise)}async removeSubscription(){await(this.ready?.catch(()=>{})),await(this.subscribePromise?.catch(()=>{})),await(this.syncPromise?.catch(()=>{}));const e=await this.getRegistration(),t=await e.pushManager.getSubscription()||this.subscription;if(this.disposed)return;if(!t)return null;if(!this.owns(t))throw new Error("The existing Push subscription belongs to a different application");this.subscription=t;const s=await M.pushIdentities.destroy({subscription:t.toJSON()});return s.failed?s:this.disposed?void 0:(await t.unsubscribe(),this.subscription=null,this.clearRetryTimeout(),s)}sync(){return this.disposed?Promise.resolve():(this.syncPromise||(this.clearRetryTimeout(),this.syncPromise=this.registerIdentity().finally(()=>{this.syncPromise=null})),this.syncPromise)}async registerIdentity(){try{const e=await M.pushIdentities.create({subscription:this.subscription.toJSON(),...this.channelId?{channel_id:this.channelId}:{}});return e.succeeded?this.retryAttempts=0:this.scheduleRetry(),e}catch(e){throw this.scheduleRetry(),e}}scheduleRetry(){this.disposed||this.unsubscribePromise||this.retryTimeout||this.retryAttempts>=3||(this.retryTimeout=setTimeout(()=>{this.retryTimeout=null,this.sync().catch(()=>{})},1e3*2**this.retryAttempts),this.retryAttempts+=1)}clearRetryTimeout(){clearTimeout(this.retryTimeout),this.retryTimeout=null}dispose(){this.disposed=!0,this.clearRetryTimeout()}get subscribed(){return!!this.subscription}get applicationServerKey(){const e=this.publicKey.replace(/-/g,"+").replace(/_/g,"/");return Uint8Array.from(atob(e.padEnd(4*Math.ceil(e.length/4),"=")),e=>e.charCodeAt(0))}owns(e){const t=e.options?.applicationServerKey;if(!t)return!1;const s=new Uint8Array(t),i=this.applicationServerKey;return s.length===i.length&&s.every((e,t)=>e===i[t])}getRegistration(){return this.registrationPromise||(this.registrationPromise=this.loadRegistration().catch(e=>{throw this.registrationPromise=null,e})),this.registrationPromise}async loadRegistration(){if(this.serviceWorkerUrl){const e=await navigator.serviceWorker.register(this.serviceWorkerUrl);!e.active||e.installing||e.waiting||await e.update();const t=e.installing||e.waiting||e.active;return"activated"===t?.state?e:new Promise((s,i)=>{const n=setTimeout(()=>r(new Error("Push service worker did not become active")),1e4),r=r=>{clearTimeout(n),t?.removeEventListener("statechange",a),r?i(r):s(e)},a=()=>{"activated"===t?.state&&r(),"redundant"===t?.state&&r(new Error("Push service worker installation failed"))};t?.addEventListener("statechange",a),a()})}return new Promise((e,t)=>{const s=setTimeout(()=>t(new Error("Push service worker is not available")),1e4);navigator.serviceWorker.ready.then(t=>{clearTimeout(s),e(t)},e=>{clearTimeout(s),t(e)})})}static get supported(){return"undefined"!=typeof window&&!0===window.isSecureContext&&"undefined"!=typeof navigator&&"serviceWorker"in navigator&&"undefined"!=typeof PushManager&&"undefined"!=typeof Notification}}class lt{constructor(e,t,s){this.business=t,this.push=s,this.disposed=!1,this.showRequest=0,this.controller=null,this.element=(new DOMParser).parseFromString(e.html,"text/html").querySelector('[data-controller~="hellotext--alert"]'),this.connected=new Promise(e=>{this.resolveConnected=e}),this.onConnect=this.onConnect.bind(this),this.ready=this.render()}onConnect(e){this.controller=e.detail.controller,this.controller.alert=this,this.resolveConnected(!0)}async render(){return!!this.element&&(this.element.addEventListener("hellotext--alert:connected",this.onConnect),!(!await this.business.stylesheetLoaded||this.disposed)&&(document.body.appendChild(this.element),this.connected))}async show(e,t={}){const s=++this.showRequest;return!(!await this.ready||this.disposed||s!==this.showRequest)&&this.controller.show(e,t)}hide(){this.showRequest+=1,this.controller?.close()}dispose(){this.disposed=!0,this.hide(),this.resolveConnected(!1),this.element?.removeEventListener("hellotext--alert:connected",this.onConnect),this.element?.remove()}}class ht{static async load(e){const t=new ht({id:e,html:await M.webchats.get(e)});return t.rendered=t.render(),t}constructor(e){this.data=e,this.mounted=!1,this.rendered=Promise.resolve(!1)}async render(){return this.applyBehaviourOverride(),await this.stylesheetLoaded?(this.containerToAppendTo.appendChild(this.data.html),this.markCoexistingWidgets(),this.mounted=!0,!0):(console.warn("Hellotext webchat was not mounted because its stylesheet failed to load."),!1)}applyBehaviourOverride(){g.webchat.hasBehaviourOverride&&g.webchat.behaviour&&this.data.html.setAttribute("data-hellotext--webchat-behaviour-value",JSON.stringify(this.serializedBehaviour))}get serializedBehaviour(){const e=g.webchat.behaviour;return{trigger:this.serializeTrigger(e.trigger),delay_seconds:e.delaySeconds,first_visit_only:e.firstVisitOnly,once_per_session:e.oncePerSession}}serializeTrigger(e){return"onLoad"===e?"on_load":"onClick"===e?"on_click":e}get containerToAppendTo(){return document.querySelector(g.webchat.container)}get stylesheetLoaded(){return L.waitForStylesheet(L.latestStylesheet)}markCoexistingWidgets(){const e=this.data.html,t=document.querySelector(".hellotext--whatsapp-widget");e&&t&&(e.classList.add("hellotext--with-whatsapp-widget"),t.classList.add("hellotext--with-webchat"))}}class ut{static async load(e){const t=new ut({id:e,html:await M.whatsappWidgets.get(e)});return t.rendered=t.render(),t}constructor(e){this.data=e,this.mounted=!1,this.rendered=Promise.resolve(!1)}async render(){if(!this.data.html)return!1;const e=this.containerToAppendTo;return e?await this.stylesheetLoaded?(e.appendChild(this.data.html),this.markCoexistingWidgets(),this.mounted=!0,!0):(console.warn("Hellotext WhatsApp widget was not mounted because its stylesheet failed to load."),!1):(console.warn(`Hellotext WhatsApp widget was not mounted because the container ${g.whatsapp.container} was not found.`),!1)}get containerToAppendTo(){try{return document.querySelector(g.whatsapp.container)}catch(e){return null}}get stylesheetLoaded(){return L.waitForStylesheet(L.latestStylesheet)}markCoexistingWidgets(){const e=document.querySelector(".hellotext--webchat:not(.hellotext--whatsapp-widget)"),t=this.data.html;e&&t&&(e.classList.add("hellotext--with-whatsapp-widget"),t.classList.add("hellotext--with-webchat"))}}class dt{static get id(){return _.get("hello_user_id")}static get source(){return _.get("hello_user_source")}static get fingerprint(){return _.get("hello_user_identification_hash")}static remember(e,t,s){t&&_.set("hello_user_source",t),s&&_.set("hello_user_identification_hash",s),_.set("hello_user_id",e)}static forget(){_.delete("hello_user_id"),_.delete("hello_user_source"),_.delete("hello_user_identification_hash")}static get identificationData(){return this.id?{id:this.id,source:this.source}:{}}}function pt(e){if(null!=e){if("string"==typeof e){const t=e.trim();return""===t?void 0:t}if(Array.isArray(e))return e.map(e=>pt(e)).filter(e=>void 0!==e);if(e instanceof Date)return e.toISOString();if("object"==typeof e){const t=Object.keys(e).sort((e,t)=>e.localeCompare(t)).reduce((t,s)=>{const i=pt(e[s]);return void 0!==i&&(t[s]=i),t},{});return Object.keys(t).length>0?t:void 0}return"number"==typeof e||"boolean"==typeof e?e:void 0}}function mt(e,t,s={}){const i=pt({session:e,user_id:t,...s})||{};return JSON.stringify(i)}class gt{static matches(e,t){return!!e&&e===t}static async generate(e,t,s={}){return await async function(e){if(!globalThis.crypto?.subtle||"undefined"==typeof TextEncoder)return function(e){let t=5381;for(let s=0;s>>0).toString(16)}`}(e);const t=await globalThis.crypto.subtle.digest("SHA-256",(new TextEncoder).encode(e));return`v1:${Array.from(new Uint8Array(t)).map(e=>e.toString(16).padStart(2,"0")).join("")}`}(mt(e,t,s))}}class ft{static eventEmitter=new r;static forms;static business;static webchat;static whatsapp;static push;static alert;static async initialize(e,t={}){this.alert?.dispose(),this.alert=null,this.push?.dispose(),this.push=null;const s=new L(e);this.business=s,this.page=new P,g.assign({push:{},...t}),F.initialize(this.page),this.forms=new ot,this.query=new b;const i=await s.hydrate();if(this.business!==s)return;!1!==t.push&&i?.push?.public_key&&ct.supported&&(this.push=new ct(i.push),this.push.initialize().catch(e=>{console.warn("Hellotext Push initialization failed:",e)}),i.alert?.html&&(this.alert=new lt(i.alert,s,this.push)));const n=!1!==t.webchat&&this.mergeWebchatConfig(i&&i.webchat||{},t.webchat||{}),r=!1!==t.whatsappWidget&&this.mergeWhatsAppConfig(i&&i.whatsapp||{},t.whatsappWidget||{}),a=t.webchat&&!1!==t.webchat&&Object.prototype.hasOwnProperty.call(t.webchat,"behaviour");g.webchat.behaviourOverride=a,n&&n.id&&(g.webchat.assign(n),this.webchat=await ht.load(n.id)),r&&r.id&&(g.whatsapp.assign(r),this.whatsapp=await ut.load(r.id)),"undefined"!=typeof MutationObserver&&this.forms.collectExistingFormsOnPage()}static mergeWebchatConfig(e,t){return this.deepMergePlainObjects(e,t)}static mergeWhatsAppConfig(e,t){return this.deepMergePlainObjects(e,t)}static deepMergePlainObjects(e,t){const s={...e};return Object.entries(t).forEach(([e,t])=>{this.isPlainObject(t)&&this.isPlainObject(s[e])?s[e]=this.deepMergePlainObjects(s[e],t):s[e]=t}),s}static isPlainObject(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}static async track(e,t={}){if(this.notInitialized)throw new at;const s={...t&&t.headers||{},...this.headers},i={...dt.identificationData,...t.user_parameters||{}},n=t&&t.url?new P(t.url):this.page,r={session:this.session,user_parameters:i,action:e,...t,...n.trackingData};return delete r.headers,await M.events.create({headers:s,body:r,keepalive:x(r)})}static async identify(e,t={}){const s=await gt.generate(this.session,e,t);if(gt.matches(dt.fingerprint,s))return new y(!0,{json:async()=>({already_identified:!0})});const i=await M.identifications.create({user_id:e,...t});return i.succeeded&&dt.remember(e,t.source,s),i}static forget(){dt.forget()}static on(e,t){this.eventEmitter.addSubscriber(e,t)}static removeEventListener(e,t){this.eventEmitter.removeSubscriber(e,t)}static get session(){return F.session}static get isInitialized(){return void 0!==F.session}static get notInitialized(){return!this.business||void 0===this.business.id}static get headers(){if(this.notInitialized)throw new at;return{Authorization:`Bearer ${this.business.id}`,Accept:"application/json","Content-Type":"application/json"}}}const bt=ft,yt=new Map,vt=class extends i.xI{static values={sections:Array};static targets=["title","description","primaryAction","secondaryAction"];initialize(){this.showRequest=0,this.submitting=!1,this.onStorage=this.onStorage.bind(this)}connect(){this.dispatch("connected",{detail:{controller:this}}),window.addEventListener("storage",this.onStorage)}disconnect(){this.close(),window.removeEventListener("storage",this.onStorage)}onStorage(e){e.key===this.storageKey&&this.dismissal.dismissedUntil>Date.now()&&this.close()}async show(e,{force:t=!1,title:s,description:i,primaryAction:n,secondaryAction:r}={}){const a=++this.showRequest,o=this.sectionsValue.find(t=>t.kind===e);return o?(await(this.alert.push.ready?.catch(()=>{})),!(a!==this.showRequest||this.alert.disposed||!this.element.isConnected||(this.unavailable||!t&&this.dismissal.dismissedUntil>Date.now()?(this.close(),1):(this.titleTarget.textContent=s??o.title,this.descriptionTarget.textContent=i??o.description,this.primaryActionTarget.textContent=n??o.primary_action,this.secondaryActionTarget.textContent=r??o.secondary_action,this.kind=e,this.page=bt.page.trackingData.page,this.element.hidden=!1,this.record("shown"),bt.eventEmitter.dispatch("alert:shown",{kind:e}),0)))):(this.close(),!1)}hide(){if(this.element.hidden||this.submitting)return;const e=this.dismissal.dismissals+1,t={dismissals:e,dismissedUntil:Date.now()+864e5*(1===e?7:30)};yt.set(this.storageKey,t);try{localStorage.setItem(this.storageKey,JSON.stringify(t))}catch(e){}this.close(),this.record("dismissed"),bt.eventEmitter.dispatch("alert:dismissed",{kind:this.kind})}close(){this.showRequest+=1,this.element.hidden=!0}async subscribe(){if(!this.submitting&&!this.element.hidden){if(this.unavailable)return this.close();this.submitting=!0,this.primaryActionTarget.disabled=!0,this.secondaryActionTarget.disabled=!0,this.element.setAttribute("aria-busy","true");try{this.record("accepted"),bt.eventEmitter.dispatch("alert:accepted",{kind:this.kind});const e=await this.alert.push.subscribe();return this.unavailable&&this.close(),e?.failed&&this.dispatch("error",{detail:{response:e}}),e}catch(e){this.unavailable&&this.close(),this.dispatch("error",{detail:{error:e}})}finally{this.submitting=!1,this.primaryActionTarget.disabled=!1,this.secondaryActionTarget.disabled=!1,this.element.removeAttribute("aria-busy")}}}async record(e){try{const t=await M.pushAlerts.create({section:this.kind,kind:e,page:this.page});t.failed&&console.warn("Hellotext Smart Alert submission failed:",t)}catch(e){console.warn("Hellotext Smart Alert submission failed:",e)}}get unavailable(){return this.alert.push.disposed||this.alert.push.subscribed||"undefined"==typeof Notification||"denied"===Notification.permission}get storageKey(){return`hellotext:alert:${this.alert.business.id}`}get dismissal(){try{const e=JSON.parse(localStorage.getItem(this.storageKey));Number.isSafeInteger(e?.dismissals)&&e.dismissals>0&&Number.isFinite(e.dismissedUntil)&&e.dismissedUntil>=0&&yt.set(this.storageKey,e)}catch(e){}return yt.get(this.storageKey)||{dismissals:0,dismissedUntil:0}}},wt=class extends i.xI{static values={data:Object,step:{type:Number,default:1}};static targets=["inputContainer","input","button","otpContainer"];initialize(){this.form=new rt(this.dataValue,this.element)}connect(){super.connect(),this.element.addEventListener("submit",this.submit.bind(this)),"INPUT"!==document.activeElement.tagName&&this.inputTargets[0].focus()}async submit(e){if(e.preventDefault(),this.invalid)return this.showErrorMessages();this.clearErrorMessages(),this.formData=Object.fromEntries(new FormData(this.element)),this.buttonTarget.disabled=!0;const t=await w.submit(this.form.id,this.formData);this.buttonTarget.disabled=!1;const s=await t.json();if(t.failed)return s.errors.forEach(e=>{const{type:t,parameter:s}=e,i=this.inputTargets.find(e=>e.name===s);i.setCustomValidity(bt.business.locale.errors[t]),i.reportValidity(),i.addEventListener("input",()=>{i.setCustomValidity(""),i.reportValidity()})}),this.showErrorMessages();this.buttonTarget.style.display="none",this.element.querySelectorAll("input").forEach(e=>e.disabled=!0),this.completed()}completed(){if(this.form.markAsCompleted(this.formData),!g.forms.shouldShowSuccessMessage)return this.element.remove();"string"==typeof g.forms.successMessage?this.element.innerHTML=g.forms.successMessage:this.element.innerHTML=bt.business.locale.forms[this.form.localeAuthKey]}showErrorMessages(){this.inputTargets.forEach(e=>{const t=e.closest("article").querySelector("[data-error-container]");e.validity.valid?t.innerText="":t.innerText=e.validationMessage})}clearErrorMessages(){this.inputTargets.forEach(e=>{e.setCustomValidity(""),e.closest("article").querySelector("[data-error-container]").innerText=""})}inputTargetConnected(e){e.getAttribute("data-default-value")&&(e.value=e.getAttribute("data-default-value"))}get requiredInputs(){return this.inputTargets.filter(e=>e.required)}get invalid(){return!this.element.checkValidity()}},Tt=class extends i.xI{static values={fadeDistance:{type:Number,default:64},id:String,kind:String,pageStartOffset:{type:Number,default:0},utm:Object};static targets=["carouselContainer","leftFade","rightFade","carouselCard"];connect(){this.updateFades(),this.observeContainerSize()}disconnect(){this.resizeObserver?.disconnect()}setId({detail:e}){this.idValue=e,this.element.id=e}onScroll(){this.updateFades()}quickReply({currentTarget:e}){const t=e.closest('[data-hellotext--message-target="carouselCard"]'),s=e.closest('[data-controller~="hellotext--message"]'),i=e.dataset.text||e.textContent.trim();this.dispatch("quickReply",{detail:{id:this.idValue,product:t?.dataset.id,buttonId:e.dataset.id,body:i,cardElement:t||s||e}})}addToCart({currentTarget:e}){const t=e.closest('[data-hellotext--message-target="carouselCard"]'),{id:s,reference:i,source:n}=t.dataset,r={product:s,quantity:1};this.hasUtmValue&&bt.page.utm.save(this.utmValue),bt.eventEmitter.dispatch("cart.added",{object_parameters:{items:[{...r,...i&&{reference:i},...n&&{source:n}}]},source:{kind:this.kindValue,message_id:this.idValue,button_id:e.dataset.id}})}moveToLeft(){if(!this.hasCarouselContainerTarget)return;const e=this.getPreviousPageScrollLeft(),t=this.carouselContainerTarget.scrollLeft-e;t<1||this.carouselContainerTarget.scrollBy({left:-t,behavior:"smooth"})}moveToRight(){if(!this.hasCarouselContainerTarget)return;const e=this.getNextPageScrollLeft()-this.carouselContainerTarget.scrollLeft;e<1||this.carouselContainerTarget.scrollBy({left:e,behavior:"smooth"})}getScrollAmount(){return this.getCardScrollAmount()}getCardScrollAmount(){const e=this.carouselContainerTarget.querySelector(".message__carousel_card");return e?e.offsetWidth+this.getGap():280}getPageScrollAmount(){const e=this.carouselContainerTarget.clientWidth-this.getGap();return e>0?e:this.getCardScrollAmount()}getNextPageScrollLeft(){const e=this.getCurrentScrollLeft(),t=e+this.carouselContainerTarget.clientWidth,s=this.getCardMetrics().find(e=>e.end>t+1),i=s?this.getPageAlignedScrollLeft(s.start):e+this.getPageScrollAmount(),n=e+this.getPageScrollAmount();return this.clampScrollLeft(i>e+1?i:n)}getPreviousPageScrollLeft(){const e=this.getCurrentScrollLeft();if(e<=1)return 0;const t=Math.max(e-this.getPageScrollAmount(),0);if(t<=1)return 0;const s=this.getCardMetrics(),i=s.find(s=>s.start>=t-1&&s.startt.start{const t=this.getCardScrollLeft(e);return{start:t,end:t+e.offsetWidth}})}getCardScrollLeft(e){const t=e.getBoundingClientRect(),s=this.carouselContainerTarget.getBoundingClientRect();return t.left||t.width||s.left||s.width?t.left-s.left+this.carouselContainerTarget.scrollLeft:e.offsetLeft||0}getCurrentScrollLeft(){return this.clampScrollLeft(this.carouselContainerTarget.scrollLeft)}clampScrollLeft(e){const t=Math.max(this.carouselContainerTarget.scrollWidth-this.carouselContainerTarget.clientWidth,0);return Math.min(Math.max(e,0),t)}getGap(){const e=window.getComputedStyle(this.carouselContainerTarget),t=Number.parseFloat(e.columnGap||e.gap);return Number.isFinite(t)?t:16}getFadeDistance(){return Number.isFinite(this.fadeDistanceValue)?this.fadeDistanceValue:64}getPageStartOffset(){return Number.isFinite(this.pageStartOffsetValue)?this.pageStartOffsetValue:0}observeContainerSize(){this.hasCarouselContainerTarget&&window.ResizeObserver&&(this.resizeObserver=new ResizeObserver(()=>this.updateFades()),this.resizeObserver.observe(this.carouselContainerTarget))}updateFades(){if(!this.hasCarouselContainerTarget)return;const e=Math.max(this.carouselContainerTarget.scrollWidth-this.carouselContainerTarget.clientWidth,0);if(e<=1)return this.hideFade(this.leftFadeTarget),void this.hideFade(this.rightFadeTarget);const t=Math.min(Math.max(this.carouselContainerTarget.scrollLeft,0),e),s=this.getFadeDistance();this.setFadeOpacity(this.leftFadeTarget,t/s),this.setFadeOpacity(this.rightFadeTarget,(e-t)/s)}setFadeOpacity(e,t){const s=Math.min(Math.max(t,0),1);s<=.05?this.hideFade(e):(e.classList.remove("hidden"),e.removeAttribute("disabled"),e.removeAttribute("tabindex"),e.setAttribute("aria-hidden","false"),e.style.opacity=s.toFixed(3),e.style.pointerEvents="auto")}hideFade(e){e.style.opacity="0",e.style.pointerEvents="none",e.setAttribute("aria-hidden","true"),e.setAttribute("tabindex","-1"),"disabled"in e&&(e.disabled=!0),e.classList.add("hidden")}},St=["start","end"],Ct=["top","right","bottom","left"].reduce((e,t)=>e.concat(t,t+"-"+St[0],t+"-"+St[1]),[]),Ot=Math.min,At=Math.max,Et=Math.round,xt=Math.floor,Mt=e=>({x:e,y:e}),kt={left:"right",right:"left",bottom:"top",top:"bottom"},It={start:"end",end:"start"};function Lt(e,t,s){return At(e,Ot(t,s))}function _t(e,t){return"function"==typeof e?e(t):e}function Nt(e){return e.split("-")[0]}function Pt(e){return e.split("-")[1]}function Ft(e){return"x"===e?"y":"x"}function Rt(e){return"y"===e?"height":"width"}const Dt=new Set(["top","bottom"]);function jt(e){return Dt.has(Nt(e))?"y":"x"}function Bt(e){return Ft(jt(e))}function $t(e,t,s){void 0===s&&(s=!1);const i=Pt(e),n=Bt(e),r=Rt(n);let a="x"===n?i===(s?"end":"start")?"right":"left":"start"===i?"bottom":"top";return t.reference[r]>t.floating[r]&&(a=Ht(a)),[a,Ht(a)]}function Vt(e){return e.replace(/start|end/g,e=>It[e])}const qt=["left","right"],Ut=["right","left"],zt=["top","bottom"],Wt=["bottom","top"];function Ht(e){return e.replace(/left|right|bottom|top/g,e=>kt[e])}function Kt(e){const{x:t,y:s,width:i,height:n}=e;return{width:i,height:n,top:s,left:t,right:t+i,bottom:s+n,x:t,y:s}}function Gt(e,t,s){let{reference:i,floating:n}=e;const r=jt(t),a=Bt(t),o=Rt(a),c=Nt(t),l="y"===r,h=i.x+i.width/2-n.width/2,u=i.y+i.height/2-n.height/2,d=i[o]/2-n[o]/2;let p;switch(c){case"top":p={x:h,y:i.y-n.height};break;case"bottom":p={x:h,y:i.y+i.height};break;case"right":p={x:i.x+i.width,y:u};break;case"left":p={x:i.x-n.width,y:u};break;default:p={x:i.x,y:i.y}}switch(Pt(t)){case"start":p[a]-=d*(s&&l?-1:1);break;case"end":p[a]+=d*(s&&l?-1:1)}return p}async function Jt(e,t){var s;void 0===t&&(t={});const{x:i,y:n,platform:r,rects:a,elements:o,strategy:c}=e,{boundary:l="clippingAncestors",rootBoundary:h="viewport",elementContext:u="floating",altBoundary:d=!1,padding:p=0}=_t(t,e),m=function(e){return"number"!=typeof e?function(e){return{top:0,right:0,bottom:0,left:0,...e}}(e):{top:e,right:e,bottom:e,left:e}}(p),g=o[d?"floating"===u?"reference":"floating":u],f=Kt(await r.getClippingRect({element:null==(s=await(null==r.isElement?void 0:r.isElement(g)))||s?g:g.contextElement||await(null==r.getDocumentElement?void 0:r.getDocumentElement(o.floating)),boundary:l,rootBoundary:h,strategy:c})),b="floating"===u?{x:i,y:n,width:a.floating.width,height:a.floating.height}:a.reference,y=await(null==r.getOffsetParent?void 0:r.getOffsetParent(o.floating)),v=await(null==r.isElement?void 0:r.isElement(y))&&await(null==r.getScale?void 0:r.getScale(y))||{x:1,y:1},w=Kt(r.convertOffsetParentRelativeRectToViewportRelativeRect?await r.convertOffsetParentRelativeRectToViewportRelativeRect({elements:o,rect:b,offsetParent:y,strategy:c}):b);return{top:(f.top-w.top+m.top)/v.y,bottom:(w.bottom-f.bottom+m.bottom)/v.y,left:(f.left-w.left+m.left)/v.x,right:(w.right-f.right+m.right)/v.x}}const Yt=new Set(["left","top"]);function Zt(){return"undefined"!=typeof window}function Xt(e){return ts(e)?(e.nodeName||"").toLowerCase():"#document"}function Qt(e){var t;return(null==e||null==(t=e.ownerDocument)?void 0:t.defaultView)||window}function es(e){var t;return null==(t=(ts(e)?e.ownerDocument:e.document)||window.document)?void 0:t.documentElement}function ts(e){return!!Zt()&&(e instanceof Node||e instanceof Qt(e).Node)}function ss(e){return!!Zt()&&(e instanceof Element||e instanceof Qt(e).Element)}function is(e){return!!Zt()&&(e instanceof HTMLElement||e instanceof Qt(e).HTMLElement)}function ns(e){return!(!Zt()||"undefined"==typeof ShadowRoot)&&(e instanceof ShadowRoot||e instanceof Qt(e).ShadowRoot)}const rs=new Set(["inline","contents"]);function as(e){const{overflow:t,overflowX:s,overflowY:i,display:n}=ys(e);return/auto|scroll|overlay|hidden|clip/.test(t+i+s)&&!rs.has(n)}const os=new Set(["table","td","th"]);function cs(e){return os.has(Xt(e))}const ls=[":popover-open",":modal"];function hs(e){return ls.some(t=>{try{return e.matches(t)}catch(e){return!1}})}const us=["transform","translate","scale","rotate","perspective"],ds=["transform","translate","scale","rotate","perspective","filter"],ps=["paint","layout","strict","content"];function ms(e){const t=gs(),s=ss(e)?ys(e):e;return us.some(e=>!!s[e]&&"none"!==s[e])||!!s.containerType&&"normal"!==s.containerType||!t&&!!s.backdropFilter&&"none"!==s.backdropFilter||!t&&!!s.filter&&"none"!==s.filter||ds.some(e=>(s.willChange||"").includes(e))||ps.some(e=>(s.contain||"").includes(e))}function gs(){return!("undefined"==typeof CSS||!CSS.supports)&&CSS.supports("-webkit-backdrop-filter","none")}const fs=new Set(["html","body","#document"]);function bs(e){return fs.has(Xt(e))}function ys(e){return Qt(e).getComputedStyle(e)}function vs(e){return ss(e)?{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}:{scrollLeft:e.scrollX,scrollTop:e.scrollY}}function ws(e){if("html"===Xt(e))return e;const t=e.assignedSlot||e.parentNode||ns(e)&&e.host||es(e);return ns(t)?t.host:t}function Ts(e){const t=ws(e);return bs(t)?e.ownerDocument?e.ownerDocument.body:e.body:is(t)&&as(t)?t:Ts(t)}function Ss(e,t,s){var i;void 0===t&&(t=[]),void 0===s&&(s=!0);const n=Ts(e),r=n===(null==(i=e.ownerDocument)?void 0:i.body),a=Qt(n);if(r){const e=Cs(a);return t.concat(a,a.visualViewport||[],as(n)?n:[],e&&s?Ss(e):[])}return t.concat(n,Ss(n,[],s))}function Cs(e){return e.parent&&Object.getPrototypeOf(e.parent)?e.frameElement:null}function Os(e){const t=ys(e);let s=parseFloat(t.width)||0,i=parseFloat(t.height)||0;const n=is(e),r=n?e.offsetWidth:s,a=n?e.offsetHeight:i,o=Et(s)!==r||Et(i)!==a;return o&&(s=r,i=a),{width:s,height:i,$:o}}function As(e){return ss(e)?e:e.contextElement}function Es(e){const t=As(e);if(!is(t))return Mt(1);const s=t.getBoundingClientRect(),{width:i,height:n,$:r}=Os(t);let a=(r?Et(s.width):s.width)/i,o=(r?Et(s.height):s.height)/n;return a&&Number.isFinite(a)||(a=1),o&&Number.isFinite(o)||(o=1),{x:a,y:o}}const xs=Mt(0);function Ms(e){const t=Qt(e);return gs()&&t.visualViewport?{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}:xs}function ks(e,t,s,i){void 0===t&&(t=!1),void 0===s&&(s=!1);const n=e.getBoundingClientRect(),r=As(e);let a=Mt(1);t&&(i?ss(i)&&(a=Es(i)):a=Es(e));const o=function(e,t,s){return void 0===t&&(t=!1),!(!s||t&&s!==Qt(e))&&t}(r,s,i)?Ms(r):Mt(0);let c=(n.left+o.x)/a.x,l=(n.top+o.y)/a.y,h=n.width/a.x,u=n.height/a.y;if(r){const e=Qt(r),t=i&&ss(i)?Qt(i):i;let s=e,n=Cs(s);for(;n&&i&&t!==s;){const e=Es(n),t=n.getBoundingClientRect(),i=ys(n),r=t.left+(n.clientLeft+parseFloat(i.paddingLeft))*e.x,a=t.top+(n.clientTop+parseFloat(i.paddingTop))*e.y;c*=e.x,l*=e.y,h*=e.x,u*=e.y,c+=r,l+=a,s=Qt(n),n=Cs(s)}}return Kt({width:h,height:u,x:c,y:l})}function Is(e,t){const s=vs(e).scrollLeft;return t?t.left+s:ks(es(e)).left+s}function Ls(e,t,s){void 0===s&&(s=!1);const i=e.getBoundingClientRect();return{x:i.left+t.scrollLeft-(s?0:Is(e,i)),y:i.top+t.scrollTop}}const _s=new Set(["absolute","fixed"]);function Ns(e,t,s){let i;if("viewport"===t)i=function(e,t){const s=Qt(e),i=es(e),n=s.visualViewport;let r=i.clientWidth,a=i.clientHeight,o=0,c=0;if(n){r=n.width,a=n.height;const e=gs();(!e||e&&"fixed"===t)&&(o=n.offsetLeft,c=n.offsetTop)}return{width:r,height:a,x:o,y:c}}(e,s);else if("document"===t)i=function(e){const t=es(e),s=vs(e),i=e.ownerDocument.body,n=At(t.scrollWidth,t.clientWidth,i.scrollWidth,i.clientWidth),r=At(t.scrollHeight,t.clientHeight,i.scrollHeight,i.clientHeight);let a=-s.scrollLeft+Is(e);const o=-s.scrollTop;return"rtl"===ys(i).direction&&(a+=At(t.clientWidth,i.clientWidth)-n),{width:n,height:r,x:a,y:o}}(es(e));else if(ss(t))i=function(e,t){const s=ks(e,!0,"fixed"===t),i=s.top+e.clientTop,n=s.left+e.clientLeft,r=is(e)?Es(e):Mt(1);return{width:e.clientWidth*r.x,height:e.clientHeight*r.y,x:n*r.x,y:i*r.y}}(t,s);else{const s=Ms(e);i={x:t.x-s.x,y:t.y-s.y,width:t.width,height:t.height}}return Kt(i)}function Ps(e,t){const s=ws(e);return!(s===t||!ss(s)||bs(s))&&("fixed"===ys(s).position||Ps(s,t))}function Fs(e,t,s){const i=is(t),n=es(t),r="fixed"===s,a=ks(e,!0,r,t);let o={scrollLeft:0,scrollTop:0};const c=Mt(0);function l(){c.x=Is(n)}if(i||!i&&!r)if(("body"!==Xt(t)||as(n))&&(o=vs(t)),i){const e=ks(t,!0,r,t);c.x=e.x+t.clientLeft,c.y=e.y+t.clientTop}else n&&l();r&&!i&&n&&l();const h=!n||i||r?Mt(0):Ls(n,o);return{x:a.left+o.scrollLeft-c.x-h.x,y:a.top+o.scrollTop-c.y-h.y,width:a.width,height:a.height}}function Rs(e){return"static"===ys(e).position}function Ds(e,t){if(!is(e)||"fixed"===ys(e).position)return null;if(t)return t(e);let s=e.offsetParent;return es(e)===s&&(s=s.ownerDocument.body),s}function js(e,t){const s=Qt(e);if(hs(e))return s;if(!is(e)){let t=ws(e);for(;t&&!bs(t);){if(ss(t)&&!Rs(t))return t;t=ws(t)}return s}let i=Ds(e,t);for(;i&&cs(i)&&Rs(i);)i=Ds(i,t);return i&&bs(i)&&Rs(i)&&!ms(i)?s:i||function(e){let t=ws(e);for(;is(t)&&!bs(t);){if(ms(t))return t;if(hs(t))return null;t=ws(t)}return null}(e)||s}const Bs={convertOffsetParentRelativeRectToViewportRelativeRect:function(e){let{elements:t,rect:s,offsetParent:i,strategy:n}=e;const r="fixed"===n,a=es(i),o=!!t&&hs(t.floating);if(i===a||o&&r)return s;let c={scrollLeft:0,scrollTop:0},l=Mt(1);const h=Mt(0),u=is(i);if((u||!u&&!r)&&(("body"!==Xt(i)||as(a))&&(c=vs(i)),is(i))){const e=ks(i);l=Es(i),h.x=e.x+i.clientLeft,h.y=e.y+i.clientTop}const d=!a||u||r?Mt(0):Ls(a,c,!0);return{width:s.width*l.x,height:s.height*l.y,x:s.x*l.x-c.scrollLeft*l.x+h.x+d.x,y:s.y*l.y-c.scrollTop*l.y+h.y+d.y}},getDocumentElement:es,getClippingRect:function(e){let{element:t,boundary:s,rootBoundary:i,strategy:n}=e;const r=[..."clippingAncestors"===s?hs(t)?[]:function(e,t){const s=t.get(e);if(s)return s;let i=Ss(e,[],!1).filter(e=>ss(e)&&"body"!==Xt(e)),n=null;const r="fixed"===ys(e).position;let a=r?ws(e):e;for(;ss(a)&&!bs(a);){const t=ys(a),s=ms(a);s||"fixed"!==t.position||(n=null),(r?!s&&!n:!s&&"static"===t.position&&n&&_s.has(n.position)||as(a)&&!s&&Ps(e,a))?i=i.filter(e=>e!==a):n=t,a=ws(a)}return t.set(e,i),i}(t,this._c):[].concat(s),i],a=r[0],o=r.reduce((e,s)=>{const i=Ns(t,s,n);return e.top=At(i.top,e.top),e.right=Ot(i.right,e.right),e.bottom=Ot(i.bottom,e.bottom),e.left=At(i.left,e.left),e},Ns(t,a,n));return{width:o.right-o.left,height:o.bottom-o.top,x:o.left,y:o.top}},getOffsetParent:js,getElementRects:async function(e){const t=this.getOffsetParent||js,s=this.getDimensions,i=await s(e.floating);return{reference:Fs(e.reference,await t(e.floating),e.strategy),floating:{x:0,y:0,width:i.width,height:i.height}}},getClientRects:function(e){return Array.from(e.getClientRects())},getDimensions:function(e){const{width:t,height:s}=Os(e);return{width:t,height:s}},getScale:Es,isElement:ss,isRTL:function(e){return"rtl"===ys(e).direction}};function $s(e,t){return e.x===t.x&&e.y===t.y&&e.width===t.width&&e.height===t.height}const Vs=function(e){return void 0===e&&(e=0),{name:"offset",options:e,async fn(t){var s,i;const{x:n,y:r,placement:a,middlewareData:o}=t,c=await async function(e,t){const{placement:s,platform:i,elements:n}=e,r=await(null==i.isRTL?void 0:i.isRTL(n.floating)),a=Nt(s),o=Pt(s),c="y"===jt(s),l=Yt.has(a)?-1:1,h=r&&c?-1:1,u=_t(t,e);let{mainAxis:d,crossAxis:p,alignmentAxis:m}="number"==typeof u?{mainAxis:u,crossAxis:0,alignmentAxis:null}:{mainAxis:u.mainAxis||0,crossAxis:u.crossAxis||0,alignmentAxis:u.alignmentAxis};return o&&"number"==typeof m&&(p="end"===o?-1*m:m),c?{x:p*h,y:d*l}:{x:d*l,y:p*h}}(t,e);return a===(null==(s=o.offset)?void 0:s.placement)&&null!=(i=o.arrow)&&i.alignmentOffset?{}:{x:n+c.x,y:r+c.y,data:{...c,placement:a}}}}},qs=function(e){return void 0===e&&(e={}),{name:"shift",options:e,async fn(t){const{x:s,y:i,placement:n}=t,{mainAxis:r=!0,crossAxis:a=!1,limiter:o={fn:e=>{let{x:t,y:s}=e;return{x:t,y:s}}},...c}=_t(e,t),l={x:s,y:i},h=await Jt(t,c),u=jt(Nt(n)),d=Ft(u);let p=l[d],m=l[u];if(r){const e="y"===d?"bottom":"right";p=Lt(p+h["y"===d?"top":"left"],p,p-h[e])}if(a){const e="y"===u?"bottom":"right";m=Lt(m+h["y"===u?"top":"left"],m,m-h[e])}const g=o.fn({...t,[d]:p,[u]:m});return{...g,data:{x:g.x-s,y:g.y-i,enabled:{[d]:r,[u]:a}}}}}},Us=function(e){return void 0===e&&(e={}),{name:"flip",options:e,async fn(t){var s,i;const{placement:n,middlewareData:r,rects:a,initialPlacement:o,platform:c,elements:l}=t,{mainAxis:h=!0,crossAxis:u=!0,fallbackPlacements:d,fallbackStrategy:p="bestFit",fallbackAxisSideDirection:m="none",flipAlignment:g=!0,...f}=_t(e,t);if(null!=(s=r.arrow)&&s.alignmentOffset)return{};const b=Nt(n),y=jt(o),v=Nt(o)===o,w=await(null==c.isRTL?void 0:c.isRTL(l.floating)),T=d||(v||!g?[Ht(o)]:function(e){const t=Ht(e);return[Vt(e),t,Vt(t)]}(o)),S="none"!==m;!d&&S&&T.push(...function(e,t,s,i){const n=Pt(e);let r=function(e,t,s){switch(e){case"top":case"bottom":return s?t?Ut:qt:t?qt:Ut;case"left":case"right":return t?zt:Wt;default:return[]}}(Nt(e),"start"===s,i);return n&&(r=r.map(e=>e+"-"+n),t&&(r=r.concat(r.map(Vt)))),r}(o,g,m,w));const C=[o,...T],O=await Jt(t,f),A=[];let E=(null==(i=r.flip)?void 0:i.overflows)||[];if(h&&A.push(O[b]),u){const e=$t(n,a,w);A.push(O[e[0]],O[e[1]])}if(E=[...E,{placement:n,overflows:A}],!A.every(e=>e<=0)){var x,M;const e=((null==(x=r.flip)?void 0:x.index)||0)+1,t=C[e];if(t&&("alignment"!==u||y===jt(t)||E.every(e=>jt(e.placement)!==y||e.overflows[0]>0)))return{data:{index:e,overflows:E},reset:{placement:t}};let s=null==(M=E.filter(e=>e.overflows[0]<=0).sort((e,t)=>e.overflows[1]-t.overflows[1])[0])?void 0:M.placement;if(!s)switch(p){case"bestFit":{var k;const e=null==(k=E.filter(e=>{if(S){const t=jt(e.placement);return t===y||"y"===t}return!0}).map(e=>[e.placement,e.overflows.filter(e=>e>0).reduce((e,t)=>e+t,0)]).sort((e,t)=>e[1]-t[1])[0])?void 0:k[0];e&&(s=e);break}case"initialPlacement":s=o}if(n!==s)return{reset:{placement:s}}}return{}}}},zs=e=>{Object.assign(e,{show(){this.cancelBehaviourOpen?.(),this.openValue=!0},hide(){this.openValue=!1},toggle(){this.cancelBehaviourOpen?.(),this.openValue=!this.openValue},setupFloatingUI({trigger:e,popover:t,strategy:s}){this.floatingUICleanup=function(e,t,s,i){void 0===i&&(i={});const{ancestorScroll:n=!0,ancestorResize:r=!0,elementResize:a="function"==typeof ResizeObserver,layoutShift:o="function"==typeof IntersectionObserver,animationFrame:c=!1}=i,l=As(e),h=n||r?[...l?Ss(l):[],...Ss(t)]:[];h.forEach(e=>{n&&e.addEventListener("scroll",s,{passive:!0}),r&&e.addEventListener("resize",s)});const u=l&&o?function(e,t){let s,i=null;const n=es(e);function r(){var e;clearTimeout(s),null==(e=i)||e.disconnect(),i=null}return function a(o,c){void 0===o&&(o=!1),void 0===c&&(c=1),r();const l=e.getBoundingClientRect(),{left:h,top:u,width:d,height:p}=l;if(o||t(),!d||!p)return;const m={rootMargin:-xt(u)+"px "+-xt(n.clientWidth-(h+d))+"px "+-xt(n.clientHeight-(u+p))+"px "+-xt(h)+"px",threshold:At(0,Ot(1,c))||1};let g=!0;function f(t){const i=t[0].intersectionRatio;if(i!==c){if(!g)return a();i?a(!1,i):s=setTimeout(()=>{a(!1,1e-7)},1e3)}1!==i||$s(l,e.getBoundingClientRect())||a(),g=!1}try{i=new IntersectionObserver(f,{...m,root:n.ownerDocument})}catch(e){i=new IntersectionObserver(f,m)}i.observe(e)}(!0),r}(l,s):null;let d,p=-1,m=null;a&&(m=new ResizeObserver(e=>{let[i]=e;i&&i.target===l&&m&&(m.unobserve(t),cancelAnimationFrame(p),p=requestAnimationFrame(()=>{var e;null==(e=m)||e.observe(t)})),s()}),l&&!c&&m.observe(l),m.observe(t));let g=c?ks(e):null;return c&&function t(){const i=ks(e);g&&!$s(g,i)&&s(),g=i,d=requestAnimationFrame(t)}(),s(),()=>{var e;h.forEach(e=>{n&&e.removeEventListener("scroll",s),r&&e.removeEventListener("resize",s)}),null==u||u(),null==(e=m)||e.disconnect(),m=null,c&&cancelAnimationFrame(d)}}(e,t,()=>{((e,t,s)=>{const i=new Map,n={platform:Bs,...s},r={...n.platform,_c:i};return(async(e,t,s)=>{const{placement:i="bottom",strategy:n="absolute",middleware:r=[],platform:a}=s,o=r.filter(Boolean),c=await(null==a.isRTL?void 0:a.isRTL(t));let l=await a.getElementRects({reference:e,floating:t,strategy:n}),{x:h,y:u}=Gt(l,i,c),d=i,p={},m=0;for(let s=0;s{const n={left:`${e}px`,top:`${s}px`,position:i};Object.assign(t.style,n)})})},openValueChanged(){this.disabledValue||(this.openValue?(this.preparePopoverOpenAnimation?.(),this.popoverTarget.showPopover(),this.popoverTarget.setAttribute("aria-expanded","true"),this.onPopoverOpened&&this.onPopoverOpened()):(this.popoverTarget.hidePopover(),this.popoverTarget.removeAttribute("aria-expanded"),this.onPopoverClosed&&this.onPopoverClosed()))}})},Ws=class extends i.xI{static targets=["button","popover"];static values={placement:{type:String,default:"bottom-end"},open:{type:Boolean,default:!1},autoPlacement:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},size:{type:Number,default:24},perLine:{type:Number,default:9}};initialize(){this.onEmojiSelect=this.onEmojiSelect.bind(this),this.pickerLoaded=!1,this.pickerLoadPromise=null,this.connected=!1,super.initialize()}connect(){this.connected=!0,zs(this),this.setupFloatingUI({trigger:this.buttonTarget,popover:this.popoverTarget,strategy:"absolute"}),super.connect()}disconnect(){this.connected=!1,this.pickerLoadPromise=null,this.floatingUICleanup(),super.disconnect()}onEmojiSelect(e){this.dispatch("selected",{detail:e.native}),this.hide()}onClickOutside(e){this.openValue&&e.target.nodeType&&!1===this.element.contains(e.target)&&(this.openValue=!1)}async onPopoverOpened(){await this.loadPicker()}async loadPicker(){if(this.pickerLoaded)return;this.pickerLoadPromise||=this.loadPickerDependencies();const{Picker:e,i18n:t}=await this.pickerLoadPromise;this.connected&&!this.pickerLoaded&&(this.popoverTarget.appendChild(this.buildPicker(e,t)),this.pickerLoaded=!0)}async loadPickerDependencies(){const[e,t]=await Promise.all([s.e(160).then(s.bind(s,405)),this.loadI18n()]);return{Picker:e.Picker,i18n:t.default||t}}loadI18n(){return"es"===Hellotext.business.locale?s.e(437).then(s.t.bind(s,9,19)):s.e(200).then(s.t.bind(s,714,19))}buildPicker(e,t){return new e({onEmojiSelect:this.onEmojiSelect,theme:"light",dynamicWidth:!0,previewPosition:"none",skinTonePosition:"none",emojiSize:this.sizeValue,perLine:this.perLineValue,i18n:t})}get middlewares(){return[Vs(5),qs({padding:24}),(e={allowedPlacements:["top","bottom"]},void 0===e&&(e={}),{name:"autoPlacement",options:e,async fn(t){var s,i,n;const{rects:r,middlewareData:a,placement:o,platform:c,elements:l}=t,{crossAxis:h=!1,alignment:u,allowedPlacements:d=Ct,autoAlignment:p=!0,...m}=_t(e,t),g=void 0!==u||d===Ct?function(e,t,s){return(e?[...s.filter(t=>Pt(t)===e),...s.filter(t=>Pt(t)!==e)]:s.filter(e=>Nt(e)===e)).filter(s=>!e||Pt(s)===e||!!t&&Vt(s)!==s)}(u||null,p,d):d,f=await Jt(t,m),b=(null==(s=a.autoPlacement)?void 0:s.index)||0,y=g[b];if(null==y)return{};const v=$t(y,r,await(null==c.isRTL?void 0:c.isRTL(l.floating)));if(o!==y)return{reset:{placement:g[0]}};const w=[f[Nt(y)],f[v[0]],f[v[1]]],T=[...(null==(i=a.autoPlacement)?void 0:i.overflows)||[],{placement:y,overflows:w}],S=g[b+1];if(S)return{data:{index:b+1,overflows:T},reset:{placement:S}};const C=T.map(e=>{const t=Pt(e.placement);return[e.placement,t&&h?e.overflows.slice(0,2).reduce((e,t)=>e+t,0):e.overflows[0],e.overflows]}).sort((e,t)=>e[1]-t[1]),O=(null==(n=C.filter(e=>e[2].slice(0,Pt(e[0])?2:3).every(e=>e<=0))[0])?void 0:n[0])||C[0][0];return O!==o?{data:{index:b+1,overflows:T},reset:{placement:O}}:{}}})];var e}};class Hs{static get endpoint(){return g.endpoint("public/webchats/:id/messages")}constructor(e){this.webchatId=e}async index(e){const t=new URL(this.url);return Object.entries(e).forEach(([e,s])=>{t.searchParams.append(e,s)}),await fetch(t,{method:"GET",headers:bt.headers})}catchUp(e){return this.index({after_id:e,session:bt.session})}async create(e){const t=await fetch(this.url,{method:"POST",headers:{Authorization:`Bearer ${bt.business.id}`},body:e});return new y(t.ok,t)}markAsSeen(e=null){const t=e?this.url+`/${e}`:this.url+"/seen";fetch(t,{method:"PATCH",headers:bt.headers,body:JSON.stringify({session:bt.session})})}get url(){return Hs.endpoint.replace(":id",this.webchatId)}}const Ks=Hs;class Gs{static webSocket;static channels=new Set;static messageHandlers=new Set;static disconnectHandlers=new Set;static subscriptionConfirmHandlers=new Set;static reconnectTimeout=null;static reconnectAttempts=0;static reconnectBaseDelay=500;static reconnectMaxDelay=1e4;static reconnectJitter=.3;static needsResubscribe=!1;constructor(){Gs.channels.add(this)}send({command:e,identifier:t,data:s}){const i={command:e,identifier:JSON.stringify(t),data:JSON.stringify(s||{})},n=Gs.ensureWebSocket(),r=JSON.stringify(i);n.readyState===WebSocket.OPEN?n.send(r):n.addEventListener("open",()=>{n.send(r)})}onMessage(e){const t=t=>{const s=JSON.parse(t.data),{type:i,message:n}=s;this.ignoredEvents.includes(i)||e(n)};Gs.messageHandlers.add(t),Gs.ensureWebSocket().addEventListener("message",t)}onDisconnect(e){Gs.disconnectHandlers.add(e)}onSubscriptionConfirmed(e){Gs.subscriptionConfirmHandlers.add(e)}get webSocket(){return Gs.ensureWebSocket()}static ensureWebSocket(){return this.webSocket&&!this.closedWebSocket(this.webSocket)?this.webSocket:(this.webSocket&&(this.needsResubscribe=!0),this.openWebSocket())}static openWebSocket(){this.clearReconnectTimeout();const e=new WebSocket(g.actionCableUrl);return this.webSocket=e,this.installWebSocketHandlers(e),e}static installWebSocketHandlers(e){e.addEventListener("open",()=>this.handleOpen(e)),e.addEventListener("close",()=>this.handleDisconnect(e)),e.addEventListener("error",()=>this.handleDisconnect(e)),e.addEventListener("message",e=>this.handleControlMessage(e)),this.messageHandlers.forEach(t=>{e.addEventListener("message",t)})}static handleOpen(e){e===this.webSocket&&(this.reconnectAttempts=0,this.needsResubscribe&&(this.needsResubscribe=!1,this.resubscribeChannels()))}static handleControlMessage(e){let t;try{t=JSON.parse(e.data)}catch{return}"confirm_subscription"===t.type&&this.subscriptionConfirmHandlers.forEach(e=>e(t.identifier))}static handleDisconnect(e){e===this.webSocket&&(this.disconnectHandlers.forEach(e=>e()),this.webSocket=null,this.needsResubscribe=!0,this.scheduleReconnect())}static scheduleReconnect(){this.reconnectTimeout||(this.reconnectTimeout=setTimeout(()=>{this.reconnectTimeout=null,this.reconnectAttempts+=1,this.openWebSocket()},this.reconnectDelay))}static clearReconnectTimeout(){this.reconnectTimeout&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=null)}static resubscribeChannels(){this.channels.forEach(e=>{const t=e.resubscribe||e.subscribe;"function"==typeof t&&t.call(e)})}static closedWebSocket(e){return e.readyState===WebSocket.CLOSED||e.readyState===WebSocket.CLOSING}static get reconnectDelay(){const e=Math.min(this.reconnectMaxDelay,this.reconnectBaseDelay*2**this.reconnectAttempts);return e+Math.round(e*this.reconnectJitter*Math.random())}get ignoredEvents(){return["ping","confirm_subscription","welcome"]}}const Js=Gs,Ys=class extends Js{constructor(e,t,s){super(),this.id=e,this.session=t,this.conversation=s,this.subscribed=!1,this.awaitingReconnectConfirmation=!1,this.reconnectCallbacks=new Set,this.onSubscriptionConfirmed(e=>this.handleSubscriptionConfirmed(e)),this.subscribe()}subscribe(){this.subscribed=!0;const e={channel:"WebchatChannel",id:this.id,session:this.session,conversation:this.conversation};this.send({command:"subscribe",identifier:e})}unsubscribe(){this.subscribed=!1;const e={channel:"WebchatChannel",id:this.id,session:this.session,conversation:this.conversation};this.send({command:"unsubscribe",identifier:e})}resubscribe(){!1!==this.subscribed&&(this.awaitingReconnectConfirmation=!0,this.subscribe())}onReconnect(e){this.reconnectCallbacks.add(e)}handleSubscriptionConfirmed(e){this.awaitingReconnectConfirmation&&this.matchesIdentifier(e)&&(this.awaitingReconnectConfirmation=!1,this.reconnectCallbacks.forEach(e=>e()))}matchesIdentifier(e){let t;try{t="string"==typeof e?JSON.parse(e):e}catch{return!1}return"WebchatChannel"===t.channel&&t.id===this.id&&t.session===this.session&&t.conversation===this.conversation}startTypingIndicator(){const e={channel:"WebchatChannel",id:this.id,session:this.session,conversation:this.conversation};this.send({command:"message",identifier:e,data:{action:"started_typing"}})}stopTypingIndicator(){const e={channel:"WebchatChannel",id:this.id,session:this.session,conversation:this.conversation};this.send({command:"typing:stop",identifier:e,data:{action:"stopped_typing"}})}onMessage(e){super.onMessage(t=>{"message"===t.type&&e(t)})}onReaction(e){super.onMessage(t=>{"reaction.create"!==t.type&&"reaction.destroy"!==t.type||e(t)})}onTypingStart(e){super.onMessage(t=>{"started_typing"===t.type&&e(t)})}updateSubscriptionWith(e){this.unsubscribe(),setTimeout(()=>{this.conversation=e,this.subscribe()},1e3)}},Zs=e=>{Object.assign(e,{scheduleBehaviourOpen(){if(!this.shouldAutoOpenFromBehaviour())return;const e=1e3*Number(this.behaviourValue.delay_seconds||0);this.behaviourOpenTimeout=window.setTimeout(()=>{this.behaviourOpenTimeout=null,this.openValue||(this.openValue=!0,this.markBehaviourAutoOpened())},e)},cancelBehaviourOpen(){window.clearTimeout(this.behaviourOpenTimeout),this.behaviourOpenTimeout=null},shouldAutoOpenFromBehaviour(){const e=this.behaviourValue;return!(!e||"on_load"!==e.trigger||e.first_visit_only&&localStorage.getItem(this.firstVisitKey())||e.once_per_session&&sessionStorage.getItem(this.sessionKey()))},markBehaviourAutoOpened(){this.behaviourValue.first_visit_only&&localStorage.setItem(this.firstVisitKey(),"1"),this.behaviourValue.once_per_session&&sessionStorage.setItem(this.sessionKey(),"1")},firstVisitKey(){return`hellotext--webchat--${this.idValue}--auto-opened`},sessionKey(){return`hellotext--webchat--${this.idValue}--auto-opened-session`}})},Xs=e=>{Object.assign(e,{setupOpeningSequence(){this.openingSequenceStarted=!1,this.openingSequenceCancelled=!1,this.openingSequenceTimeout=null,this.openingSequenceMessages=[],this.revealedOpeningSequenceMessageIds=[]},teardownOpeningSequence(){this.cancelOpeningSequence()},startOpeningSequence(){this.openingSequenceMessages=Array.from(this.openingSequenceMessageTargets||[]),this.openingSequenceCanStart()&&(this.openingSequenceStarted=!0,this.openingSequenceCancelled=!1,this.revealedOpeningSequenceMessageIds=[],this.playOpeningSequenceMessageAt(0))},openingSequenceCanStart(){return!this.conversationIdValue&&this.hasOpeningSequenceTarget&&this.openingSequenceMessages.length>0&&!this.openingSequenceStarted},playOpeningSequenceMessageAt(e){const t=this.openingSequenceMessages[e];if(!t)return;const s=1e3*this.openingSequenceMessageDelay(t);this.openingSequenceTimeout=window.setTimeout(()=>{this.openingSequenceTimeout=null,this.openingSequenceCancelled||(this.revealOpeningSequenceMessage(t),this.playOpeningSequenceMessageAt(e+1))},s)},revealOpeningSequenceMessage(e){this.messagesContainerTarget.insertBefore(e,this.messageTemplateTarget),e.hidden=!1,this.recordOpeningSequenceMessage(e),this.scrollOpeningSequenceToBottom()},recordOpeningSequenceMessage(e){const t=e.dataset.openingSequenceMessageId;t&&!this.revealedOpeningSequenceMessageIds.includes(t)&&this.revealedOpeningSequenceMessageIds.push(t)},openingSequenceMessageDelay(e){const t=Number(e.dataset.delaySeconds||0);return Number.isFinite(t)?t:0},scrollOpeningSequenceToBottom(){this.messagesContainerTarget.scroll&&this.messagesContainerTarget.scroll({top:this.messagesContainerTarget.scrollHeight,behavior:"smooth"})},cancelOpeningSequence(){this.openingSequenceCancelled=!0,null!==this.openingSequenceTimeout&&void 0!==this.openingSequenceTimeout&&(window.clearTimeout(this.openingSequenceTimeout),this.openingSequenceTimeout=null)},appendOpeningSequenceMessageIds(e){this.cancelOpeningSequence(),(this.revealedOpeningSequenceMessageIds||[]).forEach(t=>{e.append("message[opening_sequence_message_ids][]",t)})},clearRevealedOpeningSequenceMessageIds(){this.revealedOpeningSequenceMessageIds=[]}})},Qs=e=>{Object.assign(e,{setupTeaser(){this.teaserCycleTimeout=null,this.teaserMessages=[],this.boundOnTeaserClick=this.boundOnTeaserClick||this.onTeaserClick.bind(this),this.hasTeaserTarget&&(this.teaserTarget.addEventListener("click",this.boundOnTeaserClick),this.startTeaserPresentation())},teardownTeaser(){this.stopTeaserCycle(),this.hasTeaserTarget&&this.boundOnTeaserClick&&this.teaserTarget.removeEventListener("click",this.boundOnTeaserClick)},collectTeaserMessages(){return this.hasTeaserTarget?Array.from(this.teaserTarget.querySelectorAll("[data-teaser-message]")):[]},startTeaserPresentation(){this.stopTeaserCycle(),this.teaserMessages=this.collectTeaserMessages(),this.hasTeaserTarget&&(0!==this.teaserMessages.length?this.openValue||this.conversationIdValue||this.hasRenderedConversationMessages()?this.dismissTeaserForSession():this.teaserSeenForSession()?this.hideTeaser():(this.teaserTarget.classList.remove("invisible"),this.showTeaserMessage(0),this.teaserMessages.length<2||this.scheduleNextTeaserMessage(0)):this.hideTeaser())},scheduleNextTeaserMessage(e){const t=e+1;if(t>=this.teaserMessages.length)return;const s=this.teaserMessages[e],i=this.teaserPresentationDelay(s);this.teaserCycleTimeout=window.setTimeout(()=>{this.teaserCycleTimeout=null,this.showTeaserMessage(t),this.scheduleNextTeaserMessage(t)},i)},showTeaserMessage(e){this.teaserMessages.forEach((t,s)=>{t.classList.toggle("hidden",s!==e)})},stopTeaserCycle(){null!==this.teaserCycleTimeout&&void 0!==this.teaserCycleTimeout&&(window.clearTimeout(this.teaserCycleTimeout),this.teaserCycleTimeout=null)},teaserMessageDelay(e){const t=Number(e.dataset.delaySeconds||0);return Number.isFinite(t)?t:0},teaserPresentationDelay(e){return Math.max(1e3*this.teaserMessageDelay(e),250)},hasRenderedConversationMessages(){let e=[];try{e=Array.from(this.messageTargets||[])}catch(t){e=[]}return e.some(e=>e!==this.messageTemplateTarget)},teaserSeenKey(){const e=this.hasTeaserTarget?this.teaserTarget.dataset.teaserVersion:"",t=e?`:${e}`:"";return`hellotext:webchat:${this.idValue||this.element.id}:teaser-seen${t}`},teaserSeenForSession(){try{return"true"===window.sessionStorage.getItem(this.teaserSeenKey())}catch(e){return!1}},markTeaserSeenForSession(){try{window.sessionStorage.setItem(this.teaserSeenKey(),"true")}catch(e){}},dismissTeaserForSession(){this.markTeaserSeenForSession(),this.hideTeaser()},hideTeaser(){this.stopTeaserCycle(),this.hasTeaserTarget&&this.teaserTarget.classList.add("invisible")},onTeaserClick(e){e.target.closest("a")||(this.dismissTeaserForSession(),this.show())}})},ei={hour:"numeric",minute:"2-digit"},ti=/Android|iPhone|iPad|iPod/i,si={capture:!0,passive:!0},ii=class extends i.xI{static messageTimestampFormatters={};static values={id:String,conversationId:String,media:Object,fileSizeErrorMessage:String,placement:{type:String,default:"bottom-end"},open:{type:Boolean,default:!1},autoPlacement:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},nextPage:{type:Number,default:void 0},fullScreenThreshold:{type:Number,default:1024},typingIndicatorKeepAlive:{type:Number,default:3e4},offset:{type:Number,default:24},padding:{type:Number,default:24},optimisticTypingIndicatorWait:{type:Number,default:1e3},teaser:Object,messageTeaser:String,behaviour:Object};static classes=["fadeOut"];static targets=["trigger","popover","input","attachmentInput","attachmentButton","errorMessageContainer","attachmentTemplate","attachmentContainer","attachment","messageTemplate","messagesContainer","title","attachmentImage","footer","toolbar","message","unreadCounter","typingIndicator","typingIndicatorTemplate","teaser","teaserMessage","inboundMessageTeaser","inboundMessageTeaserBody","openingSequence","openingSequenceMessage"];initialize(){this.messagesAPI=new Ks(this.idValue),this.webChatChannel=new Ys(this.idValue,bt.session,this.conversationIdValue),this.files=[],this.messageIds=new Set,this.catchUpAfterMessageId=null,this.fetchingCatchUpMessages=!1,this.onMessageReceived=this.onMessageReceived.bind(this),this.onMessageReaction=this.onMessageReaction.bind(this),this.onTypingStart=this.onTypingStart.bind(this),this.captureCatchUpCursor=this.captureCatchUpCursor.bind(this),this.catchUpMessages=this.catchUpMessages.bind(this),this.onScroll=this.onScroll.bind(this),this.onOutboundMessageSent=this.onOutboundMessageSent.bind(this),this.closePopoverOnEscape=this.closePopoverOnEscape.bind(this),this.broadcastChannel=new BroadcastChannel(`hellotext--webchat--${this.idValue}`),this.webChatChannel.onDisconnect(this.captureCatchUpCursor),this.webChatChannel.onReconnect(this.catchUpMessages),super.initialize()}connect(){Zs(this),zs(this),Xs(this),Qs(this),this.setupFloatingUI({trigger:this.triggerTarget,popover:this.popoverTarget}),this.hasTeaserTarget&&this.setupFloatingUI({trigger:this.triggerTarget,popover:this.teaserTarget,strategy:"absolute"}),this.setupTeaser(),this.setupOpeningSequence(),this.localizeMessageTimestamps(),this.webChatChannel.onMessage(this.onMessageReceived),this.webChatChannel.onTypingStart(this.onTypingStart),this.webChatChannel.onReaction(this.onMessageReaction),this.setupMessagesContainerScrollIsolation(),this.messagesContainerTarget.addEventListener("scroll",this.onScroll),this.messagesContainerTarget.addEventListener("wheel",this.stopHostScrollPropagation,si),this.messagesContainerTarget.addEventListener("touchmove",this.stopHostScrollPropagation,si),this.shouldOpenOnMount&&(this.openValue=!0),bt.eventEmitter.dispatch("webchat:mounted"),this.broadcastChannel.addEventListener("message",this.onOutboundMessageSent),window.addEventListener("keydown",this.closePopoverOnEscape,!0),this.scheduleBehaviourOpen(),super.connect()}disconnect(){this.cancelBehaviourOpen(),this.clearPopoverOpenAnimation(),this.teardownTeaser(),this.teardownOpeningSequence(),this.broadcastChannel.removeEventListener("message",this.onOutboundMessageSent),this.messagesContainerTarget.removeEventListener("scroll",this.onScroll),this.messagesContainerTarget.removeEventListener("wheel",this.stopHostScrollPropagation,si),this.messagesContainerTarget.removeEventListener("touchmove",this.stopHostScrollPropagation,si),window.removeEventListener("keydown",this.closePopoverOnEscape,!0),this.clearTypingIndicator(),this.broadcastChannel.close(),this.floatingUICleanup(),super.disconnect()}setupMessagesContainerScrollIsolation(){this.messagesContainerTarget.style.overscrollBehavior="contain",this.messagesContainerTarget.style.webkitOverflowScrolling="touch",this.messagesContainerTarget.style.touchAction="pan-y",this.messagesContainerTarget.setAttribute("data-lenis-prevent",""),this.messagesContainerTarget.setAttribute("data-lenis-prevent-wheel",""),this.messagesContainerTarget.setAttribute("data-lenis-prevent-touch","")}stopHostScrollPropagation(e){e.stopPropagation()}onTypingStart(){if(this.typingIndicatorVisible)return this.resetTypingIndicatorTimer();this.showTypingIndicator()}showOptimisticTypingIndicator(){this.typingIndicatorVisible||this.showTypingIndicator()}showTypingIndicator(){this.clearTypingIndicator(),this.typingIndicatorVisible=!0;const e=this.typingIndicatorTemplateTarget.cloneNode(!0);e.setAttribute("data-hellotext--webchat-target","typingIndicator"),e.style.display="flex",this.messagesContainerTarget.appendChild(e),requestAnimationFrame(()=>{this.messagesContainerTarget.scroll({top:this.messagesContainerTarget.scrollHeight,behavior:"instant"})});const t=this.typingIndicatorKeepAliveValue;this.incomingTypingIndicatorTimeout=setTimeout(()=>{this.clearTypingIndicator()},t)}resetTypingIndicatorTimer(){if(!this.typingIndicatorVisible)return;clearTimeout(this.incomingTypingIndicatorTimeout),clearTimeout(this.optimisticTypingTimeout);const e=this.typingIndicatorKeepAliveValue;this.incomingTypingIndicatorTimeout=setTimeout(()=>{this.clearTypingIndicator()},e)}clearTypingIndicator(){this.hasTypingIndicatorTarget&&this.typingIndicatorTarget.remove(),this.typingIndicatorVisible=!1,clearTimeout(this.incomingTypingIndicatorTimeout),clearTimeout(this.optimisticTypingTimeout)}onMessageInputChange(){this.resizeInput(),clearTimeout(this.typingIndicatorTimeout),this.hasSentTypingIndicator||(this.webChatChannel.startTypingIndicator(),this.hasSentTypingIndicator=!0),this.typingIndicatorTimeout=setTimeout(()=>{this.hasSentTypingIndicator=!1},3e3)}onOutboundMessageSent(e){const{data:t}=e,s={"message:sent":e=>{const t=(new DOMParser).parseFromString(e.element,"text/html").body.firstElementChild;this.localizeMessageTimestamps(t),this.typingIndicatorVisible&&this.hasTypingIndicatorTarget?this.messagesContainerTarget.insertBefore(t,this.typingIndicatorTarget):this.messagesContainerTarget.appendChild(t),t.scrollIntoView({behavior:"instant"})},"message:failed":e=>{const t=this.messagesContainerTarget.querySelector(`#${e.id}`);this.markMessageFailed(t,e.reason)}};s[t.type]?s[t.type](t):console.log(`Unhandled message event: ${t.type}`)}async onScroll(){if(this.messagesContainerTarget.scrollTop>300||!this.nextPageValue||this.fetchingNextPage)return;this.fetchingNextPage=!0;const e=await this.messagesAPI.index({page:this.nextPageValue,session:bt.session}),{next:t,messages:s}=await e.json();this.nextPageValue=t,this.oldScrollHeight=this.messagesContainerTarget.scrollHeight,s.forEach(e=>{const{body:t,attachments:s}=e,i=e.created_at||e.createdAt,n=this.messageTemplateTarget.cloneNode(!0);n.classList.add("hellotext--webchat-message"),n.setAttribute("data-hellotext--webchat-target","message"),n.setAttribute("data-id",e.id),i&&n.setAttribute("data-created-at",i),n.style.removeProperty("display"),nt(n.querySelector("[data-body]"),t),"received"===e.state?n.classList.add("received"):n.classList.remove("received"),s&&s.forEach(e=>{const t=this.attachmentImageTarget.cloneNode(!0);t.removeAttribute("data-hellotext--webchat-target"),t.src=e,t.style.display="block",this.messageAttachmentsContainer(n)?.appendChild(t)}),n.setAttribute("data-body",t),this.localizeMessageTimestamp(n.querySelector("[data-message-timestamp]"),i),this.messagesContainerTarget.prepend(n)}),this.messagesContainerTarget.scroll({top:this.messagesContainerTarget.scrollHeight-this.oldScrollHeight,behavior:"instant"}),this.fetchingNextPage=!1}onClickOutside(e){u.mode===h.POPOVER&&this.openValue&&e.target.nodeType&&!1===this.element.contains(e.target)&&(this.openValue=!1)}closePopover(){this.clearPopoverOpenAnimation(),this.popoverTarget.classList.remove(...this.fadeOutClasses),this.openValue=!1}preparePopoverOpenAnimation(){this.clearPopoverOpenAnimation(),this.popoverTarget.classList.remove(...this.fadeOutClasses),this.popoverTarget.classList.add("hellotext--webchat-popover-opening"),this.popoverOpenAnimationTimeout=setTimeout(()=>{this.popoverTarget.classList.remove("hellotext--webchat-popover-opening"),this.popoverOpenAnimationTimeout=null},120)}clearPopoverOpenAnimation(){this.popoverOpenAnimationTimeout&&(clearTimeout(this.popoverOpenAnimationTimeout),this.popoverOpenAnimationTimeout=null),this.popoverTarget?.classList.remove("hellotext--webchat-popover-opening")}onPopoverOpened(){this.popoverTarget.classList.remove(...this.fadeOutClasses),this.dismissTeaserForSession?.(),this.onMobile||this.focusComposeInput(),this.scrolled||(requestAnimationFrame(()=>{this.messagesContainerTarget.scroll({top:this.messagesContainerTarget.scrollHeight,behavior:"instant"})}),this.scrolled=!0),bt.eventEmitter.dispatch("webchat:opened"),localStorage.setItem(`hellotext--webchat--${this.idValue}`,"opened"),this.messageTeaserValue&&(this.messageTeaserValue=null),this.startOpeningSequence(),"none"!==this.unreadCounterTarget.style.display&&(this.unreadCounterTarget.style.display="none",this.unreadCounterTarget.innerText="0",this.messagesAPI.markAsSeen())}onPopoverClosed(){this.clearPopoverOpenAnimation(),bt.eventEmitter.dispatch("webchat:closed"),localStorage.setItem(`hellotext--webchat--${this.idValue}`,"closed")}onMessageReaction(e){const{message:t,reaction:s,type:i}=e,n=this.messageTargets.find(e=>e.dataset.id===t).querySelector("[data-reactions]");if("reaction.destroy"===i)return n.querySelector(`[data-id="${s.id}"]`).remove();if(n.querySelector(`[data-id="${s.id}"]`))n.querySelector(`[data-id="${s.id}"]`).innerText=s.emoji;else{const e=document.createElement("span");e.innerText=s.emoji,e.setAttribute("data-id",s.id),n.appendChild(e)}}onMessageReceived(e,t={}){const{id:s,body:i,attachments:n,teaser:r}=e,a=e.created_at||e.createdAt;if(!this.claimMessageId(s))return;if(this.hideTeaser?.(),e.carousel)return this.insertCarouselMessage(e,t);const o=this.messageTemplateTarget.cloneNode(!0);o.classList.add("hellotext--webchat-message"),o.style.display="flex",nt(o.querySelector("[data-body]"),i),o.setAttribute("data-id",s),o.setAttribute("data-hellotext--webchat-target","message"),this.setMessageCreatedAt(o,a),this.localizeMessageTimestamp(o.querySelector("[data-message-timestamp]"),a),n&&n.forEach(e=>{const t=this.attachmentImageTarget.cloneNode(!0);t.src=e,t.style.display="block",this.messageAttachmentsContainer(o)?.appendChild(t)}),this.clearTypingIndicator(),this.insertMessageElement(o),bt.eventEmitter.dispatch("webchat:message:received",{...e,body:o.querySelector("[data-body]").innerText}),!1!==t.scroll&&o.scrollIntoView({behavior:"smooth"}),this.updateMessageTeaser(r),this.openValue?this.messagesAPI.markAsSeen(s):this.incrementUnreadCounter()}claimMessageId(e){const t=this.messageTargets||[];return!this.messageIds.has(e)&&(this.messageIds.add(e),!t.some(t=>t.dataset.id===e))}captureCatchUpCursor(){this.catchUpAfterMessageId=this.lastRenderedMessageId}async catchUpMessages(){const e=this.catchUpAfterMessageId;if(e&&!this.fetchingCatchUpMessages){this.fetchingCatchUpMessages=!0;try{const t=await this.messagesAPI.catchUp(e),{messages:s=[]}=await t.json();s.forEach(e=>this.onMessageReceived(e,{scroll:!1})),this.catchUpAfterMessageId=this.lastRenderedMessageId}finally{this.fetchingCatchUpMessages=!1}}}get lastRenderedMessageId(){const e=this.persistedMessageElements;return e[e.length-1]?.dataset.id||null}get persistedMessageElements(){return Array.from(this.messagesContainerTarget.querySelectorAll(".hellotext--webchat-message[data-id]"))}setMessageCreatedAt(e,t){t&&e.setAttribute("data-created-at",t)}insertMessageElement(e){const t=this.nextMessageElementFor(e);t?this.messagesContainerTarget.insertBefore(e,t):this.messagesContainerTarget.appendChild(e)}nextMessageElementFor(e){const t=Date.parse(e.dataset.createdAt);return Number.isNaN(t)?null:this.persistedMessageElements.find(s=>{if(s===e)return!1;const i=Date.parse(s.dataset.createdAt);return!Number.isNaN(i)&&i>t})}updateMessageTeaser(e){this.messageTeaserValue=e,this.messageTeaserValue&&this.hasTeaserTarget&&this.hasInboundMessageTeaserTarget&&this.hasInboundMessageTeaserBodyTarget&&(this.teaserMessageTargets.forEach(e=>e.classList.add("hidden")),this.inboundMessageTeaserBodyTarget.textContent=this.messageTeaserValue,this.inboundMessageTeaserTarget.classList.remove("hidden"),this.teaserTarget.classList.toggle("invisible",this.openValue))}insertCarouselMessage(e,t={}){const s=e.html,i=e.created_at||e.createdAt,n=function(e){return it(e,st)}(s).firstElementChild;n.classList.add("hellotext--webchat-message"),n.setAttribute("data-id",e.id),n.setAttribute("data-hellotext--webchat-target","message"),this.setMessageCreatedAt(n,i),this.localizeMessageTimestamps(n),this.clearTypingIndicator(),this.insertMessageElement(n),!1!==t.scroll&&n.scrollIntoView({behavior:"smooth"}),bt.eventEmitter.dispatch("webchat:message:received",{...e,body:n.querySelector("[data-body]")?.innerText||""}),this.updateMessageTeaser(e.teaser),this.openValue?this.messagesAPI.markAsSeen(e.id):this.incrementUnreadCounter()}resizeInput(){this.inputTarget.style.height="auto";const e=this.inputTarget.scrollHeight;this.inputTarget.style.height=`${Math.min(e,96)}px`}async sendQuickReplyMessage({detail:{id:e,product:t,buttonId:s,body:i,cardElement:n}}){this.dismissTeaserForSession?.();const r=new FormData;r.append("message[body]",i),e&&r.append("message[replied_to]",e),t&&r.append("message[product]",t),s&&r.append("message[button]",s),r.append("session",bt.session),r.append("locale",o.toString()),this.appendOpeningSequenceMessageIds(r);const a=this.buildMessageElement(),c=n?.querySelector("img")?.cloneNode(!0);a.querySelector("[data-body]").innerText=i,c&&(c.removeAttribute("width"),c.removeAttribute("height"),this.messageAttachmentsContainer(a)?.appendChild(c)),this.typingIndicatorVisible&&this.hasTypingIndicatorTarget?this.messagesContainerTarget.insertBefore(a,this.typingIndicatorTarget):this.messagesContainerTarget.appendChild(a),a.scrollIntoView({behavior:"smooth"}),this.broadcastChannel.postMessage({type:"message:sent",element:a.outerHTML});const l=await this.messagesAPI.create(r);if(l.failed)return clearTimeout(this.optimisticTypingTimeout),this.markMessageFailedFromResponse(l,a);const h=await l.json();this.dispatch("set:id",{target:a,detail:h.id}),this.localizeMessageTimestamp(a.querySelector("[data-message-timestamp]"),h.created_at||h.createdAt),this.clearRevealedOpeningSequenceMessageIds();const u={id:h.id,body:i,attachments:c?[c.src]:[],replied_to:e,product:t,button:s,type:"quick_reply"};bt.eventEmitter.dispatch("webchat:message:sent",u)}async sendTeaserQuickReply(e){e.preventDefault(),e.stopPropagation();const t=e.currentTarget,s=(t.dataset.value||"").trim(),i=[t.dataset.text,t.textContent].map(e=>(e||"").trim()).find(e=>e.length>0),n=s||i;if(!n)return;this.dismissTeaserForSession?.(),this.show();const r=(t.dataset.type||"").trim()||"quick_reply",a=new FormData;a.append("message[body]",n),a.append("session",bt.session),a.append("locale",o.toString()),this.appendOpeningSequenceMessageIds(a);const c=this.buildMessageElement();c.querySelector("[data-body]").innerText=n,this.typingIndicatorVisible&&this.hasTypingIndicatorTarget?this.messagesContainerTarget.insertBefore(c,this.typingIndicatorTarget):this.messagesContainerTarget.appendChild(c),c.scrollIntoView({behavior:"smooth"}),this.broadcastChannel.postMessage({type:"message:sent",element:c.outerHTML}),this.typingIndicatorVisible||(clearTimeout(this.optimisticTypingTimeout),this.optimisticTypingTimeout=setTimeout(()=>{this.showOptimisticTypingIndicator()},this.optimisticTypingIndicatorWaitValue));const l=await this.messagesAPI.create(a);if(l.failed)return clearTimeout(this.optimisticTypingTimeout),this.markMessageFailedFromResponse(l,c);const h=await l.json();c.setAttribute("data-id",h.id),this.localizeMessageTimestamp(c.querySelector("[data-message-timestamp]"),h.created_at||h.createdAt),this.clearRevealedOpeningSequenceMessageIds(),bt.eventEmitter.dispatch("webchat:message:sent",{id:h.id,body:n,attachments:[],type:"quick_reply",teaser:{text:i||n,value:s||n,type:r}}),h.conversation&&h.conversation!==this.conversationIdValue&&(this.conversationIdValue=h.conversation,this.webChatChannel.updateSubscriptionWith(this.conversationIdValue)),this.typingIndicatorVisible&&this.resetTypingIndicatorTimer()}async sendMessage(e){const t={body:this.inputTarget.value,attachments:this.files};if(0===this.inputTarget.value.trim().length&&0===this.files.length)return void(e&&e.target&&e.preventDefault());this.dismissTeaserForSession?.();const s=new FormData;this.inputTarget.value.trim().length>0?s.append("message[body]",this.inputTarget.value):delete t.body,this.files.forEach(e=>{s.append("message[attachments][]",e)}),s.append("session",bt.session),s.append("locale",o.toString()),this.appendOpeningSequenceMessageIds(s);const i=this.buildMessageElement();this.inputTarget.value.trim().length>0?i.querySelector("[data-body]").innerText=this.inputTarget.value:i.querySelector("[data-message-bubble]").remove();const n=this.attachmentContainerTarget.querySelectorAll("img");n.length>0&&n.forEach(e=>{this.messageAttachmentsContainer(i)?.appendChild(e.cloneNode(!0))}),this.typingIndicatorVisible&&this.hasTypingIndicatorTarget?this.messagesContainerTarget.insertBefore(i,this.typingIndicatorTarget):this.messagesContainerTarget.appendChild(i),i.scrollIntoView({behavior:"smooth"}),this.broadcastChannel.postMessage({type:"message:sent",element:i.outerHTML}),this.inputTarget.value="",this.resizeInput(),this.files=[],this.attachmentInputTarget.value="",this.attachmentContainerTarget.innerHTML="",this.attachmentContainerTarget.style.display="none",this.errorMessageContainerTarget.style.display="none",this.focusComposeInput(),this.typingIndicatorVisible||(clearTimeout(this.optimisticTypingTimeout),this.optimisticTypingTimeout=setTimeout(()=>{this.showOptimisticTypingIndicator()},this.optimisticTypingIndicatorWaitValue));const r=await this.messagesAPI.create(s);if(r.failed)return clearTimeout(this.optimisticTypingTimeout),this.markMessageFailedFromResponse(r,i);const a=await r.json();i.setAttribute("data-id",a.id),t.id=a.id,this.localizeMessageTimestamp(i.querySelector("[data-message-timestamp]"),a.created_at||a.createdAt),this.clearRevealedOpeningSequenceMessageIds(),bt.eventEmitter.dispatch("webchat:message:sent",t),a.conversation!==this.conversationIdValue&&(this.conversationIdValue=a.conversation,this.webChatChannel.updateSubscriptionWith(this.conversationIdValue)),this.typingIndicatorVisible&&this.resetTypingIndicatorTimer(),this.attachmentContainerTarget.style.display=""}buildMessageElement(){const e=this.messageTemplateTarget.cloneNode(!0);return e.id=`hellotext--webchat--${this.idValue}--message--${Date.now()}`,e.classList.add("received"),e.style.removeProperty("display"),e.setAttribute("data-controller","hellotext--message"),e.setAttribute("data-hellotext--webchat-target","message"),this.localizeMessageTimestamp(e.querySelector("[data-message-timestamp]"),new Date),e}focusCompose(e){const{target:t}=e,s=["button","a","input","textarea","select","label",'[role="button"]',"em-emoji-picker",'[data-hellotext--webchat--emoji-target~="popover"]','[data-controller~="hellotext--webchat--emoji"]'].join(", ");this.hasInputTarget&&!t.closest(s)&&this.focusComposeInput({moveCursorToEnd:!0})&&e.preventDefault()}closePopoverFromHeader(e){const{target:t}=e;t.closest(".hellotext--webchat-header-channel-button, .hellotext--webchat-close-button")||(e.preventDefault(),this.closePopover())}closePopoverOnEscape(e){"Escape"===e.key&&this.openValue&&(e.preventDefault(),e.stopPropagation(),this.closePopover(),this.triggerTarget?.focus?.())}async markMessageFailedFromResponse(e,t){const s=await this.messageFailureReason(e);this.markMessageFailed(t,s),this.broadcastChannel.postMessage({type:"message:failed",id:t.id,reason:s})}markMessageFailed(e,t){if(!e)return;if(e.classList.add("failed"),!t)return;const s=e.querySelector("[data-message-timestamp]");s&&(s.textContent=t)}localizeMessageTimestamps(e=this.element){e&&(e.matches?.("time[datetime][data-message-timestamp]")?[e]:Array.from(e.querySelectorAll?.("time[datetime][data-message-timestamp]")||[])).forEach(e=>this.localizeMessageTimestamp(e))}localizeMessageTimestamp(e,t=e?.getAttribute("datetime")){if(!e||!t)return;const s=t instanceof Date?t:new Date(t);Number.isNaN(s.getTime())||(e.setAttribute("datetime",s.toISOString()),e.textContent=this.formatMessageTimestamp(s))}formatMessageTimestamp(e){return this.constructor.messageTimestampFormatterFor(o.toString()).format(e)}static messageTimestampFormatterFor(e){const t=e||"default";return this.messageTimestampFormatters[t]||(this.messageTimestampFormatters[t]=this.buildMessageTimestampFormatter(e)),this.messageTimestampFormatters[t]}static buildMessageTimestampFormatter(e){try{return new Intl.DateTimeFormat(e||void 0,ei)}catch(e){return new Intl.DateTimeFormat(void 0,ei)}}async messageFailureReason(e){const t=e?.data||e?.response,s=t?.statusText||"Message failed";try{const e=t?.clone?t.clone():t,s=await(e?.json?.()),i=this.messageFailureReasonFromPayload(s);if(i)return i}catch(e){}try{const e=t?.clone?t.clone():t,i=await(e?.text?.());return this.messageFailureReasonFromText(i)||s}catch(e){return s}}messageFailureReasonFromText(e){if("string"!=typeof e)return null;const t=e.trim();if(!t||t.startsWith("<"))return null;try{return this.messageFailureReasonFromPayload(JSON.parse(t))||t}catch(e){return t}}messageFailureReasonFromPayload(e){return e?[e.error?.message,e.message,e.errors?.message,e.errors?.[0]?.message,e.errors?.[0]?.description].find(e=>"string"==typeof e&&e.trim().length>0):null}messageAttachmentsContainer(e){return e.querySelector("[data-attachments-container], [data-attachment-container]")}incrementUnreadCounter(){this.unreadCounterTarget.style.display="flex";const e=(parseInt(this.unreadCounterTarget.innerText)||0)+1;this.unreadCounterTarget.innerText=Math.min(e,9)}openAttachment(){this.attachmentInputTarget.click()}onFileInputChange(){this.errorMessageContainerTarget.style.display="none";const e=Array.from(this.attachmentInputTarget.files);this.attachmentInputTarget.value="";const t=e.find(e=>{const t=e.type.split("/")[0];return["image","video","audio"].includes(t)?this.mediaValue[t].max_sizethis.createAttachmentElement(e)),this.focusComposeInput()}createAttachmentElement(e){const t=this.attachmentElement();if(this.attachmentContainerTarget.style.display="",t.setAttribute("data-name",e.name),e.type.startsWith("image/")){const s=this.attachmentImageTarget.cloneNode(!0);s.src=URL.createObjectURL(e),s.style.display="block",t.appendChild(s),this.attachmentContainerTarget.appendChild(t),this.attachmentContainerTarget.style.display="flex"}else{const s=t.querySelector("main");s.style.height="5rem",s.style.borderRadius="0.375rem",s.style.backgroundColor="#e5e7eb",s.style.padding="0.25rem",t.querySelector("p[data-attachment-name]").innerText=e.name,this.attachmentContainerTarget.appendChild(t),this.attachmentContainerTarget.style.display="flex"}}removeAttachment({currentTarget:e}){const t=e.closest("[data-hellotext--webchat-target='attachment']");this.files=this.files.filter(e=>e.name!==t.dataset.name),this.attachmentInputTarget.value="",t.remove(),this.focusComposeInput()}attachmentTargetDisconnected(){0===this.attachmentTargets.length&&(this.attachmentContainerTarget.innerHTML="",this.attachmentContainerTarget.style.display="none")}attachmentElement(){const e=this.attachmentTemplateTarget.cloneNode(!0);return e.removeAttribute("hidden"),e.style.display="flex",e.setAttribute("data-hellotext--webchat-target","attachment"),e}onEmojiSelect({detail:e}){const t=this.inputTarget.value,s=this.inputTarget.selectionStart,i=this.inputTarget.selectionEnd;this.inputTarget.value=t.slice(0,s)+e+t.slice(i),this.inputTarget.selectionStart=this.inputTarget.selectionEnd=s+e.length,this.focusComposeInput()}focusComposeInput({moveCursorToEnd:e=!1}={}){if(!this.shouldAutofocusCompose)return!1;if(!1===this.hasInputTarget)return!1;if(void 0===this.hasInputTarget&&!this.inputTarget)return!1;if(this.inputTarget.focus(),e&&"number"==typeof this.inputTarget.selectionStart){const e=this.inputTarget.value.length;this.inputTarget.setSelectionRange(e,e)}return!0}byteToMegabyte(e){return Math.ceil(e/1024/1024)}get middlewares(){return[Vs(this.offsetValue),qs({padding:this.paddingValue}),Us()]}get shouldOpenOnMount(){return"opened"===localStorage.getItem(`hellotext--webchat--${this.idValue}`)&&!this.onMobile}get shouldAutofocusCompose(){return!this.usesVirtualKeyboard}get usesVirtualKeyboard(){if("undefined"==typeof navigator)return!1;const e=navigator.userAgent||"",t="MacIntel"===navigator.platform&&navigator.maxTouchPoints>1,s=ti.test(e),i=!0===navigator.userAgentData?.mobile;return s||t||i||this.hasTouchOnlyPointer}get hasTouchOnlyPointer(){return"undefined"!=typeof window&&"function"==typeof window.matchMedia&&window.matchMedia("(pointer: coarse)").matches&&window.matchMedia("(hover: none)").matches}get onMobile(){return"undefined"!=typeof window&&"function"==typeof window.matchMedia&&window.matchMedia(`(max-width: ${this.fullScreenThresholdValue}px)`).matches}},ni=i.lg.start();ni.register("hellotext--alert",vt),ni.register("hellotext--form",wt),ni.register("hellotext--webchat",ii),ni.register("hellotext--webchat--emoji",Ws),ni.register("hellotext--message",Tt),window.Hellotext=bt;const ri=bt}};const t={};function s(i){const n=t[i];if(void 0!==n)return n.exports;const r=t[i]={exports:{}};return e[i](r,r.exports,s),r.exports}s.m=e,(()=>{const e=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__;let t;s.t=function(i,n){if(1&n&&(i=this(i)),8&n)return i;if("object"==typeof i&&i){if(4&n&&i.__esModule)return i;if(16&n&&"function"==typeof i.then)return i}const r=Object.create(null);s.r(r);const a={};t=t||[null,e({}),e([]),e(e)];for(var o=2&n&&i;("object"==typeof o||"function"==typeof o)&&!~t.indexOf(o);o=e(o))Object.getOwnPropertyNames(o).forEach(e=>a[e]=()=>i[e]);return a.default=()=>i,s.d(r,a),r}})(),s.d=(e,t)=>{if(Array.isArray(t))for(var i=0;iPromise.all(Object.keys(s.f).reduce((t,i)=>(s.f[i](e,t),t),[])),s.u=e=>({160:"webchat-emoji",200:"webchat-emoji-en",437:"webchat-emoji-es"}[e]+".js"),s.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),s.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{const e={},t="Hellotext:";s.l=(i,n,r,a)=>{if(e[i])return void e[i].push(n);let o,c;if(void 0!==r){const e=document.getElementsByTagName("script");for(var l=0;l{o.onerror=o.onload=null,clearTimeout(u);const n=e[i];if(delete e[i],o.parentNode?.removeChild(o),n?.forEach(e=>e(s)),t)return t(s)},u=setTimeout(h.bind(null,void 0,{type:"timeout",target:o}),12e4);o.onerror=h.bind(null,o.onerror),o.onload=h.bind(null,o.onload),c&&document.head.appendChild(o)}})(),s.r=e=>{Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{let e;s.g.importScripts&&(e=s.g.location+"");const t=s.g.document;if(!e&&t&&("SCRIPT"===t.currentScript?.tagName.toUpperCase()&&(e=t.currentScript.src),!e)){const s=t.getElementsByTagName("script");if(s.length){let t=s.length-1;for(;t>-1&&(!e||!/^http(s?):/.test(e));)e=s[t--].src}}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),s.p=e})(),(()=>{const e={792:0};s.f.j=(t,i)=>{let n=s.o(e,t)?e[t]:void 0;if(0!==n)if(n)i.push(n[2]);else{const r=new Promise((s,i)=>n=e[t]=[s,i]);i.push(n[2]=r);const a=s.p+s.u(t),o=new Error,c=i=>{if(s.o(e,t)&&(n=e[t],0!==n&&(e[t]=void 0),n)){const e=i&&("load"===i.type?"missing":i.type),s=i&&i.target&&i.target.src;o.message="Loading chunk "+t+" failed.\n("+e+": "+s+")",o.name="ChunkLoadError",o.type=e,o.request=s,n[1](o)}};s.l(a,c,"chunk-"+t,t)}};const t=(t,i)=>{let[n,r,a]=i;var o,c,l=0;if(n.some(t=>0!==e[t])){for(o in r)s.o(r,o)&&(s.m[o]=r[o]);a&&a(s)}for(t&&t(i);l} Whether the server accepted the interaction. */ static async create({ section, - kind + kind, + page }) { const response = await fetch(this.endpoint, { method: 'POST', @@ -35,7 +37,8 @@ class PushAlertsAPI { body: JSON.stringify({ session: _hellotext.default.session, section, - kind + kind, + page }) }); return new _response.Response(response.ok, response); diff --git a/lib/api/push/alerts.js b/lib/api/push/alerts.js index 76384143..3e191c30 100644 --- a/lib/api/push/alerts.js +++ b/lib/api/push/alerts.js @@ -16,11 +16,13 @@ class PushAlertsAPI { * @param {Object} data - Alert interaction. * @param {import('../../../index').HellotextAlertSection} data.section - Displayed section. * @param {'shown'|'dismissed'|'accepted'} data.kind - Interaction to record. + * @param {{url: string, title: string, path: string}} data.page - Page snapshot from display. * @returns {Promise} Whether the server accepted the interaction. */ static async create({ section, - kind + kind, + page }) { const response = await fetch(this.endpoint, { method: 'POST', @@ -29,7 +31,8 @@ class PushAlertsAPI { body: JSON.stringify({ session: Hellotext.session, section, - kind + kind, + page }) }); return new Response(response.ok, response); diff --git a/lib/controllers/alert_controller.cjs b/lib/controllers/alert_controller.cjs index 94560ab1..12bc25b4 100644 --- a/lib/controllers/alert_controller.cjs +++ b/lib/controllers/alert_controller.cjs @@ -111,6 +111,7 @@ class _default extends _stimulus.Controller { this.primaryActionTarget.textContent = primaryAction ?? section.primary_action; this.secondaryActionTarget.textContent = secondaryAction ?? section.secondary_action; this.kind = kind; + this.page = _hellotext.default.page.trackingData.page; this.element.hidden = false; this.record('shown'); _hellotext.default.eventEmitter.dispatch('alert:shown', { @@ -205,7 +206,8 @@ class _default extends _stimulus.Controller { } /** - * Posts an interaction without delaying display, dismissal, or native permission. + * Posts an interaction with the page snapshot captured when the alert was shown. + * Does not delay display, dismissal, or native permission. * Recording failures leave the alert interaction unchanged. * * @private @@ -216,7 +218,8 @@ class _default extends _stimulus.Controller { try { const response = await _api.default.pushAlerts.create({ section: this.kind, - kind + kind, + page: this.page }); if (response.failed) console.warn('Hellotext Smart Alert submission failed:', response); } catch (error) { diff --git a/lib/controllers/alert_controller.js b/lib/controllers/alert_controller.js index b90feb2c..f957ec36 100644 --- a/lib/controllers/alert_controller.js +++ b/lib/controllers/alert_controller.js @@ -104,6 +104,7 @@ export default class extends Controller { this.primaryActionTarget.textContent = primaryAction ?? section.primary_action; this.secondaryActionTarget.textContent = secondaryAction ?? section.secondary_action; this.kind = kind; + this.page = Hellotext.page.trackingData.page; this.element.hidden = false; this.record('shown'); Hellotext.eventEmitter.dispatch('alert:shown', { @@ -198,7 +199,8 @@ export default class extends Controller { } /** - * Posts an interaction without delaying display, dismissal, or native permission. + * Posts an interaction with the page snapshot captured when the alert was shown. + * Does not delay display, dismissal, or native permission. * Recording failures leave the alert interaction unchanged. * * @private @@ -209,7 +211,8 @@ export default class extends Controller { try { const response = await API.pushAlerts.create({ section: this.kind, - kind + kind, + page: this.page }); if (response.failed) console.warn('Hellotext Smart Alert submission failed:', response); } catch (error) {