@redacto.io/dpdpa-report-sdk-js 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/core/dom.ts","../src/core/state.ts","../src/api/types.ts","../src/api/index.ts","../src/services/storage.ts","../src/styles/inject.ts","../src/form/colors.ts","../src/form/validation.ts","../src/form/view.ts","../src/form/index.ts"],"sourcesContent":["import { FormController } from \"./form\";\nimport { loadLead } from \"./services/storage\";\nimport type { CapturedLead, InitOptions } from \"./types\";\n\nexport const version = \"0.1.0\";\n\nlet activeController: FormController | null = null;\n\nexport function init(options: InitOptions): void {\n destroy();\n activeController = new FormController(options);\n activeController.init().catch((err) => {\n try {\n options.onError?.(\n Object.assign(err instanceof Error ? err : new Error(String(err)), {\n phase: \"validation\" as const,\n })\n );\n } catch (handlerErr) {\n console.error(\"onError handler threw:\", handlerErr);\n }\n });\n}\n\nexport function destroy(): void {\n if (activeController) {\n activeController.destroy();\n activeController = null;\n }\n}\n\nexport function getCapturedLead(): CapturedLead | null {\n return loadLead();\n}\n\nconst RedactoDpdpaReport = { init, destroy, getCapturedLead, version };\nexport default RedactoDpdpaReport;\n\nexport type {\n InitOptions,\n BrandingConfig,\n CapturedLead,\n FormError,\n} from \"./types\";\n","export const DEFAULT_BASE_URL = \"https://salazar.redacto.tech\";\n\nexport const PATHS = {\n submit: \"/webhook/dpdpa/generate\",\n status: \"/webhook/dpdpa/status\",\n} as const;\n\nexport const DEFAULT_POLL_INTERVAL_MS = 3000;\nexport const DEFAULT_POLL_TIMEOUT_MS = 300_000;\nexport const MAX_CONSECUTIVE_ERRORS = 3;\nexport const REQUEST_TIMEOUT_MS = 15_000;\n\nexport const STORAGE_KEY = \"redacto_dpdpa_lead\";\n\nexport const DEFAULT_LOGO_URL = \"https://cdn.redacto.io/assets/redacto-logo.svg\";\n\nexport const DEFAULT_BRAND = {\n name: \"Redacto\",\n primaryColor: \"#4262ff\",\n accentColor: \"#a259ff\",\n textColor: \"#050038\",\n borderColor: \"#e5e5e5\",\n backgroundColor: \"#f7f7f7\",\n borderRadius: \"8px\",\n fontFamily: \"inherit\",\n} as const;\n\nexport const SUCCESS_COLOR = \"#a6c03d\";\nexport const ERROR_COLOR = \"#f24e1e\";\n\nexport const NAME_MIN_LENGTH = 2;\nexport const NAME_MAX_LENGTH = 120;\n\nexport const DOMAIN_REGEX =\n /^(?!-)[a-z0-9-]{1,63}(?<!-)(\\.[a-z0-9-]{1,63})+$/i;\n\nexport const EMAIL_REGEX = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nexport const FREEMAIL_DOMAINS = new Set([\n \"gmail.com\",\n \"googlemail.com\",\n \"yahoo.com\",\n \"yahoo.co.in\",\n \"yahoo.co.uk\",\n \"hotmail.com\",\n \"outlook.com\",\n \"live.com\",\n \"icloud.com\",\n \"me.com\",\n \"aol.com\",\n \"proton.me\",\n \"protonmail.com\",\n \"mail.com\",\n \"gmx.com\",\n \"zoho.com\",\n \"rediffmail.com\",\n]);\n","/**\n * DOM creation helpers — replaces JSX.\n */\n\ntype Attrs = Record<string, any>;\n\n/**\n * Create an HTML element with attributes, styles, events, and children.\n *\n * Attribute keys:\n * - \"style\" → merged into element.style\n * - \"className\" → element.className\n * - \"on...\" → addEventListener (e.g. onClick → \"click\")\n * - \"dataset\" → Object.assign(element.dataset, value)\n * - anything else → setAttribute\n */\nexport function el(\n tag: string,\n attrs?: Attrs | null,\n ...children: (Node | string | null | undefined | false)[]\n): HTMLElement {\n const element = document.createElement(tag);\n if (attrs) applyAttrs(element, attrs);\n appendChildren(element, children);\n return element;\n}\n\n/**\n * Create an SVG element.\n */\nexport function svg(\n tag: string,\n attrs?: Attrs | null,\n ...children: (Node | string | null | undefined | false)[]\n): SVGElement {\n const element = document.createElementNS(\n \"http://www.w3.org/2000/svg\",\n tag\n );\n if (attrs) {\n for (const [key, value] of Object.entries(attrs)) {\n if (value == null || value === false) continue;\n if (key === \"style\" && typeof value === \"object\") {\n applyStyles(element as unknown as HTMLElement, value);\n } else {\n element.setAttribute(key, String(value));\n }\n }\n }\n appendChildren(element as unknown as HTMLElement, children);\n return element;\n}\n\nfunction applyAttrs(element: HTMLElement, attrs: Attrs): void {\n for (const [key, value] of Object.entries(attrs)) {\n if (value == null || value === false) continue;\n\n if (key === \"style\" && typeof value === \"object\") {\n applyStyles(element, value);\n } else if (key === \"className\") {\n element.className = value;\n } else if (key === \"dataset\" && typeof value === \"object\") {\n Object.assign(element.dataset, value);\n } else if (key.startsWith(\"on\") && typeof value === \"function\") {\n const event = key.slice(2).toLowerCase();\n element.addEventListener(event, value);\n } else if (key === \"checked\" || key === \"disabled\" || key === \"readOnly\") {\n (element as any)[key] = value;\n } else {\n element.setAttribute(key, String(value));\n }\n }\n}\n\nconst UNITLESS_PROPS = new Set([\n \"animationIterationCount\",\n \"aspectRatio\",\n \"borderImageOutset\",\n \"borderImageSlice\",\n \"borderImageWidth\",\n \"boxFlex\",\n \"boxFlexGroup\",\n \"boxOrdinalGroup\",\n \"columnCount\",\n \"columns\",\n \"flex\",\n \"flexGrow\",\n \"flexPositive\",\n \"flexShrink\",\n \"flexNegative\",\n \"flexOrder\",\n \"fontWeight\",\n \"gridArea\",\n \"gridRow\",\n \"gridRowEnd\",\n \"gridRowSpan\",\n \"gridRowStart\",\n \"gridColumn\",\n \"gridColumnEnd\",\n \"gridColumnSpan\",\n \"gridColumnStart\",\n \"lineClamp\",\n \"lineHeight\",\n \"opacity\",\n \"order\",\n \"orphans\",\n \"scale\",\n \"tabSize\",\n \"widows\",\n \"zIndex\",\n \"zoom\",\n]);\n\n/**\n * Apply a camelCase style object to an element.\n *\n * Numeric values are interpreted as pixels EXCEPT for unitless properties\n * (fontWeight, lineHeight, opacity, zIndex, …) — appending \"px\" to those\n * produces invalid CSS and the browser falls back to user-agent defaults.\n */\nexport function applyStyles(\n element: HTMLElement,\n styles: Record<string, any>\n): void {\n for (const [key, value] of Object.entries(styles)) {\n if (value == null) continue;\n const stringValue =\n typeof value === \"number\" && !UNITLESS_PROPS.has(key)\n ? `${value}px`\n : String(value);\n (element.style as any)[key] = stringValue;\n }\n}\n\nfunction appendChildren(\n parent: HTMLElement,\n children: (Node | string | null | undefined | false)[]\n): void {\n for (const child of children) {\n if (child == null || child === false) continue;\n if (typeof child === \"string\") {\n parent.appendChild(document.createTextNode(child));\n } else {\n parent.appendChild(child);\n }\n }\n}\n\nexport function clearElement(element: HTMLElement): void {\n while (element.firstChild) {\n element.removeChild(element.firstChild);\n }\n}\n","/**\n * Simple observable store — replaces React useState.\n * Shallow-merges updates and notifies subscribers.\n */\n\nexport type Listener<T> = (state: T, prevState: T) => void;\n\nexport class Store<T extends Record<string, any>> {\n private state: T;\n private listeners: Set<Listener<T>> = new Set();\n\n constructor(initialState: T) {\n this.state = { ...initialState };\n }\n\n getState(): Readonly<T> {\n return { ...this.state };\n }\n\n setState(partial: Partial<T>): void {\n const prevState = this.state;\n this.state = { ...this.state, ...partial };\n this.listeners.forEach((listener) => listener(this.state, prevState));\n }\n\n subscribe(listener: Listener<T>): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n destroy(): void {\n this.listeners.clear();\n }\n}\n","export type SubmitRequest = {\n company_name: string;\n company_domain: string;\n};\n\nexport type SubmitSuccess = {\n status: \"accepted\";\n job_id: string;\n};\n\nexport type SubmitError = {\n status: \"error\";\n message: string;\n};\n\nexport type SubmitResponse = SubmitSuccess | SubmitError;\n\nexport type StatusInProgress = {\n job_id: string;\n status: \"pending\" | \"researching\" | \"analysis_complete\";\n company_name: string;\n};\n\nexport type StatusComplete = {\n job_id: string;\n status: \"complete\";\n company_name: string;\n report_url: string;\n};\n\nexport type StatusErrorShape = {\n status: \"error\";\n message: string;\n};\n\nexport type StatusResponse = StatusInProgress | StatusComplete | StatusErrorShape;\n\nexport class ApiError extends Error {\n status?: number;\n constructor(message: string, status?: number) {\n super(message);\n this.name = \"ApiError\";\n this.status = status;\n }\n}\n","import { PATHS, REQUEST_TIMEOUT_MS } from \"../constants\";\nimport { ApiError } from \"./types\";\nimport type { SubmitRequest, SubmitResponse, StatusResponse } from \"./types\";\n\ntype SubmitArgs = {\n baseUrl: string;\n body: SubmitRequest;\n};\n\ntype StatusArgs = {\n baseUrl: string;\n jobId: string;\n};\n\nfunction timedFetch(url: string, init: RequestInit = {}): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);\n return fetch(url, { ...init, signal: controller.signal }).finally(() =>\n clearTimeout(timer)\n );\n}\n\nfunction toNetworkError(err: unknown): ApiError {\n if (err instanceof DOMException && err.name === \"AbortError\") {\n return new ApiError(\"Request timed out\", undefined);\n }\n return new ApiError(\n err instanceof Error ? err.message : \"Network error\",\n undefined\n );\n}\n\nexport async function submitLead({\n baseUrl,\n body,\n}: SubmitArgs): Promise<SubmitResponse> {\n let res: Response;\n try {\n res = await timedFetch(`${baseUrl}${PATHS.submit}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n } catch (err) {\n throw toNetworkError(err);\n }\n\n let json: SubmitResponse;\n try {\n json = (await res.json()) as SubmitResponse;\n } catch {\n throw new ApiError(`Unexpected response (HTTP ${res.status})`, res.status);\n }\n\n if (!res.ok) {\n const message =\n json && \"message\" in json && json.message\n ? json.message\n : `Request failed (HTTP ${res.status})`;\n throw new ApiError(message, res.status);\n }\n\n return json;\n}\n\nexport async function fetchJobStatus({\n baseUrl,\n jobId,\n}: StatusArgs): Promise<StatusResponse> {\n const url = `${baseUrl}${PATHS.status}?job_id=${encodeURIComponent(jobId)}`;\n let res: Response;\n try {\n res = await timedFetch(url, { method: \"GET\" });\n } catch (err) {\n throw toNetworkError(err);\n }\n\n let json: StatusResponse;\n try {\n json = (await res.json()) as StatusResponse;\n } catch {\n throw new ApiError(`Unexpected response (HTTP ${res.status})`, res.status);\n }\n\n if (!res.ok) {\n const message =\n json && \"message\" in json && json.message\n ? json.message\n : `Status check failed (HTTP ${res.status})`;\n throw new ApiError(message, res.status);\n }\n\n return json;\n}\n","import { STORAGE_KEY } from \"../constants\";\nimport type { CapturedLead } from \"../types\";\n\nconst isBrowser = (): boolean =>\n typeof window !== \"undefined\" && typeof window.localStorage !== \"undefined\";\n\nexport const saveLead = (lead: CapturedLead): void => {\n if (!isBrowser()) return;\n try {\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(lead));\n } catch (error) {\n console.error(\"Failed to save lead:\", error);\n }\n};\n\nconst isCapturedLead = (v: unknown): v is CapturedLead => {\n if (!v || typeof v !== \"object\") return false;\n const o = v as Record<string, unknown>;\n return (\n typeof o.email === \"string\" &&\n typeof o.company_name === \"string\" &&\n typeof o.company_domain === \"string\" &&\n (o.job_id === null || typeof o.job_id === \"string\") &&\n typeof o.timestamp === \"string\"\n );\n};\n\nexport const loadLead = (): CapturedLead | null => {\n if (!isBrowser()) return null;\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n return isCapturedLead(parsed) ? parsed : null;\n } catch (error) {\n console.error(\"Failed to load lead:\", error);\n return null;\n }\n};\n\nexport const clearLead = (): void => {\n if (!isBrowser()) return;\n try {\n window.localStorage.removeItem(STORAGE_KEY);\n } catch (error) {\n console.error(\"Failed to clear lead:\", error);\n }\n};\n","import type { ResolvedBrand } from \"../form/colors\";\n\nconst STYLE_ID = \"redacto-dpdpa-form-styles\";\n\nfunction buildCss(brand: ResolvedBrand): string {\n return `\n :host {\n display: block;\n width: 100%;\n container-type: inline-size;\n container-name: dpdpa-card;\n }\n\n :host, :host > *, :host *, :host *::before, :host *::after {\n box-sizing: border-box;\n }\n\n .dpdpa-card {\n box-sizing: border-box;\n width: 100%;\n min-height: 520px;\n display: flex;\n flex-direction: column;\n padding: 28px 24px;\n background: ${brand.background};\n color: ${brand.text};\n border: 1px solid ${brand.border};\n border-radius: ${brand.borderRadius};\n font-family: ${brand.fontFamily};\n font-size: 15px;\n line-height: 1.5;\n text-align: left;\n }\n\n @container dpdpa-card (max-width: 420px) {\n .dpdpa-card {\n padding: 20px 16px;\n min-height: 480px;\n }\n .dpdpa-heading {\n font-size: 18px;\n }\n .dpdpa-success-title,\n .dpdpa-error-title {\n font-size: 16px;\n }\n .dpdpa-header {\n margin-bottom: 16px;\n }\n }\n\n @supports not (container-type: inline-size) {\n @media (max-width: 480px) {\n .dpdpa-card {\n padding: 20px 16px;\n }\n .dpdpa-heading {\n font-size: 18px;\n }\n }\n }\n\n .dpdpa-header {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 10px;\n margin-bottom: 20px;\n }\n\n .dpdpa-logo {\n max-height: 28px;\n max-width: 140px;\n display: inline-block;\n object-fit: contain;\n }\n\n .dpdpa-wordmark {\n font-weight: 700;\n font-size: 17px;\n color: ${brand.text};\n letter-spacing: 0.3px;\n }\n\n .dpdpa-footer {\n margin-top: 20px;\n padding-top: 16px;\n border-top: 1px solid ${brand.border};\n font-size: 12px;\n color: ${brand.text};\n opacity: 0.7;\n text-align: center;\n }\n\n .dpdpa-form {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n gap: 14px;\n margin: 0;\n }\n\n .dpdpa-heading {\n font-size: 20px;\n font-weight: 700;\n margin: 0 0 4px;\n color: ${brand.text};\n line-height: 1.3;\n }\n\n .dpdpa-subheading {\n margin: 0 0 8px;\n font-size: 14px;\n color: ${brand.text};\n opacity: 0.75;\n }\n\n .dpdpa-field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n .dpdpa-label {\n font-size: 13px;\n font-weight: 600;\n color: ${brand.text};\n }\n\n .dpdpa-input {\n width: 100%;\n min-width: 0;\n padding: 11px 13px;\n font-family: inherit;\n font-size: 14px;\n color: ${brand.text};\n background: #ffffff;\n border: 1px solid ${brand.border};\n border-radius: ${brand.borderRadius};\n outline: none;\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\n }\n\n .dpdpa-input:focus {\n border-color: ${brand.primary};\n box-shadow: 0 0 0 3px ${brand.primaryFocus};\n }\n\n .dpdpa-input:disabled {\n background: ${brand.border};\n opacity: 0.7;\n cursor: not-allowed;\n }\n\n .dpdpa-field-error,\n .dpdpa-general-error {\n font-size: 12px;\n color: ${brand.errorColor};\n line-height: 1.4;\n }\n\n .dpdpa-general-error {\n padding: 10px 12px;\n background: ${brand.errorColor}14;\n border: 1px solid ${brand.errorColor}33;\n border-radius: ${brand.borderRadius};\n }\n\n .dpdpa-btn-primary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 8px;\n width: 100%;\n padding: 12px 18px;\n font-family: inherit;\n font-size: 15px;\n font-weight: 600;\n color: ${brand.primaryText};\n background: ${brand.primary};\n border: none;\n border-radius: ${brand.borderRadius};\n cursor: pointer;\n text-decoration: none;\n transition: background-color 0.15s ease, transform 0.05s ease;\n margin-top: 6px;\n }\n\n .dpdpa-btn-primary:hover:not(:disabled) {\n background: ${brand.primaryHover};\n }\n\n .dpdpa-btn-primary:active:not(:disabled) {\n transform: translateY(1px);\n }\n\n .dpdpa-btn-primary:disabled {\n opacity: 0.7;\n cursor: not-allowed;\n }\n\n .dpdpa-btn-link {\n text-decoration: none;\n color: ${brand.primaryText};\n }\n\n .dpdpa-spinner {\n display: inline-block;\n border-radius: 50%;\n border-style: solid;\n border-color: ${brand.primaryText}4D;\n animation: dpdpa-spin 0.7s linear infinite;\n }\n\n .dpdpa-spinner-inline {\n width: 14px;\n height: 14px;\n border-width: 2px;\n border-top-color: ${brand.primaryText};\n }\n\n .dpdpa-polling {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n padding: 4px 2px 8px;\n gap: 16px;\n }\n\n .dpdpa-polling-sub {\n margin: 0;\n font-size: 13px;\n color: ${brand.text};\n opacity: 0.6;\n text-align: center;\n }\n\n .dpdpa-steps {\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n\n .dpdpa-step {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 15px;\n animation: dpdpa-step-in 0.35s ease-out both;\n }\n\n .dpdpa-step-done .dpdpa-step-label {\n color: ${brand.text};\n opacity: 0.6;\n }\n\n .dpdpa-step-icon {\n flex: none;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n }\n\n .dpdpa-step-icon-active {\n position: relative;\n width: 10px;\n height: 10px;\n margin: 0 4px;\n box-shadow: 0 0 0 0 ${brand.primaryFocus};\n animation: dpdpa-pulse 1.4s ease-out infinite;\n }\n\n .dpdpa-step-label {\n color: ${brand.text};\n font-weight: 500;\n word-break: break-word;\n }\n\n .dpdpa-shimmer {\n background: linear-gradient(\n 90deg,\n ${brand.text} 0%,\n ${brand.primary} 40%,\n ${brand.accent} 50%,\n ${brand.primary} 60%,\n ${brand.text} 100%\n );\n background-size: 200% 100%;\n -webkit-background-clip: text;\n background-clip: text;\n -webkit-text-fill-color: transparent;\n color: transparent;\n animation: dpdpa-shimmer 2.2s linear infinite;\n }\n\n .dpdpa-dots {\n display: inline-flex;\n align-items: center;\n gap: 3px;\n margin-left: 2px;\n }\n\n .dpdpa-dots > span {\n width: 4px;\n height: 4px;\n border-radius: 50%;\n background: ${brand.primary};\n opacity: 0.4;\n animation: dpdpa-dot-bounce 1.2s ease-in-out infinite;\n }\n\n .dpdpa-dots > span:nth-child(2) { animation-delay: 0.15s; }\n .dpdpa-dots > span:nth-child(3) { animation-delay: 0.3s; }\n\n @keyframes dpdpa-shimmer {\n from { background-position: 200% 0; }\n to { background-position: -200% 0; }\n }\n\n @keyframes dpdpa-dot-bounce {\n 0%, 80%, 100% { opacity: 0.3; transform: translateY(0); }\n 40% { opacity: 1; transform: translateY(-3px); }\n }\n\n @keyframes dpdpa-pulse {\n 0% { box-shadow: 0 0 0 0 ${brand.primaryFocus}; }\n 70% { box-shadow: 0 0 0 8px rgba(0, 0, 0, 0); }\n 100% { box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); }\n }\n\n @keyframes dpdpa-step-in {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n .dpdpa-progress {\n width: 100%;\n height: 6px;\n background: ${brand.border};\n border-radius: 999px;\n overflow: hidden;\n margin-top: 4px;\n }\n\n .dpdpa-progress-fill {\n height: 100%;\n background: linear-gradient(to right, ${brand.primary}, ${brand.accent});\n transition: width 0.5s ease;\n }\n\n .dpdpa-success {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n text-align: center;\n gap: 12px;\n padding: 8px 4px;\n }\n\n .dpdpa-check-circle {\n width: 56px;\n height: 56px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .dpdpa-success-title {\n margin: 0;\n font-size: 18px;\n font-weight: 700;\n color: ${brand.text};\n line-height: 1.35;\n }\n\n .dpdpa-success-sub {\n margin: 0;\n font-size: 14px;\n color: ${brand.text};\n opacity: 0.75;\n }\n\n .dpdpa-reset-link {\n font-size: 13px;\n color: ${brand.primary};\n text-decoration: none;\n margin-top: 4px;\n cursor: pointer;\n }\n\n .dpdpa-reset-link:hover {\n text-decoration: underline;\n }\n\n .dpdpa-error-view {\n flex: 1;\n display: flex;\n flex-direction: column;\n justify-content: center;\n gap: 12px;\n text-align: center;\n padding: 8px 4px;\n }\n\n .dpdpa-error-title {\n margin: 0;\n font-size: 18px;\n font-weight: 700;\n color: ${brand.errorColor};\n }\n\n .dpdpa-error-message {\n margin: 0;\n font-size: 14px;\n color: ${brand.text};\n }\n\n @keyframes dpdpa-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n `;\n}\n\nexport function injectFormStyles(\n root: ShadowRoot,\n brand: ResolvedBrand\n): void {\n if (typeof document === \"undefined\") return;\n if (root.querySelector(`#${STYLE_ID}`)) return;\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = buildCss(brand);\n root.appendChild(style);\n}\n","import {\n DEFAULT_BRAND,\n DEFAULT_LOGO_URL,\n SUCCESS_COLOR,\n ERROR_COLOR,\n} from \"../constants\";\nimport type { BrandingConfig } from \"../types\";\n\nexport type ResolvedBrand = {\n logo: string;\n name: string;\n primary: string;\n accent: string;\n primaryHover: string;\n primaryFocus: string;\n primaryText: string;\n text: string;\n border: string;\n background: string;\n borderRadius: string;\n fontFamily: string;\n successColor: string;\n errorColor: string;\n};\n\nconst HEX_RE = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i;\n\nfunction normalizeHex(hex: string | undefined, fallback: string): string {\n if (!hex || !HEX_RE.test(hex.trim())) return fallback;\n return hex.trim();\n}\n\nfunction hexToRgb(hex: string): { r: number; g: number; b: number } {\n const h = hex.replace(\"#\", \"\").trim();\n const full = h.length === 3 ? h.split(\"\").map((c) => c + c).join(\"\") : h;\n return {\n r: parseInt(full.slice(0, 2), 16),\n g: parseInt(full.slice(2, 4), 16),\n b: parseInt(full.slice(4, 6), 16),\n };\n}\n\nfunction darken(hex: string, amount: number): string {\n const { r, g, b } = hexToRgb(hex);\n const d = (c: number) => Math.max(0, Math.round(c * (1 - amount)));\n return `rgb(${d(r)}, ${d(g)}, ${d(b)})`;\n}\n\nfunction rgba(hex: string, alpha: number): string {\n const { r, g, b } = hexToRgb(hex);\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n}\n\n/** Relative luminance per WCAG; returns 0..1. */\nfunction relativeLuminance(hex: string): number {\n const { r, g, b } = hexToRgb(hex);\n const norm = (c: number) => {\n const s = c / 255;\n return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);\n };\n return 0.2126 * norm(r) + 0.7152 * norm(g) + 0.0722 * norm(b);\n}\n\n/** Returns \"#ffffff\" or \"#050038\" — whichever has better contrast on `bg`. */\nexport function contrastingTextOn(bg: string): string {\n return relativeLuminance(bg) > 0.55 ? \"#050038\" : \"#ffffff\";\n}\n\nexport function resolveBranding(b?: BrandingConfig): ResolvedBrand {\n const primary = normalizeHex(b?.primaryColor, DEFAULT_BRAND.primaryColor);\n const accent = normalizeHex(\n b?.accentColor ?? b?.primaryColor,\n DEFAULT_BRAND.accentColor\n );\n return {\n logo: b?.logo || DEFAULT_LOGO_URL,\n name: b?.name || DEFAULT_BRAND.name,\n primary,\n accent,\n primaryHover: darken(primary, 0.08),\n primaryFocus: rgba(primary, 0.3),\n primaryText: contrastingTextOn(primary),\n text: b?.textColor || DEFAULT_BRAND.textColor,\n border: b?.borderColor || DEFAULT_BRAND.borderColor,\n background: b?.backgroundColor || DEFAULT_BRAND.backgroundColor,\n borderRadius: b?.borderRadius || DEFAULT_BRAND.borderRadius,\n fontFamily: b?.fontFamily || DEFAULT_BRAND.fontFamily,\n successColor: SUCCESS_COLOR,\n errorColor: ERROR_COLOR,\n };\n}\n","import {\n DOMAIN_REGEX,\n EMAIL_REGEX,\n FREEMAIL_DOMAINS,\n NAME_MAX_LENGTH,\n NAME_MIN_LENGTH,\n} from \"../constants\";\n\nexport type Fields = {\n company_name: string;\n company_domain: string;\n email: string;\n};\n\nexport type FieldErrors = Partial<Record<keyof Fields, string>>;\n\nexport function normalizeDomain(raw: string): string {\n return raw\n .trim()\n .toLowerCase()\n .replace(/^https?:\\/\\//, \"\")\n .replace(/^www\\./, \"\")\n .replace(/\\/.*$/, \"\");\n}\n\nexport function validateField(\n field: keyof Fields,\n rawValue: string\n): string | null {\n const value = rawValue.trim();\n switch (field) {\n case \"company_name\": {\n if (value.length < NAME_MIN_LENGTH) return \"Please enter a company name\";\n if (value.length > NAME_MAX_LENGTH) return \"Company name is too long\";\n return null;\n }\n case \"company_domain\": {\n if (!value) return \"Enter your company domain\";\n const normalized = normalizeDomain(value);\n if (!DOMAIN_REGEX.test(normalized))\n return \"Enter a valid domain like example.com\";\n return null;\n }\n case \"email\": {\n if (!value) return \"Enter your work email\";\n if (!EMAIL_REGEX.test(value)) return \"Enter a valid email\";\n const domain = value.split(\"@\")[1]?.toLowerCase();\n if (domain && FREEMAIL_DOMAINS.has(domain))\n return \"Please use your work email\";\n return null;\n }\n }\n}\n\nexport function validateAll(fields: Fields): FieldErrors {\n const errors: FieldErrors = {};\n (Object.keys(fields) as (keyof Fields)[]).forEach((key) => {\n const err = validateField(key, fields[key]);\n if (err) errors[key] = err;\n });\n return errors;\n}\n","import { el, svg } from \"../core/dom\";\nimport type { ResolvedBrand } from \"./colors\";\nimport type { Fields, FieldErrors } from \"./validation\";\n\ntype IdleHandlers = {\n onInput: (field: keyof Fields, value: string) => void;\n onBlur: (field: keyof Fields) => void;\n onSubmit: () => void;\n};\n\nexport type IdleRefs = {\n root: HTMLElement;\n fieldInputs: Record<keyof Fields, HTMLInputElement>;\n fieldErrors: Record<keyof Fields, HTMLElement>;\n submitBtn: HTMLButtonElement;\n generalError: HTMLElement;\n};\n\nfunction header(brand: ResolvedBrand): HTMLElement {\n const logoImg = el(\"img\", {\n src: brand.logo,\n alt: `${brand.name} logo`,\n className: \"dpdpa-logo\",\n onerror: (ev: Event) => {\n const img = ev.currentTarget as HTMLImageElement;\n img.style.display = \"none\";\n const wordmark = img.nextElementSibling as HTMLElement | null;\n if (wordmark) wordmark.style.display = \"inline-block\";\n },\n }) as HTMLImageElement;\n\n const wordmark = el(\n \"span\",\n { className: \"dpdpa-wordmark\", style: { display: \"none\" } },\n brand.name\n );\n\n return el(\"div\", { className: \"dpdpa-header\" }, logoImg, wordmark);\n}\n\nfunction inputRow(\n brand: ResolvedBrand,\n opts: {\n field: keyof Fields;\n label: string;\n type: string;\n placeholder: string;\n value: string;\n error: string | undefined;\n autocomplete?: string;\n onInput: (value: string) => void;\n onBlur: () => void;\n }\n): { row: HTMLElement; input: HTMLInputElement; errorSlot: HTMLElement } {\n const inputEl = el(\"input\", {\n type: opts.type,\n className: \"dpdpa-input\",\n placeholder: opts.placeholder,\n value: opts.value,\n autocomplete: opts.autocomplete,\n \"aria-label\": opts.label,\n onInput: (ev: Event) => opts.onInput((ev.currentTarget as HTMLInputElement).value),\n onBlur: () => opts.onBlur(),\n }) as HTMLInputElement;\n\n const errorSlot = el(\n \"div\",\n {\n className: \"dpdpa-field-error\",\n role: \"alert\",\n style: { display: opts.error ? \"block\" : \"none\" },\n },\n opts.error || \"\"\n );\n\n const labelEl = el(\"label\", { className: \"dpdpa-label\" }, opts.label);\n\n const row = el(\n \"div\",\n { className: \"dpdpa-field\" },\n labelEl,\n inputEl,\n errorSlot\n );\n\n return { row, input: inputEl, errorSlot };\n}\n\nfunction footer(brand: ResolvedBrand): HTMLElement {\n return el(\n \"div\",\n { className: \"dpdpa-footer\" },\n \"Powered by \",\n el(\"strong\", null, brand.name)\n );\n}\n\nexport function renderIdle(\n brand: ResolvedBrand,\n fields: Fields,\n errors: FieldErrors,\n generalErrorText: string | null,\n handlers: IdleHandlers\n): IdleRefs {\n const nameRow = inputRow(brand, {\n field: \"company_name\",\n label: \"Company name\",\n type: \"text\",\n placeholder: \"Acme Inc\",\n value: fields.company_name,\n error: errors.company_name,\n autocomplete: \"organization\",\n onInput: (v) => handlers.onInput(\"company_name\", v),\n onBlur: () => handlers.onBlur(\"company_name\"),\n });\n const domainRow = inputRow(brand, {\n field: \"company_domain\",\n label: \"Company domain\",\n type: \"text\",\n placeholder: \"acme.com\",\n value: fields.company_domain,\n error: errors.company_domain,\n autocomplete: \"url\",\n onInput: (v) => handlers.onInput(\"company_domain\", v),\n onBlur: () => handlers.onBlur(\"company_domain\"),\n });\n const emailRow = inputRow(brand, {\n field: \"email\",\n label: \"Work email\",\n type: \"email\",\n placeholder: \"you@acme.com\",\n value: fields.email,\n error: errors.email,\n autocomplete: \"email\",\n onInput: (v) => handlers.onInput(\"email\", v),\n onBlur: () => handlers.onBlur(\"email\"),\n });\n\n const generalError = el(\n \"div\",\n {\n className: \"dpdpa-general-error\",\n role: \"alert\",\n style: { display: generalErrorText ? \"block\" : \"none\" },\n },\n generalErrorText || \"\"\n );\n\n const submitBtn = el(\n \"button\",\n {\n type: \"submit\",\n className: \"dpdpa-btn-primary\",\n },\n \"Get my free report\"\n ) as HTMLButtonElement;\n\n const form = el(\n \"form\",\n {\n className: \"dpdpa-form\",\n novalidate: \"true\",\n onSubmit: (ev: Event) => {\n ev.preventDefault();\n handlers.onSubmit();\n },\n },\n el(\n \"h2\",\n { className: \"dpdpa-heading\" },\n \"Get your free DPDPA compliance report\"\n ),\n el(\n \"p\",\n { className: \"dpdpa-subheading\" },\n \"We'll analyse your site and deliver a compliance assessment PDF.\"\n ),\n generalError,\n nameRow.row,\n domainRow.row,\n emailRow.row,\n submitBtn\n );\n\n const card = el(\n \"div\",\n { className: \"dpdpa-card\" },\n header(brand),\n form,\n footer(brand)\n );\n\n return {\n root: card,\n fieldInputs: {\n company_name: nameRow.input,\n company_domain: domainRow.input,\n email: emailRow.input,\n },\n fieldErrors: {\n company_name: nameRow.errorSlot,\n company_domain: domainRow.errorSlot,\n email: emailRow.errorSlot,\n },\n submitBtn,\n generalError,\n };\n}\n\nexport function renderSubmitting(\n brand: ResolvedBrand,\n fields: Fields\n): HTMLElement {\n const refs = renderIdle(brand, fields, {}, null, {\n onInput: () => {},\n onBlur: () => {},\n onSubmit: () => {},\n });\n Object.values(refs.fieldInputs).forEach((inp) => {\n inp.disabled = true;\n });\n refs.submitBtn.disabled = true;\n refs.submitBtn.textContent = \"\";\n refs.submitBtn.appendChild(\n el(\"span\", { className: \"dpdpa-spinner dpdpa-spinner-inline\" })\n );\n refs.submitBtn.appendChild(document.createTextNode(\" Submitting…\"));\n return refs.root;\n}\n\nfunction animatedDots(): HTMLElement {\n return el(\n \"span\",\n { className: \"dpdpa-dots\", \"aria-hidden\": \"true\" },\n el(\"span\"),\n el(\"span\"),\n el(\"span\")\n );\n}\n\nfunction stepCheck(brand: ResolvedBrand): HTMLElement {\n return el(\n \"div\",\n {\n className: \"dpdpa-step-icon dpdpa-step-icon-done\",\n style: { backgroundColor: brand.successColor },\n },\n svg(\n \"svg\",\n { width: 12, height: 12, viewBox: \"0 0 24 24\", fill: \"none\" },\n svg(\"path\", {\n d: \"M5 12l5 5L20 7\",\n stroke: \"#ffffff\",\n \"stroke-width\": 3,\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n })\n )\n );\n}\n\nfunction stepPulse(brand: ResolvedBrand): HTMLElement {\n return el(\"div\", {\n className: \"dpdpa-step-icon dpdpa-step-icon-active\",\n style: { backgroundColor: brand.primary },\n });\n}\n\ntype PollStatus = \"pending\" | \"researching\" | \"analysis_complete\";\n\nconst STEP_ORDER: Record<PollStatus, number> = {\n pending: 0,\n researching: 0,\n analysis_complete: 2,\n};\n\nconst STEPS: Array<{ label: (company: string) => string }> = [\n { label: (company) => `Researching ${company}` },\n { label: () => \"Analysing DPDPA compliance\" },\n { label: () => \"Generating your report\" },\n];\n\nexport function renderPolling(\n brand: ResolvedBrand,\n opts: {\n companyName: string;\n subStatus: PollStatus;\n elapsedMs: number;\n pollTimeoutMs: number;\n }\n): HTMLElement {\n const pct = Math.min(100, Math.round((opts.elapsedMs / opts.pollTimeoutMs) * 100));\n const progressFill = el(\"div\", {\n className: \"dpdpa-progress-fill\",\n style: { width: `${pct}%` },\n });\n const progressBar = el(\n \"div\",\n {\n className: \"dpdpa-progress\",\n role: \"progressbar\",\n \"aria-label\": \"Report generation progress\",\n \"aria-valuemin\": \"0\",\n \"aria-valuemax\": \"100\",\n \"aria-valuenow\": String(pct),\n },\n progressFill\n );\n\n const currentIdx = STEP_ORDER[opts.subStatus];\n const stepsList = el(\"div\", { className: \"dpdpa-steps\" });\n STEPS.forEach((step, idx) => {\n if (idx > currentIdx) return;\n const isActive = idx === currentIdx;\n const row = el(\n \"div\",\n {\n className: `dpdpa-step ${isActive ? \"dpdpa-step-active\" : \"dpdpa-step-done\"}`,\n },\n isActive ? stepPulse(brand) : stepCheck(brand),\n el(\n \"span\",\n {\n className: isActive\n ? \"dpdpa-step-label dpdpa-shimmer\"\n : \"dpdpa-step-label\",\n },\n step.label(opts.companyName)\n )\n );\n if (isActive) row.appendChild(animatedDots());\n stepsList.appendChild(row);\n });\n\n const body = el(\n \"div\",\n { className: \"dpdpa-polling\" },\n stepsList,\n el(\n \"p\",\n { className: \"dpdpa-polling-sub\" },\n \"This usually takes 60 to 120 seconds. Keep this tab open.\"\n ),\n progressBar\n );\n\n return el(\"div\", { className: \"dpdpa-card\" }, header(brand), body, footer(brand));\n}\n\nfunction checkIcon(brand: ResolvedBrand): HTMLElement {\n return el(\n \"div\",\n {\n className: \"dpdpa-check-circle\",\n style: { backgroundColor: brand.successColor },\n },\n svg(\n \"svg\",\n {\n width: 28,\n height: 28,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n },\n svg(\"path\", {\n d: \"M5 12l5 5L20 7\",\n stroke: \"#ffffff\",\n \"stroke-width\": 3,\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n })\n )\n );\n}\n\nfunction isSafeUrl(raw: string): boolean {\n const s = (raw || \"\").trim();\n if (!s) return false;\n // Allow relative paths or absolute http(s) URLs only.\n if (/^https?:\\/\\//i.test(s)) return true;\n if (/^\\/[^/]/.test(s) || s.startsWith(\"./\") || s.startsWith(\"../\"))\n return true;\n return false;\n}\n\nexport function renderComplete(\n brand: ResolvedBrand,\n opts: {\n companyName: string;\n reportUrl: string;\n onReset: () => void;\n }\n): HTMLElement {\n const safeHref = isSafeUrl(opts.reportUrl) ? opts.reportUrl : \"#\";\n const downloadBtn = el(\n \"a\",\n {\n href: safeHref,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n className: \"dpdpa-btn-primary dpdpa-btn-link\",\n },\n \"Download PDF\"\n );\n\n const resetLink = el(\n \"a\",\n {\n href: \"#\",\n className: \"dpdpa-reset-link\",\n onClick: (ev: Event) => {\n ev.preventDefault();\n opts.onReset();\n },\n },\n \"Request another report\"\n );\n\n const body = el(\n \"div\",\n { className: \"dpdpa-success\" },\n checkIcon(brand),\n el(\n \"h3\",\n { className: \"dpdpa-success-title\" },\n `Your DPDPA report for ${opts.companyName} is ready`\n ),\n el(\n \"p\",\n { className: \"dpdpa-success-sub\" },\n \"Click below to download your compliance assessment PDF.\"\n ),\n downloadBtn,\n resetLink\n );\n\n return el(\"div\", { className: \"dpdpa-card\" }, header(brand), body, footer(brand));\n}\n\nexport function renderError(\n brand: ResolvedBrand,\n opts: {\n message: string;\n retryable: boolean;\n onRetry: () => void;\n onBack: () => void;\n }\n): HTMLElement {\n const retryBtn = el(\n \"button\",\n {\n type: \"button\",\n className: \"dpdpa-btn-primary\",\n onClick: () => (opts.retryable ? opts.onRetry() : opts.onBack()),\n },\n opts.retryable ? \"Try again\" : \"Edit details\"\n );\n\n const body = el(\n \"div\",\n { className: \"dpdpa-error-view\" },\n el(\"h3\", { className: \"dpdpa-error-title\" }, \"Something went wrong\"),\n el(\"p\", { className: \"dpdpa-error-message\" }, opts.message),\n retryBtn\n );\n\n return el(\"div\", { className: \"dpdpa-card\" }, header(brand), body, footer(brand));\n}\n","import {\n DEFAULT_BASE_URL,\n DEFAULT_POLL_INTERVAL_MS,\n DEFAULT_POLL_TIMEOUT_MS,\n MAX_CONSECUTIVE_ERRORS,\n} from \"../constants\";\nimport { clearElement } from \"../core/dom\";\nimport { Store } from \"../core/state\";\nimport { fetchJobStatus, submitLead } from \"../api\";\nimport { ApiError } from \"../api/types\";\nimport { saveLead } from \"../services/storage\";\nimport { injectFormStyles } from \"../styles/inject\";\nimport type { CapturedLead, FormError, InitOptions } from \"../types\";\nimport type { ResolvedBrand } from \"./colors\";\nimport { resolveBranding } from \"./colors\";\nimport type { Fields, FieldErrors } from \"./validation\";\nimport { normalizeDomain, validateAll, validateField } from \"./validation\";\nimport {\n renderComplete,\n renderError,\n renderIdle,\n renderPolling,\n renderSubmitting,\n type IdleRefs,\n} from \"./view\";\n\ntype Phase = \"idle\" | \"submitting\" | \"polling\" | \"complete\" | \"error\";\n\ntype StoreShape = {\n phase: Phase;\n subStatus: \"pending\" | \"researching\" | \"analysis_complete\";\n elapsedMs: number;\n jobId: string | null;\n reportUrl: string | null;\n errors: FieldErrors;\n generalError: string | null;\n errorMessage: string;\n retryable: boolean;\n};\n\nconst EMPTY_FIELDS: Fields = {\n company_name: \"\",\n company_domain: \"\",\n email: \"\",\n};\n\nexport class FormController {\n private options: InitOptions;\n private brand: ResolvedBrand;\n private store: Store<StoreShape>;\n private fields: Fields;\n private targetEl: HTMLElement | null = null;\n private hostEl: HTMLElement | null = null;\n private shadowRoot: ShadowRoot | null = null;\n private idleRefs: IdleRefs | null = null;\n private pollTimer: ReturnType<typeof setTimeout> | null = null;\n private pollStartedAt: number = 0;\n private pollHiddenSince: number | null = null;\n private pollHiddenTotalMs = 0;\n private pollResumePending = false;\n private lastSubStatus: \"pending\" | \"researching\" | \"analysis_complete\" | null = null;\n private consecutiveErrors = 0;\n private destroyed = false;\n private unsubscribe: (() => void) | null = null;\n private visibilityHandler: (() => void) | null = null;\n\n constructor(options: InitOptions) {\n this.options = options;\n this.brand = resolveBranding(options.branding);\n this.fields = { ...EMPTY_FIELDS };\n this.store = new Store<StoreShape>({\n phase: \"idle\",\n subStatus: \"pending\",\n elapsedMs: 0,\n jobId: null,\n reportUrl: null,\n errors: {},\n generalError: null,\n errorMessage: \"\",\n retryable: true,\n });\n }\n\n async init(): Promise<void> {\n if (typeof this.options.target === \"string\") {\n const found = document.querySelector(this.options.target);\n if (!found)\n throw new Error(\n `DPDPA report form: target element not found for selector \"${this.options.target}\"`\n );\n this.targetEl = found as HTMLElement;\n } else {\n this.targetEl = this.options.target;\n }\n\n this.hostEl = document.createElement(\"div\");\n this.hostEl.setAttribute(\"data-redacto-dpdpa-report\", \"\");\n this.hostEl.style.display = \"block\";\n this.targetEl.appendChild(this.hostEl);\n\n this.shadowRoot = this.hostEl.attachShadow({ mode: \"open\" });\n injectFormStyles(this.shadowRoot, this.brand);\n\n this.unsubscribe = this.store.subscribe((state, prev) => {\n if (state.phase !== prev.phase) this.render();\n else if (\n state.phase === \"polling\" &&\n state.subStatus !== prev.subStatus\n )\n this.render();\n else if (state.phase === \"polling\" && state.elapsedMs !== prev.elapsedMs)\n this.updateProgress();\n });\n\n this.visibilityHandler = () => this.handleVisibilityChange();\n document.addEventListener(\"visibilitychange\", this.visibilityHandler);\n\n this.render();\n }\n\n destroy(): void {\n this.destroyed = true;\n this.clearPolling();\n this.unsubscribe?.();\n this.unsubscribe = null;\n if (this.visibilityHandler) {\n document.removeEventListener(\"visibilitychange\", this.visibilityHandler);\n this.visibilityHandler = null;\n }\n this.store.destroy();\n if (this.hostEl && this.hostEl.parentNode)\n this.hostEl.parentNode.removeChild(this.hostEl);\n this.hostEl = null;\n this.shadowRoot = null;\n this.targetEl = null;\n this.idleRefs = null;\n }\n\n private render(): void {\n if (!this.shadowRoot) return;\n clearElement(this.shadowRoot as unknown as HTMLElement);\n // Re-inject styles — injectFormStyles is a no-op if already present.\n injectFormStyles(this.shadowRoot, this.brand);\n this.idleRefs = null;\n\n const s = this.store.getState();\n let node: HTMLElement;\n switch (s.phase) {\n case \"idle\":\n this.idleRefs = renderIdle(\n this.brand,\n this.fields,\n s.errors,\n s.generalError,\n {\n onInput: (field, value) => this.handleInput(field, value),\n onBlur: (field) => this.handleBlur(field),\n onSubmit: () => this.handleSubmit(),\n }\n );\n node = this.idleRefs.root;\n break;\n case \"submitting\":\n node = renderSubmitting(this.brand, this.fields);\n break;\n case \"polling\":\n node = renderPolling(this.brand, {\n companyName: this.fields.company_name,\n subStatus: s.subStatus,\n elapsedMs: s.elapsedMs,\n pollTimeoutMs: this.getPollTimeout(),\n });\n break;\n case \"complete\":\n node = renderComplete(this.brand, {\n companyName: this.fields.company_name,\n reportUrl: s.reportUrl || \"#\",\n onReset: () => this.resetToIdle(),\n });\n break;\n case \"error\":\n node = renderError(this.brand, {\n message: s.errorMessage,\n retryable: s.retryable,\n onRetry: () => this.submit(),\n onBack: () => this.backToIdle(s.generalError ?? s.errorMessage),\n });\n break;\n }\n this.shadowRoot.appendChild(node);\n\n if (s.phase === \"idle\" && this.idleRefs) {\n const firstErrorField = (Object.keys(s.errors) as (keyof Fields)[]).find(\n (f) => !!s.errors[f]\n );\n if (firstErrorField) this.idleRefs.fieldInputs[firstErrorField].focus();\n }\n }\n\n private updateProgress(): void {\n if (!this.shadowRoot) return;\n const bar = this.shadowRoot.querySelector<HTMLElement>(\".dpdpa-progress-fill\");\n const track = this.shadowRoot.querySelector<HTMLElement>(\".dpdpa-progress\");\n if (!bar) return;\n const pct = Math.min(\n 100,\n Math.round((this.store.getState().elapsedMs / this.getPollTimeout()) * 100)\n );\n bar.style.width = `${pct}%`;\n if (track) track.setAttribute(\"aria-valuenow\", String(pct));\n }\n\n private handleInput(field: keyof Fields, value: string): void {\n this.fields[field] = value;\n const prev = this.store.getState().errors[field];\n if (prev) {\n const next = { ...this.store.getState().errors };\n delete next[field];\n this.store.setState({ errors: next });\n if (this.idleRefs) this.clearFieldErrorSlot(field);\n }\n }\n\n private handleBlur(field: keyof Fields): void {\n const err = validateField(field, this.fields[field]);\n const next = { ...this.store.getState().errors };\n if (err) next[field] = err;\n else delete next[field];\n this.store.setState({ errors: next });\n this.updateFieldErrorSlot(field, err);\n }\n\n private updateFieldErrorSlot(field: keyof Fields, err: string | null): void {\n if (!this.idleRefs) return;\n const slot = this.idleRefs.fieldErrors[field];\n if (err) {\n slot.textContent = err;\n slot.style.display = \"block\";\n } else {\n slot.textContent = \"\";\n slot.style.display = \"none\";\n }\n }\n\n private clearFieldErrorSlot(field: keyof Fields): void {\n if (!this.idleRefs) return;\n const slot = this.idleRefs.fieldErrors[field];\n slot.textContent = \"\";\n slot.style.display = \"none\";\n }\n\n private handleSubmit(): void {\n const normalizedFields: Fields = {\n company_name: this.fields.company_name.trim(),\n company_domain: normalizeDomain(this.fields.company_domain),\n email: this.fields.email.trim(),\n };\n this.fields = normalizedFields;\n\n const errors = validateAll(normalizedFields);\n if (Object.keys(errors).length > 0) {\n this.store.setState({ errors, generalError: null });\n // Trigger a render so focus lands on first invalid (render handles focus).\n this.render();\n this.emitError(\"One or more fields need your attention.\", \"validation\");\n return;\n }\n\n this.store.setState({ errors: {}, generalError: null });\n this.submit();\n }\n\n private async submit(): Promise<void> {\n const lead = this.makeLead(null);\n try {\n this.options.onSubmit?.({\n email: lead.email,\n company_name: lead.company_name,\n company_domain: lead.company_domain,\n timestamp: lead.timestamp,\n });\n } catch (err) {\n console.error(\"onSubmit handler threw:\", err);\n }\n saveLead(lead);\n\n this.store.setState({ phase: \"submitting\" });\n\n try {\n const res = await submitLead({\n baseUrl: this.getBaseUrl(),\n body: {\n company_name: lead.company_name,\n company_domain: lead.company_domain,\n },\n });\n\n if (this.destroyed) return;\n\n if (res.status === \"error\") {\n this.showError(res.message || \"We couldn't accept that submission.\", false);\n this.emitError(res.message || \"Submission rejected\", \"submit\");\n return;\n }\n\n const acceptedLead: CapturedLead = { ...lead, job_id: res.job_id };\n saveLead(acceptedLead);\n try {\n this.options.onJobAccepted?.(res.job_id, acceptedLead);\n } catch (err) {\n console.error(\"onJobAccepted handler threw:\", err);\n }\n\n this.startPolling(res.job_id);\n } catch (err) {\n if (this.destroyed) return;\n const apiErr = err as ApiError;\n const retryable = !apiErr.status || apiErr.status >= 500;\n this.showError(\n apiErr.message || \"We couldn't reach our server. Please try again.\",\n retryable\n );\n this.emitError(apiErr.message || \"Submit failed\", \"submit\", apiErr.status);\n }\n }\n\n private startPolling(jobId: string): void {\n this.clearPolling();\n this.pollStartedAt = Date.now();\n this.pollHiddenSince = null;\n this.pollHiddenTotalMs = 0;\n this.lastSubStatus = null;\n this.consecutiveErrors = 0;\n this.store.setState({\n phase: \"polling\",\n subStatus: \"pending\",\n elapsedMs: 0,\n jobId,\n });\n this.schedulePoll();\n }\n\n private schedulePoll(): void {\n if (this.destroyed) return;\n if (typeof document !== \"undefined\" && document.hidden) {\n if (this.pollHiddenSince === null) this.pollHiddenSince = Date.now();\n this.pollResumePending = true;\n return;\n }\n const interval = this.options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;\n this.pollTimer = setTimeout(() => this.pollTick(), interval);\n }\n\n private getActiveElapsed(): number {\n return Date.now() - this.pollStartedAt - this.pollHiddenTotalMs;\n }\n\n private async pollTick(): Promise<void> {\n if (this.destroyed) return;\n const jobId = this.store.getState().jobId;\n if (!jobId) return;\n\n const activeElapsed = this.getActiveElapsed();\n if (activeElapsed >= this.getPollTimeout()) {\n this.showError(\n \"Report generation is taking longer than expected. Our team has been notified.\",\n false\n );\n this.emitError(\"Polling timed out\", \"timeout\");\n return;\n }\n\n try {\n const res = await fetchJobStatus({ baseUrl: this.getBaseUrl(), jobId });\n if (this.destroyed) return;\n this.consecutiveErrors = 0;\n\n if (\"status\" in res && res.status === \"error\") {\n this.showError(res.message || \"Report generation failed.\", true);\n this.emitError(res.message || \"Job errored\", \"poll\");\n return;\n }\n\n if (res.status === \"complete\" && \"report_url\" in res && res.report_url) {\n const acceptedLead: CapturedLead = this.makeLead(jobId);\n saveLead(acceptedLead);\n this.store.setState({\n phase: \"complete\",\n reportUrl: res.report_url,\n });\n try {\n this.options.onComplete?.(res.report_url, acceptedLead);\n } catch (err) {\n console.error(\"onComplete handler threw:\", err);\n }\n return;\n }\n\n const sub = res.status as \"pending\" | \"researching\" | \"analysis_complete\";\n if (sub !== this.lastSubStatus) {\n this.lastSubStatus = sub;\n try {\n this.options.onStatusChange?.(sub);\n } catch (err) {\n console.error(\"onStatusChange handler threw:\", err);\n }\n }\n this.store.setState({\n phase: \"polling\",\n subStatus: sub,\n elapsedMs: activeElapsed,\n });\n this.schedulePoll();\n } catch (err) {\n if (this.destroyed) return;\n this.consecutiveErrors++;\n if (this.consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) {\n this.showError(\n \"We can't reach our server right now. Please try again.\",\n true\n );\n this.emitError(\n err instanceof Error ? err.message : \"Poll failed\",\n \"poll\"\n );\n return;\n }\n this.schedulePoll();\n }\n }\n\n private clearPolling(): void {\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n this.pollResumePending = false;\n }\n\n private handleVisibilityChange(): void {\n if (this.destroyed) return;\n if (document.hidden) {\n if (\n this.store.getState().phase === \"polling\" &&\n this.pollHiddenSince === null\n ) {\n this.pollHiddenSince = Date.now();\n }\n return;\n }\n if (this.pollHiddenSince !== null) {\n this.pollHiddenTotalMs += Date.now() - this.pollHiddenSince;\n this.pollHiddenSince = null;\n }\n if (this.pollResumePending && this.store.getState().phase === \"polling\") {\n this.pollResumePending = false;\n this.pollTick();\n }\n }\n\n private showError(message: string, retryable: boolean): void {\n this.store.setState({\n phase: \"error\",\n errorMessage: message,\n retryable,\n });\n }\n\n private resetToIdle(): void {\n this.fields = { ...EMPTY_FIELDS };\n this.lastSubStatus = null;\n this.store.setState({\n phase: \"idle\",\n errors: {},\n generalError: null,\n errorMessage: \"\",\n reportUrl: null,\n jobId: null,\n subStatus: \"pending\",\n elapsedMs: 0,\n });\n }\n\n private backToIdle(generalError: string | null): void {\n this.store.setState({\n phase: \"idle\",\n errors: {},\n generalError,\n errorMessage: \"\",\n });\n }\n\n private emitError(message: string, phase: FormError[\"phase\"], status?: number): void {\n try {\n const err = Object.assign(new Error(message), { phase, status }) as FormError;\n this.options.onError?.(err);\n } catch (e) {\n console.error(\"onError handler threw:\", e);\n }\n }\n\n private makeLead(jobId: string | null): CapturedLead {\n return {\n email: this.fields.email,\n company_name: this.fields.company_name,\n company_domain: this.fields.company_domain,\n job_id: jobId,\n timestamp: new Date().toISOString(),\n };\n }\n\n private getBaseUrl(): string {\n return (this.options.baseUrl || DEFAULT_BASE_URL).replace(/\\/$/, \"\");\n }\n\n private getPollTimeout(): number {\n return this.options.pollTimeoutMs ?? DEFAULT_POLL_TIMEOUT_MS;\n }\n}\n"],"mappings":"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","names":["src_exports","__export","src_default","destroy","getCapturedLead","init","version","DEFAULT_BASE_URL","PATHS","DEFAULT_POLL_INTERVAL_MS","DEFAULT_POLL_TIMEOUT_MS","MAX_CONSECUTIVE_ERRORS","REQUEST_TIMEOUT_MS","STORAGE_KEY","DEFAULT_LOGO_URL","DEFAULT_BRAND","SUCCESS_COLOR","ERROR_COLOR","NAME_MIN_LENGTH","NAME_MAX_LENGTH","DOMAIN_REGEX","EMAIL_REGEX","FREEMAIL_DOMAINS","el","tag","attrs","children","element","applyAttrs","appendChildren","svg","key","value","applyStyles","event","UNITLESS_PROPS","styles","stringValue","parent","child","clearElement","Store","initialState","partial","prevState","listener","ApiError","message","status","timedFetch","url","init","controller","timer","REQUEST_TIMEOUT_MS","toNetworkError","err","ApiError","submitLead","baseUrl","body","res","PATHS","json","message","fetchJobStatus","jobId","isBrowser","saveLead","lead","STORAGE_KEY","error","isCapturedLead","v","o","loadLead","raw","parsed","STYLE_ID","buildCss","brand","injectFormStyles","root","style","HEX_RE","normalizeHex","hex","fallback","hexToRgb","h","full","c","darken","amount","g","b","d","rgba","alpha","relativeLuminance","r","norm","s","contrastingTextOn","bg","resolveBranding","_a","primary","DEFAULT_BRAND","accent","DEFAULT_LOGO_URL","SUCCESS_COLOR","ERROR_COLOR","normalizeDomain","raw","validateField","field","rawValue","_a","value","NAME_MIN_LENGTH","NAME_MAX_LENGTH","normalized","DOMAIN_REGEX","EMAIL_REGEX","domain","FREEMAIL_DOMAINS","validateAll","fields","errors","key","err","header","brand","logoImg","el","ev","img","wordmark","inputRow","opts","inputEl","errorSlot","labelEl","footer","renderIdle","fields","errors","generalErrorText","handlers","nameRow","v","domainRow","emailRow","generalError","submitBtn","form","renderSubmitting","refs","inp","animatedDots","stepCheck","svg","stepPulse","STEP_ORDER","STEPS","company","renderPolling","pct","progressFill","progressBar","currentIdx","stepsList","step","idx","isActive","row","body","checkIcon","isSafeUrl","raw","s","renderComplete","safeHref","downloadBtn","resetLink","renderError","retryBtn","EMPTY_FIELDS","FormController","options","resolveBranding","Store","found","injectFormStyles","state","prev","_a","clearElement","s","node","renderIdle","field","value","renderSubmitting","renderPolling","renderComplete","renderError","firstErrorField","f","bar","track","pct","next","err","validateField","slot","normalizedFields","normalizeDomain","errors","validateAll","_b","_c","_d","lead","saveLead","res","submitLead","acceptedLead","apiErr","retryable","jobId","interval","DEFAULT_POLL_INTERVAL_MS","activeElapsed","fetchJobStatus","sub","MAX_CONSECUTIVE_ERRORS","message","generalError","phase","status","e","DEFAULT_BASE_URL","DEFAULT_POLL_TIMEOUT_MS","version","activeController","init","options","destroy","FormController","err","_a","handlerErr","getCapturedLead","loadLead","RedactoDpdpaReport","src_default"]}