@redacto.io/consent-sdk-js 1.0.0 → 1.2.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/core/state.ts","../src/core/dom.ts","../src/core/media-query.ts","../src/services/cache.ts","../../../node_modules/.pnpm/jwt-decode@4.0.0/node_modules/jwt-decode/build/esm/index.js","../src/core/jwt-decode.ts","../src/api/sandbox.ts","../src/api/constants.ts","../src/api/language.ts","../src/api/index.ts","../src/api/notice-consent-status.ts","../src/styles/inject.ts","../src/styles/modal.ts","../src/modal/purposes.ts","../src/modal/language-selector.ts","../src/modal/keyboard.ts","../src/services/storage.ts","../src/constants.ts","../src/modal/tts.ts","../src/modal/age-verification.ts","../src/modal/guardian-form.ts","../src/modal/verification-screen.ts","../src/modal/colors.ts","../src/modal/layout.ts","../src/modal/index.ts","../src/styles/inline.ts","../src/inline/purposes.ts","../src/inline/index.ts","../src/modal/digilocker-callback.ts"],"sourcesContent":["import { ModalController } from \"./modal\";\nimport { InlineController } from \"./inline\";\nimport { handleDigilockerCallback } from \"./modal/digilocker-callback\";\nimport type { ModalOptions, InlineOptions, DigiLockerCallbackOptions } from \"./types\";\n\nlet activeModal: ModalController | null = null;\nlet activeInline: InlineController | null = null;\n\n/**\n * Initialize a modal consent dialog.\n * Renders a full-screen overlay with the consent form.\n */\nfunction init(options: ModalOptions): void {\n // Destroy any existing instance\n destroy();\n\n activeModal = new ModalController(options);\n activeModal.init().catch((err) => {\n options.onError?.(err);\n });\n}\n\n/**\n * Initialize an inline consent form.\n * Renders consent purposes inside a target container element.\n */\nfunction inline(options: InlineOptions): void {\n // Destroy any existing inline instance\n if (activeInline) {\n activeInline.destroy();\n activeInline = null;\n }\n\n activeInline = new InlineController(options);\n activeInline.init().catch((err) => {\n options.onError?.(err);\n });\n}\n\n/**\n * Destroy all active consent instances.\n */\nfunction destroy(): void {\n if (activeModal) {\n activeModal.destroy();\n activeModal = null;\n }\n if (activeInline) {\n activeInline.destroy();\n activeInline = null;\n }\n}\n\n/**\n * Handle DigiLocker callback (for guardian verification redirect flow).\n * Call this on the DigiLocker callback page.\n */\nfunction digilockerCallback(options: DigiLockerCallbackOptions): void {\n handleDigilockerCallback(options);\n}\n\nconst RedactoConsent = {\n init,\n inline,\n destroy,\n digilockerCallback,\n version: \"0.1.0\",\n};\n\nexport default RedactoConsent;\nexport { init, inline, destroy, digilockerCallback };\nexport type { ModalOptions, InlineOptions, DigiLockerCallbackOptions };\nexport type { Settings } from \"./api/types\";\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","/**\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\n/**\n * CSS properties that take a unitless number, mirroring React's CSSProperty\n * list. For these we MUST NOT append \"px\" — doing so produces invalid CSS\n * (e.g. `font-weight: 400px`) and the browser falls back to the user-agent\n * default (which is what made <h3> purpose descriptions render as bold).\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 (matching React's behavior) EXCEPT\n * for the unitless properties listed above, which are passed through as-is.\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\n/**\n * Remove all children from an element.\n */\nexport function clearElement(element: HTMLElement): void {\n while (element.firstChild) {\n element.removeChild(element.firstChild);\n }\n}\n","/**\n * matchMedia wrapper with subscribe — replaces useMediaQuery hook.\n */\n\nexport type MediaQuerySubscription = {\n matches: boolean;\n subscribe: (cb: (matches: boolean) => void) => void;\n destroy: () => void;\n};\n\nexport function createMediaQuery(query: string): MediaQuerySubscription {\n const mql = window.matchMedia(query);\n let currentMatches = mql.matches;\n const listeners: Set<(matches: boolean) => void> = new Set();\n\n const handler = (e: MediaQueryListEvent) => {\n currentMatches = e.matches;\n listeners.forEach((cb) => cb(currentMatches));\n };\n\n mql.addEventListener(\"change\", handler);\n\n return {\n get matches() {\n return currentMatches;\n },\n subscribe(cb: (matches: boolean) => void) {\n listeners.add(cb);\n },\n destroy() {\n mql.removeEventListener(\"change\", handler);\n listeners.clear();\n },\n };\n}\n","const apiCache = new Map<string, { data: any; timestamp: number; ttl: number }>();\nconst CACHE_TTL = 5 * 60 * 1000; // 5 minutes\n\nexport function getCachedData(key: string): any | null {\n const cached = apiCache.get(key);\n if (cached && Date.now() - cached.timestamp < cached.ttl) {\n return cached.data;\n }\n if (cached) {\n apiCache.delete(key);\n }\n return null;\n}\n\nexport function setCachedData(key: string, data: any, ttl = CACHE_TTL): void {\n apiCache.set(key, { data, timestamp: Date.now(), ttl });\n}\n\nexport function clearApiCache(): void {\n apiCache.clear();\n}\n","export class InvalidTokenError extends Error {\n}\nInvalidTokenError.prototype.name = \"InvalidTokenError\";\nfunction b64DecodeUnicode(str) {\n return decodeURIComponent(atob(str).replace(/(.)/g, (m, p) => {\n let code = p.charCodeAt(0).toString(16).toUpperCase();\n if (code.length < 2) {\n code = \"0\" + code;\n }\n return \"%\" + code;\n }));\n}\nfunction base64UrlDecode(str) {\n let output = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\n switch (output.length % 4) {\n case 0:\n break;\n case 2:\n output += \"==\";\n break;\n case 3:\n output += \"=\";\n break;\n default:\n throw new Error(\"base64 string is not of the correct length\");\n }\n try {\n return b64DecodeUnicode(output);\n }\n catch (err) {\n return atob(output);\n }\n}\nexport function jwtDecode(token, options) {\n if (typeof token !== \"string\") {\n throw new InvalidTokenError(\"Invalid token specified: must be a string\");\n }\n options || (options = {});\n const pos = options.header === true ? 0 : 1;\n const part = token.split(\".\")[pos];\n if (typeof part !== \"string\") {\n throw new InvalidTokenError(`Invalid token specified: missing part #${pos + 1}`);\n }\n let decoded;\n try {\n decoded = base64UrlDecode(part);\n }\n catch (e) {\n throw new InvalidTokenError(`Invalid token specified: invalid base64 for part #${pos + 1} (${e.message})`);\n }\n try {\n return JSON.parse(decoded);\n }\n catch (e) {\n throw new InvalidTokenError(`Invalid token specified: invalid json for part #${pos + 1} (${e.message})`);\n }\n}\n","import { jwtDecode } from \"jwt-decode\";\nimport type { RedactoJwtPayload } from \"../api/types\";\n\n/**\n * Decode JWT with error handling — returns null on failure.\n */\nexport function decodeTokenSafely(token: string): RedactoJwtPayload | null {\n try {\n return jwtDecode(token) as RedactoJwtPayload;\n } catch (error) {\n console.warn(\"Failed to decode JWT token:\", error);\n return null;\n }\n}\n","/**\n * Sandbox-mode auth primitives for the consent PoC.\n *\n * In sandbox mode the SDK talks to the consent-server with a pasted static\n * token and an explicit test subject, bypassing the JWT entirely. Org/workspace\n * UUIDs come from options (they still build the `/public/organisations/{org}/\n * workspaces/{ws}/...` URL paths) instead of being decoded from a token.\n *\n * Auth is the single `X-Consent-Token` header carrying the static token; its\n * presence alone marks the request as `environment=test`. There is no subject\n * header. The acting identity (the test subject) rides the request's own\n * payload: query params (`primary_email` / `primary_mobile`) on GET/query reads,\n * and the body on POSTs. The server normalizes and namespaces it `test::`\n * server-side. Call sites resolve the credential via {@link buildAuthHeaders}\n * and the identity via {@link sandboxQueryIdentity} / {@link sandboxBodyIdentity}.\n *\n * This file exists so every JWT-decode / Authorization site resolves its\n * org/workspace UUIDs and builds its auth header through one place, keeping\n * sandbox vs. JWT branching from drifting across the fetch sites.\n */\nimport { decodeTokenSafely } from \"../core/jwt-decode\";\nimport type {\n ResolvedRequestAuth,\n SandboxAuth,\n SandboxIdentityPayload,\n SandboxOptions,\n} from \"./types\";\n\n/** HTTP header carrying the static sandbox token (the credential). */\nexport const SANDBOX_TOKEN_HEADER = \"X-Consent-Token\";\n\n/**\n * Resolve a {@link SandboxAuth} from sandbox options, or null when sandbox mode\n * is not active (no token).\n *\n * @throws Error when a sandbox token is provided but org/workspace or the acting\n * identity are incomplete — sandbox mode cannot build URLs or identify the\n * acting principal without them.\n */\nexport const resolveSandboxAuth = (\n options: SandboxOptions\n): SandboxAuth | null => {\n const token = options.token?.trim();\n if (!token) {\n return null;\n }\n\n const organisationUuid = options.organisationUuid?.trim();\n const workspaceUuid = options.workspaceUuid?.trim();\n const ucic = options.sandboxUcic?.trim();\n const subject = options.sandboxSubject?.trim();\n\n if (!organisationUuid || !workspaceUuid) {\n throw new Error(\n \"Sandbox mode requires organisationUuid and workspaceUuid\"\n );\n }\n if (!ucic && !subject) {\n throw new Error(\"Sandbox mode requires a UCIC, email, or mobile\");\n }\n\n return { token, ucic, subject: subject ?? \"\", organisationUuid, workspaceUuid };\n};\n\n/**\n * Resolve org/workspace UUIDs plus the sandbox context for an authenticated\n * request. In sandbox mode these come from options; otherwise they are decoded\n * from the JWT (preserving the pre-sandbox error messages exactly).\n *\n * @throws Error when neither a valid sandbox config nor a decodable token with\n * org/workspace UUIDs is available.\n */\nexport const resolveRequestAuth = (\n accessToken: string | undefined,\n options: SandboxOptions\n): ResolvedRequestAuth => {\n const sandbox = resolveSandboxAuth(options);\n if (sandbox) {\n return {\n organisationUuid: sandbox.organisationUuid,\n workspaceUuid: sandbox.workspaceUuid,\n sandbox,\n };\n }\n\n const decodedToken = accessToken ? decodeTokenSafely(accessToken) : null;\n if (!decodedToken) {\n throw new Error(\"Invalid access token\");\n }\n const { organisation_uuid, workspace_uuid } = decodedToken;\n if (!organisation_uuid || !workspace_uuid) {\n throw new Error(\"Invalid token: missing organization or workspace UUID\");\n }\n return {\n organisationUuid: organisation_uuid,\n workspaceUuid: workspace_uuid,\n sandbox: null,\n };\n};\n\n/**\n * Build the request headers for an authenticated call. In sandbox mode this is\n * the single `X-Consent-Token` credential (its presence marks the request as\n * `environment=test`); otherwise the standard `Authorization: Bearer`. There is\n * no subject header — the acting identity travels in the request's own payload\n * (see {@link sandboxQueryIdentity} for reads, {@link sandboxBodyIdentity} for\n * POSTs).\n */\nexport const buildAuthHeaders = (\n accessToken: string | undefined,\n sandbox: SandboxAuth | null\n): Record<string, string> => {\n if (sandbox) {\n return { [SANDBOX_TOKEN_HEADER]: sandbox.token };\n }\n return { Authorization: `Bearer ${accessToken}` };\n};\n\n/**\n * The identity payload fragment for the sandbox acting principal:\n * `{ org_user_id }` when a UCIC is set (it takes precedence), else\n * `{ primary_email }` when the subject looks like an email (contains \"@\"),\n * otherwise `{ primary_mobile }`. Merge this into a JSON request body (POST) or\n * into query params (GET) so the server can resolve the acting test identity.\n */\nexport const sandboxBodyIdentity = (\n sandbox: SandboxAuth\n): SandboxIdentityPayload => {\n if (sandbox.ucic) {\n return { org_user_id: sandbox.ucic };\n }\n return sandbox.subject.includes(\"@\")\n ? { primary_email: sandbox.subject }\n : { primary_mobile: sandbox.subject };\n};\n\n/**\n * The identity query fragment for GET/query reads: `{ org_user_id }` when a UCIC\n * is set (it takes precedence), else `{ primary_email }` when the subject looks\n * like an email (contains \"@\"), otherwise `{ primary_mobile }`. Append these to\n * the request's query string so the server can resolve the acting test identity\n * (the server reads `org_user_id` / `primary_email` / `primary_mobile` query\n * params on sandbox reads).\n */\nexport const sandboxQueryIdentity = (\n sandbox: SandboxAuth\n): SandboxIdentityPayload => sandboxBodyIdentity(sandbox);\n","export const CODE_BY_NAME = new Map<string, string>([\n [\"english\", \"en\"],\n [\"assamese\", \"as\"],\n [\"bengali\", \"bn\"],\n [\"bodo\", \"brx\"],\n [\"dogri\", \"doi\"],\n [\"goan konkani\", \"gom\"],\n [\"gujarati\", \"gu\"],\n [\"hindi\", \"hi\"],\n [\"kannada\", \"kn\"],\n [\"kashmiri\", \"ks\"],\n [\"maithili\", \"mai\"],\n [\"malayalam\", \"ml\"],\n [\"manipuri\", \"mni-Mtei\"],\n [\"marathi\", \"mr\"],\n [\"nepali\", \"ne\"],\n [\"odia\", \"or\"],\n [\"punjabi\", \"pa\"],\n [\"sanskrit\", \"sa\"],\n [\"santali\", \"sat\"],\n [\"sindhi\", \"sd\"],\n [\"tamil\", \"ta\"],\n [\"telugu\", \"te\"],\n [\"urdu\", \"ur\"],\n]);\n\nexport const CODE_BY_LOWER = new Map<string, string>(\n [...CODE_BY_NAME.values()].map((c) => [c.toLowerCase(), c])\n);\n","import { CODE_BY_LOWER, CODE_BY_NAME } from \"./constants\";\n\nexport function toLanguageCode(lang?: string | null): string | undefined {\n if (!lang) {\n return undefined;\n }\n const trimmed = lang.trim();\n if (!trimmed) {\n return undefined;\n }\n const lower = trimmed.toLowerCase();\n return CODE_BY_LOWER.get(lower) ?? CODE_BY_NAME.get(lower) ?? trimmed;\n}\n\nexport function resolveDisplayLanguage(\n requested: string | undefined,\n defaultLanguage: string | undefined,\n translations: Record<string, unknown> | undefined\n): string {\n const fallback = defaultLanguage || \"en\";\n const requestedCode = toLanguageCode(requested);\n if (!requestedCode) {\n return fallback;\n }\n\n for (const key of Object.keys(translations || {})) {\n if (toLanguageCode(key) === requestedCode) {\n return key;\n }\n }\n\n return fallback;\n}\n","import { clearApiCache, getCachedData, setCachedData } from \"../services/cache\";\nimport { decodeTokenSafely } from \"../core/jwt-decode\";\nimport {\n buildAuthHeaders,\n resolveRequestAuth,\n sandboxBodyIdentity,\n sandboxQueryIdentity,\n} from \"./sandbox\";\nimport { toLanguageCode } from \"./language\";\nimport type {\n ConsentContent,\n ConsentEventPayload,\n FetchConsentContentParams,\n FetchConsentContentPublicParams,\n FetchTTSAudioUrlsParams,\n InitiateGuardianVerificationParams,\n InitiateGuardianVerificationResponse,\n SubmitConsentEventParams,\n SubmitConsentEventPublicParams,\n TTSAudioUrlsResponse,\n VerifyGuardianStatusParams,\n VerifyGuardianStatusResponse,\n} from \"./types\";\n\nconst BASE_URL = \"https://api.redacto.io/consent\";\nconst BASE_URL_PUBLIC = \"https://api.redacto.tech/consent\";\n\n// ─── Modal: fetch notice (authenticated, JWT-decoded) ───\n\nexport const fetchConsentContent = async ({\n noticeId,\n accessToken,\n baseUrl,\n language = \"en\",\n specific_uuid,\n validate_against = \"all\",\n include_fully_consented_data = false,\n signal,\n ...sandboxParams\n}: FetchConsentContentParams & { signal?: AbortSignal }): Promise<ConsentContent> => {\n if (!noticeId || !validate_against) {\n throw new Error(\"noticeId is required\");\n }\n if (!accessToken && !sandboxParams.token) {\n throw new Error(\"accessToken or token is required\");\n }\n\n const { organisationUuid: ORG, workspaceUuid: WS, sandbox } = resolveRequestAuth(\n accessToken,\n sandboxParams\n );\n\n const apiBaseUrl = baseUrl || BASE_URL;\n\n // Include org + workspace in the sandbox cache identity so two sessions\n // sharing a subject but scoped to different orgs never collide.\n const cacheIdentity = sandbox\n ? `sandbox:${sandbox.organisationUuid}:${sandbox.workspaceUuid}:${sandbox.ucic || sandbox.subject}`\n : accessToken;\n const cacheKey = `${cacheIdentity}-${noticeId}-${validate_against}-${language}-${specific_uuid || \"\"}-${include_fully_consented_data}`;\n\n if (validate_against === \"all\" && !specific_uuid) {\n const cached = getCachedData(cacheKey);\n if (cached) return cached;\n }\n\n const url = new URL(`${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/notices/${noticeId}`);\n if (specific_uuid) url.searchParams.append(\"specific_uuid\", specific_uuid);\n url.searchParams.append(\"validate_against\", validate_against);\n if (include_fully_consented_data) url.searchParams.append(\"include_fully_consented_data\", \"true\");\n // Sandbox mode: the acting identity travels as query params\n // (primary_email / primary_mobile); the credential is the X-Consent-Token header.\n if (sandbox) {\n for (const [key, value] of Object.entries(sandboxQueryIdentity(sandbox))) {\n url.searchParams.append(key, value);\n }\n }\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n ...buildAuthHeaders(accessToken, sandbox),\n \"Accept-Language\": language,\n },\n signal,\n });\n\n if (!response.ok) {\n let errorMessage = `Failed to fetch consent content: ${response.status} ${response.statusText}`;\n if (response.status === 401) errorMessage = \"Unauthorized: Invalid or expired token\";\n else if (response.status === 403) errorMessage = \"Forbidden: Access denied\";\n else if (response.status === 404) errorMessage = \"Notice not found\";\n else if (response.status === 409) errorMessage = \"User has already provided consent\";\n else if (response.status >= 500) errorMessage = \"Server error: Please try again later\";\n\n const error = new Error(errorMessage) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n const data: ConsentContent = await response.json();\n\n if (validate_against === \"all\" && !specific_uuid) {\n setCachedData(cacheKey, data);\n }\n\n return data;\n};\n\n// ─── Inline: fetch notice (public, no auth) ───\n\nexport const fetchConsentContentPublic = async ({\n org_uuid,\n workspace_uuid,\n notice_uuid,\n accessToken,\n baseUrl,\n language = \"en\",\n specific_uuid,\n}: FetchConsentContentPublicParams): Promise<ConsentContent> => {\n const apiBaseUrl = baseUrl || BASE_URL_PUBLIC;\n const noticesUrl = `${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/notices`;\n\n const url = new URL(\n accessToken ? `${noticesUrl}/${notice_uuid}` : `${noticesUrl}/get-notice/${notice_uuid}`\n );\n if (specific_uuid) url.searchParams.append(\"specific_uuid\", specific_uuid);\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Accept-Language\": language,\n ...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}),\n },\n });\n\n if (response.status === 401) {\n const error = new Error(\"Unauthorized\") as Error & { status?: number };\n error.status = 401;\n throw error;\n }\n if (response.status === 409) {\n const error = new Error(\"User has already provided consent\") as Error & { status?: number };\n error.status = 409;\n throw error;\n }\n if (!response.ok) {\n throw new Error(`Failed to fetch consent content: ${response.statusText}`);\n }\n\n return await response.json();\n};\n\n// ─── Modal: submit consent (JWT-decoded) ───\n\nexport const submitConsentEvent = async ({\n accessToken,\n baseUrl,\n ledgerBaseUrl,\n noticeUuid,\n purposes,\n declined,\n meta_data,\n guardianVerificationReference,\n selfDeclaredAdult,\n language,\n signal,\n ...sandboxParams\n}: SubmitConsentEventParams & { signal?: AbortSignal }): Promise<void> => {\n if (!noticeUuid || !Array.isArray(purposes)) {\n throw new Error(\"noticeUuid and purposes array are required\");\n }\n if (!accessToken && !sandboxParams.token) {\n throw new Error(\"accessToken or token is required\");\n }\n\n const { organisationUuid: ORG, workspaceUuid: WS, sandbox } = resolveRequestAuth(\n accessToken,\n sandboxParams\n );\n\n // Route the write to the Go ledger when configured; fall back to the consent\n // server so existing integrations that only pass baseUrl keep working. Sandbox\n // never routes to the Go ledger (no X-Consent-Token support), so a sandbox\n // session forces the consent-server path even if a ledgerBaseUrl is set.\n const apiBaseUrl = (sandbox ? null : ledgerBaseUrl) || baseUrl || BASE_URL;\n\n const validatedPurposes = purposes.map((purpose) => {\n if (!purpose.uuid) throw new Error(\"Invalid purpose data: missing uuid\");\n\n const dataElements = (purpose.data_elements || [])\n .filter((element) => element.enabled)\n .map((element) => ({\n uuid: element.uuid,\n selected: element.required ? true : Boolean(element.selected),\n }));\n\n return {\n purpose_uuid: purpose.uuid,\n selected: Boolean(purpose.selected),\n data_elements: dataElements.length > 0 ? dataElements : undefined,\n };\n });\n\n const payload: ConsentEventPayload = {\n notice_uuid: noticeUuid,\n purposes: validatedPurposes,\n select_all_mandatory: false,\n source: \"WEB\",\n declined: Boolean(declined),\n meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid, minor_age: meta_data.minor_age } : undefined,\n guardian_verification_reference: guardianVerificationReference,\n self_declared_adult: selfDeclaredAdult,\n language: toLanguageCode(language),\n };\n\n // Sandbox mode: merge the acting test identity into the body (the server has\n // no subject header; it namespaces this identity `test::`).\n const requestBody = sandbox ? { ...payload, ...sandboxBodyIdentity(sandbox) } : payload;\n\n const response = await fetch(\n `${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/submit-consent`,\n {\n method: \"POST\",\n headers: {\n ...buildAuthHeaders(accessToken, sandbox),\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(requestBody),\n signal,\n }\n );\n\n if (!response.ok) {\n let errorMessage = `Failed to submit consent: ${response.status} ${response.statusText}`;\n if (response.status === 400) {\n try {\n const errorData = await response.json();\n errorMessage = errorData.message || \"Invalid request data\";\n } catch {\n errorMessage = \"Invalid request data\";\n }\n } else if (response.status === 401) errorMessage = \"Unauthorized: Invalid or expired token\";\n else if (response.status === 403) errorMessage = \"Forbidden: Access denied\";\n else if (response.status === 404) errorMessage = \"Notice not found\";\n else if (response.status >= 500) errorMessage = \"Server error: Please try again later\";\n\n const error = new Error(errorMessage) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n clearApiCache();\n};\n\n// ─── Inline: submit consent (direct org/workspace) ───\n\nexport const submitConsentEventPublic = async ({\n org_uuid,\n workspace_uuid,\n accessToken,\n baseUrl,\n ledgerBaseUrl,\n noticeUuid,\n purposes,\n declined,\n meta_data,\n language,\n}: SubmitConsentEventPublicParams): Promise<void> => {\n // Route the write to the Go ledger when configured; fall back to the consent\n // server so existing integrations that only pass baseUrl keep working.\n const apiBaseUrl = ledgerBaseUrl || baseUrl || BASE_URL_PUBLIC;\n\n const payload: ConsentEventPayload = {\n notice_uuid: noticeUuid,\n purposes: purposes.map((purpose) => {\n if (!purpose.uuid) throw new Error(\"Invalid purpose data: missing uuid\");\n\n const dataElements = purpose.data_elements\n .filter((element) => element.enabled)\n .map((element) => ({\n uuid: element.uuid,\n selected: element.required ? true : Boolean(element.selected),\n }));\n\n return {\n purpose_uuid: purpose.uuid,\n selected: Boolean(purpose.selected),\n data_elements: dataElements.length > 0 ? dataElements : undefined,\n };\n }),\n select_all_mandatory: false,\n source: \"WEB\",\n declined,\n meta_data,\n language: toLanguageCode(language),\n };\n\n const response = await fetch(\n `${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/submit-consent`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n }\n );\n\n if (!response.ok) {\n let errorData;\n try {\n errorData = await response.json();\n } catch {\n errorData = { message: response.statusText };\n }\n\n if (response.status === 409) {\n const error = new Error(\n errorData.detail?.message || errorData.message || \"User has already provided consent\"\n ) as Error & { status?: number; code?: number };\n error.status = 409;\n error.code = errorData.code || 409;\n throw error;\n }\n\n const error = new Error(\n errorData.detail?.message || errorData.message || `Failed to submit consent event: ${response.statusText}`\n ) as Error & { status?: number; code?: number };\n error.status = response.status;\n error.code = errorData.code;\n throw error;\n }\n};\n\n// ─── TTS Audio ───\n\nexport const fetchTTSAudioUrls = async ({\n accessToken,\n baseUrl,\n ledgerBaseUrl,\n noticeUuid,\n language,\n signal,\n ...sandboxParams\n}: FetchTTSAudioUrlsParams & { signal?: AbortSignal }): Promise<TTSAudioUrlsResponse> => {\n if ((!accessToken && !sandboxParams.token) || !noticeUuid || !language) {\n throw new Error(\"accessToken (or token), noticeUuid, and language are required\");\n }\n\n const { organisationUuid: ORG, workspaceUuid: WS, sandbox } = resolveRequestAuth(\n accessToken,\n sandboxParams\n );\n\n // Prefer the Go ledger for audio, but a sandbox session never routes there:\n // the ledger's public reads are JWT-gated and don't support X-Consent-Token.\n // Without this a ledger-minted token is rejected by the consent server and\n // per-language audio silently disappears.\n const apiBaseUrl = (sandbox ? null : ledgerBaseUrl) || baseUrl || BASE_URL;\n const url = new URL(\n `${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/notices/${noticeUuid}/audio/${language}`\n );\n // Sandbox mode: the acting identity travels as query params\n // (primary_email / primary_mobile); the credential is the X-Consent-Token header.\n if (sandbox) {\n for (const [key, value] of Object.entries(sandboxQueryIdentity(sandbox))) {\n url.searchParams.append(key, value);\n }\n }\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n ...buildAuthHeaders(accessToken, sandbox),\n Accept: \"application/json\",\n },\n signal,\n });\n\n if (!response.ok) {\n let errorMessage = `Failed to fetch TTS audio URLs: ${response.status} ${response.statusText}`;\n if (response.status === 401) errorMessage = \"Unauthorized: Invalid or expired token\";\n else if (response.status === 403) errorMessage = \"Forbidden: Access denied\";\n else if (response.status === 404) errorMessage = \"Notice or audio not found\";\n else if (response.status >= 500) errorMessage = \"Server error: Please try again later\";\n\n const error = new Error(errorMessage) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n return await response.json();\n};\n\n// ─── Guardian Verification ───\n\nexport const initiateGuardianVerification = async ({\n accessToken,\n baseUrl,\n guardianName,\n guardianContact,\n guardianRelationship,\n frontendCallbackUrl,\n metadata,\n signal,\n}: InitiateGuardianVerificationParams): Promise<InitiateGuardianVerificationResponse> => {\n // Guardian verification is JWT-only: sandbox sessions have no minor-notice /\n // guardian support (the server 403s them, and C1 blocks minor notices at\n // render), so no sandbox identity is wired through here.\n if (!accessToken) throw new Error(\"accessToken is required\");\n if (!guardianName?.trim()) throw new Error(\"Guardian name is required\");\n if (!guardianContact?.trim()) throw new Error(\"Guardian contact is required\");\n if (!guardianRelationship?.trim()) throw new Error(\"Guardian relationship is required\");\n\n const decodedToken = decodeTokenSafely(accessToken);\n if (!decodedToken) throw new Error(\"Invalid access token\");\n const { organisation_uuid: ORG, workspace_uuid: WS } = decodedToken;\n if (!ORG || !WS) throw new Error(\"Invalid token: missing organization or workspace UUID\");\n\n const apiBaseUrl = baseUrl || BASE_URL;\n\n const payload: Record<string, any> = {\n guardian_name: guardianName.trim(),\n guardian_contact: guardianContact.trim(),\n guardian_relationship: guardianRelationship.trim(),\n };\n if (frontendCallbackUrl) payload.frontend_callback_url = frontendCallbackUrl;\n if (metadata) payload.metadata = metadata;\n\n const response = await fetch(\n `${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/guardian/initiate-verification`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n signal,\n }\n );\n\n if (!response.ok) {\n let errorMessage = `Failed to initiate verification: ${response.status} ${response.statusText}`;\n if (response.status === 400) {\n try {\n const errorData = await response.json();\n errorMessage = errorData.message || \"Invalid request data\";\n } catch {\n errorMessage = \"Invalid request data\";\n }\n } else if (response.status === 401) errorMessage = \"Unauthorized: Invalid or expired token\";\n else if (response.status === 404) errorMessage = \"Organization or workspace not found\";\n else if (response.status === 422) {\n try {\n const errorData = await response.json();\n errorMessage = errorData.message || \"Validation error: Please check your input\";\n } catch {\n errorMessage = \"Validation error: Please check your input\";\n }\n } else if (response.status >= 500) errorMessage = \"Server error: Please try again later\";\n\n const error = new Error(errorMessage) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n const responseData = await response.json();\n const detail = responseData.detail || responseData;\n\n if (detail.already_verified) {\n return {\n success: true,\n guardian_info_uuid: detail.guardian_info_uuid,\n already_verified: true,\n verification_reference: detail.verification_reference,\n };\n }\n\n if (!detail.session_token || !detail.digilocker_redirect_url) {\n throw new Error(\"Invalid response: missing session_token or digilocker_redirect_url\");\n }\n\n return {\n success: detail.success ?? true,\n guardian_info_uuid: detail.guardian_info_uuid,\n already_verified: false,\n session_token: detail.session_token,\n digilocker_redirect_url: detail.digilocker_redirect_url,\n expires_at: detail.expires_at,\n };\n};\n\nexport const verifyGuardianStatus = async ({\n accessToken,\n baseUrl,\n sessionToken,\n signal,\n}: VerifyGuardianStatusParams): Promise<VerifyGuardianStatusResponse> => {\n // Guardian verification is JWT-only: sandbox sessions have no minor-notice /\n // guardian support (the server 403s them, and C1 blocks minor notices at\n // render), so no sandbox identity is wired through here.\n if (!accessToken || !sessionToken) {\n throw new Error(\"accessToken and sessionToken are required\");\n }\n\n const decodedToken = decodeTokenSafely(accessToken);\n if (!decodedToken) throw new Error(\"Invalid access token\");\n const { organisation_uuid: ORG, workspace_uuid: WS } = decodedToken;\n if (!ORG || !WS) throw new Error(\"Invalid token: missing organization or workspace UUID\");\n\n const apiBaseUrl = baseUrl || BASE_URL;\n\n const response = await fetch(\n `${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/guardian/verify-status`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ session_token: sessionToken }),\n signal,\n }\n );\n\n if (!response.ok) {\n let errorMessage = `Failed to check verification status: ${response.status} ${response.statusText}`;\n if (response.status === 400) {\n try {\n const errorData = await response.json();\n errorMessage = errorData.message || errorData.detail?.message || \"Invalid session token\";\n } catch {\n errorMessage = \"Invalid session token\";\n }\n } else if (response.status === 401) errorMessage = \"Unauthorized: Invalid or expired token\";\n else if (response.status === 404)\n errorMessage = \"Verification session not found or expired. Please restart the verification process.\";\n else if (response.status === 410)\n errorMessage = \"Verification session has expired. Please restart the verification process.\";\n else if (response.status >= 500) errorMessage = \"Server error: Please try again later\";\n\n const error = new Error(errorMessage) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n const responseData = await response.json();\n const detail = responseData.detail || responseData;\n\n return {\n status: detail.status ?? \"in_progress\",\n guardian_info_uuid: detail.guardian_info_uuid ?? null,\n verification_reference: detail.verification_reference ?? null,\n guardian_details: detail.guardian_details ?? null,\n error: detail.error ?? null,\n error_code: detail.error_code ?? null,\n can_retry: detail.can_retry ?? true,\n };\n};\n","import { decodeTokenSafely } from \"../core/jwt-decode\";\nimport type {\n ConsentContent,\n DataElementSelection,\n FetchNoticeConsentStatusForScopeParams,\n FetchNoticeConsentStatusParams,\n LedgerConsentOverlay,\n NoticeConsentStatusResponse,\n PurposeSelection,\n} from \"./types\";\n\n/**\n * Go-ledger notice `check-consent` read.\n *\n * Post-cutover, consent records live in the Go ledger, so Python's notice\n * validation (which powered the 409 CONSENT_ALREADY_PROVIDED and the\n * `purpose_selections` / `reconsent_required` overlay) reads an empty consent\n * DB. When a `ledgerBaseUrl` is configured, the modal and the inline embed ask\n * the ledger directly instead.\n *\n * Every failure mode (no ledger configured, undecodable token, non-OK\n * response, network/abort/parse error) degrades to `null` so callers fall\n * back to the legacy Python-driven flow.\n */\n\n/**\n * Fetch the principal's current consent status for a notice from the Go\n * ledger (`check-consent`), with org/workspace supplied explicitly. The\n * principal resolves from the bearer token server-side, so the body is empty.\n * Returns null on any failure so the caller can fall back to the legacy flow.\n */\nexport const fetchNoticeConsentStatusForScope = async ({\n accessToken,\n ledgerBaseUrl,\n organisationUuid,\n workspaceUuid,\n noticeUuid,\n signal,\n}: FetchNoticeConsentStatusForScopeParams): Promise<NoticeConsentStatusResponse | null> => {\n if (!accessToken || !ledgerBaseUrl || !organisationUuid || !workspaceUuid || !noticeUuid) {\n return null;\n }\n\n try {\n const response = await fetch(\n `${ledgerBaseUrl}/public/organisations/${organisationUuid}/workspaces/${workspaceUuid}/notices/${noticeUuid}/check-consent`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: \"{}\",\n signal,\n }\n );\n\n if (!response.ok) return null;\n\n const data = (await response.json()) as\n | NoticeConsentStatusResponse\n | { detail?: NoticeConsentStatusResponse };\n // The ledger returns the response directly; tolerate a {detail} envelope too.\n const body =\n data && typeof data === \"object\" && \"detail\" in data && data.detail\n ? data.detail\n : (data as NoticeConsentStatusResponse);\n\n if (!body || !Array.isArray(body.purposes)) return null;\n return body;\n } catch {\n // Network / abort / parse failure — degrade to the legacy Python flow.\n return null;\n }\n};\n\n/**\n * Same read, resolving org/workspace by decoding the JWT (the modal's tokens\n * carry them). Returns null on any failure.\n */\nexport const fetchNoticeConsentStatus = async ({\n accessToken,\n ledgerBaseUrl,\n noticeUuid,\n signal,\n}: FetchNoticeConsentStatusParams): Promise<NoticeConsentStatusResponse | null> => {\n if (!accessToken || !ledgerBaseUrl || !noticeUuid) return null;\n\n const decodedToken = decodeTokenSafely(accessToken);\n if (!decodedToken) return null;\n\n const { organisation_uuid: ORG, workspace_uuid: WS } = decodedToken;\n if (!ORG || !WS) return null;\n\n return fetchNoticeConsentStatusForScope({\n accessToken,\n ledgerBaseUrl,\n organisationUuid: ORG,\n workspaceUuid: WS,\n noticeUuid,\n signal,\n });\n};\n\n/**\n * Whether the principal has already fully consented to this notice with no\n * reconsent needed — the ledger equivalent of Python's 409\n * `CONSENT_ALREADY_PROVIDED`. Requires an active consent record with every\n * mandatory purpose still ACTIVE.\n */\nexport const isNoticeFullyConsented = (status: NoticeConsentStatusResponse): boolean =>\n status.consented && status.all_mandatory_active;\n\n/**\n * Translate the ledger's notice consent status into the\n * `{ purpose_selections, reconsent_required }` shape the modal already\n * consumes, so prior-consent pre-fill and reconsent categorization work off\n * the ledger. Returns null for a first-time principal (no consent record —\n * every purpose INACTIVE), preserving the normal first-time consent flow.\n *\n * `needs_reconsent` is derived from `status` (anything not ACTIVE needs\n * reconsent: expired / withdrawn / declined / inactive). NOTE: notice-version\n * reconsent is NOT covered — the ledger's check-consent has no version\n * awareness yet, so a republished-notice version bump won't re-prompt until\n * that lands on the ledger (tracked fast-follow).\n */\nexport const buildLedgerConsentOverlay = (\n status: NoticeConsentStatusResponse,\n configPurposes: ConsentContent[\"detail\"][\"active_config\"][\"purposes\"]\n): LedgerConsentOverlay | null => {\n const byUuid = new Map(status.purposes.map((p) => [p.uuid, p]));\n const hasHistory = status.purposes.some((p) => (p.status || \"INACTIVE\") !== \"INACTIVE\");\n if (!hasHistory) return null;\n\n const purpose_selections: Record<string, PurposeSelection> = {};\n for (const cp of configPurposes) {\n const lp = byUuid.get(cp.uuid);\n const purposeStatus = lp?.status || \"INACTIVE\";\n const selectedByUuid = new Map((lp?.data_elements || []).map((de) => [de.uuid, de.selected]));\n const data_elements: Record<string, DataElementSelection> = {};\n for (const de of cp.data_elements) {\n data_elements[de.uuid] = {\n selected: selectedByUuid.get(de.uuid) ?? false,\n enabled: de.enabled,\n required: de.required,\n };\n }\n purpose_selections[cp.uuid] = {\n selected: lp?.selected ?? false,\n status: purposeStatus,\n needs_reconsent: purposeStatus !== \"ACTIVE\",\n data_elements,\n };\n }\n\n const reconsent_required = configPurposes.some(\n (cp) => (purpose_selections[cp.uuid]?.status || \"INACTIVE\") !== \"ACTIVE\"\n );\n return { reconsent_required, purpose_selections };\n};\n","const STYLE_ID = \"redacto-consent-checkbox-styles\";\n\nconst STYLE_CONTENT = `\n /* Redacto Consent SDK Checkbox Styles */\n .redacto-checkbox-large {\n appearance: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n height: 20px !important;\n width: 20px !important;\n border: 2px solid #d0d5dd !important;\n border-radius: 5px !important;\n background-color: transparent !important;\n cursor: pointer !important;\n position: relative !important;\n box-sizing: border-box !important;\n margin: 0 !important;\n padding: 4px !important;\n }\n\n .redacto-checkbox-small {\n appearance: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n height: 16px !important;\n width: 16px !important;\n border: 2px solid #d0d5dd !important;\n border-radius: 5px !important;\n background-color: transparent !important;\n cursor: pointer !important;\n position: relative !important;\n box-sizing: border-box !important;\n margin: 0 !important;\n padding: 4px !important;\n }\n\n .redacto-checkbox-large:checked {\n background-color: #4f87ff !important;\n border-color: #4f87ff !important;\n }\n\n .redacto-checkbox-small:checked {\n background-color: #4f87ff !important;\n border-color: #4f87ff !important;\n }\n\n .redacto-checkbox-large:checked::after {\n content: '' !important;\n position: absolute !important;\n left: 50% !important;\n top: 50% !important;\n transform: translate(-50%, -50%) rotate(45deg) !important;\n width: 4px !important;\n height: 8px !important;\n border: solid white !important;\n border-width: 0 2px 2px 0 !important;\n box-sizing: border-box !important;\n }\n\n .redacto-checkbox-small:checked::after {\n content: '' !important;\n position: absolute !important;\n left: 50% !important;\n top: 50% !important;\n transform: translate(-50%, -50%) rotate(45deg) !important;\n width: 3px !important;\n height: 6px !important;\n border: solid white !important;\n border-width: 0 1.5px 1.5px 0 !important;\n box-sizing: border-box !important;\n }\n\n .redacto-checkbox-large:focus {\n outline: 2px solid #4f87ff !important;\n outline-offset: 2px !important;\n }\n\n .redacto-checkbox-small:focus {\n outline: 2px solid #4f87ff !important;\n outline-offset: 2px !important;\n }\n\n /* TTS Highlight Styles */\n .redacto-tts-highlight {\n position: relative !important;\n transition: background-color 0.3s ease, outline 0.3s ease !important;\n }\n\n h2.redacto-tts-highlight,\n h3.redacto-tts-highlight {\n background-color: #FFF9C4 !important;\n border-radius: 3px !important;\n padding: 2px 4px !important;\n margin: -2px -4px !important;\n }\n\n span.redacto-tts-highlight,\n a.redacto-tts-highlight {\n background-color: #FFF9C4 !important;\n border-radius: 3px !important;\n padding: 2px 4px !important;\n margin: -2px -4px !important;\n }\n\n p.redacto-tts-highlight {\n background-color: #FFF9C4 !important;\n border-radius: 3px !important;\n padding: 2px 4px !important;\n margin: -2px -4px !important;\n }\n\n button.redacto-tts-highlight {\n outline: 3px solid #FFF9C4 !important;\n outline-offset: 2px !important;\n }\n\n /* Overlay fade-in */\n @keyframes overlayFadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n\n /* Spinner animation */\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n\n /* DigiLocker callback retry button hover */\n .redacto-dl-retry-btn:hover {\n background-color: #2563eb !important;\n }\n `;\n\n/**\n * Inject the checkbox / TTS / animation stylesheet into the given root.\n *\n * - When called with a `Document`, the style tag is placed in `document.head`.\n * - When called with a `ShadowRoot`, the style tag is placed inside the shadow\n * so it only applies within that shadow tree (full CSS isolation from the\n * host page).\n *\n * No-ops if the stylesheet is already present in the target root.\n */\nexport const injectCheckboxStyles = (\n root: Document | ShadowRoot\n): void => {\n if (typeof document === \"undefined\") return;\n\n // Skip if already injected into this root.\n const existing =\n root instanceof Document\n ? root.getElementById(STYLE_ID)\n : root.querySelector(`#${STYLE_ID}`);\n if (existing) return;\n\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = STYLE_CONTENT;\n\n if (root instanceof Document) {\n root.head.appendChild(style);\n } else {\n root.appendChild(style);\n }\n};\n","export const styles = {\n overlay: {\n position: \"fixed\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n backgroundColor: \"rgba(0, 0, 0, 0.5)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n zIndex: 999,\n animation: \"overlayFadeIn 0.2s cubic-bezier(0.16, 1, 0.3, 1)\",\n pointerEvents: \"all\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n modal: {\n position: \"fixed\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n width: \"700px\",\n borderRadius: \"8px\",\n backgroundColor: \"#ffffff\",\n boxShadow: \"4px 0px 4px 0px #00000040\",\n border: \"none\",\n display: \"flex\",\n flexDirection: \"column\",\n maxHeight: \"90vh\",\n zIndex: 1000,\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n fontFamily: \"inherit\",\n },\n\n content: {\n margin: \"22px\",\n display: \"flex\",\n flexDirection: \"column\",\n flexGrow: 1,\n overflow: \"hidden\",\n minHeight: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n topSection: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"flex-start\",\n gap: \"10px\",\n paddingBottom: \"15px\",\n borderBottom: \"none\",\n backgroundColor: \"#ffffff\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n topLeft: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n flex: \"1 1 0\",\n minWidth: 0,\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n // The main notice header is two stacked rows: the logo alone on row 1,\n // aligned per active_config.logo_position, then the title and the\n // TTS/language controls on row 2. `topSection` and `topLeft` above keep their\n // single-row shape for the age-verification, guardian and verification\n // screens, which have no controls to place and share those styles.\n // Mirrors consent-sdk-react/src/RedactoNoticeConsent/styles.ts.\n headerStack: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n gap: \"10px\",\n paddingBottom: \"15px\",\n borderBottom: \"none\",\n backgroundColor: \"#ffffff\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n logoRow: {\n display: \"flex\",\n alignItems: \"center\",\n width: \"100%\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n headerRow: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"10px\",\n width: \"100%\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n logo: {\n height: \"32px\",\n width: \"auto\",\n maxWidth: \"140px\",\n objectFit: \"contain\",\n flexShrink: 0,\n margin: 0,\n padding: 0,\n display: \"block\",\n },\n\n title: {\n fontSize: \"18px\",\n fontWeight: 700,\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n verticalAlign: \"middle\",\n color: \"#101828\",\n flex: \"1 1 auto\",\n minWidth: 0,\n wordBreak: \"normal\",\n overflowWrap: \"anywhere\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n topRight: {\n borderRadius: \"8px\",\n padding: \"3px 9px\",\n border: \"1px solid #d0d5dd\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n fontWeight: 400,\n fontSize: \"12px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n verticalAlign: \"middle\",\n color: \"#344054\",\n gap: \"5px\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n cursor: \"pointer\",\n backgroundColor: \"#ffffff\",\n },\n\n middleSection: {\n margin: \"0px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"12px\",\n flexGrow: 1,\n overflowY: \"auto\",\n minHeight: 0,\n paddingRight: \"15px\",\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n privacyText: {\n fontSize: \"16px\",\n fontWeight: 400,\n lineHeight: \"150%\",\n color: \"#344054\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n link: {\n color: \"#4f87ff\",\n textDecoration: \"none\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n subTitle: {\n fontWeight: 600,\n fontSize: \"16px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#101828\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n optionsContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"10px\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionItem: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionLeft: {\n display: \"flex\",\n gap: \"12px\",\n alignItems: \"center\",\n cursor: \"pointer\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionTextContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionTitle: {\n fontWeight: 500,\n fontSize: \"16px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#101828\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n optionDescription: {\n fontWeight: 400,\n fontSize: \"12px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#475467\",\n verticalAlign: \"middle\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n checkboxLarge: {\n height: \"20px\",\n width: \"20px\",\n padding: \"4px\",\n borderRadius: \"5px\",\n border: \"2px solid #d0d5dd\",\n margin: 0,\n boxSizing: \"border-box\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n MozAppearance: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n backgroundColor: \"transparent\",\n },\n\n dataElementsContainer: {\n marginLeft: \"27px\",\n display: \"flex\",\n flexDirection: \"column\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n paddingLeft: \"22px\",\n },\n\n dataElementItem: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n justifyContent: \"space-between\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n minHeight: \"24px\",\n },\n\n dataElementText: {\n fontWeight: 400,\n fontSize: \"14px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#344054\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n checkboxSmall: {\n height: \"16px\",\n width: \"16px\",\n padding: \"4px\",\n borderRadius: \"5px\",\n border: \"2px solid #d0d5dd\",\n margin: 0,\n boxSizing: \"border-box\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n MozAppearance: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n backgroundColor: \"transparent\",\n },\n\n bottomSection: {\n display: \"flex\",\n justifyContent: \"space-between\",\n gap: \"29px\",\n paddingTop: \"15px\",\n borderTop: \"none\",\n backgroundColor: \"#ffffff\",\n margin: 0,\n boxSizing: \"border-box\",\n },\n\n button: {\n width: \"100%\",\n borderRadius: \"8px\",\n padding: \"9px 45px\",\n fontWeight: 400,\n fontSize: \"16px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n cursor: \"pointer\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"center\",\n },\n\n acceptButton: {\n backgroundColor: \"#4f87ff\",\n border: \"none\",\n color: \"#ffffff\",\n },\n\n cancelButton: {\n border: \"1px solid #d0d5dd\",\n backgroundColor: \"#ffffff\",\n color: \"#000000\",\n },\n\n languageSelectorContainer: {\n position: \"relative\",\n // Shares `headerRow` with the title, which grows; without this a long\n // heading squeezes the language button instead of wrapping itself.\n flexShrink: 0,\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n languageDropdown: {\n position: \"absolute\",\n top: \"100%\",\n right: 0,\n backgroundColor: \"#ffffff\",\n border: \"1px solid #d0d5dd\",\n borderRadius: \"4px\",\n boxShadow: \"0px 2px 4px rgba(0, 0, 0, 0.1)\",\n zIndex: 10,\n width: \"max-content\",\n maxHeight: \"200px\",\n overflowY: \"auto\",\n marginTop: \"4px\",\n padding: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n languageItem: {\n padding: \"8px 12px\",\n cursor: \"pointer\",\n fontSize: \"12px\",\n color: \"#344054\",\n backgroundColor: \"#ffffff\",\n borderBottom: \"1px solid #e5e7eb\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n selectedLanguageItem: {\n backgroundColor: \"#f3f4f6\",\n fontWeight: 600,\n },\n\n loadingContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"2rem\",\n minHeight: \"200px\",\n margin: 0,\n boxSizing: \"border-box\",\n },\n\n loadingSpinner: {\n width: \"40px\",\n height: \"40px\",\n border: \"4px solid #f3f3f3\",\n borderTop: \"4px solid #3498db\",\n borderRadius: \"50%\",\n animation: \"spin 1s linear infinite\",\n marginBottom: \"1rem\",\n boxSizing: \"border-box\",\n },\n} as const;\n","import { el, svg, applyStyles } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { PurposeItemData, Settings } from \"../api/types\";\n\nexport type ModalPurposeRefs = {\n container: HTMLElement;\n checkboxes: Map<string, HTMLInputElement>;\n collapseButtons: Map<string, HTMLElement>;\n dataElementContainers: Map<string, HTMLElement>;\n chevrons: Map<string, SVGElement>;\n titleElements: Map<string, HTMLElement>;\n descriptionElements: Map<string, HTMLElement>;\n dataElementLabels: Map<string, HTMLElement>;\n};\n\nexport function renderModalPurposes(\n purposes: PurposeItemData[],\n options: {\n selectedPurposes: Record<string, boolean>;\n collapsedPurposes: Record<string, boolean>;\n selectedDataElements: Record<string, boolean>;\n initialDataElementSelections?: Record<string, boolean>;\n settings?: Partial<Settings>;\n isMobile: boolean;\n isAlreadyConsented: boolean;\n getTranslatedText: (key: string, defaultText: string, itemId?: string) => string;\n onPurposeToggle: (purposeUuid: string) => void;\n onPurposeCollapse: (purposeUuid: string) => void;\n onDataElementToggle: (elementUuid: string, purposeUuid: string) => void;\n }\n): ModalPurposeRefs {\n const {\n selectedPurposes,\n collapsedPurposes,\n selectedDataElements,\n initialDataElementSelections = {},\n settings,\n isMobile,\n isAlreadyConsented,\n getTranslatedText,\n onPurposeToggle,\n onPurposeCollapse,\n onDataElementToggle,\n } = options;\n\n const checkboxes = new Map<string, HTMLInputElement>();\n const collapseButtons = new Map<string, HTMLElement>();\n const dataElementContainers = new Map<string, HTMLElement>();\n const chevrons = new Map<string, SVGElement>();\n const titleElements = new Map<string, HTMLElement>();\n const descriptionElements = new Map<string, HTMLElement>();\n const dataElementLabels = new Map<string, HTMLElement>();\n\n const headingColor = settings?.headingColor || \"#323B4B\";\n const textColor = settings?.textColor || \"#344054\";\n const font = settings?.font || \"inherit\";\n\n const container = el(\"div\", { style: styles.optionsContainer });\n\n for (const purpose of purposes) {\n const purposeWrapper = el(\"div\");\n\n // Chevron\n const chevron = svg(\n \"svg\",\n {\n width: \"7\",\n height: \"12\",\n viewBox: \"0 0 7 12\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n stroke: headingColor,\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n style: {\n transform: !collapsedPurposes[purpose.uuid] ? \"rotate(90deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.3s ease\",\n },\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", { d: \"M1 1L6 6L1 11\" })\n );\n chevrons.set(purpose.uuid, chevron);\n\n const chevronContainer = el(\n \"div\",\n { style: { display: \"flex\", alignItems: \"center\", justifyContent: \"center\", marginLeft: \"5px\" } },\n chevron\n );\n\n // Title\n const titleEl = el(\"h2\", {\n id: `purpose-name-${purpose.uuid}`,\n style: {\n ...styles.optionTitle,\n fontSize: isMobile ? \"14px\" : \"16px\",\n color: headingColor,\n fontFamily: font,\n },\n });\n titleEl.textContent = getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid);\n titleElements.set(purpose.uuid, titleEl);\n\n // Description\n const descEl = el(\"h3\", {\n id: `purpose-description-${purpose.uuid}`,\n style: {\n ...styles.optionDescription,\n fontSize: isMobile ? \"11px\" : \"12px\",\n color: textColor,\n fontFamily: font,\n },\n });\n descEl.textContent = getTranslatedText(\"purposes.description\", purpose.description, purpose.uuid);\n descriptionElements.set(purpose.uuid, descEl);\n\n const textContainer = el(\"div\", { style: styles.optionTextContainer }, titleEl, descEl);\n\n // Collapse button\n const collapseBtn = el(\"div\", {\n style: styles.optionLeft,\n role: \"button\",\n tabIndex: \"0\",\n \"aria-expanded\": String(!collapsedPurposes[purpose.uuid]),\n \"aria-controls\": `purpose-${purpose.uuid}`,\n \"aria-label\": `${collapsedPurposes[purpose.uuid] ? \"Expand\" : \"Collapse\"} ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)} details`,\n onClick: () => onPurposeCollapse(purpose.uuid),\n onKeydown: (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onPurposeCollapse(purpose.uuid);\n }\n },\n }, chevronContainer, textContainer);\n collapseButtons.set(purpose.uuid, collapseBtn);\n\n // Purpose checkbox or green checkmark\n let rightElement: HTMLElement;\n if (!isAlreadyConsented) {\n const purposeCheckbox = el(\"input\", {\n className: \"redacto-checkbox-large\",\n type: \"checkbox\",\n checked: selectedPurposes[purpose.uuid] || false,\n \"aria-label\": `Select all data elements for ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)}`,\n onChange: () => onPurposeToggle(purpose.uuid),\n }) as HTMLInputElement;\n checkboxes.set(purpose.uuid, purposeCheckbox);\n rightElement = purposeCheckbox;\n } else {\n rightElement = createGreenCheckmark(\n 20,\n `Already consented to ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)}`\n );\n applyStyles(rightElement, { marginLeft: \"12px\" });\n }\n\n const optionRow = el(\"div\", { style: styles.optionItem }, collapseBtn, rightElement);\n\n // Data elements\n const deContainer = el(\"div\", {\n id: `purpose-${purpose.uuid}`,\n style: styles.dataElementsContainer,\n });\n\n if (purpose.data_elements?.length > 0) {\n for (const dataElement of purpose.data_elements) {\n const combinedId = `${purpose.uuid}-${dataElement.uuid}`;\n\n const labelSpan = el(\"span\", {\n id: `data-element-${purpose.uuid}-${dataElement.uuid}`,\n style: {\n ...styles.dataElementText,\n fontSize: isMobile ? \"12px\" : \"14px\",\n color: textColor,\n fontFamily: font,\n },\n });\n labelSpan.textContent = getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid);\n dataElementLabels.set(combinedId, labelSpan);\n\n if (dataElement.required) {\n const asterisk = el(\"span\", { style: { color: \"red\", marginLeft: \"4px\" }, \"aria-label\": \"required\" });\n asterisk.textContent = \"*\";\n labelSpan.appendChild(asterisk);\n }\n\n let deRightElement: HTMLElement;\n if (!isAlreadyConsented) {\n const deCheckbox = el(\"input\", {\n className: \"redacto-checkbox-small\",\n type: \"checkbox\",\n checked: selectedDataElements[combinedId] || false,\n \"aria-label\": `Select ${getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid)}${dataElement.required ? \" (required)\" : \"\"}`,\n onChange: () => onDataElementToggle(dataElement.uuid, purpose.uuid),\n }) as HTMLInputElement;\n checkboxes.set(combinedId, deCheckbox);\n deRightElement = deCheckbox;\n } else {\n const wasSelected = initialDataElementSelections[combinedId] || false;\n if (wasSelected) {\n deRightElement = createGreenCheckmark(\n 16,\n `Consented to ${getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid)}`\n );\n } else {\n deRightElement = el(\"div\", {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"16px\",\n height: \"16px\",\n borderRadius: \"50%\",\n border: \"2px solid #d0d5dd\",\n backgroundColor: \"transparent\",\n },\n \"aria-label\": `Not consented to ${getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid)}`,\n });\n }\n }\n\n const deRow = el(\"div\", { style: styles.dataElementItem }, labelSpan, deRightElement);\n deContainer.appendChild(deRow);\n }\n }\n\n dataElementContainers.set(purpose.uuid, deContainer);\n deContainer.style.display = !collapsedPurposes[purpose.uuid] && purpose.data_elements?.length > 0 ? \"flex\" : \"none\";\n\n purposeWrapper.appendChild(optionRow);\n purposeWrapper.appendChild(deContainer);\n container.appendChild(purposeWrapper);\n }\n\n return {\n container,\n checkboxes,\n collapseButtons,\n dataElementContainers,\n chevrons,\n titleElements,\n descriptionElements,\n dataElementLabels,\n };\n}\n\nfunction createGreenCheckmark(size: number, ariaLabel: string): HTMLElement {\n const svgSize = size === 20 ? 12 : 10;\n const strokeWidth = size === 20 ? \"2\" : \"1.5\";\n const pathD = size === 20 ? \"M4 6L5.5 7.5L8.5 4.5\" : \"M3 5L4.5 6.5L7.5 3.5\";\n\n const checkSvg = svg(\n \"svg\",\n {\n width: String(svgSize),\n height: String(svgSize),\n viewBox: `0 0 ${svgSize} ${svgSize}`,\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", {\n d: pathD,\n stroke: \"white\",\n \"stroke-width\": strokeWidth,\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n })\n );\n\n return el(\"div\", {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: `${size}px`,\n height: `${size}px`,\n borderRadius: \"50%\",\n backgroundColor: \"#10B981\",\n },\n \"aria-label\": ariaLabel,\n }, checkSvg);\n}\n","import { el, svg, applyStyles } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { Settings } from \"../api/types\";\n\nconst LANGUAGE_NATIVE_LABELS: Record<string, string> = {\n English: \"English\",\n Assamese: \"অসমীয়া (Assamese)\",\n Bengali: \"বাংলা (Bengali)\",\n Bodo: \"बड़ो (Bodo)\",\n Dogri: \"डोगरी (Dogri)\",\n \"Goan Konkani\": \"कोंकणी (Goan Konkani)\",\n Gujarati: \"ગુજરાતી (Gujarati)\",\n Hindi: \"हिन्दी (Hindi)\",\n Kannada: \"ಕನ್ನಡ (Kannada)\",\n Kashmiri: \"كٲشُر (Kashmiri)\",\n Maithili: \"मैथिली (Maithili)\",\n Malayalam: \"മലയാളം (Malayalam)\",\n Manipuri: \"ꯃꯩꯇꯩꯂꯣꯟ (Manipuri)\",\n Marathi: \"मराठी (Marathi)\",\n Nepali: \"नेपाली (Nepali)\",\n Odia: \"ଓଡ଼ିଆ (Odia)\",\n Punjabi: \"ਪੰਜਾਬੀ (Punjabi)\",\n Sanskrit: \"संस्कृतम् (Sanskrit)\",\n Santali: \"ᱥᱟᱱᱛᱟᱲᱤ (Santali)\",\n Sindhi: \"سنڌي (Sindhi)\",\n Tamil: \"தமிழ் (Tamil)\",\n Telugu: \"తెలుగు (Telugu)\",\n Urdu: \"اردو (Urdu)\",\n};\n\nconst toNativeLabel = (name: string): string => LANGUAGE_NATIVE_LABELS[name] ?? name;\n\nexport type LanguageSelectorRefs = {\n container: HTMLElement;\n button: HTMLElement;\n dropdown: HTMLElement;\n buttonText: HTMLElement;\n};\n\nexport function renderLanguageSelector(options: {\n languages: string[];\n selectedLanguage: string;\n settings?: Partial<Settings>;\n onSelect: (lang: string) => void;\n /**\n * Where the dropdown panel itself is appended. We append it as a sibling of\n * the modal (rather than inside `container`) so it can escape the modal's\n * `transform: translate(...)` stacking context. Pass the shadow root when\n * the modal is rendered inside a shadow boundary; otherwise pass\n * `document.body`.\n */\n dropdownContainer: HTMLElement | ShadowRoot;\n}): LanguageSelectorRefs {\n const { languages, selectedLanguage, settings, onSelect, dropdownContainer } = options;\n\n let isOpen = false;\n\n const buttonText = el(\"span\");\n buttonText.textContent = toNativeLabel(selectedLanguage);\n\n const chevronSvg = svg(\n \"svg\",\n {\n width: \"8\",\n height: \"5\",\n viewBox: \"0 0 8 5\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n },\n svg(\"path\", {\n d: \"M1 1L4 4L7 1\",\n stroke: settings?.button?.language?.textColor || \"#344054\",\n \"stroke-width\": \"1.5\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n })\n );\n\n const buttonStyle: Record<string, any> = { ...styles.topRight };\n if (settings?.button?.language) {\n buttonStyle.backgroundColor = settings.button.language.backgroundColor;\n buttonStyle.color = settings.button.language.textColor;\n }\n\n const button = el(\"div\", {\n style: buttonStyle,\n role: \"button\",\n tabIndex: \"0\",\n \"aria-haspopup\": \"listbox\",\n \"aria-expanded\": \"false\",\n \"aria-label\": `Language selector, current: ${toNativeLabel(selectedLanguage)}`,\n onClick: () => toggleDropdown(),\n onKeydown: (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n toggleDropdown();\n } else if (e.key === \"Escape\") {\n closeDropdown();\n }\n },\n }, buttonText, chevronSvg);\n\n // Dropdown — uses position:fixed to escape modal's transform stacking context\n const dropdown = el(\"div\", {\n style: {\n position: \"fixed\",\n backgroundColor: \"#ffffff\",\n border: \"1px solid #d0d5dd\",\n borderRadius: \"4px\",\n boxShadow: \"0px 4px 12px rgba(0, 0, 0, 0.15)\",\n zIndex: 2147483647, // max int — always on top\n minWidth: \"140px\",\n maxHeight: \"200px\",\n overflowY: \"auto\",\n padding: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n display: \"none\",\n },\n role: \"listbox\",\n \"aria-label\": \"Select language\",\n });\n\n for (const lang of languages) {\n const isSelected = lang === selectedLanguage;\n const itemStyle = isSelected\n ? { ...styles.languageItem, ...styles.selectedLanguageItem }\n : { ...styles.languageItem };\n\n if (settings?.button?.language) {\n if (isSelected && settings.button.language.selectedBackgroundColor) {\n itemStyle.backgroundColor = settings.button.language.selectedBackgroundColor;\n }\n if (isSelected && settings.button.language.selectedTextColor) {\n itemStyle.color = settings.button.language.selectedTextColor;\n }\n }\n\n const item = el(\"div\", {\n style: itemStyle,\n role: \"option\",\n \"aria-selected\": String(isSelected),\n onClick: () => {\n onSelect(lang);\n closeDropdown();\n },\n onMouseenter: (e: Event) => {\n (e.target as HTMLElement).style.backgroundColor = \"#f3f4f6\";\n },\n onMouseleave: (e: Event) => {\n (e.target as HTMLElement).style.backgroundColor = isSelected ? \"#f3f4f6\" : \"#ffffff\";\n },\n });\n item.textContent = toNativeLabel(lang);\n dropdown.appendChild(item);\n }\n\n // Container only holds the button — dropdown is appended to its container\n // (shadow root in the modal flow, body for non-shadow callers) so it can\n // escape the modal's transform stacking context.\n const container = el(\"div\", { style: styles.languageSelectorContainer }, button);\n\n dropdownContainer.appendChild(dropdown);\n\n function positionDropdown() {\n const rect = button.getBoundingClientRect();\n dropdown.style.top = `${rect.bottom + 4}px`;\n dropdown.style.right = `${window.innerWidth - rect.right}px`;\n dropdown.style.left = \"auto\";\n }\n\n // Click outside handler. When the modal is inside a shadow root the click\n // event's `target` is retargeted to the shadow host for listeners on the\n // document. `composedPath()` returns the real path through the shadow tree\n // so we can correctly detect whether the click originated inside the\n // selector or its dropdown.\n const clickOutsideHandler = (e: Event) => {\n const path = (e as Event & { composedPath?: () => EventTarget[] }).composedPath?.() ?? [];\n if (path.includes(container) || path.includes(dropdown)) return;\n\n // Fallback for environments without composedPath()\n if (path.length === 0) {\n const target = e.target as Node;\n if (container.contains(target) || dropdown.contains(target)) return;\n }\n closeDropdown();\n };\n\n // Reposition on scroll/resize while open\n const repositionHandler = () => {\n if (isOpen) positionDropdown();\n };\n\n function toggleDropdown() {\n isOpen ? closeDropdown() : openDropdown();\n }\n\n function openDropdown() {\n isOpen = true;\n positionDropdown();\n dropdown.style.display = \"block\";\n button.setAttribute(\"aria-expanded\", \"true\");\n setTimeout(() => {\n document.addEventListener(\"click\", clickOutsideHandler);\n }, 0);\n window.addEventListener(\"scroll\", repositionHandler, true);\n window.addEventListener(\"resize\", repositionHandler);\n }\n\n function closeDropdown() {\n isOpen = false;\n dropdown.style.display = \"none\";\n button.setAttribute(\"aria-expanded\", \"false\");\n document.removeEventListener(\"click\", clickOutsideHandler);\n window.removeEventListener(\"scroll\", repositionHandler, true);\n window.removeEventListener(\"resize\", repositionHandler);\n }\n\n return { container, button, dropdown, buttonText };\n}\n","/**\n * Focus trap + keyboard navigation for the modal.\n */\n\nexport type KeyboardTrapCleanup = () => void;\n\nexport function setupKeyboardTrap(\n modalEl: HTMLElement,\n onEscape: () => void\n): KeyboardTrapCleanup {\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onEscape();\n return;\n }\n\n if (e.key === \"Tab\") {\n const focusableElements = modalEl.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n const focusable = Array.from(focusableElements).filter(\n (el) => !el.hasAttribute(\"disabled\") && el.offsetParent !== null\n );\n\n if (focusable.length === 0) {\n e.preventDefault();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n // When the modal lives inside a shadow root, document.activeElement\n // returns the shadow host rather than the actually focused element.\n // Read activeElement from the modal's own root for a correct answer.\n const root = modalEl.getRootNode() as Document | ShadowRoot;\n const active =\n (root as ShadowRoot).activeElement ?? document.activeElement;\n\n if (e.shiftKey) {\n if (active === first) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (active === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n };\n\n document.addEventListener(\"keydown\", handler);\n\n // Auto-focus first focusable element\n requestAnimationFrame(() => {\n const firstFocusable = modalEl.querySelector<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n firstFocusable?.focus();\n });\n\n return () => {\n document.removeEventListener(\"keydown\", handler);\n };\n}\n","import type { PersistedConsentState } from \"../api/types\";\n\nconst STORAGE_KEY = \"redacto_consent_sdk_state\";\nconst STATE_EXPIRY_MS = 30 * 60 * 1000; // 30 minutes\n\nconst isBrowser = (): boolean => {\n return typeof window !== \"undefined\" && typeof window.sessionStorage !== \"undefined\";\n};\n\nexport const saveConsentState = (state: PersistedConsentState): void => {\n if (!isBrowser()) {\n console.warn(\"SessionStorage not available - state not persisted\");\n return;\n }\n\n try {\n const stateWithTimestamp = {\n ...state,\n timestamp: new Date().toISOString(),\n };\n sessionStorage.setItem(STORAGE_KEY, JSON.stringify(stateWithTimestamp));\n } catch (error) {\n console.error(\"Failed to save consent state:\", error);\n }\n};\n\nexport const getConsentState = (): PersistedConsentState | null => {\n if (!isBrowser()) return null;\n\n try {\n const savedState = sessionStorage.getItem(STORAGE_KEY);\n if (!savedState) return null;\n\n const parsed: PersistedConsentState = JSON.parse(savedState);\n\n const stateAge = Date.now() - new Date(parsed.timestamp).getTime();\n if (stateAge > STATE_EXPIRY_MS) {\n clearConsentState();\n return null;\n }\n\n return parsed;\n } catch (error) {\n console.error(\"Failed to get consent state:\", error);\n return null;\n }\n};\n\nexport const clearConsentState = (): void => {\n if (!isBrowser()) return;\n\n try {\n sessionStorage.removeItem(STORAGE_KEY);\n } catch (error) {\n console.error(\"Failed to clear consent state:\", error);\n }\n};\n\nexport const updateConsentState = (updates: Partial<PersistedConsentState>): void => {\n const currentState = getConsentState();\n if (currentState) {\n saveConsentState({\n ...currentState,\n ...updates,\n timestamp: new Date().toISOString(),\n });\n }\n};\n\nexport const hasPendingVerification = (): boolean => {\n const state = getConsentState();\n return state !== null && state.flowState === \"digilocker-pending\";\n};\n\nexport const getVerificationResult = (): \"pending\" | \"verified\" | \"failed\" | \"in_progress\" | \"expired\" | null => {\n const state = getConsentState();\n return state?.verificationResult ?? null;\n};\n\nexport const getVerificationReference = (): string | null => {\n const state = getConsentState();\n return state?.verificationReference ?? null;\n};\n","import type { DpoInfoAudioKey, LogoPosition } from \"./api/types\";\n\nexport const DEFAULT_LOGO_POSITION: LogoPosition = \"left\";\n\n/**\n * `justify-content` for the logo row, keyed by the configured position. The row\n * is full width, so aligning it is the whole of the layout change.\n */\nexport const LOGO_POSITION_JUSTIFY: Record<LogoPosition, string> = {\n left: \"flex-start\",\n center: \"center\",\n right: \"flex-end\",\n};\n\nexport const DPO_AUDIO_ELEMENT_MAP: ReadonlyArray<{\n audioKey: DpoInfoAudioKey;\n elementId: string;\n}> = [\n { audioKey: \"grievance_text_audio_url\", elementId: \"dpo-grievance-text\" },\n { audioKey: \"grievance_anchor_text_audio_url\", elementId: \"dpo-grievance-link\" },\n { audioKey: \"grievance_email_connector_text_audio_url\", elementId: \"dpo-grievance-email-connector\" },\n { audioKey: \"grievance_email_audio_url\", elementId: \"dpo-grievance-email\" },\n { audioKey: \"dp_board_text_audio_url\", elementId: \"dpo-dp-board-text\" },\n { audioKey: \"dp_board_anchor_text_audio_url\", elementId: \"dpo-dp-board-link\" },\n { audioKey: \"dpo_text_audio_url\", elementId: \"dpo-dpo-text\" },\n { audioKey: \"dpo_anchor_text_audio_url\", elementId: \"dpo-dpo-link\" },\n] as const;\n","import { fetchTTSAudioUrls } from \"../api\";\nimport { DPO_AUDIO_ELEMENT_MAP } from \"../constants\";\nimport type {\n ActiveConfig,\n SandboxOptions,\n TTSAudioUrlsResponse,\n} from \"../api/types\";\n\nexport class TTSManager {\n private audioUrls: TTSAudioUrlsResponse[\"detail\"] | null = null;\n private audioSequence: string[] = [];\n private elementIdSequence: string[] = [];\n private currentAudio: HTMLAudioElement | null = null;\n private currentIndex = 0;\n private _isPlaying = false;\n private _isPaused = false;\n private _isAvailable = false;\n private highlightedElementId: string | null = null;\n private abortController: AbortController | null = null;\n private onStateChange: () => void;\n private root: Document | ShadowRoot;\n\n /**\n * @param onStateChange Invoked whenever playback state changes so the host\n * can refresh its UI (e.g. swap the play/pause icon).\n * @param root The root in which to look up highlightable elements by id.\n * When the modal is rendered inside a shadow root, pass that shadow root\n * so queries stay scoped to the SDK's tree (and don't accidentally hit\n * element ids that the host page also defines).\n */\n constructor(onStateChange: () => void, root: Document | ShadowRoot) {\n this.onStateChange = onStateChange;\n this.root = root;\n }\n\n get isPlaying(): boolean { return this._isPlaying; }\n get isPaused(): boolean { return this._isPaused; }\n get isAvailable(): boolean { return this._isAvailable; }\n\n async fetchAudioUrls(params: SandboxOptions & {\n accessToken?: string;\n baseUrl?: string;\n ledgerBaseUrl?: string;\n noticeUuid: string;\n language: string;\n content: ActiveConfig;\n }): Promise<void> {\n // Reset availability + sequences SYNCHRONOUSLY before notifying. The\n // language can change while a previous language's URLs are still loaded;\n // if we don't clear here, a click on the speaker icon (or the in-flight\n // stop()) would either keep the icon showing or replay the previous\n // language's audio. We then fire a single onStateChange() so the UI hides\n // the icon while the new language's audio is being fetched.\n this.stopInternal();\n this._isAvailable = false;\n this.audioUrls = null;\n this.audioSequence = [];\n this.elementIdSequence = [];\n this.onStateChange();\n\n this.abortController?.abort();\n this.abortController = new AbortController();\n\n try {\n const response = await fetchTTSAudioUrls({\n accessToken: params.accessToken,\n baseUrl: params.baseUrl,\n ledgerBaseUrl: params.ledgerBaseUrl,\n noticeUuid: params.noticeUuid,\n language: params.language,\n signal: this.abortController.signal,\n token: params.token,\n sandboxUcic: params.sandboxUcic,\n sandboxSubject: params.sandboxSubject,\n organisationUuid: params.organisationUuid,\n workspaceUuid: params.workspaceUuid,\n });\n\n this.audioUrls = response.detail;\n this.buildSequences(params.content);\n // Only mark TTS as available if the backend actually returned playable\n // audio for this language. Some languages (e.g. Santali) come back with\n // a 200 but empty / partial fields — surfacing the speaker icon in that\n // case would let users click it and replay the previous language.\n this._isAvailable = this.audioSequence.length > 0;\n this.onStateChange();\n } catch (error) {\n if ((error as Error).name !== \"AbortError\") {\n this._isAvailable = false;\n this.audioUrls = null;\n this.audioSequence = [];\n this.elementIdSequence = [];\n this.onStateChange();\n }\n }\n }\n\n private buildSequences(content: ActiveConfig): void {\n if (!this.audioUrls) return;\n const urls = this.audioUrls;\n\n const audioSeq: string[] = [];\n const elementSeq: string[] = [];\n\n const push = (url: string | undefined, elementId: string) => {\n if (url) {\n audioSeq.push(url);\n elementSeq.push(elementId);\n }\n };\n\n // 1. Notice banner heading\n push(urls.notice_banner_heading_audio_url, \"privacy-notice-title\");\n // 2. Notice text\n push(urls.notice_text_audio_url, \"privacy-notice-text\");\n // 3. Privacy policy prefix text\n push(urls.privacy_policy_prefix_text_audio_url, \"privacy-policy-text\");\n // 4. Privacy policy anchor text\n push(urls.privacy_policy_anchor_text_audio_url, \"privacy-policy-link\");\n // 5. Purpose section heading\n push(urls.purpose_section_heading_audio_url, \"purpose-section-heading\");\n\n // 6. For each purpose: name, description, data elements\n for (const purpose of content.purposes) {\n const purposeAudio = urls.purposes_audio?.[purpose.uuid];\n if (purposeAudio) {\n push(purposeAudio.name_audio_url, `purpose-name-${purpose.uuid}`);\n push(purposeAudio.description_audio_url, `purpose-description-${purpose.uuid}`);\n }\n\n for (const de of purpose.data_elements) {\n const deAudio = urls.data_elements_audio?.[de.uuid];\n if (deAudio) {\n push(deAudio.name_audio_url, `data-element-${purpose.uuid}-${de.uuid}`);\n }\n }\n }\n\n // 7. Additional text\n push(urls.additional_text_audio_url, \"additional-text\");\n // 8. Privacy center anchor text\n push(urls.privacy_center_anchor_text_audio_url, \"privacy-center-link\");\n\n // 9. DPO info audio\n if (urls.dpo_info_audio) {\n for (const mapping of DPO_AUDIO_ELEMENT_MAP) {\n const audioUrl = urls.dpo_info_audio[mapping.audioKey];\n push(audioUrl, mapping.elementId);\n }\n }\n\n // 10. Confirm / Decline buttons\n push(urls.confirm_button_text_audio_url, \"confirm-button-text\");\n push(urls.decline_button_text_audio_url, \"decline-button-text\");\n\n this.audioSequence = audioSeq;\n this.elementIdSequence = elementSeq;\n }\n\n toggle(): void {\n this._isPlaying ? this.pause() : this.play();\n }\n\n play(): void {\n if (this.audioSequence.length === 0) return;\n\n if (this._isPaused && this.currentAudio) {\n this.currentAudio.play()\n .then(() => {\n this._isPlaying = true;\n this._isPaused = false;\n this.onStateChange();\n })\n .catch(() => {});\n } else {\n const startIndex = this._isPlaying ? this.currentIndex : 0;\n this.playNextAudio(startIndex);\n }\n }\n\n pause(): void {\n if (this.currentAudio && this._isPlaying) {\n this.currentAudio.pause();\n this._isPlaying = false;\n this._isPaused = true;\n this.onStateChange();\n }\n }\n\n stop(): void {\n this.stopInternal();\n this.onStateChange();\n }\n\n /**\n * Internal stop used by code paths (like fetchAudioUrls) that will fire\n * their own onStateChange after composing a richer state update — we don't\n * want the intermediate notification to flicker the UI based on a half-set\n * state (e.g. _isAvailable still true from the previous language).\n */\n private stopInternal(): void {\n if (this.currentAudio) {\n this.currentAudio.pause();\n this.currentAudio.currentTime = 0;\n this.currentAudio = null;\n }\n this._isPlaying = false;\n this._isPaused = false;\n this.currentIndex = 0;\n this.removeHighlights();\n this.highlightedElementId = null;\n }\n\n destroy(): void {\n this.abortController?.abort();\n this.stop();\n }\n\n private playNextAudio(index: number): void {\n if (index >= this.audioSequence.length) {\n this.stop();\n return;\n }\n\n if (this.currentAudio) {\n this.currentAudio.pause();\n this.currentAudio = null;\n }\n\n const audio = new Audio(this.audioSequence[index]);\n this.currentAudio = audio;\n this.currentIndex = index;\n this._isPlaying = true;\n this._isPaused = false;\n\n // Highlight\n const elementId = this.elementIdSequence[index];\n if (elementId) {\n this.highlightElement(elementId);\n }\n\n audio.onended = () => this.playNextAudio(index + 1);\n audio.onerror = () => {\n console.warn(`Failed to load audio at index ${index}`);\n this.playNextAudio(index + 1);\n };\n\n audio.play().catch((error) => {\n console.warn(`Failed to play audio at index ${index}:`, error);\n this._isPlaying = false;\n this.onStateChange();\n });\n\n this.onStateChange();\n }\n\n private highlightElement(elementId: string): void {\n this.removeHighlights();\n this.highlightedElementId = elementId;\n\n setTimeout(() => {\n // ShadowRoot has getElementById in modern browsers; fall back to\n // querySelector with CSS.escape for safety.\n const element =\n \"getElementById\" in this.root\n ? (this.root as Document | ShadowRoot & { getElementById(id: string): HTMLElement | null }).getElementById(elementId)\n : (this.root as ShadowRoot).querySelector<HTMLElement>(`#${CSS.escape(elementId)}`);\n if (element) {\n element.classList.add(\"redacto-tts-highlight\");\n\n const rect = element.getBoundingClientRect();\n const isVisible =\n rect.top >= 0 &&\n rect.left >= 0 &&\n rect.bottom <= window.innerHeight &&\n rect.right <= window.innerWidth;\n\n if (!isVisible) {\n element.scrollIntoView({\n behavior: \"smooth\",\n block: \"center\",\n inline: \"nearest\",\n });\n }\n }\n }, 50);\n }\n\n private removeHighlights(): void {\n this.root.querySelectorAll(\".redacto-tts-highlight\").forEach((el) => {\n el.classList.remove(\"redacto-tts-highlight\");\n });\n }\n}\n","import { el, svg } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { Settings } from \"../api/types\";\nimport type { ResolvedColors } from \"./colors\";\n\nexport type AgeVerificationRefs = {\n container: HTMLElement;\n};\n\nexport function renderAgeVerification(options: {\n settings?: Partial<Settings>;\n colors: ResolvedColors;\n isMobile: boolean;\n logoUrl: string;\n onYes: () => void;\n onNo: () => void;\n onClose: () => void;\n}): AgeVerificationRefs {\n const { settings, colors, isMobile, logoUrl, onYes, onNo, onClose } = options;\n\n const headingColor = settings?.headingColor || \"#101828\";\n const textColor = colors.text;\n const font = colors.font;\n\n // ─── Top Section (matches React: logo+title left, X button right) ───\n const logo = el(\"img\", { src: logoUrl, style: styles.logo, alt: \"Redacto Logo\" });\n\n const title = el(\"h2\", {\n id: \"age-verification-title\",\n style: {\n ...styles.title,\n fontSize: isMobile ? \"16px\" : \"18px\",\n color: headingColor,\n fontFamily: font,\n },\n });\n title.textContent = \"Age Verification Required\";\n\n const topLeft = el(\"div\", { style: styles.topLeft }, logo, title);\n\n const closeBtn = el(\"button\", {\n style: {\n background: \"none\",\n border: \"none\",\n color: headingColor,\n cursor: \"pointer\",\n padding: isMobile ? \"2px\" : \"4px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n type: \"button\",\n \"aria-label\": \"Close modal\",\n onClick: onClose,\n });\n const closeSvg = svg(\n \"svg\",\n {\n width: isMobile ? \"18\" : \"20\",\n height: isMobile ? \"18\" : \"20\",\n viewBox: \"0 0 20 20\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", {\n d: \"M15 5L5 15M5 5L15 15\",\n stroke: \"currentColor\",\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n })\n );\n closeBtn.appendChild(closeSvg);\n\n const topSection = el(\"div\", {\n style: { ...styles.topSection, color: textColor, fontFamily: font },\n }, topLeft, closeBtn);\n\n // ─── Middle Section ───\n const description = el(\"p\", {\n style: {\n ...styles.privacyText,\n fontSize: isMobile ? \"14px\" : \"16px\",\n color: textColor,\n fontFamily: font,\n marginBottom: \"16px\",\n },\n });\n description.textContent = \"To proceed with this consent form, we need to verify your age.\";\n\n const question = el(\"p\", {\n style: {\n ...styles.subTitle,\n color: textColor,\n fontFamily: font,\n marginBottom: \"24px\",\n textAlign: \"left\",\n },\n });\n question.textContent = \"Are you 18 years of age or older?\";\n\n const middleSection = el(\"div\", {\n style: { ...styles.middleSection, color: textColor, fontFamily: font },\n }, description, question);\n\n // ─── Bottom Section (Yes first, No second — matches React) ───\n const btnBase = {\n ...styles.button,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n const yesBtn = el(\"button\", {\n style: {\n ...btnBase,\n ...styles.acceptButton,\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderRadius: colors.borderRadius,\n },\n type: \"button\",\n \"aria-label\": \"Confirm that I am 18 years of age or older\",\n onClick: onYes,\n });\n yesBtn.textContent = \"Yes, I am 18 or older\";\n\n const noBtn = el(\"button\", {\n style: {\n ...btnBase,\n ...styles.cancelButton,\n backgroundColor: colors.declineBg,\n color: colors.declineText,\n borderColor: colors.declineBorder,\n borderRadius: colors.borderRadius,\n },\n type: \"button\",\n \"aria-label\": \"Indicate that I am under 18 years of age\",\n onClick: onNo,\n });\n noBtn.textContent = \"No, I am under 18\";\n\n const bottomSection = el(\"div\", {\n style: { ...styles.bottomSection, color: textColor, fontFamily: font },\n }, yesBtn, noBtn);\n\n // ─── Assemble (wrapped in content div like modal) ───\n const container = el(\"div\", { style: styles.content }, topSection, middleSection, bottomSection);\n\n return { container };\n}\n","import { el, svg } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { Settings } from \"../api/types\";\nimport type { ResolvedColors } from \"./colors\";\n\nconst RELATIONSHIP_OPTIONS = [\n { value: \"Father\", label: \"Father\" },\n { value: \"Mother\", label: \"Mother\" },\n { value: \"Legal Guardian\", label: \"Legal Guardian\" },\n { value: \"Grandparent\", label: \"Grandparent\" },\n];\n\nexport type GuardianFormData = {\n guardianName: string;\n guardianContact: string;\n guardianRelationship: string;\n};\n\nexport type GuardianFormRefs = {\n container: HTMLElement;\n nameInput: HTMLInputElement;\n contactInput: HTMLInputElement;\n relationshipDisplay: HTMLElement;\n nameError: HTMLElement;\n contactError: HTMLElement;\n relationshipError: HTMLElement;\n submitBtn: HTMLButtonElement;\n generalError: HTMLElement;\n};\n\nexport function renderGuardianForm(options: {\n formData: GuardianFormData;\n settings?: Partial<Settings>;\n colors: ResolvedColors;\n isMobile: boolean;\n logoUrl: string;\n isSubmitting: boolean;\n onSubmit: () => void;\n onCancel: () => void;\n onFieldChange: (field: keyof GuardianFormData, value: string) => void;\n}): GuardianFormRefs {\n const { formData, settings, colors, isMobile, logoUrl, isSubmitting, onSubmit, onCancel, onFieldChange } = options;\n\n const headingColor = settings?.headingColor || \"#101828\";\n const textColor = colors.text;\n const borderColor = colors.declineBorder;\n const bgColor = settings?.backgroundColor || \"#ffffff\";\n const radius = colors.borderRadius;\n const font = colors.font;\n const accentColor = colors.acceptBg;\n\n const inputStyle: Record<string, any> = {\n width: \"100%\",\n padding: \"10px 12px\",\n border: `1px solid ${borderColor}`,\n borderRadius: radius,\n fontSize: \"13px\",\n fontFamily: font,\n color: textColor,\n backgroundColor: bgColor,\n marginBottom: \"2px\",\n boxSizing: \"border-box\",\n outline: \"none\",\n };\n\n const errorStyle: Record<string, any> = {\n color: \"#DC2626\",\n fontSize: \"11px\",\n marginTop: \"4px\",\n marginBottom: \"0px\",\n display: \"none\",\n };\n\n const labelStyle: Record<string, any> = {\n fontSize: \"13px\",\n fontWeight: 500,\n color: textColor,\n fontFamily: font,\n marginBottom: \"4px\",\n display: \"block\",\n };\n\n const hintStyle: Record<string, any> = {\n fontSize: \"11px\",\n color: \"#667085\",\n marginTop: \"2px\",\n marginBottom: \"0px\",\n lineHeight: \"1.4\",\n };\n\n // ─── Top Section ───\n const logo = el(\"img\", { src: logoUrl, style: styles.logo, alt: \"Logo\" });\n const title = el(\"h2\", {\n id: \"guardian-form-title\",\n style: {\n ...styles.title,\n fontSize: \"16px\",\n fontWeight: 600,\n color: headingColor,\n fontFamily: font,\n },\n });\n title.textContent = \"Guardian Verification\";\n\n const topLeft = el(\"div\", { style: styles.topLeft }, logo, title);\n const topSection = el(\"div\", {\n style: { ...styles.topSection, color: textColor, fontFamily: font },\n }, topLeft);\n\n // ─── Middle Section ───\n const subtitle = el(\"p\", {\n style: {\n ...styles.privacyText,\n fontSize: \"13px\",\n lineHeight: \"1.5\",\n color: textColor,\n fontFamily: font,\n marginBottom: \"12px\",\n },\n });\n subtitle.textContent = \"Since you are under the age of consent, a legal guardian must verify their identity via DigiLocker before you can proceed.\";\n\n // Info banner with SVG icon\n const infoIcon = svg(\n \"svg\",\n {\n width: \"16\", height: \"16\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: \"#2563EB\", \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"circle\", { cx: \"12\", cy: \"12\", r: \"10\" }),\n svg(\"line\", { x1: \"12\", y1: \"16\", x2: \"12\", y2: \"12\" }),\n svg(\"line\", { x1: \"12\", y1: \"8\", x2: \"12.01\", y2: \"8\" })\n );\n (infoIcon as unknown as HTMLElement).style.cssText = \"flex-shrink:0;margin-top:1px\";\n\n const infoText = el(\"span\");\n infoText.textContent = \"The guardian's name will be matched against their DigiLocker identity document (e.g. Aadhaar). Please enter the name exactly as it appears on the document.\";\n\n const infoBanner = el(\"div\", {\n style: {\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: \"8px\",\n padding: \"10px 12px\",\n backgroundColor: \"#EFF6FF\",\n border: \"1px solid #BFDBFE\",\n borderRadius: radius,\n marginBottom: \"16px\",\n fontSize: \"12px\",\n lineHeight: \"1.5\",\n color: \"#1E40AF\",\n },\n }, infoIcon, infoText);\n\n // ─── Name field ───\n const nameLabel = el(\"label\", { for: \"guardianName\", style: labelStyle });\n nameLabel.innerHTML = `Guardian's Full Name <span style=\"color:#DC2626\">*</span>`;\n\n const nameInput = el(\"input\", {\n id: \"guardianName\",\n type: \"text\",\n style: inputStyle,\n value: formData.guardianName,\n placeholder: \"e.g. Rajesh Kumar\",\n autoComplete: \"name\",\n \"aria-describedby\": \"guardianName-hint\",\n onInput: (e: Event) => onFieldChange(\"guardianName\", (e.target as HTMLInputElement).value),\n }) as HTMLInputElement;\n\n const nameHint = el(\"p\", { id: \"guardianName-hint\", style: hintStyle });\n nameHint.textContent = \"Enter the full name as per government ID (Aadhaar, PAN, etc.)\";\n\n const nameError = el(\"div\", { style: errorStyle, role: \"alert\" });\n const nameGroup = el(\"div\", null, nameLabel, nameInput, nameHint, nameError);\n\n // ─── Contact field ───\n const contactLabel = el(\"label\", { for: \"guardianContact\", style: labelStyle });\n contactLabel.innerHTML = `Guardian's Phone Number <span style=\"color:#DC2626\">*</span>`;\n\n const contactInput = el(\"input\", {\n id: \"guardianContact\",\n type: \"tel\",\n inputMode: \"tel\",\n style: inputStyle,\n value: formData.guardianContact,\n placeholder: \"e.g. 9876543210\",\n autoComplete: \"tel\",\n \"aria-describedby\": \"guardianContact-hint\",\n onInput: (e: Event) => onFieldChange(\"guardianContact\", (e.target as HTMLInputElement).value),\n }) as HTMLInputElement;\n\n const contactHint = el(\"p\", { id: \"guardianContact-hint\", style: hintStyle });\n contactHint.textContent = \"Mobile number linked to guardian's Aadhaar\";\n\n const contactError = el(\"div\", { style: errorStyle, role: \"alert\" });\n const contactGroup = el(\"div\", null, contactLabel, contactInput, contactHint, contactError);\n\n // ─── Relationship dropdown ───\n const relLabel = el(\"label\", { id: \"guardianRelationship-label\", style: labelStyle });\n relLabel.innerHTML = `Relationship <span style=\"color:#DC2626\">*</span>`;\n\n const selectedLabel = RELATIONSHIP_OPTIONS.find((o) => o.value === formData.guardianRelationship)?.label;\n\n const chevronSvg = svg(\n \"svg\",\n {\n width: \"14\", height: \"14\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: \"#667085\", \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"polyline\", { points: \"6 9 12 15 18 9\" })\n );\n (chevronSvg as unknown as HTMLElement).style.cssText = \"flex-shrink:0;margin-left:8px;transition:transform 0.2s\";\n\n const selectedSpan = el(\"span\", {\n style: { overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" },\n });\n selectedSpan.textContent = selectedLabel || \"Select relationship\";\n\n const relationshipDisplay = el(\"div\", {\n role: \"combobox\",\n \"aria-expanded\": \"false\",\n \"aria-haspopup\": \"listbox\",\n \"aria-labelledby\": \"guardianRelationship-label\",\n tabIndex: \"0\",\n style: {\n ...inputStyle,\n color: selectedLabel ? textColor : \"#9CA3AF\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n userSelect: \"none\",\n transition: \"border-color 0.15s, box-shadow 0.15s\",\n },\n }, selectedSpan, chevronSvg);\n\n // Dropdown list\n const dropdownList = el(\"div\", {\n id: \"guardianRelationship-listbox\",\n role: \"listbox\",\n \"aria-labelledby\": \"guardianRelationship-label\",\n style: {\n position: \"absolute\",\n top: \"calc(100% + 4px)\",\n left: 0,\n right: 0,\n backgroundColor: bgColor,\n border: `1px solid ${borderColor}`,\n borderRadius: radius,\n boxShadow: \"0 4px 12px rgba(0,0,0,0.1), 0 1px 3px rgba(0,0,0,0.06)\",\n zIndex: 50,\n overflow: \"hidden\",\n padding: \"4px 0\",\n maxHeight: \"220px\",\n overflowY: \"auto\",\n display: \"none\",\n },\n });\n\n for (let i = 0; i < RELATIONSHIP_OPTIONS.length; i++) {\n const option = RELATIONSHIP_OPTIONS[i];\n const isSelected = formData.guardianRelationship === option.value;\n\n const optionEl = el(\"div\", {\n id: `guardianRelationship-option-${i}`,\n role: \"option\",\n \"aria-selected\": String(isSelected),\n style: {\n padding: \"9px 12px\",\n fontSize: \"13px\",\n fontFamily: font,\n color: isSelected ? accentColor : textColor,\n backgroundColor: \"transparent\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n transition: \"background-color 0.1s\",\n },\n onClick: () => {\n onFieldChange(\"guardianRelationship\", option.value);\n selectedSpan.textContent = option.label;\n relationshipDisplay.style.color = textColor;\n doClose();\n },\n onMouseenter: (e: Event) => { (e.target as HTMLElement).style.backgroundColor = \"#F3F4F6\"; },\n onMouseleave: (e: Event) => { (e.target as HTMLElement).style.backgroundColor = \"transparent\"; },\n });\n\n const label = el(\"span\");\n label.textContent = option.label;\n optionEl.appendChild(label);\n\n if (isSelected) {\n const checkSvg = svg(\n \"svg\",\n {\n width: \"14\", height: \"14\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: accentColor, \"stroke-width\": \"2.5\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"polyline\", { points: \"20 6 9 17 4 12\" })\n );\n (checkSvg as unknown as HTMLElement).style.flexShrink = \"0\";\n optionEl.appendChild(checkSvg);\n }\n\n dropdownList.appendChild(optionEl);\n }\n\n let dropdownOpen = false;\n\n const relContainer = el(\"div\", { style: { position: \"relative\" } });\n\n const handleClickOutside = (e: Event) => {\n if (!relContainer.contains(e.target as Node)) {\n doClose();\n }\n };\n\n function doOpen() {\n dropdownOpen = true;\n dropdownList.style.display = \"block\";\n relationshipDisplay.setAttribute(\"aria-expanded\", \"true\");\n (chevronSvg as unknown as HTMLElement).style.transform = \"rotate(180deg)\";\n relationshipDisplay.style.borderColor = accentColor;\n relationshipDisplay.style.boxShadow = `0 0 0 1px ${accentColor}`;\n\n // Determine direction: open upward if not enough space below\n const rect = relContainer.getBoundingClientRect();\n const spaceBelow = window.innerHeight - rect.bottom;\n const dropdownHeight = 220;\n const shouldOpenUpward = spaceBelow < dropdownHeight && rect.top > dropdownHeight;\n\n if (shouldOpenUpward) {\n dropdownList.style.top = \"auto\";\n dropdownList.style.bottom = \"calc(100% + 4px)\";\n dropdownList.style.boxShadow = \"0 -4px 12px rgba(0,0,0,0.1), 0 -1px 3px rgba(0,0,0,0.06)\";\n } else {\n dropdownList.style.top = \"calc(100% + 4px)\";\n dropdownList.style.bottom = \"auto\";\n dropdownList.style.boxShadow = \"0 4px 12px rgba(0,0,0,0.1), 0 1px 3px rgba(0,0,0,0.06)\";\n }\n\n // Scroll the dropdown into view\n requestAnimationFrame(() => {\n dropdownList.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n });\n\n // Listen for clicks outside (next tick so current click doesn't trigger it)\n setTimeout(() => document.addEventListener(\"mousedown\", handleClickOutside), 0);\n }\n\n function doClose() {\n dropdownOpen = false;\n dropdownList.style.display = \"none\";\n relationshipDisplay.setAttribute(\"aria-expanded\", \"false\");\n (chevronSvg as unknown as HTMLElement).style.transform = \"rotate(0deg)\";\n relationshipDisplay.style.borderColor = borderColor;\n relationshipDisplay.style.boxShadow = \"none\";\n document.removeEventListener(\"mousedown\", handleClickOutside);\n }\n\n relationshipDisplay.addEventListener(\"click\", () => {\n dropdownOpen ? doClose() : doOpen();\n });\n\n relationshipDisplay.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \" || e.key === \"ArrowDown\") {\n e.preventDefault();\n if (!dropdownOpen) doOpen();\n } else if (e.key === \"Escape\" || e.key === \"Tab\") {\n doClose();\n }\n });\n\n const relationshipError = el(\"div\", { style: errorStyle, role: \"alert\" });\n\n relContainer.appendChild(relLabel);\n relContainer.appendChild(relationshipDisplay);\n relContainer.appendChild(dropdownList);\n relContainer.appendChild(relationshipError);\n\n // General error\n const generalError = el(\"div\", {\n role: \"alert\",\n style: {\n color: \"#DC2626\",\n fontSize: \"13px\",\n marginTop: \"16px\",\n padding: \"12px\",\n borderRadius: \"6px\",\n border: \"1px solid #FCA5A5\",\n backgroundColor: \"#FEF2F2\",\n textAlign: \"center\",\n display: \"none\",\n },\n });\n\n const fieldsContainer = el(\"div\", {\n style: { display: \"flex\", flexDirection: \"column\", gap: \"14px\" },\n }, nameGroup, contactGroup, relContainer);\n\n const middleSection = el(\"div\", {\n style: { ...styles.middleSection, overflow: \"visible\", color: textColor, fontFamily: font },\n }, subtitle, infoBanner, fieldsContainer, generalError);\n\n // ─── Bottom Section (Verify first, Cancel second — matches React) ───\n const btnBase = {\n ...styles.button,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n const submitBtn = el(\"button\", {\n style: {\n ...btnBase,\n ...styles.acceptButton,\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderRadius: colors.borderRadius,\n },\n type: \"button\",\n disabled: isSubmitting,\n \"aria-label\": isSubmitting ? \"Verifying guardian identity\" : \"Proceed to guardian verification\",\n onClick: onSubmit,\n }) as HTMLButtonElement;\n submitBtn.textContent = isSubmitting ? \"Verifying...\" : \"Verify via DigiLocker\";\n\n const cancelBtn = el(\"button\", {\n style: {\n ...btnBase,\n ...styles.cancelButton,\n backgroundColor: colors.declineBg,\n color: colors.declineText,\n borderColor: colors.declineBorder,\n borderRadius: colors.borderRadius,\n },\n type: \"button\",\n \"aria-label\": \"Cancel\",\n onClick: onCancel,\n });\n cancelBtn.textContent = \"Cancel\";\n\n const bottomSection = el(\"div\", {\n style: { ...styles.bottomSection, paddingTop: \"12px\", color: textColor, fontFamily: font },\n }, submitBtn, cancelBtn);\n\n // ─── Assemble ───\n const container = el(\"div\", { style: { ...styles.content, overflow: \"visible\" } }, topSection, middleSection, bottomSection);\n\n return {\n container,\n nameInput,\n contactInput,\n relationshipDisplay,\n nameError,\n contactError,\n relationshipError,\n submitBtn,\n generalError,\n };\n}\n\nexport function validateGuardianForm(data: GuardianFormData): Record<string, string> {\n const errors: Record<string, string> = {};\n if (!data.guardianName.trim()) errors.guardianName = \"Guardian name is required\";\n if (!data.guardianContact.trim()) errors.guardianContact = \"Guardian contact is required\";\n if (!data.guardianRelationship.trim()) errors.guardianRelationship = \"Relationship to guardian is required\";\n return errors;\n}\n","import { el, svg } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { Settings, GuardianVerificationErrorCode } from \"../api/types\";\nimport type { ResolvedColors } from \"./colors\";\n\nexport type VerificationScreenRefs = {\n container: HTMLElement;\n};\n\nexport function getVerificationErrorMessage(\n errorCode: string | null,\n fallbackError: string | null\n): string {\n switch (errorCode) {\n case \"GUARDIAN_UNDER_18\":\n return \"The guardian must be 18 years or older. Please provide details of a different guardian.\";\n case \"TOKEN_FAILED\":\n return \"DigiLocker verification could not be completed. Please try again.\";\n case \"DIGILOCKER_AUTH_FAILED\":\n return \"DigiLocker authorization was cancelled or failed. Please try again.\";\n case \"NO_AUTH_CODE\":\n return \"DigiLocker did not return an authorization code. Please try again.\";\n case \"SESSION_EXPIRED\":\n return \"Verification session has expired. Please try again.\";\n default:\n return fallbackError || \"Verification failed. Please try again.\";\n }\n}\n\nexport function renderVerificationScreen(options: {\n settings?: Partial<Settings>;\n colors: ResolvedColors;\n isMobile: boolean;\n logoUrl: string;\n isInitiating: boolean;\n isPolling: boolean;\n isComplete: boolean;\n isAutoTransitioning?: boolean;\n error: string | null;\n errorCode: string | null;\n canRetry: boolean;\n onContinue: () => void;\n onBack: (clearName?: boolean) => void;\n}): VerificationScreenRefs {\n const {\n settings, colors, isMobile, logoUrl,\n isInitiating, isPolling, isComplete, isAutoTransitioning,\n error, errorCode, canRetry,\n onContinue, onBack,\n } = options;\n\n const headingColor = settings?.headingColor || \"#101828\";\n const textColor = colors.text;\n const font = colors.font;\n const accentColor = colors.acceptBg;\n\n // ─── Top Section ───\n const logo = el(\"img\", { src: logoUrl, style: styles.logo, alt: \"Logo\" });\n const title = el(\"h2\", {\n id: \"verification-title\",\n style: {\n ...styles.title,\n fontSize: \"16px\",\n fontWeight: 600,\n color: headingColor,\n fontFamily: font,\n },\n });\n title.textContent = \"Guardian Verification\";\n\n const topLeft = el(\"div\", { style: styles.topLeft }, logo, title);\n const topSection = el(\"div\", {\n style: { ...styles.topSection, color: textColor, fontFamily: font },\n }, topLeft);\n\n // ─── Middle Section ───\n const middleSection = el(\"div\", {\n style: {\n ...styles.middleSection,\n color: textColor,\n fontFamily: font,\n textAlign: \"center\",\n },\n });\n\n if (isComplete && !error) {\n // Success state: green checkmark circle\n const successCircle = el(\"div\", {\n style: {\n width: \"64px\",\n height: \"64px\",\n borderRadius: \"50%\",\n backgroundColor: \"#D1FAE5\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n });\n const checkSvg = svg(\n \"svg\",\n {\n width: \"32\", height: \"32\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: \"#059669\", \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"polyline\", { points: \"20 6 9 17 4 12\" })\n );\n successCircle.appendChild(checkSvg);\n\n const successText = el(\"p\", {\n style: {\n color: headingColor,\n fontFamily: font,\n fontSize: \"16px\",\n fontWeight: 600,\n lineHeight: \"1.5\",\n marginTop: \"12px\",\n marginBottom: \"24px\",\n },\n });\n successText.textContent = \"Verification Completed\";\n\n const wrapper = el(\"div\", {\n style: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flex: \"1\",\n },\n }, successCircle, successText);\n middleSection.appendChild(wrapper);\n\n } else if ((isInitiating || isPolling) && !error) {\n // Polling state: spinner + status message\n const spinner = el(\"div\", {\n style: {\n width: \"48px\",\n height: \"48px\",\n border: \"4px solid #e5e7eb\",\n borderTopColor: accentColor,\n borderRadius: \"50%\",\n animation: \"spin 1s linear infinite\",\n margin: \"24px auto\",\n },\n });\n\n const statusMsg = el(\"div\", {\n style: {\n color: \"#059669\",\n fontSize: \"14px\",\n marginTop: \"16px\",\n padding: \"12px\",\n borderRadius: \"6px\",\n border: \"1px solid #A7F3D0\",\n backgroundColor: \"#D1FAE5\",\n textAlign: \"center\",\n },\n });\n statusMsg.textContent = isInitiating\n ? \"Opening DigiLocker in a new tab...\"\n : \"Please complete the verification in the DigiLocker tab. This page will update automatically when verification is complete.\";\n\n middleSection.appendChild(spinner);\n middleSection.appendChild(statusMsg);\n }\n\n if (error) {\n // Error state: red X circle + error text\n const errorCircle = el(\"div\", {\n style: {\n width: \"64px\",\n height: \"64px\",\n borderRadius: \"50%\",\n backgroundColor: \"#fee2e2\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n margin: \"24px auto\",\n },\n });\n const xSvg = svg(\n \"svg\",\n {\n width: \"32\", height: \"32\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: \"#dc2626\", \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"line\", { x1: \"18\", y1: \"6\", x2: \"6\", y2: \"18\" }),\n svg(\"line\", { x1: \"6\", y1: \"6\", x2: \"18\", y2: \"18\" })\n );\n errorCircle.appendChild(xSvg);\n\n const failedText = el(\"p\", {\n style: {\n ...styles.privacyText,\n color: textColor,\n fontFamily: font,\n fontSize: \"14px\",\n lineHeight: \"1.5\",\n marginBottom: \"12px\",\n },\n });\n failedText.textContent = \"Verification failed\";\n\n const errorBox = el(\"div\", {\n style: {\n color: \"#DC2626\",\n fontSize: \"14px\",\n marginTop: \"16px\",\n padding: \"12px\",\n borderRadius: \"6px\",\n border: \"1px solid #FCA5A5\",\n backgroundColor: \"#FEF2F2\",\n textAlign: \"center\",\n },\n });\n errorBox.textContent = error;\n\n middleSection.appendChild(errorCircle);\n middleSection.appendChild(failedText);\n middleSection.appendChild(errorBox);\n }\n\n // ─── Bottom Section ───\n const btnBase = {\n ...styles.button,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n const bottomSection = el(\"div\", {\n style: {\n ...styles.bottomSection,\n paddingTop: \"12px\",\n display: \"flex\",\n gap: \"12px\",\n justifyContent: \"center\",\n color: textColor,\n fontFamily: font,\n },\n });\n\n const acceptBtnStyle = {\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderRadius: colors.borderRadius,\n };\n const declineBtnStyle = {\n backgroundColor: colors.declineBg,\n color: colors.declineText,\n borderColor: colors.declineBorder,\n borderRadius: colors.borderRadius,\n };\n\n // Hide bottom section during auto-transition\n if (!isAutoTransitioning) {\n if (isComplete && !error) {\n const continueBtn = el(\"button\", {\n style: { ...btnBase, ...acceptBtnStyle },\n type: \"button\",\n \"aria-label\": \"Continue to consent form\",\n onClick: onContinue,\n });\n continueBtn.textContent = \"Continue\";\n bottomSection.appendChild(continueBtn);\n } else if (error && canRetry) {\n const retryBtn = el(\"button\", {\n style: { ...btnBase, ...styles.acceptButton, ...acceptBtnStyle },\n type: \"button\",\n \"aria-label\": errorCode === \"GUARDIAN_UNDER_18\" ? \"Change guardian details\" : \"Try verification again\",\n onClick: () => onBack(errorCode === \"GUARDIAN_UNDER_18\"),\n });\n retryBtn.textContent = errorCode === \"GUARDIAN_UNDER_18\" ? \"Change Guardian\" : \"Try Again\";\n bottomSection.appendChild(retryBtn);\n } else if (error) {\n const goBackBtn = el(\"button\", {\n style: { ...btnBase, ...styles.cancelButton, ...declineBtnStyle },\n type: \"button\",\n \"aria-label\": \"Go back\",\n onClick: () => onBack(false),\n });\n goBackBtn.textContent = \"Go Back\";\n bottomSection.appendChild(goBackBtn);\n } else {\n // Polling state — show cancel\n const cancelBtn = el(\"button\", {\n style: { ...btnBase, ...styles.cancelButton, ...declineBtnStyle },\n type: \"button\",\n \"aria-label\": \"Cancel verification\",\n onClick: () => onBack(false),\n });\n cancelBtn.textContent = \"Cancel\";\n bottomSection.appendChild(cancelBtn);\n }\n }\n\n // ─── Assemble ───\n const container = el(\"div\", { style: styles.content }, topSection, middleSection, bottomSection);\n\n return { container };\n}\n","import type { ActiveConfig, Settings } from \"../api/types\";\n\nexport type ResolvedColors = {\n acceptBg: string;\n acceptText: string;\n declineBg: string;\n declineText: string;\n declineBorder: string;\n link: string;\n heading: string;\n text: string;\n font: string;\n borderRadius: string;\n primaryColor: string;\n secondaryColor: string;\n};\n\n/**\n * Resolves colors using the React SDK's fallback chain:\n * settings → API active_config → hardcoded default\n */\nexport function resolveColors(\n settings: Partial<Settings> | undefined,\n activeConfig: ActiveConfig | null | undefined\n): ResolvedColors {\n const primaryColor = activeConfig?.primary_color || \"#4f87ff\";\n const secondaryColor = activeConfig?.secondary_color || \"#4f87ff\";\n\n return {\n acceptBg: settings?.button?.accept?.backgroundColor || primaryColor,\n acceptText: settings?.button?.accept?.textColor || \"#ffffff\",\n declineBg: settings?.button?.decline?.backgroundColor || \"#ffffff\",\n declineText: settings?.button?.decline?.textColor || \"#000000\",\n declineBorder: settings?.borderColor || \"#d0d5dd\",\n link: settings?.link || secondaryColor,\n heading: settings?.headingColor || \"#323B4B\",\n text: settings?.textColor || \"#344054\",\n font: settings?.font || \"inherit\",\n borderRadius: settings?.borderRadius || \"8px\",\n primaryColor,\n secondaryColor,\n };\n}\n","import type { LogoPosition } from \"../api/types\";\nimport { DEFAULT_LOGO_POSITION, LOGO_POSITION_JUSTIFY } from \"../constants\";\n\n/**\n * Resolves `active_config.logo_position` onto a position the header can lay out.\n *\n * The field is absent on notices published before it existed and on responses\n * from an older consent-server, so an unrecognised value is not an error — it\n * simply means \"the customer never chose\", which is the left-aligned default.\n *\n * Sibling of `resolveColors` in ./colors.ts: same config-then-default shape,\n * kept deliberately parallel with the React package's layout.ts.\n */\nexport function resolveLogoPosition(raw: string | undefined | null): LogoPosition {\n return raw === \"center\" || raw === \"right\" ? raw : DEFAULT_LOGO_POSITION;\n}\n\nexport function logoRowJustify(position: LogoPosition): string {\n return LOGO_POSITION_JUSTIFY[position];\n}\n","import { Store } from \"../core/state\";\nimport { el, svg, clearElement } from \"../core/dom\";\nimport { createMediaQuery, type MediaQuerySubscription } from \"../core/media-query\";\nimport {\n fetchConsentContent,\n submitConsentEvent,\n fetchTTSAudioUrls,\n initiateGuardianVerification,\n verifyGuardianStatus,\n} from \"../api\";\nimport {\n buildLedgerConsentOverlay,\n fetchNoticeConsentStatus,\n} from \"../api/notice-consent-status\";\nimport { resolveDisplayLanguage } from \"../api/language\";\nimport { clearApiCache } from \"../services/cache\";\nimport { injectCheckboxStyles } from \"../styles/inject\";\nimport { styles } from \"../styles/modal\";\nimport { renderModalPurposes, type ModalPurposeRefs } from \"./purposes\";\nimport { renderLanguageSelector, type LanguageSelectorRefs } from \"./language-selector\";\nimport { setupKeyboardTrap, type KeyboardTrapCleanup } from \"./keyboard\";\nimport {\n saveConsentState,\n getConsentState,\n clearConsentState,\n updateConsentState,\n} from \"../services/storage\";\nimport { TTSManager } from \"./tts\";\nimport { renderAgeVerification } from \"./age-verification\";\nimport {\n renderGuardianForm,\n validateGuardianForm,\n type GuardianFormData,\n type GuardianFormRefs,\n} from \"./guardian-form\";\nimport {\n renderVerificationScreen,\n getVerificationErrorMessage,\n} from \"./verification-screen\";\nimport { resolveColors } from \"./colors\";\nimport { logoRowJustify, resolveLogoPosition } from \"./layout\";\nimport type { SandboxOptions } from \"../api/types\";\nimport type { ModalOptions } from \"../types\";\nimport type {\n ActiveConfig,\n ConsentContent,\n PurposeItemData,\n PurposeSelection,\n Settings,\n TranslationObject,\n} from \"../api/types\";\n\ntype ModalState = {\n isLoading: boolean;\n isSubmitting: boolean;\n isSubmittingAccept: boolean;\n isSubmittingDecline: boolean;\n content: ConsentContent | null;\n selectedPurposes: Record<string, boolean>;\n selectedDataElements: Record<string, boolean>;\n initialDataElementSelections: Record<string, boolean>;\n collapsedPurposes: Record<string, boolean>;\n hasAlreadyConsented: boolean;\n isFullyConsentedReviewMode: boolean;\n selectedLanguage: string;\n errorMessage: string | null;\n fetchError: Error | null;\n needsConsentPurposes: PurposeItemData[];\n alreadyConsentedPurposes: PurposeItemData[];\n // Age/Guardian flow\n isMinorFlow: boolean;\n selfDeclaredAdult: boolean;\n showAgeVerification: boolean;\n showGuardianForm: boolean;\n showVerificationScreen: boolean;\n verificationReference: string | null;\n isVerificationComplete: boolean;\n isInitiatingVerification: boolean;\n isPollingStatus: boolean;\n verificationError: string | null;\n verificationErrorCode: string | null;\n canRetryVerification: boolean;\n guardianFormData: GuardianFormData;\n};\n\nexport class ModalController {\n private store: Store<ModalState>;\n private options: ModalOptions;\n private hostEl: HTMLElement | null = null;\n private shadowRoot: ShadowRoot | null = null;\n private previousBodyOverflow: string | null = null;\n private previousHtmlOverflow: string | null = null;\n private overlayEl: HTMLElement | null = null;\n private modalEl: HTMLElement | null = null;\n private mediaQuery: MediaQuerySubscription;\n private purposeRefs: ModalPurposeRefs | null = null;\n private alreadyConsentedPurposeRefs: ModalPurposeRefs | null = null;\n private langSelectorRefs: LanguageSelectorRefs | null = null;\n private keyboardCleanup: KeyboardTrapCleanup | null = null;\n private abortController: AbortController | null = null;\n private unsubscribe: (() => void) | null = null;\n private ttsManager: TTSManager | null = null;\n private guardianFormRefs: GuardianFormRefs | null = null;\n private statusPollTimeout: ReturnType<typeof setTimeout> | null = null;\n private popupCheckInterval: ReturnType<typeof setInterval> | null = null;\n private verificationPopup: Window | null = null;\n private verificationSessionToken: string | null = null;\n private visibilityChangeHandler: (() => void) | null = null;\n\n // DOM refs for targeted updates\n private acceptBtn: HTMLButtonElement | null = null;\n private declineBtn: HTMLButtonElement | null = null;\n private middleSection: HTMLElement | null = null;\n private errorEl: HTMLElement | null = null;\n private noticeTitleEl: HTMLElement | null = null;\n private noticeTextEl: HTMLElement | null = null;\n private purposeHeadingEl: HTMLElement | null = null;\n private additionalTextEl: HTMLElement | null = null;\n private privacyPolicyLinkEl: HTMLAnchorElement | null = null;\n private privacyCenterLinkEl: HTMLAnchorElement | null = null;\n private ttsButton: HTMLElement | null = null;\n\n constructor(options: ModalOptions) {\n this.options = options;\n this.store = new Store<ModalState>({\n isLoading: true,\n isSubmitting: false,\n isSubmittingAccept: false,\n isSubmittingDecline: false,\n content: null,\n selectedPurposes: {},\n selectedDataElements: {},\n initialDataElementSelections: {},\n collapsedPurposes: {},\n hasAlreadyConsented: false,\n isFullyConsentedReviewMode: false,\n selectedLanguage: options.language || \"en\",\n errorMessage: null,\n fetchError: null,\n needsConsentPurposes: [],\n alreadyConsentedPurposes: [],\n isMinorFlow: false,\n selfDeclaredAdult: false,\n showAgeVerification: false,\n showGuardianForm: false,\n showVerificationScreen: false,\n verificationReference: null,\n isVerificationComplete: false,\n isInitiatingVerification: false,\n isPollingStatus: false,\n verificationError: null,\n verificationErrorCode: null,\n canRetryVerification: false,\n guardianFormData: { guardianName: \"\", guardianContact: \"\", guardianRelationship: \"\" },\n });\n this.mediaQuery = createMediaQuery(\"(max-width: 768px)\");\n // TTSManager is instantiated lazily in renderOverlayWithLoading() once the\n // shadow root exists, so it can scope its DOM queries inside the shadow.\n }\n\n async init(): Promise<void> {\n this.unsubscribe = this.store.subscribe((state, prevState) => {\n this.handleStateChange(state, prevState);\n });\n\n this.mediaQuery.subscribe(() => this.rebuildUI());\n\n // Render loading state\n this.renderOverlayWithLoading();\n\n // Fetch content\n await this.fetchNotice();\n }\n\n destroy(): void {\n this.abortController?.abort();\n this.keyboardCleanup?.();\n this.unsubscribe?.();\n this.mediaQuery.destroy();\n this.ttsManager?.destroy();\n this.stopPolling();\n this.store.destroy();\n\n // Removing the shadow host nukes the entire shadow tree (overlay, modal,\n // language dropdown, injected stylesheet) in a single operation.\n if (this.hostEl && this.hostEl.parentNode) {\n this.hostEl.parentNode.removeChild(this.hostEl);\n }\n\n // Restore the host page's scroll lock to whatever it was before we opened.\n if (this.previousBodyOverflow !== null) {\n document.body.style.overflow = this.previousBodyOverflow;\n this.previousBodyOverflow = null;\n }\n if (this.previousHtmlOverflow !== null) {\n document.documentElement.style.overflow = this.previousHtmlOverflow;\n this.previousHtmlOverflow = null;\n }\n\n this.hostEl = null;\n this.shadowRoot = null;\n this.overlayEl = null;\n this.modalEl = null;\n this.purposeRefs = null;\n this.langSelectorRefs = null;\n }\n\n // ─── Private ───\n\n /**\n * Sandbox auth options to forward to every API call. When `token` is set the\n * API layer sends the single `X-Consent-Token` header, injects the subject\n * into each request's payload, and reads org/workspace from these fields\n * instead of decoding the JWT. Empty in the normal JWT flow.\n */\n private sandboxParams(): SandboxOptions {\n return {\n token: this.options.token,\n // The static token carries no identity; read the acting principal from the\n // optional ucic/email/mobile. UCIC takes precedence server-side.\n // sandboxUcic / sandboxSubject stay as fallbacks.\n sandboxUcic: this.options.ucic || this.options.sandboxUcic,\n sandboxSubject:\n this.options.email || this.options.mobile || this.options.sandboxSubject,\n organisationUuid: this.options.organisationUuid,\n workspaceUuid: this.options.workspaceUuid,\n };\n }\n\n private async fetchNotice(): Promise<void> {\n this.abortController = new AbortController();\n this.store.setState({ isLoading: true, fetchError: null });\n\n try {\n // Standard flow reads the notice from the Go ledger. The magic-link flow\n // (applicationId/specific_uuid) and sandbox sessions stay on the consent\n // server: the ledger notice read supports neither (no specific_uuid, no\n // X-Consent-Token auth). Without this a ledger-minted token is rejected\n // by the consent server and the modal renders with no content.\n const noticeBaseUrl =\n this.options.ledgerBaseUrl &&\n !this.options.applicationId &&\n !this.options.token\n ? this.options.ledgerBaseUrl\n : this.options.baseUrl;\n const data = await fetchConsentContent({\n noticeId: this.options.noticeId,\n accessToken: this.options.accessToken,\n refreshToken: this.options.refreshToken,\n baseUrl: noticeBaseUrl,\n language: this.options.language,\n specific_uuid: this.options.applicationId,\n validate_against: this.options.validateAgainst || \"all\",\n include_fully_consented_data: this.options.includeFullyConsentedData,\n signal: this.abortController.signal,\n ...this.sandboxParams(),\n });\n\n const activeConfig = data.detail.active_config;\n\n // Overlay the prior-consent / reconsent state from the Go ledger's\n // check-consent. Consents live in the ledger post-cutover, so Python's\n // notice-validation overlay is empty; the notice text/config still comes\n // from Python (above). Falls back to the Python-provided values when the\n // ledger is unavailable, and is skipped for the magic-link flow\n // (applicationId), which pre-fills from a specific event.\n let purposeSelections = data.detail.purpose_selections;\n let reconsentRequired = data.detail.reconsent_required;\n let ledgerOverlayApplied = false;\n if (this.options.ledgerBaseUrl && !this.options.applicationId) {\n const ledgerStatus = await fetchNoticeConsentStatus({\n accessToken: this.options.accessToken,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n noticeUuid: this.options.noticeId,\n signal: this.abortController.signal,\n });\n if (ledgerStatus) {\n const overlay = buildLedgerConsentOverlay(ledgerStatus, activeConfig.purposes);\n reconsentRequired = overlay?.reconsent_required ?? false;\n purposeSelections = overlay?.purpose_selections;\n ledgerOverlayApplied = Boolean(overlay);\n }\n }\n\n // Initialize state\n const initialCollapsed: Record<string, boolean> = {};\n const initialPurposes: Record<string, boolean> = {};\n const initialElements: Record<string, boolean> = {};\n const initialDataElementSelections: Record<string, boolean> = {};\n\n // Categorize purposes for reconsent. With a ledger overlay, categorize\n // whenever prior consent exists (even without reconsent needed) so a\n // fully-consented principal gets the already-consented presentation /\n // review mode instead of a fresh consent flow — the ledger-mode\n // equivalent of Python's 409-driven short-circuit.\n let needsConsentPurposes: PurposeItemData[] = [];\n let alreadyConsentedPurposes: PurposeItemData[] = [];\n let isFullyConsentedReviewMode = false;\n\n if (purposeSelections && (reconsentRequired || ledgerOverlayApplied)) {\n for (const purpose of activeConfig.purposes) {\n const selection = purposeSelections[purpose.uuid];\n initialCollapsed[purpose.uuid] = true;\n\n if (selection && selection.selected && !selection.needs_reconsent) {\n alreadyConsentedPurposes.push(purpose);\n initialPurposes[purpose.uuid] = true;\n for (const de of purpose.data_elements) {\n const combinedId = `${purpose.uuid}-${de.uuid}`;\n const deSelection = selection.data_elements?.[de.uuid];\n const wasSelected = deSelection?.selected || false;\n initialElements[combinedId] = wasSelected;\n initialDataElementSelections[combinedId] = wasSelected;\n }\n } else {\n needsConsentPurposes.push(purpose);\n initialPurposes[purpose.uuid] = false;\n for (const de of purpose.data_elements) {\n initialElements[`${purpose.uuid}-${de.uuid}`] = false;\n }\n }\n }\n } else {\n needsConsentPurposes = activeConfig.purposes;\n for (const purpose of activeConfig.purposes) {\n initialCollapsed[purpose.uuid] = true;\n initialPurposes[purpose.uuid] = false;\n for (const de of purpose.data_elements) {\n initialElements[`${purpose.uuid}-${de.uuid}`] = false;\n }\n }\n }\n\n // Check if all purposes are already consented (review mode)\n if (\n this.options.includeFullyConsentedData &&\n needsConsentPurposes.length === 0 &&\n alreadyConsentedPurposes.length > 0\n ) {\n isFullyConsentedReviewMode = true;\n }\n\n const selectedLanguage = resolveDisplayLanguage(\n this.options.language,\n activeConfig.default_language,\n activeConfig.supported_languages_and_translations\n );\n\n // Check if minor flow is required, and restore in-progress verification\n // state from a previous session (e.g. user closed the SDK or returned\n // from a DigiLocker redirect mid-flow). Without this restoration, the\n // notice would be shown directly and guardian verification skipped.\n let isMinorFlow = false;\n let showAgeVerification = false;\n let restoreState: Partial<ModalState> = {};\n let pollingTokenToResume: string | null = null;\n if (data.detail.is_minor) {\n isMinorFlow = true;\n const persistedState = getConsentState();\n\n // Discard persisted state from a different notice\n if (persistedState?.noticeId && persistedState.noticeId !== this.options.noticeId) {\n clearConsentState();\n } else if (\n persistedState?.flowState === \"digilocker-pending\" &&\n persistedState.sessionToken\n ) {\n // User is mid-verification — resume the verification screen and polling\n restoreState = {\n showVerificationScreen: true,\n isPollingStatus: true,\n };\n pollingTokenToResume = persistedState.sessionToken;\n } else if (\n persistedState?.verificationResult === \"verified\" &&\n persistedState.verificationReference\n ) {\n // Verification completed during a redirect — show success state\n restoreState = {\n showVerificationScreen: true,\n isVerificationComplete: true,\n verificationReference: persistedState.verificationReference,\n };\n clearConsentState();\n } else if (\n persistedState?.verificationResult === \"failed\" ||\n persistedState?.verificationResult === \"expired\"\n ) {\n // Verification failed/expired during a redirect — show error\n restoreState = {\n showVerificationScreen: true,\n verificationError:\n persistedState.verificationResult === \"expired\"\n ? \"Verification session has expired. Please try again.\"\n : \"Verification failed. Please try again.\",\n canRetryVerification: true,\n };\n clearConsentState();\n } else {\n // No in-progress verification — start with age verification\n showAgeVerification = true;\n }\n }\n\n this.store.setState({\n content: data,\n isLoading: false,\n selectedLanguage,\n collapsedPurposes: initialCollapsed,\n selectedPurposes: initialPurposes,\n selectedDataElements: initialElements,\n initialDataElementSelections,\n needsConsentPurposes,\n alreadyConsentedPurposes,\n isFullyConsentedReviewMode,\n isMinorFlow,\n showAgeVerification,\n ...restoreState,\n });\n\n // Resume polling after state has been applied so the verification screen\n // is visible while polling runs.\n if (pollingTokenToResume) {\n this.startStatusPolling(pollingTokenToResume);\n }\n } catch (err: unknown) {\n if ((err as Error).name === \"AbortError\") return;\n const error = err as Error & { status?: number };\n if (error.status === 409) {\n this.store.setState({ hasAlreadyConsented: true, isLoading: false });\n this.options.onAccept();\n } else {\n this.store.setState({ fetchError: error, isLoading: false });\n this.options.onError?.(error);\n }\n }\n }\n\n private handleStateChange(state: ModalState, prevState: ModalState): void {\n // Loading → content loaded\n if (prevState.isLoading && !state.isLoading && state.content) {\n this.rebuildUI();\n return;\n }\n\n // Already consented → close\n if (state.hasAlreadyConsented && !prevState.hasAlreadyConsented) {\n this.destroy();\n return;\n }\n\n // Fetch error → show error\n if (state.fetchError && !prevState.fetchError) {\n this.renderError(state.fetchError.message);\n return;\n }\n\n // Screen transitions (age → guardian → verification → consent)\n if (state.showAgeVerification !== prevState.showAgeVerification ||\n state.showGuardianForm !== prevState.showGuardianForm ||\n state.showVerificationScreen !== prevState.showVerificationScreen) {\n this.rebuildUI();\n return;\n }\n\n // Verification screen state changes\n if (state.showVerificationScreen && (\n state.isVerificationComplete !== prevState.isVerificationComplete ||\n state.verificationError !== prevState.verificationError ||\n state.isPollingStatus !== prevState.isPollingStatus ||\n state.isInitiatingVerification !== prevState.isInitiatingVerification)) {\n this.rebuildUI();\n return;\n }\n\n // Checkbox changes\n if (\n state.selectedPurposes !== prevState.selectedPurposes ||\n state.selectedDataElements !== prevState.selectedDataElements\n ) {\n this.updateCheckboxes(state);\n }\n\n // Collapse changes\n if (state.collapsedPurposes !== prevState.collapsedPurposes) {\n this.updateCollapseState(state);\n }\n\n // Error message\n if (state.errorMessage !== prevState.errorMessage) {\n this.updateErrorMessage(state);\n }\n\n // Submitting state\n if (state.isSubmittingAccept !== prevState.isSubmittingAccept ||\n state.isSubmittingDecline !== prevState.isSubmittingDecline) {\n this.updateButtonStates(state);\n }\n }\n\n private renderOverlayWithLoading(): void {\n // Mount a single host <div> on document.body and attach an open shadow\n // root. All overlay, modal, and stylesheet content lives inside the shadow\n // so the host page's CSS cannot bleed in (and vice versa). This is what\n // makes the SDK render identically across customer sites and WordPress\n // installs that ship aggressive global stylesheets / accessibility plugins.\n this.hostEl = document.createElement(\"div\");\n this.hostEl.setAttribute(\"data-redacto-consent\", \"\");\n // Lock the host to a zero-size, fixed-position box so it cannot perturb a\n // flex / grid body layout. We deliberately DO NOT reset inherited text\n // properties (font-family, color, line-height) — those flow through the\n // shadow boundary so the modal picks up the host page's font, matching\n // how the React SDK renders.\n this.hostEl.style.position = \"fixed\";\n this.hostEl.style.top = \"0\";\n this.hostEl.style.left = \"0\";\n this.hostEl.style.width = \"0\";\n this.hostEl.style.height = \"0\";\n this.hostEl.style.zIndex = \"2147483646\";\n document.body.appendChild(this.hostEl);\n this.shadowRoot = this.hostEl.attachShadow({ mode: \"open\" });\n\n // Lock background scroll on the host page while the modal is open. We\n // capture the previous values so destroy() can restore exactly what was\n // there (including the empty string, which means \"use stylesheet rule\").\n this.previousBodyOverflow = document.body.style.overflow;\n this.previousHtmlOverflow = document.documentElement.style.overflow;\n document.body.style.overflow = \"hidden\";\n document.documentElement.style.overflow = \"hidden\";\n\n // Inject SDK stylesheet into the shadow root (not document.head).\n injectCheckboxStyles(this.shadowRoot);\n\n // Lazy-instantiate TTSManager now that we have a root for it to query.\n this.ttsManager = new TTSManager(\n () => this.updateTTSButton(),\n this.shadowRoot\n );\n\n const blockUI = this.options.blockUI !== false;\n\n if (blockUI) {\n this.overlayEl = el(\"div\", {\n style: styles.overlay,\n role: \"presentation\",\n });\n this.shadowRoot.appendChild(this.overlayEl);\n }\n\n const settingsObj = this.options.settings;\n const modalStyle = { ...styles.modal } as Record<string, any>;\n if (settingsObj?.backgroundColor) modalStyle.backgroundColor = settingsObj.backgroundColor;\n if (settingsObj?.borderRadius) modalStyle.borderRadius = settingsObj.borderRadius;\n if (settingsObj?.borderColor) modalStyle.border = `1px solid ${settingsObj.borderColor}`;\n if (settingsObj?.font) modalStyle.fontFamily = settingsObj.font;\n if (this.mediaQuery.matches) {\n modalStyle.width = \"90%\";\n modalStyle.maxWidth = \"90%\";\n }\n\n this.modalEl = el(\"div\", {\n style: modalStyle,\n role: \"dialog\",\n \"aria-modal\": \"true\",\n \"aria-label\": \"Privacy consent\",\n });\n\n // Loading content\n const loadingEl = el(\n \"div\",\n { style: styles.loadingContainer },\n el(\"div\", { style: styles.loadingSpinner }),\n el(\"p\", { style: { ...styles.privacyText, color: settingsObj?.textColor || \"#344054\" } }, \"Loading...\")\n );\n\n const contentEl = el(\"div\", { style: styles.content }, loadingEl);\n this.modalEl.appendChild(contentEl);\n this.shadowRoot.appendChild(this.modalEl);\n }\n\n private rebuildUI(): void {\n const state = this.store.getState();\n if (!state.content || !this.modalEl) return;\n\n const activeConfig = state.content.detail.active_config;\n const settingsObj = this.options.settings;\n const isMobile = this.mediaQuery.matches;\n const colors = resolveColors(settingsObj, activeConfig);\n\n // ─── Age Verification Screen ───\n if (state.showAgeVerification) {\n clearElement(this.modalEl);\n const ageRefs = renderAgeVerification({\n settings: settingsObj,\n colors,\n isMobile,\n logoUrl: activeConfig.logo_url,\n onYes: () => this.handleAgeVerificationYes(),\n onNo: () => this.handleAgeVerificationNo(),\n onClose: () => this.handleDecline(),\n });\n this.modalEl.appendChild(ageRefs.container);\n this.keyboardCleanup?.();\n this.keyboardCleanup = setupKeyboardTrap(this.modalEl, () => this.handleDecline());\n return;\n }\n\n // ─── Guardian Form Screen ───\n if (state.showGuardianForm) {\n clearElement(this.modalEl);\n this.guardianFormRefs = renderGuardianForm({\n formData: state.guardianFormData,\n settings: settingsObj,\n colors,\n isMobile,\n logoUrl: activeConfig.logo_url,\n isSubmitting: state.isInitiatingVerification,\n onSubmit: () => this.handleGuardianFormSubmit(),\n onCancel: () => this.handleDecline(),\n onFieldChange: (field, value) => {\n const s = this.store.getState();\n this.store.setState({\n guardianFormData: { ...s.guardianFormData, [field]: value },\n });\n },\n });\n this.modalEl.appendChild(this.guardianFormRefs.container);\n this.keyboardCleanup?.();\n this.keyboardCleanup = setupKeyboardTrap(this.modalEl, () => this.handleDecline());\n return;\n }\n\n // ─── Verification Screen ───\n if (state.showVerificationScreen) {\n clearElement(this.modalEl);\n const verRefs = renderVerificationScreen({\n settings: settingsObj,\n colors,\n isMobile,\n logoUrl: activeConfig.logo_url,\n isInitiating: state.isInitiatingVerification,\n isPolling: state.isPollingStatus,\n isComplete: state.isVerificationComplete,\n error: state.verificationError,\n errorCode: state.verificationErrorCode,\n canRetry: state.canRetryVerification,\n onContinue: () => this.handleVerificationContinue(),\n onBack: (clearName?: boolean) => {\n if (clearName) {\n this.handleChangeGuardian();\n } else if (state.verificationError && state.canRetryVerification) {\n this.handleVerificationRetry();\n } else {\n this.handleDecline();\n }\n },\n });\n this.modalEl.appendChild(verRefs.container);\n this.keyboardCleanup?.();\n this.keyboardCleanup = setupKeyboardTrap(this.modalEl, () => {});\n return;\n }\n\n // Clear modal content\n clearElement(this.modalEl);\n\n const headingColor = settingsObj?.headingColor || \"#101828\";\n const textColor = colors.text;\n const linkColor = colors.link;\n const font = colors.font;\n\n // ─── Top Section ───\n const logoImg = activeConfig.logo_url\n ? el(\"img\", {\n src: activeConfig.logo_url,\n style: {\n ...styles.logo,\n maxWidth: isMobile ? \"96px\" : \"140px\",\n maxHeight: isMobile ? \"28px\" : \"32px\",\n },\n alt: \"Logo\",\n })\n : null;\n\n this.noticeTitleEl = el(\"span\", {\n id: \"privacy-notice-title\",\n style: { ...styles.title, color: headingColor, fontFamily: font, fontSize: isMobile ? \"16px\" : \"18px\" },\n });\n this.noticeTitleEl.textContent = this.getTranslatedText(\"notice_banner_heading\", activeConfig.notice_banner_heading);\n\n // Clean up previous language dropdown (since rebuildUI re-creates it).\n // The dropdown lives inside the shadow root (sibling of the modal) so we\n // remove it from there.\n if (\n this.langSelectorRefs?.dropdown &&\n this.shadowRoot &&\n this.langSelectorRefs.dropdown.parentNode === this.shadowRoot\n ) {\n this.shadowRoot.removeChild(this.langSelectorRefs.dropdown);\n }\n\n // Language selector\n const supportedLangs = Object.keys(activeConfig.supported_languages_and_translations || {});\n const allLanguages = [activeConfig.default_language || \"English\", ...supportedLangs.filter((l) => l !== activeConfig.default_language)];\n\n this.langSelectorRefs = renderLanguageSelector({\n languages: allLanguages,\n selectedLanguage: state.selectedLanguage,\n settings: settingsObj,\n onSelect: (lang) => this.handleLanguageSelect(lang),\n dropdownContainer: this.shadowRoot!,\n });\n\n // TTS button with SVG speaker icon (matches React)\n const ttsStrokeColor = settingsObj?.button?.language?.textColor || \"currentColor\";\n const speakerSvg = svg(\n \"svg\",\n {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"16\",\n height: \"16\",\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: ttsStrokeColor,\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n \"aria-hidden\": \"true\",\n },\n svg(\"polygon\", { points: \"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" }),\n svg(\"path\", { d: \"M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07\" })\n );\n\n this.ttsButton = el(\"button\", {\n style: {\n ...styles.topRight,\n display: \"none\",\n padding: \"3px 9px\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n type: \"button\",\n \"aria-label\": \"Start audio playback\",\n title: \"Start Talkback\",\n onClick: () => this.ttsManager?.toggle(),\n });\n this.ttsButton.appendChild(speakerSvg);\n\n // Fetch TTS audio (the API uses \"English\" for English, not \"en\")\n this.ttsManager?.fetchAudioUrls({\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n noticeUuid: activeConfig.notice_uuid,\n language: this.getLanguageCode(state.selectedLanguage),\n content: activeConfig,\n ...this.sandboxParams(),\n });\n\n // TTS button on LEFT, language selector on RIGHT (matches React)\n const topRight = el(\"div\", {\n style: { display: \"flex\", alignItems: \"center\", gap: \"8px\", flexShrink: 0 },\n }, this.ttsButton, this.langSelectorRefs.container);\n\n // Two stacked rows at every breakpoint: the logo alone on row 1, aligned\n // per the admin-chosen position, then title + controls on row 2.\n const logoPosition = resolveLogoPosition(activeConfig.logo_position);\n const headerRows: HTMLElement[] = [];\n // Row 1 only exists when there is a logo. This package has no bundled\n // fallback (unlike React), so rendering it regardless would leave nothing\n // but the headerStack gap — a phantom band above the title.\n if (logoImg) {\n headerRows.push(\n el(\n \"div\",\n { style: { ...styles.logoRow, justifyContent: logoRowJustify(logoPosition) } },\n logoImg\n )\n );\n }\n headerRows.push(el(\"div\", { style: styles.headerRow }, this.noticeTitleEl, topRight));\n\n const topSection = el(\n \"div\",\n { style: { ...styles.headerStack, gap: isMobile ? \"12px\" : \"10px\" } },\n ...headerRows\n );\n\n // ─── Middle Section ───\n this.middleSection = el(\"div\", { style: styles.middleSection });\n\n const baseTextStyle = { ...styles.privacyText, color: textColor, fontFamily: font, fontSize: isMobile ? \"14px\" : \"16px\" };\n\n // Notice text + Privacy policy in ONE <p> (matches React: single <p> with <br>)\n const noticeTextSpan = el(\"span\", { id: \"privacy-notice-text\" });\n noticeTextSpan.textContent = this.getTranslatedText(\"notice_text\", activeConfig.notice_text);\n\n const policyPrefixText = this.getTranslatedText(\"privacy_policy_prefix_text\", activeConfig.privacy_policy_prefix_text);\n const policyAnchorText = this.getTranslatedText(\"privacy_policy_anchor_text\", activeConfig.privacy_policy_anchor_text);\n\n this.privacyPolicyLinkEl = el(\"a\", {\n id: \"privacy-policy-link\",\n href: activeConfig.privacy_policy_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n \"aria-label\": \"Privacy Policy (opens in new tab)\",\n }) as HTMLAnchorElement;\n this.privacyPolicyLinkEl.textContent = policyAnchorText;\n\n const policySpan = el(\"span\", { id: \"privacy-policy-text\" },\n `${policyPrefixText} `,\n this.privacyPolicyLinkEl\n );\n\n const noticeAndPolicyP = el(\"p\", { style: baseTextStyle },\n noticeTextSpan,\n el(\"br\"),\n policySpan\n );\n\n // Purpose section heading\n this.purposeHeadingEl = el(\"h2\", {\n id: \"purpose-section-heading\",\n style: { ...styles.subTitle, color: headingColor, fontFamily: font },\n });\n this.purposeHeadingEl.textContent = this.getTranslatedText(\"purpose_section_heading\", activeConfig.purpose_section_heading);\n\n this.middleSection.appendChild(noticeAndPolicyP);\n this.middleSection.appendChild(this.purposeHeadingEl);\n\n // Render purposes (needs consent)\n if (state.needsConsentPurposes.length > 0) {\n this.purposeRefs = renderModalPurposes(state.needsConsentPurposes, {\n selectedPurposes: state.selectedPurposes,\n collapsedPurposes: state.collapsedPurposes,\n selectedDataElements: state.selectedDataElements,\n settings: settingsObj,\n isMobile,\n isAlreadyConsented: false,\n getTranslatedText: (key, defaultText, itemId) => this.getTranslatedText(key, defaultText, itemId),\n onPurposeToggle: (uuid) => this.handlePurposeCheckboxChange(uuid),\n onPurposeCollapse: (uuid) => this.togglePurposeCollapse(uuid),\n onDataElementToggle: (euuid, puuid) => this.handleDataElementCheckboxChange(euuid, puuid),\n });\n this.middleSection.appendChild(this.purposeRefs.container);\n }\n\n // Render already-consented purposes\n if (state.alreadyConsentedPurposes.length > 0) {\n this.alreadyConsentedPurposeRefs = renderModalPurposes(state.alreadyConsentedPurposes, {\n selectedPurposes: state.selectedPurposes,\n collapsedPurposes: state.collapsedPurposes,\n selectedDataElements: state.selectedDataElements,\n initialDataElementSelections: state.initialDataElementSelections,\n settings: settingsObj,\n isMobile,\n isAlreadyConsented: true,\n getTranslatedText: (key, defaultText, itemId) => this.getTranslatedText(key, defaultText, itemId),\n onPurposeToggle: () => {},\n onPurposeCollapse: (uuid) => this.togglePurposeCollapse(uuid),\n onDataElementToggle: () => {},\n });\n this.middleSection.appendChild(this.alreadyConsentedPurposeRefs.container);\n }\n\n // Additional text + Privacy Center + DPO Info in ONE block (matches React layout)\n if (activeConfig.privacy_center_url || activeConfig.dpo_info) {\n const footerDiv = el(\"div\", {\n style: {\n ...baseTextStyle,\n fontSize: isMobile ? \"13px\" : \"14px\",\n lineHeight: \"1.4\",\n borderTop: \"1px solid rgba(152, 162, 179, 0.3)\",\n paddingTop: \"12px\",\n marginTop: \"12px\",\n },\n });\n\n const footerP = el(\"p\", { style: { margin: \"0\", opacity: \"0.6\" } });\n\n // Privacy Center section: \"additional_text Privacy Center.\"\n if (activeConfig.privacy_center_url) {\n if (activeConfig.additional_text) {\n const addlSpan = el(\"span\", { id: \"additional-text\" });\n addlSpan.textContent = this.getTranslatedText(\"additional_text\", activeConfig.additional_text);\n footerP.appendChild(addlSpan);\n footerP.appendChild(document.createTextNode(\" \"));\n }\n\n const pcAnchorText = this.getTranslatedText(\"privacy_center_anchor_text\", activeConfig.privacy_center_anchor_text || \"Privacy Center\");\n this.privacyCenterLinkEl = el(\"a\", {\n id: \"privacy-center-link\",\n href: activeConfig.privacy_center_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n }) as HTMLAnchorElement;\n this.privacyCenterLinkEl.textContent = pcAnchorText;\n footerP.appendChild(this.privacyCenterLinkEl);\n footerP.appendChild(document.createTextNode(\".\"));\n }\n\n // DPO Info section (all inline with <br> separators, matching React)\n if (activeConfig.dpo_info) {\n const dpo = activeConfig.dpo_info;\n\n if (activeConfig.privacy_center_url) {\n footerP.appendChild(el(\"br\"));\n }\n\n // Grievance line\n if (dpo.grievance_text) {\n const gText = el(\"span\", { id: \"dpo-grievance-text\" });\n gText.textContent = this.getTranslatedDpoText(\"grievance_text\", dpo.grievance_text);\n footerP.appendChild(gText);\n footerP.appendChild(document.createTextNode(\" \"));\n\n if (dpo.grievance_url) {\n const gLink = el(\"a\", {\n id: \"dpo-grievance-link\",\n href: dpo.grievance_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n });\n gLink.textContent = this.getTranslatedDpoText(\"grievance_anchor_text\", dpo.grievance_anchor_text);\n footerP.appendChild(gLink);\n }\n\n if (dpo.grievance_email) {\n footerP.appendChild(document.createTextNode(\" \"));\n const connectorSpan = el(\"span\", { id: \"dpo-grievance-email-connector\" });\n connectorSpan.textContent = this.getTranslatedDpoText(\n \"grievance_email_connector_text\",\n dpo.grievance_email_connector_text || \"or email to\"\n );\n footerP.appendChild(connectorSpan);\n footerP.appendChild(document.createTextNode(\" \"));\n\n const emailLink = el(\"a\", {\n id: \"dpo-grievance-email\",\n href: `mailto:${dpo.grievance_email}`,\n style: { ...styles.link, color: linkColor, fontFamily: font },\n });\n emailLink.textContent = dpo.grievance_email;\n footerP.appendChild(emailLink);\n }\n }\n\n // DP Board line\n if (dpo.dp_board_text) {\n footerP.appendChild(el(\"br\"));\n const dpText = el(\"span\", { id: \"dpo-dp-board-text\" });\n dpText.textContent = this.getTranslatedDpoText(\"dp_board_text\", dpo.dp_board_text);\n footerP.appendChild(dpText);\n footerP.appendChild(document.createTextNode(\" \"));\n\n if (dpo.dp_board_url) {\n const dpLink = el(\"a\", {\n id: \"dpo-dp-board-link\",\n href: dpo.dp_board_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n });\n dpLink.textContent = this.getTranslatedDpoText(\"dp_board_anchor_text\", dpo.dp_board_anchor_text);\n footerP.appendChild(dpLink);\n }\n }\n\n // DPO line\n if (dpo.dpo_text) {\n footerP.appendChild(el(\"br\"));\n const dpoTextSpan = el(\"span\", { id: \"dpo-dpo-text\" });\n dpoTextSpan.textContent = this.getTranslatedDpoText(\"dpo_text\", dpo.dpo_text);\n footerP.appendChild(dpoTextSpan);\n footerP.appendChild(document.createTextNode(\" \"));\n\n if (dpo.dpo_url) {\n const dpoLink = el(\"a\", {\n id: \"dpo-dpo-link\",\n href: dpo.dpo_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n });\n dpoLink.textContent = this.getTranslatedDpoText(\"dpo_anchor_text\", dpo.dpo_anchor_text);\n footerP.appendChild(dpoLink);\n }\n }\n }\n\n footerDiv.appendChild(footerP);\n this.middleSection.appendChild(footerDiv);\n }\n\n // Error message\n this.errorEl = el(\"div\", {\n role: \"alert\",\n style: {\n backgroundColor: \"#FEE2E2\",\n color: \"#DC2626\",\n padding: \"12px\",\n borderRadius: \"6px\",\n fontSize: \"14px\",\n border: \"1px solid #FCA5A5\",\n display: \"none\",\n },\n });\n\n // ─── Bottom Section: Accept FIRST, then Decline (matches React) ───\n const acceptBtnText = state.isFullyConsentedReviewMode\n ? (this.options.reviewModeButtonText || \"Continue\")\n : this.getTranslatedText(\"confirm_button_text\", activeConfig.confirm_button_text);\n\n const acceptStyle: Record<string, any> = {\n ...styles.button,\n ...styles.acceptButton,\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderRadius: colors.borderRadius,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n this.acceptBtn = el(\"button\", {\n id: \"confirm-button-text\",\n style: acceptStyle,\n type: \"button\",\n onClick: () => this.handleAccept(),\n }) as HTMLButtonElement;\n this.acceptBtn.textContent = acceptBtnText;\n\n const declineBtnText = this.getTranslatedText(\"decline_button_text\", activeConfig.decline_button_text);\n const declineStyle: Record<string, any> = {\n ...styles.button,\n ...styles.cancelButton,\n backgroundColor: colors.declineBg,\n color: colors.declineText,\n borderColor: colors.declineBorder,\n borderRadius: colors.borderRadius,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n this.declineBtn = el(\"button\", {\n id: \"decline-button-text\",\n style: declineStyle,\n type: \"button\",\n onClick: () => this.handleDecline(),\n }) as HTMLButtonElement;\n\n if (!state.isFullyConsentedReviewMode) {\n this.declineBtn.textContent = declineBtnText;\n }\n\n const bottomSection = el(\"div\", { style: styles.bottomSection });\n if (!state.isFullyConsentedReviewMode) {\n // React order: Accept first, Decline second\n bottomSection.appendChild(this.acceptBtn);\n bottomSection.appendChild(this.declineBtn);\n } else {\n bottomSection.appendChild(this.acceptBtn);\n }\n\n // Assemble modal\n const contentWrapper = el(\n \"div\",\n { style: styles.content },\n topSection,\n this.errorEl,\n this.middleSection,\n bottomSection\n );\n\n this.modalEl.appendChild(contentWrapper);\n\n // Set initial accept button disabled state\n this.updateAcceptButtonState(state);\n\n // Setup keyboard trap\n this.keyboardCleanup?.();\n this.keyboardCleanup = setupKeyboardTrap(this.modalEl, () => this.handleDecline());\n }\n\n private getLanguageCode(displayLanguage: string): string {\n const content = this.store.getState().content?.detail.active_config;\n if (!content) return \"English\";\n\n // English maps to \"English\" for audio API\n if (displayLanguage === \"English\" || displayLanguage === \"en\" || displayLanguage === \"EN\") {\n return \"English\";\n }\n\n // If display language exists in translations, use it directly\n if (content.supported_languages_and_translations?.[displayLanguage]) {\n return displayLanguage;\n }\n\n // Fallback to default language or English\n return content.default_language === \"en\" || content.default_language === \"EN\"\n ? \"English\"\n : content.default_language || \"English\";\n }\n\n private getTranslatedDpoText(key: string, defaultText: string): string {\n const state = this.store.getState();\n const content = state.content?.detail.active_config;\n if (!content) return defaultText;\n\n const lang = state.selectedLanguage;\n if (lang === \"English\" || lang === \"en\" || lang === \"EN\") return defaultText;\n\n const translations = content.supported_languages_and_translations;\n if (!translations) return defaultText;\n\n const translationMap = translations[lang];\n if (!translationMap?.dpo_info) return defaultText;\n\n const value = (translationMap.dpo_info as any)[key];\n return typeof value === \"string\" && value ? value : defaultText;\n }\n\n private renderError(message: string): void {\n if (!this.modalEl) return;\n\n clearElement(this.modalEl);\n\n const errorContent = el(\n \"div\",\n { style: { ...styles.content, alignItems: \"center\", justifyContent: \"center\" } },\n el(\"div\", {\n role: \"alert\",\n style: {\n backgroundColor: \"#FEE2E2\",\n color: \"#DC2626\",\n padding: \"16px\",\n borderRadius: \"8px\",\n fontSize: \"14px\",\n border: \"1px solid #FCA5A5\",\n textAlign: \"center\",\n maxWidth: \"400px\",\n },\n }, message)\n );\n\n this.modalEl.appendChild(errorContent);\n }\n\n private getTranslatedText(key: string, defaultText: string, itemId?: string): string {\n const state = this.store.getState();\n const content = state.content?.detail.active_config;\n if (!content) return defaultText;\n\n const lang = state.selectedLanguage;\n if (lang === \"English\" || lang === \"en\" || lang === \"EN\") {\n if (key === \"privacy_policy_anchor_text\" && content.privacy_policy_anchor_text) {\n return content.privacy_policy_anchor_text;\n }\n return defaultText;\n }\n\n const translations = content.supported_languages_and_translations;\n if (!translations) return defaultText;\n\n const translationMap = translations[lang] as TranslationObject | undefined;\n if (!translationMap) return defaultText;\n\n if (itemId) {\n if (key === \"purposes.name\" || key === \"purposes.description\") {\n const purposeData = translationMap.purposes?.[itemId];\n if (purposeData) {\n if (typeof purposeData === \"string\") {\n return key === \"purposes.name\" ? purposeData : defaultText;\n }\n return key === \"purposes.name\"\n ? purposeData.name || defaultText\n : purposeData.description || defaultText;\n }\n return defaultText;\n }\n if (key.startsWith(\"data_elements.\")) {\n return translationMap.data_elements?.[itemId] || defaultText;\n }\n }\n\n const value = (translationMap as any)[key];\n if (typeof value === \"string\" && value) return value;\n return defaultText;\n }\n\n private handleLanguageSelect(lang: string): void {\n this.store.setState({ selectedLanguage: lang });\n // Rebuild UI to update all translations\n this.rebuildUI();\n }\n\n private togglePurposeCollapse(purposeUuid: string): void {\n const state = this.store.getState();\n this.store.setState({\n collapsedPurposes: {\n ...state.collapsedPurposes,\n [purposeUuid]: !state.collapsedPurposes[purposeUuid],\n },\n });\n }\n\n private handlePurposeCheckboxChange(purposeUuid: string): void {\n const state = this.store.getState();\n const content = state.content?.detail.active_config;\n if (!content) return;\n\n const purpose = content.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose) return;\n\n const newPurposeState = !state.selectedPurposes[purposeUuid];\n const updatedElements = { ...state.selectedDataElements };\n for (const de of purpose.data_elements) {\n updatedElements[`${purposeUuid}-${de.uuid}`] = newPurposeState;\n }\n\n this.store.setState({\n selectedPurposes: { ...state.selectedPurposes, [purposeUuid]: newPurposeState },\n selectedDataElements: updatedElements,\n });\n }\n\n private handleDataElementCheckboxChange(elementUuid: string, purposeUuid: string): void {\n const state = this.store.getState();\n const content = state.content?.detail.active_config;\n if (!content) return;\n\n const purpose = content.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose) return;\n\n const combinedId = `${purposeUuid}-${elementUuid}`;\n const newDataElements = {\n ...state.selectedDataElements,\n [combinedId]: !state.selectedDataElements[combinedId],\n };\n\n const requiredElements = purpose.data_elements.filter((el) => el.required);\n let shouldCheckPurpose: boolean;\n\n if (requiredElements.length > 0) {\n shouldCheckPurpose = requiredElements.every(\n (el) => newDataElements[`${purposeUuid}-${el.uuid}`]\n );\n } else {\n shouldCheckPurpose = purpose.data_elements.some(\n (el) => newDataElements[`${purposeUuid}-${el.uuid}`]\n );\n }\n\n this.store.setState({\n selectedDataElements: newDataElements,\n selectedPurposes: { ...state.selectedPurposes, [purposeUuid]: shouldCheckPurpose },\n });\n }\n\n private async handleAccept(): Promise<void> {\n const state = this.store.getState();\n if (state.isSubmitting) return;\n\n // Review mode — just close\n if (state.isFullyConsentedReviewMode) {\n this.options.onAccept();\n this.destroy();\n return;\n }\n\n // Block submission for minors who have not completed guardian verification\n if (state.isMinorFlow && !state.verificationReference && !state.selfDeclaredAdult) {\n this.store.setState({\n errorMessage: \"Guardian verification is required before consent can be submitted.\",\n });\n return;\n }\n\n const content = state.content?.detail.active_config;\n if (!content) return;\n\n this.abortController = new AbortController();\n this.store.setState({ isSubmitting: true, isSubmittingAccept: true, errorMessage: null });\n\n try {\n const purposes = content.purposes.map((purpose) => {\n const dataElements = purpose.data_elements\n .filter((de) => de.enabled)\n .map((de) => ({\n uuid: de.uuid,\n name: de.name,\n enabled: de.enabled,\n required: de.required,\n selected: state.selectedDataElements[`${purpose.uuid}-${de.uuid}`] || false,\n }));\n\n return {\n uuid: purpose.uuid,\n name: purpose.name,\n description: purpose.description,\n selected: state.selectedPurposes[purpose.uuid] || false,\n data_elements: dataElements,\n };\n });\n\n await submitConsentEvent({\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n noticeUuid: state.content!.detail.uuid,\n purposes,\n declined: false,\n meta_data: this.options.applicationId ? { specific_uuid: this.options.applicationId } : undefined,\n guardianVerificationReference: state.verificationReference || undefined,\n selfDeclaredAdult: state.selfDeclaredAdult || undefined,\n language: state.selectedLanguage,\n signal: this.abortController.signal,\n ...this.sandboxParams(),\n });\n\n this.options.onAccept();\n this.destroy();\n } catch (err) {\n if ((err as Error).name === \"AbortError\") return;\n const error = err as Error & { status?: number };\n const message = error.status === 409\n ? \"You have already provided consent.\"\n : error.status && error.status >= 500\n ? \"Server error: Please try again later.\"\n : error.message || \"Failed to submit consent.\";\n this.store.setState({ errorMessage: message, isSubmitting: false, isSubmittingAccept: false });\n this.options.onError?.(error);\n }\n }\n\n private handleDecline(): void {\n const state = this.store.getState();\n if (state.isSubmitting) return;\n\n // Stop any in-flight verification polling and clear the persisted\n // DigiLocker session so the next open starts the flow from scratch\n // (age verification → guardian form → verification screen).\n this.stopPolling();\n clearConsentState();\n\n this.options.onDecline();\n this.destroy();\n }\n\n private updateCheckboxes(state: ModalState): void {\n if (this.purposeRefs) {\n for (const [key, checkbox] of this.purposeRefs.checkboxes) {\n if (key in state.selectedPurposes) {\n checkbox.checked = state.selectedPurposes[key] || false;\n } else {\n checkbox.checked = state.selectedDataElements[key] || false;\n }\n }\n }\n // Update accept button disabled state\n this.updateAcceptButtonState(state);\n }\n\n private areAllRequiredChecked(state: ModalState): boolean {\n const content = state.content?.detail.active_config;\n if (!content?.purposes?.length) return false;\n\n return content.purposes.every((purpose) => {\n const requiredElements = purpose.data_elements.filter((de) => de.required && de.enabled);\n if (requiredElements.length === 0) return true;\n return requiredElements.every(\n (de) => state.selectedDataElements[`${purpose.uuid}-${de.uuid}`]\n );\n });\n }\n\n private updateAcceptButtonState(state: ModalState): void {\n if (!this.acceptBtn || state.isFullyConsentedReviewMode) return;\n\n const allRequiredChecked = this.areAllRequiredChecked(state);\n const disabled = !allRequiredChecked || state.isSubmittingAccept || state.isSubmittingDecline;\n\n this.acceptBtn.disabled = disabled;\n this.acceptBtn.style.opacity = disabled ? \"0.5\" : \"1\";\n this.acceptBtn.style.cursor = disabled ? \"not-allowed\" : \"pointer\";\n }\n\n private updateCollapseState(state: ModalState): void {\n const updateRefs = (refs: ModalPurposeRefs | null) => {\n if (!refs) return;\n for (const [purposeUuid, container] of refs.dataElementContainers) {\n const content = state.content?.detail.active_config;\n const purpose = content?.purposes.find((p) => p.uuid === purposeUuid);\n const isCollapsed = state.collapsedPurposes[purposeUuid];\n\n container.style.display = !isCollapsed && purpose?.data_elements?.length ? \"flex\" : \"none\";\n\n const chevron = refs.chevrons.get(purposeUuid);\n if (chevron) {\n (chevron as unknown as HTMLElement).style.transform = !isCollapsed ? \"rotate(90deg)\" : \"rotate(0deg)\";\n }\n\n const collapseBtn = refs.collapseButtons.get(purposeUuid);\n if (collapseBtn) {\n collapseBtn.setAttribute(\"aria-expanded\", String(!isCollapsed));\n }\n }\n };\n\n updateRefs(this.purposeRefs);\n updateRefs(this.alreadyConsentedPurposeRefs);\n }\n\n private updateErrorMessage(state: ModalState): void {\n if (!this.errorEl) return;\n if (state.errorMessage) {\n this.errorEl.textContent = state.errorMessage;\n this.errorEl.style.display = \"block\";\n } else {\n this.errorEl.style.display = \"none\";\n }\n }\n\n // ─── Age Verification Handlers ───\n\n private handleAgeVerificationYes(): void {\n this.store.setState({\n isMinorFlow: false,\n selfDeclaredAdult: true,\n showAgeVerification: false,\n });\n }\n\n private handleAgeVerificationNo(): void {\n this.store.setState({\n showAgeVerification: false,\n showGuardianForm: true,\n });\n }\n\n // ─── Guardian Form Handlers ───\n\n private async handleGuardianFormSubmit(): Promise<void> {\n const state = this.store.getState();\n const errors = validateGuardianForm(state.guardianFormData);\n if (Object.keys(errors).length > 0) {\n if (this.guardianFormRefs) {\n if (errors.guardianName) {\n this.guardianFormRefs.nameError.textContent = errors.guardianName;\n this.guardianFormRefs.nameError.style.display = \"block\";\n }\n if (errors.guardianContact) {\n this.guardianFormRefs.contactError.textContent = errors.guardianContact;\n this.guardianFormRefs.contactError.style.display = \"block\";\n }\n if (errors.guardianRelationship) {\n this.guardianFormRefs.relationshipError.textContent = errors.guardianRelationship;\n this.guardianFormRefs.relationshipError.style.display = \"block\";\n }\n }\n return;\n }\n\n this.store.setState({ isInitiatingVerification: true });\n\n const digilockerMode = this.options.digilockerMode || \"redirect\";\n const callbackUrl = digilockerMode === \"popup\"\n ? new URL(this.options.digilockerCallbackUrl || \"/digilocker-callback\", window.location.origin).href\n : undefined;\n\n try {\n const response = await initiateGuardianVerification({\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n guardianName: state.guardianFormData.guardianName,\n guardianContact: state.guardianFormData.guardianContact,\n guardianRelationship: state.guardianFormData.guardianRelationship,\n frontendCallbackUrl: callbackUrl,\n });\n\n if (response.already_verified && response.verification_reference) {\n this.store.setState({\n verificationReference: response.verification_reference,\n showGuardianForm: false,\n showVerificationScreen: true,\n isInitiatingVerification: false,\n isVerificationComplete: true,\n });\n // Auto-transition to consent form after 1s\n setTimeout(() => {\n this.store.setState({\n showVerificationScreen: false,\n isVerificationComplete: false,\n });\n }, 1000);\n return;\n }\n\n // Save state for redirect flow\n saveConsentState({\n flowState: \"digilocker-pending\",\n sessionToken: response.session_token,\n guardianInfoUuid: response.guardian_info_uuid,\n selectedPurposes: state.selectedPurposes,\n selectedDataElements: state.selectedDataElements,\n timestamp: new Date().toISOString(),\n originalUrl: window.location.href,\n noticeId: this.options.noticeId,\n baseUrl: this.options.baseUrl,\n });\n\n // Show verification screen with \"Opening DigiLocker...\" state\n this.store.setState({\n showGuardianForm: false,\n showVerificationScreen: true,\n isInitiatingVerification: true,\n isPollingStatus: false,\n });\n\n if (digilockerMode === \"popup\" && response.digilocker_redirect_url) {\n const popup = window.open(\n response.digilocker_redirect_url,\n \"digilocker_verification\",\n \"width=600,height=700,scrollbars=yes,resizable=yes\"\n );\n if (popup) {\n this.verificationPopup = popup;\n this.startPopupMonitoring(popup);\n } else {\n this.store.setState({\n isInitiatingVerification: false,\n verificationError: \"Popup blocked. Please allow popups for this site.\",\n canRetryVerification: true,\n });\n return;\n }\n } else if (response.digilocker_redirect_url) {\n const openedWindow = window.open(response.digilocker_redirect_url, \"_blank\");\n if (!openedWindow) {\n this.store.setState({\n isInitiatingVerification: false,\n verificationError: \"Unable to open DigiLocker. Please allow popups.\",\n canRetryVerification: true,\n });\n return;\n }\n try { openedWindow.opener = null; } catch {}\n }\n\n // Switch to polling state (spinner + \"Please complete verification...\" message)\n this.store.setState({\n isInitiatingVerification: false,\n isPollingStatus: true,\n });\n this.startStatusPolling(response.session_token!);\n } catch (error) {\n this.store.setState({ isInitiatingVerification: false });\n const err = error as Error & { status?: number };\n if (this.guardianFormRefs) {\n this.guardianFormRefs.generalError.textContent = err.message || \"Failed to initiate verification.\";\n this.guardianFormRefs.generalError.style.display = \"block\";\n }\n }\n }\n\n // ─── Verification Polling ───\n\n private startStatusPolling(token: string): void {\n this.verificationSessionToken = token;\n let attempts = 0;\n let consecutiveErrors = 0;\n let paused = false;\n const MAX_ATTEMPTS = 40;\n const MAX_CONSECUTIVE_ERRORS = 3;\n const POLL_INTERVAL = 3000;\n\n const poll = async () => {\n if (paused) return;\n attempts++;\n\n if (attempts > MAX_ATTEMPTS) {\n this.stopPolling();\n this.store.setState({\n verificationError: \"Verification is taking longer than expected. Please try again.\",\n verificationErrorCode: \"SESSION_EXPIRED\",\n canRetryVerification: true,\n isPollingStatus: false,\n });\n return;\n }\n\n try {\n const response = await verifyGuardianStatus({\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n sessionToken: token,\n });\n\n consecutiveErrors = 0;\n\n if (response.status === \"verified\") {\n this.stopPolling();\n const ref = response.verification_reference || response.guardian_details?.verification_reference;\n if (!ref) {\n this.store.setState({\n verificationError: \"Verification completed but no reference received. Please try again.\",\n canRetryVerification: true,\n isPollingStatus: false,\n });\n return;\n }\n this.store.setState({\n verificationReference: ref,\n isVerificationComplete: true,\n isPollingStatus: false,\n });\n clearConsentState();\n return;\n }\n\n if (response.status === \"failed\" || response.status === \"expired\") {\n this.stopPolling();\n this.store.setState({\n verificationError: getVerificationErrorMessage(response.error_code, response.error),\n verificationErrorCode: response.error_code,\n canRetryVerification: response.can_retry,\n isPollingStatus: false,\n });\n return;\n }\n\n if (!paused) {\n this.statusPollTimeout = setTimeout(poll, POLL_INTERVAL);\n }\n } catch (error) {\n const err = error as Error & { status?: number };\n if (err.status === 404 || err.status === 410) {\n this.stopPolling();\n this.store.setState({\n verificationError: \"Verification session not found or expired.\",\n verificationErrorCode: \"SESSION_EXPIRED\",\n canRetryVerification: true,\n isPollingStatus: false,\n });\n return;\n }\n\n consecutiveErrors++;\n if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) {\n this.stopPolling();\n this.store.setState({\n verificationError: err.message || \"Unable to check verification status.\",\n canRetryVerification: true,\n isPollingStatus: false,\n });\n return;\n }\n\n this.statusPollTimeout = setTimeout(poll, POLL_INTERVAL);\n }\n };\n\n // Pause when tab hidden, resume on return\n this.visibilityChangeHandler = () => {\n if (document.hidden) {\n paused = true;\n if (this.statusPollTimeout) {\n clearTimeout(this.statusPollTimeout);\n this.statusPollTimeout = null;\n }\n } else {\n paused = false;\n poll();\n }\n };\n document.addEventListener(\"visibilitychange\", this.visibilityChangeHandler);\n\n this.statusPollTimeout = setTimeout(poll, POLL_INTERVAL);\n }\n\n private stopPolling(): void {\n if (this.statusPollTimeout) {\n clearTimeout(this.statusPollTimeout);\n this.statusPollTimeout = null;\n }\n if (this.popupCheckInterval) {\n clearInterval(this.popupCheckInterval);\n this.popupCheckInterval = null;\n }\n if (this.visibilityChangeHandler) {\n document.removeEventListener(\"visibilitychange\", this.visibilityChangeHandler);\n this.visibilityChangeHandler = null;\n }\n this.verificationPopup?.close();\n this.verificationPopup = null;\n }\n\n private startPopupMonitoring(popup: Window): void {\n this.popupCheckInterval = setInterval(() => {\n if (popup.closed) {\n if (this.popupCheckInterval) {\n clearInterval(this.popupCheckInterval);\n this.popupCheckInterval = null;\n }\n }\n }, 500);\n }\n\n // ─── Verification Screen Handlers ───\n\n private handleVerificationContinue(): void {\n this.store.setState({\n showVerificationScreen: false,\n isVerificationComplete: false,\n });\n }\n\n private handleVerificationRetry(): void {\n this.store.setState({\n showVerificationScreen: false,\n showGuardianForm: true,\n verificationError: null,\n verificationErrorCode: null,\n canRetryVerification: false,\n isVerificationComplete: false,\n });\n }\n\n private handleChangeGuardian(): void {\n this.store.setState({\n showVerificationScreen: false,\n showGuardianForm: true,\n verificationError: null,\n verificationErrorCode: null,\n canRetryVerification: false,\n isVerificationComplete: false,\n guardianFormData: { guardianName: \"\", guardianContact: \"\", guardianRelationship: \"\" },\n });\n }\n\n // ─── TTS ───\n\n private updateTTSButton(): void {\n if (!this.ttsButton || !this.ttsManager) return;\n\n // When the current language has no TTS audio (e.g. Santali in some\n // configs), hide the speaker icon entirely. Without this branch the\n // button would keep whatever display value it had from the previous\n // language and clicking it would replay the previous language's audio.\n if (!this.ttsManager.isAvailable) {\n this.ttsButton.style.display = \"none\";\n return;\n }\n\n this.ttsButton.style.display = \"flex\";\n\n // Swap SVG: speaker icon vs pause icon\n clearElement(this.ttsButton);\n const strokeColor = this.options.settings?.button?.language?.textColor || \"currentColor\";\n\n if (this.ttsManager.isPlaying) {\n // Pause icon\n const pauseSvg = svg(\n \"svg\",\n {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"16\", height: \"16\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: strokeColor, \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n \"aria-hidden\": \"true\",\n },\n svg(\"rect\", { x: \"6\", y: \"4\", width: \"4\", height: \"16\" }),\n svg(\"rect\", { x: \"14\", y: \"4\", width: \"4\", height: \"16\" })\n );\n this.ttsButton.appendChild(pauseSvg);\n this.ttsButton.setAttribute(\"aria-label\", \"Pause audio playback\");\n this.ttsButton.setAttribute(\"title\", \"Pause Talkback\");\n } else {\n // Speaker icon\n const speakerSvg = svg(\n \"svg\",\n {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"16\", height: \"16\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: strokeColor, \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n \"aria-hidden\": \"true\",\n },\n svg(\"polygon\", { points: \"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" }),\n svg(\"path\", { d: \"M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07\" })\n );\n this.ttsButton.appendChild(speakerSvg);\n this.ttsButton.setAttribute(\"aria-label\", this.ttsManager.isPaused ? \"Resume audio playback\" : \"Start audio playback\");\n this.ttsButton.setAttribute(\"title\", this.ttsManager.isPaused ? \"Resume Talkback\" : \"Start Talkback\");\n }\n }\n\n private updateButtonStates(state: ModalState): void {\n if (this.acceptBtn) {\n if (state.isSubmittingAccept) {\n this.acceptBtn.textContent = \"Submitting...\";\n this.acceptBtn.disabled = true;\n this.acceptBtn.style.opacity = \"0.7\";\n this.acceptBtn.style.cursor = \"not-allowed\";\n } else {\n const content = state.content?.detail.active_config;\n this.acceptBtn.textContent = state.isFullyConsentedReviewMode\n ? (this.options.reviewModeButtonText || \"Continue\")\n : this.getTranslatedText(\"confirm_button_text\", content?.confirm_button_text || \"Accept\");\n this.acceptBtn.disabled = false;\n this.acceptBtn.style.opacity = \"1\";\n this.acceptBtn.style.cursor = \"pointer\";\n }\n }\n\n if (this.declineBtn) {\n this.declineBtn.disabled = state.isSubmitting;\n this.declineBtn.style.opacity = state.isSubmitting ? \"0.7\" : \"1\";\n this.declineBtn.style.cursor = state.isSubmitting ? \"not-allowed\" : \"pointer\";\n }\n }\n}\n","export const inlineStyles = {\n optionItem: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionLeft: {\n display: \"flex\",\n gap: \"12px\",\n alignItems: \"center\",\n cursor: \"pointer\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionTextContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionTitle: {\n fontWeight: 500,\n fontSize: \"16px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#101828\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n optionDescription: {\n fontWeight: 400,\n fontSize: \"12px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#475467\",\n verticalAlign: \"middle\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n checkboxLarge: {\n height: \"20px\",\n width: \"20px\",\n padding: \"4px\",\n borderRadius: \"5px\",\n border: \"2px solid #d0d5dd\",\n margin: 0,\n boxSizing: \"border-box\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n MozAppearance: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n backgroundColor: \"transparent\",\n },\n\n dataElementsContainer: {\n marginLeft: \"27px\",\n display: \"flex\",\n flexDirection: \"column\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n paddingLeft: \"22px\",\n },\n\n dataElementItem: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n justifyContent: \"space-between\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n minHeight: \"24px\",\n },\n\n dataElementText: {\n fontWeight: 400,\n fontSize: \"14px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#344054\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n checkboxSmall: {\n height: \"16px\",\n width: \"16px\",\n padding: \"4px\",\n borderRadius: \"5px\",\n border: \"2px solid #d0d5dd\",\n margin: 0,\n boxSizing: \"border-box\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n MozAppearance: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n backgroundColor: \"transparent\",\n },\n\n loadingContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"2rem\",\n minHeight: \"200px\",\n margin: 0,\n boxSizing: \"border-box\",\n },\n\n loadingSpinner: {\n width: \"40px\",\n height: \"40px\",\n border: \"4px solid #f3f3f3\",\n borderTop: \"4px solid #3498db\",\n borderRadius: \"50%\",\n animation: \"spin 1s linear infinite\",\n marginBottom: \"1rem\",\n boxSizing: \"border-box\",\n },\n} as const;\n","import { el, svg, applyStyles } from \"../core/dom\";\nimport { inlineStyles } from \"../styles/inline\";\nimport type { PurposeItemData, Settings } from \"../api/types\";\n\nexport type PurposeRenderRefs = {\n container: HTMLElement;\n checkboxes: Map<string, HTMLInputElement>; // purposeUuid or \"purposeUuid-elementUuid\"\n collapseButtons: Map<string, HTMLElement>;\n dataElementContainers: Map<string, HTMLElement>;\n chevrons: Map<string, SVGElement>;\n titleElements: Map<string, HTMLElement>;\n descriptionElements: Map<string, HTMLElement>;\n dataElementLabels: Map<string, HTMLElement>;\n};\n\nexport function renderInlinePurposes(\n purposes: PurposeItemData[],\n options: {\n selectedPurposes: Record<string, boolean>;\n collapsedPurposes: Record<string, boolean>;\n selectedDataElements: Record<string, boolean>;\n settings?: Partial<Settings>;\n isMobile: boolean;\n getTranslatedText: (key: string, defaultText: string, itemId?: string) => string;\n onPurposeToggle: (purposeUuid: string) => void;\n onPurposeCollapse: (purposeUuid: string) => void;\n onDataElementToggle: (elementUuid: string, purposeUuid: string) => void;\n }\n): PurposeRenderRefs {\n const {\n selectedPurposes,\n collapsedPurposes,\n selectedDataElements,\n settings,\n isMobile,\n getTranslatedText,\n onPurposeToggle,\n onPurposeCollapse,\n onDataElementToggle,\n } = options;\n\n const checkboxes = new Map<string, HTMLInputElement>();\n const collapseButtons = new Map<string, HTMLElement>();\n const dataElementContainers = new Map<string, HTMLElement>();\n const chevrons = new Map<string, SVGElement>();\n const titleElements = new Map<string, HTMLElement>();\n const descriptionElements = new Map<string, HTMLElement>();\n const dataElementLabels = new Map<string, HTMLElement>();\n\n const headingColor = settings?.headingColor || \"#101828\";\n const textColor = settings?.textColor || \"#344054\";\n\n const container = el(\"div\", {\n style: { display: \"flex\", flexDirection: \"column\", gap: \"16px\" },\n });\n\n for (const purpose of purposes) {\n const purposeWrapper = el(\"div\");\n\n // Chevron SVG\n const chevron = svg(\n \"svg\",\n {\n width: \"7\",\n height: \"12\",\n viewBox: \"0 0 7 12\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n stroke: settings?.headingColor || \"#323B4B\",\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n style: {\n transform: !collapsedPurposes[purpose.uuid] ? \"rotate(90deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.3s ease\",\n },\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", { d: \"M1 1L6 6L1 11\" })\n );\n chevrons.set(purpose.uuid, chevron);\n\n const chevronContainer = el(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n marginLeft: \"5px\",\n },\n },\n chevron\n );\n\n // Title\n const titleEl = el(\"h2\", {\n style: {\n ...inlineStyles.optionTitle,\n fontSize: isMobile ? \"14px\" : \"16px\",\n color: headingColor,\n },\n });\n titleEl.textContent = getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid);\n titleElements.set(purpose.uuid, titleEl);\n\n // Description\n const descEl = el(\"h3\", {\n style: {\n ...inlineStyles.optionDescription,\n fontSize: isMobile ? \"11px\" : \"12px\",\n color: textColor,\n },\n });\n descEl.textContent = getTranslatedText(\"purposes.description\", purpose.description, purpose.uuid);\n descriptionElements.set(purpose.uuid, descEl);\n\n const textContainer = el(\"div\", { style: inlineStyles.optionTextContainer }, titleEl, descEl);\n\n // Collapse button\n const collapseBtn = el(\"div\", {\n style: inlineStyles.optionLeft,\n role: \"button\",\n tabIndex: \"0\",\n \"aria-expanded\": String(!collapsedPurposes[purpose.uuid]),\n \"aria-controls\": `purpose-${purpose.uuid}`,\n \"aria-label\": `${collapsedPurposes[purpose.uuid] ? \"Expand\" : \"Collapse\"} ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)} details`,\n onClick: () => onPurposeCollapse(purpose.uuid),\n onKeydown: (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onPurposeCollapse(purpose.uuid);\n }\n },\n }, chevronContainer, textContainer);\n collapseButtons.set(purpose.uuid, collapseBtn);\n\n // Purpose checkbox\n const purposeCheckbox = el(\"input\", {\n type: \"checkbox\",\n checked: selectedPurposes[purpose.uuid] || false,\n \"aria-label\": `Select all data elements for ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)}`,\n onChange: () => onPurposeToggle(purpose.uuid),\n }) as HTMLInputElement;\n checkboxes.set(purpose.uuid, purposeCheckbox);\n\n const optionRow = el(\"div\", { style: inlineStyles.optionItem }, collapseBtn, purposeCheckbox);\n\n // Data elements container\n const deContainer = el(\"div\", {\n id: `purpose-${purpose.uuid}`,\n style: inlineStyles.dataElementsContainer,\n });\n\n if (purpose.data_elements && purpose.data_elements.length > 0) {\n for (const dataElement of purpose.data_elements) {\n const combinedId = `${purpose.uuid}-${dataElement.uuid}`;\n\n const labelSpan = el(\"span\", {\n style: {\n ...inlineStyles.dataElementText,\n fontSize: isMobile ? \"12px\" : \"14px\",\n color: textColor,\n },\n });\n labelSpan.textContent = getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid);\n dataElementLabels.set(combinedId, labelSpan);\n\n if (dataElement.required) {\n const asterisk = el(\"span\", {\n style: { color: \"red\", marginLeft: \"4px\" },\n \"aria-label\": \"required\",\n });\n asterisk.textContent = \"*\";\n labelSpan.appendChild(asterisk);\n }\n\n const deCheckbox = el(\"input\", {\n type: \"checkbox\",\n checked: selectedDataElements[combinedId] || false,\n \"aria-label\": `Select ${getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid)}${dataElement.required ? \" (required)\" : \"\"}`,\n onChange: () => onDataElementToggle(dataElement.uuid, purpose.uuid),\n }) as HTMLInputElement;\n checkboxes.set(combinedId, deCheckbox);\n\n const deRow = el(\"div\", { style: inlineStyles.dataElementItem }, labelSpan, deCheckbox);\n deContainer.appendChild(deRow);\n }\n }\n\n dataElementContainers.set(purpose.uuid, deContainer);\n\n // Show/hide data elements based on collapse state\n if (!collapsedPurposes[purpose.uuid] && purpose.data_elements?.length > 0) {\n deContainer.style.display = \"flex\";\n } else {\n deContainer.style.display = \"none\";\n }\n\n purposeWrapper.appendChild(optionRow);\n purposeWrapper.appendChild(deContainer);\n container.appendChild(purposeWrapper);\n }\n\n return {\n container,\n checkboxes,\n collapseButtons,\n dataElementContainers,\n chevrons,\n titleElements,\n descriptionElements,\n dataElementLabels,\n };\n}\n","import { Store } from \"../core/state\";\nimport { createMediaQuery, type MediaQuerySubscription } from \"../core/media-query\";\nimport { el, applyStyles, clearElement } from \"../core/dom\";\nimport { fetchConsentContentPublic, submitConsentEventPublic } from \"../api\";\nimport { resolveDisplayLanguage } from \"../api/language\";\nimport {\n fetchNoticeConsentStatusForScope,\n isNoticeFullyConsented,\n} from \"../api/notice-consent-status\";\nimport { injectCheckboxStyles } from \"../styles/inject\";\nimport { inlineStyles } from \"../styles/inline\";\nimport { renderInlinePurposes, type PurposeRenderRefs } from \"./purposes\";\nimport type { InlineOptions } from \"../types\";\nimport type { ActiveConfig, TranslationObject } from \"../api/types\";\n\ntype InlineState = {\n content: ActiveConfig | null;\n isLoading: boolean;\n isSubmitting: boolean;\n selectedLanguage: string;\n collapsedPurposes: Record<string, boolean>;\n selectedPurposes: Record<string, boolean>;\n selectedDataElements: Record<string, boolean>;\n hasAlreadyConsented: boolean;\n // Blocks auto-submit while the Go ledger check-consent read is in flight,\n // so an already-consented principal is not re-submitted post-cutover.\n isCheckingConsent: boolean;\n fetchError: Error | null;\n errorMessage: string | null;\n};\n\nexport class InlineController {\n private store: Store<InlineState>;\n private options: InlineOptions;\n private targetEl: HTMLElement | null = null;\n private hostEl: HTMLElement | null = null;\n private shadowRoot: ShadowRoot | null = null;\n private rootEl: HTMLElement | null = null;\n private mediaQuery: MediaQuerySubscription;\n private purposeRefs: PurposeRenderRefs | null = null;\n private errorEl: HTMLElement | null = null;\n private hasSubmitted = false;\n private hasCheckedLedgerConsent = false;\n private fetchedWithToken = false;\n private fetchGeneration = 0;\n private unsubscribe: (() => void) | null = null;\n private abortController: AbortController | null = null;\n\n constructor(options: InlineOptions) {\n this.options = options;\n this.store = new Store<InlineState>({\n content: null,\n isLoading: true,\n isSubmitting: false,\n selectedLanguage: options.language || \"en\",\n collapsedPurposes: {},\n selectedPurposes: {},\n selectedDataElements: {},\n hasAlreadyConsented: false,\n isCheckingConsent: false,\n fetchError: null,\n errorMessage: null,\n });\n this.mediaQuery = createMediaQuery(\"(max-width: 768px)\");\n }\n\n async init(): Promise<void> {\n this.abortController = new AbortController();\n\n // Resolve target element\n if (typeof this.options.target === \"string\") {\n this.targetEl = document.querySelector(this.options.target);\n if (!this.targetEl) {\n throw new Error(`Target element not found: ${this.options.target}`);\n }\n } else {\n this.targetEl = this.options.target;\n }\n\n // Mount the inline form inside an open shadow root attached to a host\n // <div> within the user's target container. This matches the modal's\n // isolation strategy so host-page CSS cannot bleed into the inline form\n // either.\n this.hostEl = document.createElement(\"div\");\n this.hostEl.setAttribute(\"data-redacto-consent-inline\", \"\");\n // Block-level, but no `all: initial` — we want font / color / line-height\n // to inherit from the user's page so the inline form blends in like the\n // React SDK does.\n this.hostEl.style.display = \"block\";\n this.targetEl.appendChild(this.hostEl);\n this.shadowRoot = this.hostEl.attachShadow({ mode: \"open\" });\n injectCheckboxStyles(this.shadowRoot);\n\n // Subscribe to state changes\n this.unsubscribe = this.store.subscribe((state, prevState) => {\n this.handleStateChange(state, prevState);\n });\n\n // Subscribe to media query changes\n this.mediaQuery.subscribe(() => this.rebuildUI());\n\n // Render loading state\n this.renderLoading();\n\n // Fetch content\n await this.fetchNotice();\n }\n\n destroy(): void {\n // Cancels the in-flight ledger read and marks the controller torn down, so\n // late-resolving work cannot fire host callbacks or submit consent.\n this.abortController?.abort();\n this.unsubscribe?.();\n this.mediaQuery.destroy();\n this.store.destroy();\n // Removing the host div tears down the shadow tree (and the rootEl\n // inside it) in one step.\n if (this.hostEl && this.hostEl.parentNode) {\n this.hostEl.parentNode.removeChild(this.hostEl);\n }\n this.hostEl = null;\n this.shadowRoot = null;\n this.rootEl = null;\n this.purposeRefs = null;\n }\n\n updateToken(accessToken: string): void {\n this.options = { ...this.options, accessToken };\n if (accessToken && !this.fetchedWithToken) {\n void this.fetchNotice();\n return;\n }\n // A late-arriving token is the first chance to run the ledger\n // check-consent read; it gates auto-submit synchronously before trying.\n if (this.shouldCheckLedgerConsent()) {\n void this.checkLedgerConsent();\n return;\n }\n this.tryAutoSubmit();\n }\n\n // ─── Private ───\n\n // destroy() aborts the controller, so an aborted signal is the marker that\n // teardown has happened and async continuations must not touch the host.\n private isDestroyed(): boolean {\n return Boolean(this.abortController?.signal.aborted);\n }\n\n private async fetchNotice(): Promise<void> {\n const generation = ++this.fetchGeneration;\n this.fetchedWithToken = Boolean(this.options.accessToken);\n this.store.setState({ isLoading: true, fetchError: null, hasAlreadyConsented: false });\n try {\n const data = await fetchConsentContentPublic({\n org_uuid: this.options.org_uuid,\n workspace_uuid: this.options.workspace_uuid,\n notice_uuid: this.options.notice_uuid,\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n language: this.options.language,\n specific_uuid: this.options.applicationId,\n });\n\n if (this.isDestroyed() || generation !== this.fetchGeneration) {\n return;\n }\n\n const activeConfig = data.detail.active_config;\n const initialCollapsed: Record<string, boolean> = {};\n const initialPurposes: Record<string, boolean> = {};\n const initialElements: Record<string, boolean> = {};\n\n for (const purpose of activeConfig.purposes) {\n initialCollapsed[purpose.uuid] = true;\n initialPurposes[purpose.uuid] = false;\n for (const de of purpose.data_elements) {\n initialElements[`${purpose.uuid}-${de.uuid}`] = false;\n }\n }\n\n // Post-cutover, consent records live in the Go ledger, so Python's\n // get-notice no longer 409s for an already-consented principal. Kick off\n // the ledger check BEFORE the content state lands: its synchronous\n // prologue raises isCheckingConsent, so the content state change below\n // cannot auto-submit until the read settles.\n void this.checkLedgerConsent();\n\n this.store.setState({\n content: activeConfig,\n isLoading: false,\n selectedLanguage: resolveDisplayLanguage(\n this.options.language,\n activeConfig.default_language,\n activeConfig.supported_languages_and_translations\n ),\n collapsedPurposes: initialCollapsed,\n selectedPurposes: initialPurposes,\n selectedDataElements: initialElements,\n });\n } catch (err: unknown) {\n if (this.isDestroyed() || generation !== this.fetchGeneration) {\n return;\n }\n const error = err as Error & { status?: number };\n if (error.status === 409) {\n this.store.setState({ hasAlreadyConsented: true, isLoading: false });\n this.options.onAccept?.();\n } else {\n this.store.setState({ fetchError: error, isLoading: false });\n this.options.onError?.(error);\n }\n }\n }\n\n private shouldCheckLedgerConsent(): boolean {\n return (\n Boolean(this.options.ledgerBaseUrl) &&\n !this.options.applicationId &&\n Boolean(this.options.accessToken) &&\n !this.hasCheckedLedgerConsent\n );\n }\n\n // Ask the Go ledger whether this principal has already fully consented —\n // the ledger equivalent of the legacy Python 409. Skipped without a ledger\n // (the 409 path governs) and for the magic-link applicationId flow. Any\n // failure returns null and falls through to the normal flow.\n private async checkLedgerConsent(): Promise<void> {\n if (!this.shouldCheckLedgerConsent()) return;\n this.hasCheckedLedgerConsent = true;\n this.store.setState({ isCheckingConsent: true });\n try {\n const status = await fetchNoticeConsentStatusForScope({\n accessToken: this.options.accessToken!,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n organisationUuid: this.options.org_uuid,\n workspaceUuid: this.options.workspace_uuid,\n noticeUuid: this.options.notice_uuid,\n signal: this.abortController?.signal,\n });\n if (this.isDestroyed()) {\n return;\n }\n if (status && isNoticeFullyConsented(status)) {\n this.store.setState({ hasAlreadyConsented: true });\n this.options.onAccept?.();\n }\n } finally {\n if (!this.isDestroyed()) {\n this.store.setState({ isCheckingConsent: false });\n // Re-run auto-submit now that the gate is down (no-op when already\n // consented or requirements are unmet).\n this.tryAutoSubmit();\n }\n }\n }\n\n private handleStateChange(state: InlineState, prevState: InlineState): void {\n // Loading → content loaded\n if (prevState.isLoading && !state.isLoading && state.content) {\n this.rebuildUI();\n }\n\n // Already consented or fetch error → hide\n if (state.hasAlreadyConsented || state.fetchError) {\n if (this.rootEl && this.shadowRoot && this.rootEl.parentNode === this.shadowRoot) {\n this.shadowRoot.removeChild(this.rootEl);\n this.rootEl = null;\n }\n return;\n }\n\n // Checkbox state changes → update checkboxes\n if (state.selectedPurposes !== prevState.selectedPurposes ||\n state.selectedDataElements !== prevState.selectedDataElements) {\n this.updateCheckboxes(state);\n this.notifyValidation(state);\n this.tryAutoSubmit();\n }\n\n // Collapse state changes\n if (state.collapsedPurposes !== prevState.collapsedPurposes) {\n this.updateCollapseState(state);\n }\n\n // Error message changes\n if (state.errorMessage !== prevState.errorMessage) {\n this.updateErrorMessage(state);\n }\n }\n\n private renderLoading(): void {\n if (!this.shadowRoot) return;\n\n const textColor = this.options.settings?.textColor || \"#344054\";\n\n this.rootEl = el(\n \"div\",\n { style: inlineStyles.loadingContainer },\n el(\"div\", { style: inlineStyles.loadingSpinner }),\n el(\"p\", { style: { fontSize: \"16px\", fontWeight: 400, color: textColor } }, \"Loading...\")\n );\n\n this.shadowRoot.appendChild(this.rootEl);\n }\n\n private rebuildUI(): void {\n const state = this.store.getState();\n if (!state.content || !this.shadowRoot) return;\n\n // Remove existing root\n if (this.rootEl && this.rootEl.parentNode === this.shadowRoot) {\n this.shadowRoot.removeChild(this.rootEl);\n }\n\n // Build error message element\n this.errorEl = el(\"div\", {\n role: \"alert\",\n style: {\n backgroundColor: \"#FEE2E2\",\n color: \"#DC2626\",\n padding: \"12px\",\n borderRadius: \"6px\",\n fontSize: \"14px\",\n border: \"1px solid #FCA5A5\",\n display: state.errorMessage ? \"block\" : \"none\",\n },\n });\n if (state.errorMessage) {\n this.errorEl.textContent = state.errorMessage;\n }\n\n // Build purposes\n this.purposeRefs = renderInlinePurposes(state.content.purposes, {\n selectedPurposes: state.selectedPurposes,\n collapsedPurposes: state.collapsedPurposes,\n selectedDataElements: state.selectedDataElements,\n settings: this.options.settings,\n isMobile: this.mediaQuery.matches,\n getTranslatedText: (key, defaultText, itemId) =>\n this.getTranslatedText(key, defaultText, itemId),\n onPurposeToggle: (uuid) => this.handlePurposeCheckboxChange(uuid),\n onPurposeCollapse: (uuid) => this.togglePurposeCollapse(uuid),\n onDataElementToggle: (elementUuid, purposeUuid) =>\n this.handleDataElementCheckboxChange(elementUuid, purposeUuid),\n });\n\n this.rootEl = el(\n \"div\",\n { style: { display: \"flex\", flexDirection: \"column\", gap: \"16px\" } },\n this.errorEl,\n this.purposeRefs.container\n );\n\n this.shadowRoot.appendChild(this.rootEl);\n this.notifyValidation(state);\n }\n\n private getTranslatedText(key: string, defaultText: string, itemId?: string): string {\n const state = this.store.getState();\n const content = state.content;\n if (!content) return defaultText;\n\n const lang = state.selectedLanguage;\n if (lang === \"English\" || lang === \"en\" || lang === \"EN\") {\n if (key === \"privacy_policy_anchor_text\" && content.privacy_policy_anchor_text) {\n return content.privacy_policy_anchor_text;\n }\n return defaultText;\n }\n\n const translations = content.supported_languages_and_translations;\n if (!translations) return defaultText;\n\n const translationMap = translations[lang] as TranslationObject | undefined;\n if (!translationMap) return defaultText;\n\n if (itemId) {\n if (key === \"purposes.name\" || key === \"purposes.description\") {\n const purposeData = translationMap.purposes?.[itemId];\n if (purposeData) {\n if (typeof purposeData === \"string\") {\n return key === \"purposes.name\" ? purposeData : defaultText;\n }\n return key === \"purposes.name\"\n ? purposeData.name || defaultText\n : purposeData.description || defaultText;\n }\n return defaultText;\n }\n if (key.startsWith(\"data_elements.\")) {\n return translationMap.data_elements?.[itemId] || defaultText;\n }\n }\n\n const value = (translationMap as any)[key];\n if (typeof value === \"string\" && value) return value;\n return defaultText;\n }\n\n private togglePurposeCollapse(purposeUuid: string): void {\n const state = this.store.getState();\n this.store.setState({\n collapsedPurposes: {\n ...state.collapsedPurposes,\n [purposeUuid]: !state.collapsedPurposes[purposeUuid],\n },\n });\n }\n\n private handlePurposeCheckboxChange(purposeUuid: string): void {\n const state = this.store.getState();\n const content = state.content;\n if (!content) return;\n\n const purpose = content.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose) return;\n\n const newPurposeState = !state.selectedPurposes[purposeUuid];\n\n const updatedElements = { ...state.selectedDataElements };\n for (const de of purpose.data_elements) {\n updatedElements[`${purposeUuid}-${de.uuid}`] = newPurposeState;\n }\n\n this.store.setState({\n selectedPurposes: { ...state.selectedPurposes, [purposeUuid]: newPurposeState },\n selectedDataElements: updatedElements,\n });\n }\n\n private handleDataElementCheckboxChange(elementUuid: string, purposeUuid: string): void {\n const state = this.store.getState();\n const content = state.content;\n if (!content) return;\n\n const purpose = content.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose) return;\n\n const combinedId = `${purposeUuid}-${elementUuid}`;\n const newElementState = !state.selectedDataElements[combinedId];\n\n const newDataElements = {\n ...state.selectedDataElements,\n [combinedId]: newElementState,\n };\n\n const requiredElements = purpose.data_elements.filter((el) => el.required);\n let shouldCheckPurpose: boolean;\n\n if (requiredElements.length > 0) {\n shouldCheckPurpose = requiredElements.every(\n (el) => newDataElements[`${purposeUuid}-${el.uuid}`]\n );\n } else {\n shouldCheckPurpose = purpose.data_elements.some(\n (el) => newDataElements[`${purposeUuid}-${el.uuid}`]\n );\n }\n\n this.store.setState({\n selectedDataElements: newDataElements,\n selectedPurposes: { ...state.selectedPurposes, [purposeUuid]: shouldCheckPurpose },\n });\n }\n\n private updateCheckboxes(state: InlineState): void {\n if (!this.purposeRefs) return;\n\n for (const [key, checkbox] of this.purposeRefs.checkboxes) {\n if (key in state.selectedPurposes) {\n checkbox.checked = state.selectedPurposes[key] || false;\n } else {\n checkbox.checked = state.selectedDataElements[key] || false;\n }\n }\n }\n\n private updateCollapseState(state: InlineState): void {\n if (!this.purposeRefs) return;\n\n for (const [purposeUuid, container] of this.purposeRefs.dataElementContainers) {\n const content = this.store.getState().content;\n const purpose = content?.purposes.find((p) => p.uuid === purposeUuid);\n const isCollapsed = state.collapsedPurposes[purposeUuid];\n\n container.style.display = !isCollapsed && purpose?.data_elements?.length ? \"flex\" : \"none\";\n\n const chevron = this.purposeRefs.chevrons.get(purposeUuid);\n if (chevron) {\n (chevron as unknown as HTMLElement).style.transform = !isCollapsed\n ? \"rotate(90deg)\"\n : \"rotate(0deg)\";\n }\n\n const collapseBtn = this.purposeRefs.collapseButtons.get(purposeUuid);\n if (collapseBtn) {\n collapseBtn.setAttribute(\"aria-expanded\", String(!isCollapsed));\n }\n }\n }\n\n private updateErrorMessage(state: InlineState): void {\n if (!this.errorEl) return;\n if (state.errorMessage) {\n this.errorEl.textContent = state.errorMessage;\n this.errorEl.style.display = \"block\";\n } else {\n this.errorEl.style.display = \"none\";\n }\n }\n\n private areAllRequiredElementsChecked(): boolean {\n const state = this.store.getState();\n const content = state.content;\n if (!content) return false;\n\n return content.purposes.every((purpose) => {\n const requiredElements = purpose.data_elements.filter((el) => el.required);\n return requiredElements.every(\n (el) => state.selectedDataElements[`${purpose.uuid}-${el.uuid}`]\n );\n });\n }\n\n private notifyValidation(state: InlineState): void {\n const isValid = this.areAllRequiredElementsChecked();\n this.options.onValidationChange?.(isValid);\n }\n\n private async tryAutoSubmit(): Promise<void> {\n // A submit is a network write — never start one after teardown.\n if (this.isDestroyed()) {\n return;\n }\n\n const state = this.store.getState();\n const accessToken = this.options.accessToken;\n\n if (\n accessToken &&\n state.content &&\n this.areAllRequiredElementsChecked() &&\n !state.isSubmitting &&\n !state.isCheckingConsent &&\n !state.hasAlreadyConsented &&\n !this.hasSubmitted\n ) {\n this.hasSubmitted = true;\n try {\n await this.handleSubmit(accessToken);\n } catch (err) {\n this.hasSubmitted = false;\n this.options.onError?.(err as Error);\n }\n }\n }\n\n private async handleSubmit(tokenToUse: string): Promise<void> {\n const state = this.store.getState();\n const content = state.content;\n if (!tokenToUse || !content) {\n this.store.setState({ errorMessage: \"Unable to submit consent. Please try again.\" });\n throw new Error(\"Access token or content not available\");\n }\n\n try {\n this.store.setState({ isSubmitting: true, errorMessage: null });\n\n await submitConsentEventPublic({\n org_uuid: this.options.org_uuid,\n workspace_uuid: this.options.workspace_uuid,\n accessToken: tokenToUse,\n baseUrl: this.options.baseUrl,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n noticeUuid: content.notice_uuid,\n purposes: content.purposes.map((purpose) => {\n const hasSelectedRequired = purpose.data_elements.some(\n (el) =>\n el.required && (state.selectedDataElements[`${purpose.uuid}-${el.uuid}`] || false)\n );\n const hasSelectedAny = purpose.data_elements.some(\n (el) => state.selectedDataElements[`${purpose.uuid}-${el.uuid}`] || false\n );\n const purposeSelected =\n state.selectedPurposes[purpose.uuid] || hasSelectedRequired || hasSelectedAny;\n\n return {\n ...purpose,\n selected: purposeSelected,\n data_elements: purpose.data_elements.map((element) => ({\n ...element,\n selected: state.selectedDataElements[`${purpose.uuid}-${element.uuid}`] || false,\n })),\n };\n }),\n declined: false,\n meta_data: this.options.applicationId\n ? { specific_uuid: this.options.applicationId }\n : undefined,\n language: state.selectedLanguage,\n });\n\n this.options.onAccept?.();\n this.hasSubmitted = false;\n } catch (error) {\n const err = error as Error & { status?: number };\n const message =\n err.status === 500\n ? \"An error occurred while submitting your consent. Please try again later.\"\n : err.message || \"Failed to submit consent. Please try again.\";\n this.store.setState({ errorMessage: message });\n this.hasSubmitted = false;\n throw error;\n } finally {\n this.store.setState({ isSubmitting: false });\n }\n }\n}\n","import { el } from \"../core/dom\";\nimport { injectCheckboxStyles } from \"../styles/inject\";\nimport { verifyGuardianStatus } from \"../api\";\nimport {\n getConsentState,\n updateConsentState,\n} from \"../services/storage\";\nimport type { DigiLockerCallbackOptions } from \"../types\";\nimport type { GuardianVerificationErrorCode } from \"../api/types\";\n\nfunction getErrorMessage(errorCode?: GuardianVerificationErrorCode | string | null): string {\n switch (errorCode) {\n case \"GUARDIAN_UNDER_18\":\n return \"Guardian verification failed: The guardian must be 18 years or older.\";\n case \"SESSION_EXPIRED\":\n return \"Verification session has expired. Please restart the verification process.\";\n case \"TOKEN_FAILED\":\n return \"DigiLocker authentication failed. Please try again.\";\n case \"DIGILOCKER_AUTH_FAILED\":\n return \"DigiLocker authorization was cancelled or failed. Please try again.\";\n case \"NO_AUTH_CODE\":\n return \"Missing authorization code from DigiLocker. Please try again.\";\n default:\n return \"Verification failed. Please try again.\";\n }\n}\n\nexport function handleDigilockerCallback(options: DigiLockerCallbackOptions): void {\n // The DigiLocker callback page is a standalone screen, not embedded in a\n // host site, so styles can safely live in document.head here.\n injectCheckboxStyles(document);\n\n const params = new URLSearchParams(window.location.search);\n const sessionToken = params.get(\"session_token\");\n const urlStatus = params.get(\"status\") as \"verified\" | \"failed\" | \"expired\" | null;\n const verificationReference = params.get(\"verification_reference\");\n const errorCode = params.get(\"error_code\") as GuardianVerificationErrorCode | null;\n\n const persistedState = getConsentState();\n const originalUrl = persistedState?.originalUrl || \"/\";\n const storedBaseUrl = persistedState?.baseUrl;\n const storedSessionToken = persistedState?.sessionToken;\n const activeSessionToken = sessionToken || storedSessionToken;\n const apiBaseUrl = options.baseUrl || storedBaseUrl;\n\n // Check if in iframe\n let isInIframe = false;\n try {\n isInIframe = window.self !== window.top;\n } catch {\n isInIframe = true;\n }\n\n // Render status UI\n const container = el(\"div\", {\n style: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"200px\",\n padding: \"32px\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n },\n });\n\n const statusEl = el(\"p\", {\n style: { fontSize: \"16px\", fontWeight: 600, color: \"#101828\", textAlign: \"center\" },\n });\n statusEl.textContent = \"Processing verification...\";\n\n const spinnerEl = el(\"div\", {\n style: {\n width: \"40px\",\n height: \"40px\",\n border: \"4px solid #f3f3f3\",\n borderTop: \"4px solid #3498db\",\n borderRadius: \"50%\",\n animation: \"spin 1s linear infinite\",\n marginBottom: \"16px\",\n },\n });\n\n container.appendChild(spinnerEl);\n container.appendChild(statusEl);\n document.body.appendChild(container);\n\n const redirectToOriginal = (\n result: \"verified\" | \"failed\" | \"expired\",\n ref?: string\n ) => {\n updateConsentState({\n verificationResult: result,\n verificationReference: ref,\n flowState: result === \"verified\" ? \"consent-form\" : \"error\",\n });\n\n statusEl.textContent = result === \"verified\"\n ? \"Verification successful! Redirecting...\"\n : \"Verification failed. Redirecting...\";\n\n spinnerEl.style.display = \"none\";\n\n setTimeout(() => {\n window.location.href = originalUrl;\n }, 1500);\n };\n\n // Handle direct status from URL\n if (urlStatus === \"verified\" && verificationReference) {\n if (isInIframe && window.parent) {\n window.parent.postMessage({\n type: \"DIGILOCKER_VERIFICATION_STATUS\",\n status: \"verified\",\n verificationReference,\n }, window.location.origin);\n statusEl.textContent = \"Verification successful!\";\n spinnerEl.style.display = \"none\";\n return;\n }\n options.onSuccess?.(verificationReference);\n redirectToOriginal(\"verified\", verificationReference);\n return;\n }\n\n if (urlStatus === \"failed\" || urlStatus === \"expired\") {\n const errorMsg = getErrorMessage(errorCode);\n if (isInIframe && window.parent) {\n window.parent.postMessage({\n type: \"DIGILOCKER_VERIFICATION_STATUS\",\n status: urlStatus,\n errorCode,\n error: errorMsg,\n }, window.location.origin);\n statusEl.textContent = errorMsg;\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n return;\n }\n options.onError?.(new Error(errorMsg), errorCode || undefined);\n redirectToOriginal(urlStatus);\n return;\n }\n\n // No status in URL — poll the backend\n if (!activeSessionToken) {\n statusEl.textContent = \"No verification session found.\";\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n options.onError?.(new Error(\"No session token available\"));\n return;\n }\n\n let retryCount = 0;\n const MAX_RETRIES = 3;\n\n const pollStatus = async () => {\n try {\n const response = await verifyGuardianStatus({\n accessToken: options.accessToken,\n baseUrl: apiBaseUrl,\n sessionToken: activeSessionToken,\n });\n\n if (response.status === \"verified\") {\n const ref = response.verification_reference ||\n response.guardian_details?.verification_reference;\n\n if (isInIframe && window.parent) {\n window.parent.postMessage({\n type: \"DIGILOCKER_VERIFICATION_STATUS\",\n status: \"verified\",\n verificationReference: ref,\n }, window.location.origin);\n statusEl.textContent = \"Verification successful!\";\n spinnerEl.style.display = \"none\";\n return;\n }\n\n if (ref) options.onSuccess?.(ref);\n redirectToOriginal(\"verified\", ref || undefined);\n return;\n }\n\n if (response.status === \"failed\" || response.status === \"expired\") {\n const errorMsg = getVerificationError(response.error_code, response.error);\n\n if (isInIframe && window.parent) {\n window.parent.postMessage({\n type: \"DIGILOCKER_VERIFICATION_STATUS\",\n status: response.status,\n errorCode: response.error_code,\n error: errorMsg,\n }, window.location.origin);\n statusEl.textContent = errorMsg;\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n return;\n }\n\n options.onError?.(new Error(errorMsg), response.error_code || undefined);\n redirectToOriginal(response.status);\n return;\n }\n\n // Still in progress — retry with backoff\n retryCount++;\n if (retryCount > MAX_RETRIES) {\n const timeoutMsg = \"Verification is taking too long. Please return to the original page.\";\n statusEl.textContent = timeoutMsg;\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n options.onError?.(new Error(timeoutMsg));\n redirectToOriginal(\"failed\");\n return;\n }\n\n const delay = 3000 * Math.pow(2, retryCount - 1);\n statusEl.textContent = \"Still processing... Please wait.\";\n setTimeout(pollStatus, delay);\n } catch (error) {\n retryCount++;\n if (retryCount > MAX_RETRIES) {\n const errMsg = (error as Error).message || \"Failed to check verification status.\";\n statusEl.textContent = errMsg;\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n options.onError?.(error as Error);\n redirectToOriginal(\"failed\");\n return;\n }\n\n const delay = 3000 * Math.pow(2, retryCount - 1);\n setTimeout(pollStatus, delay);\n }\n };\n\n // Start first poll after 3s\n setTimeout(pollStatus, 3000);\n}\n\nfunction getVerificationError(errorCode: string | null, fallbackError: string | null): string {\n return getErrorMessage(errorCode) || fallbackError || \"Verification failed. Please try again.\";\n}\n"],"mappings":"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","names":["src_exports","__export","src_default","destroy","digilockerCallback","init","inline","Store","initialState","partial","prevState","listener","el","tag","attrs","children","element","applyAttrs","appendChildren","svg","key","value","applyStyles","event","UNITLESS_PROPS","styles","stringValue","parent","child","clearElement","createMediaQuery","query","mql","currentMatches","listeners","handler","e","cb","apiCache","CACHE_TTL","getCachedData","key","cached","setCachedData","data","ttl","clearApiCache","InvalidTokenError","b64DecodeUnicode","str","m","p","code","base64UrlDecode","output","jwtDecode","token","options","pos","part","decoded","e","decodeTokenSafely","token","jwtDecode","error","SANDBOX_TOKEN_HEADER","resolveSandboxAuth","options","_a","_b","_c","_d","_e","token","organisationUuid","workspaceUuid","ucic","subject","resolveRequestAuth","accessToken","sandbox","decodedToken","decodeTokenSafely","organisation_uuid","workspace_uuid","buildAuthHeaders","sandboxBodyIdentity","sandboxQueryIdentity","CODE_BY_NAME","CODE_BY_LOWER","c","toLanguageCode","lang","_a","_b","trimmed","lower","CODE_BY_LOWER","CODE_BY_NAME","resolveDisplayLanguage","requested","defaultLanguage","translations","fallback","requestedCode","key","BASE_URL","BASE_URL_PUBLIC","fetchConsentContent","noticeId","accessToken","baseUrl","language","specific_uuid","validate_against","include_fully_consented_data","signal","sandboxParams","ORG","WS","sandbox","resolveRequestAuth","apiBaseUrl","cacheKey","cached","getCachedData","url","key","value","sandboxQueryIdentity","response","buildAuthHeaders","errorMessage","error","data","setCachedData","fetchConsentContentPublic","org_uuid","workspace_uuid","notice_uuid","noticesUrl","submitConsentEvent","ledgerBaseUrl","noticeUuid","purposes","declined","meta_data","guardianVerificationReference","selfDeclaredAdult","validatedPurposes","purpose","dataElements","element","payload","toLanguageCode","requestBody","sandboxBodyIdentity","clearApiCache","submitConsentEventPublic","_a","_b","errorData","fetchTTSAudioUrls","initiateGuardianVerification","guardianName","guardianContact","guardianRelationship","frontendCallbackUrl","metadata","decodedToken","decodeTokenSafely","responseData","detail","verifyGuardianStatus","sessionToken","_c","_d","_e","_f","_g","_h","fetchNoticeConsentStatusForScope","accessToken","ledgerBaseUrl","organisationUuid","workspaceUuid","noticeUuid","signal","response","data","body","fetchNoticeConsentStatus","decodedToken","decodeTokenSafely","ORG","WS","isNoticeFullyConsented","status","buildLedgerConsentOverlay","configPurposes","_a","_b","byUuid","p","purpose_selections","cp","lp","purposeStatus","selectedByUuid","de","data_elements","STYLE_ID","STYLE_CONTENT","injectCheckboxStyles","root","style","styles","renderModalPurposes","purposes","options","_a","_b","selectedPurposes","collapsedPurposes","selectedDataElements","initialDataElementSelections","settings","isMobile","isAlreadyConsented","getTranslatedText","onPurposeToggle","onPurposeCollapse","onDataElementToggle","checkboxes","collapseButtons","dataElementContainers","chevrons","titleElements","descriptionElements","dataElementLabels","headingColor","textColor","font","container","el","styles","purpose","purposeWrapper","chevron","svg","chevronContainer","titleEl","descEl","textContainer","collapseBtn","e","rightElement","createGreenCheckmark","applyStyles","purposeCheckbox","optionRow","deContainer","dataElement","combinedId","labelSpan","asterisk","deRightElement","deCheckbox","deRow","size","ariaLabel","svgSize","strokeWidth","pathD","checkSvg","LANGUAGE_NATIVE_LABELS","toNativeLabel","name","_a","renderLanguageSelector","options","_b","_c","_d","languages","selectedLanguage","settings","onSelect","dropdownContainer","isOpen","buttonText","el","chevronSvg","svg","buttonStyle","styles","button","toggleDropdown","e","closeDropdown","dropdown","lang","isSelected","itemStyle","item","container","positionDropdown","rect","clickOutsideHandler","path","target","repositionHandler","openDropdown","setupKeyboardTrap","modalEl","onEscape","handler","e","_a","focusableElements","focusable","el","first","last","active","firstFocusable","STORAGE_KEY","isBrowser","saveConsentState","state","stateWithTimestamp","STORAGE_KEY","error","getConsentState","savedState","parsed","clearConsentState","updateConsentState","updates","currentState","DEFAULT_LOGO_POSITION","LOGO_POSITION_JUSTIFY","DPO_AUDIO_ELEMENT_MAP","TTSManager","onStateChange","root","params","_a","response","fetchTTSAudioUrls","error","content","_b","urls","audioSeq","elementSeq","push","url","elementId","purpose","purposeAudio","de","deAudio","mapping","DPO_AUDIO_ELEMENT_MAP","audioUrl","startIndex","index","audio","element","rect","el","renderAgeVerification","options","settings","colors","isMobile","logoUrl","onYes","onNo","onClose","headingColor","textColor","font","logo","el","styles","title","topLeft","closeBtn","closeSvg","svg","topSection","description","question","middleSection","btnBase","yesBtn","noBtn","bottomSection","RELATIONSHIP_OPTIONS","renderGuardianForm","options","_a","formData","settings","colors","isMobile","logoUrl","isSubmitting","onSubmit","onCancel","onFieldChange","headingColor","textColor","borderColor","bgColor","radius","font","accentColor","inputStyle","errorStyle","labelStyle","hintStyle","logo","el","styles","title","topLeft","topSection","subtitle","infoIcon","svg","infoText","infoBanner","nameLabel","nameInput","e","nameHint","nameError","nameGroup","contactLabel","contactInput","contactHint","contactError","contactGroup","relLabel","selectedLabel","o","chevronSvg","selectedSpan","relationshipDisplay","dropdownList","i","option","isSelected","optionEl","doClose","label","checkSvg","dropdownOpen","relContainer","handleClickOutside","doOpen","rect","spaceBelow","dropdownHeight","relationshipError","generalError","fieldsContainer","middleSection","btnBase","submitBtn","cancelBtn","bottomSection","validateGuardianForm","data","errors","getVerificationErrorMessage","errorCode","fallbackError","renderVerificationScreen","options","settings","colors","isMobile","logoUrl","isInitiating","isPolling","isComplete","isAutoTransitioning","error","canRetry","onContinue","onBack","headingColor","textColor","font","accentColor","logo","el","styles","title","topLeft","topSection","middleSection","successCircle","checkSvg","svg","successText","wrapper","spinner","statusMsg","errorCircle","xSvg","failedText","errorBox","btnBase","bottomSection","acceptBtnStyle","declineBtnStyle","continueBtn","retryBtn","goBackBtn","cancelBtn","resolveColors","settings","activeConfig","_a","_b","_c","_d","_e","_f","_g","_h","primaryColor","secondaryColor","resolveLogoPosition","raw","DEFAULT_LOGO_POSITION","logoRowJustify","position","LOGO_POSITION_JUSTIFY","ModalController","options","Store","createMediaQuery","state","prevState","_a","_b","_c","_d","noticeBaseUrl","data","fetchConsentContent","activeConfig","purposeSelections","reconsentRequired","ledgerOverlayApplied","ledgerStatus","fetchNoticeConsentStatus","overlay","buildLedgerConsentOverlay","initialCollapsed","initialPurposes","initialElements","initialDataElementSelections","needsConsentPurposes","alreadyConsentedPurposes","isFullyConsentedReviewMode","purpose","selection","de","combinedId","deSelection","wasSelected","selectedLanguage","resolveDisplayLanguage","isMinorFlow","showAgeVerification","restoreState","pollingTokenToResume","persistedState","getConsentState","clearConsentState","err","error","injectCheckboxStyles","TTSManager","el","styles","settingsObj","modalStyle","loadingEl","contentEl","_e","_f","_g","_h","isMobile","colors","resolveColors","clearElement","ageRefs","renderAgeVerification","setupKeyboardTrap","renderGuardianForm","field","value","s","verRefs","renderVerificationScreen","clearName","headingColor","textColor","linkColor","font","logoImg","supportedLangs","allLanguages","l","renderLanguageSelector","lang","ttsStrokeColor","speakerSvg","svg","topRight","logoPosition","resolveLogoPosition","headerRows","logoRowJustify","topSection","baseTextStyle","noticeTextSpan","policyPrefixText","policyAnchorText","policySpan","noticeAndPolicyP","renderModalPurposes","key","defaultText","itemId","uuid","euuid","puuid","footerDiv","footerP","addlSpan","pcAnchorText","dpo","gText","gLink","connectorSpan","emailLink","dpText","dpLink","dpoTextSpan","dpoLink","acceptBtnText","acceptStyle","declineBtnText","declineStyle","bottomSection","contentWrapper","displayLanguage","content","translations","translationMap","message","errorContent","purposeData","purposeUuid","p","newPurposeState","updatedElements","elementUuid","newDataElements","requiredElements","shouldCheckPurpose","purposes","dataElements","submitConsentEvent","checkbox","disabled","updateRefs","refs","container","isCollapsed","chevron","collapseBtn","errors","validateGuardianForm","digilockerMode","callbackUrl","response","initiateGuardianVerification","saveConsentState","popup","openedWindow","token","attempts","consecutiveErrors","paused","MAX_ATTEMPTS","MAX_CONSECUTIVE_ERRORS","POLL_INTERVAL","poll","verifyGuardianStatus","ref","getVerificationErrorMessage","strokeColor","pauseSvg","inlineStyles","renderInlinePurposes","purposes","options","_a","selectedPurposes","collapsedPurposes","selectedDataElements","settings","isMobile","getTranslatedText","onPurposeToggle","onPurposeCollapse","onDataElementToggle","checkboxes","collapseButtons","dataElementContainers","chevrons","titleElements","descriptionElements","dataElementLabels","headingColor","textColor","container","el","purpose","purposeWrapper","chevron","svg","chevronContainer","titleEl","inlineStyles","descEl","textContainer","collapseBtn","e","purposeCheckbox","optionRow","deContainer","dataElement","combinedId","labelSpan","asterisk","deCheckbox","deRow","InlineController","options","Store","createMediaQuery","injectCheckboxStyles","state","prevState","_a","_b","accessToken","_c","_d","generation","data","fetchConsentContentPublic","activeConfig","initialCollapsed","initialPurposes","initialElements","purpose","de","resolveDisplayLanguage","err","error","status","fetchNoticeConsentStatusForScope","isNoticeFullyConsented","textColor","el","inlineStyles","renderInlinePurposes","key","defaultText","itemId","uuid","elementUuid","purposeUuid","content","lang","translations","translationMap","purposeData","value","p","newPurposeState","updatedElements","combinedId","newElementState","newDataElements","requiredElements","shouldCheckPurpose","checkbox","container","isCollapsed","chevron","collapseBtn","isValid","tokenToUse","submitConsentEventPublic","hasSelectedRequired","hasSelectedAny","purposeSelected","element","message","getErrorMessage","errorCode","handleDigilockerCallback","options","_a","_b","_c","injectCheckboxStyles","params","sessionToken","urlStatus","verificationReference","persistedState","getConsentState","originalUrl","storedBaseUrl","storedSessionToken","activeSessionToken","apiBaseUrl","isInIframe","container","el","statusEl","spinnerEl","redirectToOriginal","result","ref","updateConsentState","errorMsg","retryCount","MAX_RETRIES","pollStatus","_d","_e","response","verifyGuardianStatus","getVerificationError","timeoutMsg","delay","error","errMsg","fallbackError","activeModal","activeInline","init","options","destroy","ModalController","err","_a","inline","InlineController","digilockerCallback","handleDigilockerCallback","RedactoConsent","src_default"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/core/state.ts","../src/core/dom.ts","../src/core/media-query.ts","../src/services/cache.ts","../../../node_modules/.pnpm/jwt-decode@4.0.0/node_modules/jwt-decode/build/esm/index.js","../src/core/jwt-decode.ts","../src/api/sandbox.ts","../src/api/constants.ts","../src/api/language.ts","../src/api/submit-payload.ts","../src/shared/api-errors.ts","../src/shared/idempotency.ts","../src/constants.ts","../src/api/index.ts","../src/api/notice-consent-status.ts","../src/styles/inject.ts","../src/styles/modal.ts","../src/core/required-marker.ts","../src/core/productMatrix.ts","../src/modal/consentSelection.ts","../src/modal/selection-control.ts","../src/modal/purposes.ts","../src/modal/language-selector.ts","../src/modal/keyboard.ts","../src/services/storage.ts","../src/modal/tts.ts","../src/modal/age-verification.ts","../src/modal/guardian-form.ts","../src/modal/verification-screen.ts","../src/modal/colors.ts","../src/modal/productConsent.ts","../src/modal/productState.ts","../src/modal/product-sections.ts","../src/modal/layout.ts","../src/modal/otpGate.ts","../src/modal/otp-gate-panel.ts","../src/modal/confirm-dialog.ts","../src/modal/productPolicies.ts","../src/modal/product-policy-line.ts","../src/modal/preselection.ts","../src/modal/notice-font.ts","../src/modal/index.ts","../src/styles/inline.ts","../src/inline/selection.ts","../src/inline/purposes.ts","../src/inline/index.ts","../src/assisted/constants.ts","../src/assisted/api.ts","../src/assisted/i18n.ts","../src/assisted/icons.ts","../src/assisted/selection.ts","../src/assisted/styles.ts","../src/assisted/notice-view.ts","../src/assisted/theme.ts","../src/assisted/verify-view.ts","../src/assisted/index.ts","../src/modal/digilocker-callback.ts","../src/privacy-center/index.ts"],"sourcesContent":["import { ModalController } from \"./modal\";\nimport { InlineController } from \"./inline\";\nimport { AssistedController } from \"./assisted\";\nimport { handleDigilockerCallback } from \"./modal/digilocker-callback\";\nimport type {\n ModalOptions,\n InlineOptions,\n DigiLockerCallbackOptions,\n OtpGateOptions,\n OtpVerifyResult,\n} from \"./types\";\nimport type { AssistedOptions } from \"./assisted/types\";\nimport { mountPrivacyCenter } from \"./privacy-center\";\nimport type { PrivacyCenterHandle, PrivacyCenterOptions } from \"./privacy-center/types\";\n\nlet activeModal: ModalController | null = null;\nlet activeInline: InlineController | null = null;\nlet activeAssisted: AssistedController | null = null;\nconst activePrivacyCenters = new Set<PrivacyCenterHandle>();\n\n/**\n * Initialize a modal consent dialog.\n * Renders a full-screen overlay with the consent form.\n */\nfunction init(options: ModalOptions): void {\n // Destroy any existing instance\n destroy();\n\n activeModal = new ModalController(options);\n activeModal.init().catch((err) => {\n options.onError?.(err);\n });\n}\n\n/**\n * Initialize an inline consent form.\n * Renders consent purposes inside a target container element.\n */\nfunction inline(options: InlineOptions): void {\n // Destroy any existing inline instance\n if (activeInline) {\n activeInline.destroy();\n activeInline = null;\n }\n\n activeInline = new InlineController(options);\n activeInline.init().catch((err) => {\n options.onError?.(err);\n });\n}\n\nfunction updateToken(accessToken: string): void {\n activeModal?.updateToken(accessToken);\n activeInline?.updateToken(accessToken);\n}\n\nfunction assisted(options: AssistedOptions): void {\n if (activeAssisted) {\n activeAssisted.destroy();\n activeAssisted = null;\n }\n\n activeAssisted = new AssistedController(options);\n activeAssisted.init().catch((err) => {\n options.onError?.(err);\n });\n}\n\n/**\n * Mount the hosted Privacy Center in an iframe inside a target element.\n * Returns a handle whose `destroy()` removes it.\n */\nfunction privacyCenter(options: PrivacyCenterOptions): PrivacyCenterHandle {\n const handle = mountPrivacyCenter(options);\n const tracked: PrivacyCenterHandle = {\n iframe: handle.iframe,\n destroy: () => {\n activePrivacyCenters.delete(tracked);\n handle.destroy();\n },\n };\n activePrivacyCenters.add(tracked);\n return tracked;\n}\n\n/**\n * Destroy all active consent instances.\n */\nfunction destroy(): void {\n if (activeModal) {\n activeModal.destroy();\n activeModal = null;\n }\n if (activeInline) {\n activeInline.destroy();\n activeInline = null;\n }\n if (activeAssisted) {\n activeAssisted.destroy();\n activeAssisted = null;\n }\n for (const handle of [...activePrivacyCenters]) {\n handle.destroy();\n }\n}\n\n/**\n * Handle DigiLocker callback (for guardian verification redirect flow).\n * Call this on the DigiLocker callback page.\n */\nfunction digilockerCallback(options: DigiLockerCallbackOptions): void {\n handleDigilockerCallback(options);\n}\n\nconst RedactoConsent = {\n init,\n inline,\n assisted,\n privacyCenter,\n destroy,\n digilockerCallback,\n updateToken,\n version: \"0.1.0\",\n};\n\nexport default RedactoConsent;\nexport { init, inline, assisted, privacyCenter, destroy, digilockerCallback, updateToken };\nexport type {\n ModalOptions,\n InlineOptions,\n DigiLockerCallbackOptions,\n OtpGateOptions,\n OtpVerifyResult,\n AssistedOptions,\n PrivacyCenterOptions,\n PrivacyCenterHandle,\n};\nexport type { Settings } from \"./api/types\";\nexport { ApiError } from \"./shared/api-errors\";\nexport type { ApiErrorCode } from \"./shared/types\";\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","/**\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\n/**\n * CSS properties that take a unitless number, mirroring React's CSSProperty\n * list. For these we MUST NOT append \"px\" — doing so produces invalid CSS\n * (e.g. `font-weight: 400px`) and the browser falls back to the user-agent\n * default (which is what made <h3> purpose descriptions render as bold).\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 (matching React's behavior) EXCEPT\n * for the unitless properties listed above, which are passed through as-is.\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\n/**\n * Remove all children from an element.\n */\nexport function clearElement(element: HTMLElement): void {\n while (element.firstChild) {\n element.removeChild(element.firstChild);\n }\n}\n","/**\n * matchMedia wrapper with subscribe — replaces useMediaQuery hook.\n */\n\nexport type MediaQuerySubscription = {\n matches: boolean;\n subscribe: (cb: (matches: boolean) => void) => void;\n destroy: () => void;\n};\n\nexport function createMediaQuery(query: string): MediaQuerySubscription {\n const mql = window.matchMedia(query);\n let currentMatches = mql.matches;\n const listeners: Set<(matches: boolean) => void> = new Set();\n\n const handler = (e: MediaQueryListEvent) => {\n currentMatches = e.matches;\n listeners.forEach((cb) => cb(currentMatches));\n };\n\n mql.addEventListener(\"change\", handler);\n\n return {\n get matches() {\n return currentMatches;\n },\n subscribe(cb: (matches: boolean) => void) {\n listeners.add(cb);\n },\n destroy() {\n mql.removeEventListener(\"change\", handler);\n listeners.clear();\n },\n };\n}\n","const apiCache = new Map<string, { data: any; timestamp: number; ttl: number }>();\nconst CACHE_TTL = 5 * 60 * 1000; // 5 minutes\n\nexport function getCachedData(key: string): any | null {\n const cached = apiCache.get(key);\n if (cached && Date.now() - cached.timestamp < cached.ttl) {\n return cached.data;\n }\n if (cached) {\n apiCache.delete(key);\n }\n return null;\n}\n\nexport function setCachedData(key: string, data: any, ttl = CACHE_TTL): void {\n apiCache.set(key, { data, timestamp: Date.now(), ttl });\n}\n\nexport function clearApiCache(): void {\n apiCache.clear();\n}\n","export class InvalidTokenError extends Error {\n}\nInvalidTokenError.prototype.name = \"InvalidTokenError\";\nfunction b64DecodeUnicode(str) {\n return decodeURIComponent(atob(str).replace(/(.)/g, (m, p) => {\n let code = p.charCodeAt(0).toString(16).toUpperCase();\n if (code.length < 2) {\n code = \"0\" + code;\n }\n return \"%\" + code;\n }));\n}\nfunction base64UrlDecode(str) {\n let output = str.replace(/-/g, \"+\").replace(/_/g, \"/\");\n switch (output.length % 4) {\n case 0:\n break;\n case 2:\n output += \"==\";\n break;\n case 3:\n output += \"=\";\n break;\n default:\n throw new Error(\"base64 string is not of the correct length\");\n }\n try {\n return b64DecodeUnicode(output);\n }\n catch (err) {\n return atob(output);\n }\n}\nexport function jwtDecode(token, options) {\n if (typeof token !== \"string\") {\n throw new InvalidTokenError(\"Invalid token specified: must be a string\");\n }\n options || (options = {});\n const pos = options.header === true ? 0 : 1;\n const part = token.split(\".\")[pos];\n if (typeof part !== \"string\") {\n throw new InvalidTokenError(`Invalid token specified: missing part #${pos + 1}`);\n }\n let decoded;\n try {\n decoded = base64UrlDecode(part);\n }\n catch (e) {\n throw new InvalidTokenError(`Invalid token specified: invalid base64 for part #${pos + 1} (${e.message})`);\n }\n try {\n return JSON.parse(decoded);\n }\n catch (e) {\n throw new InvalidTokenError(`Invalid token specified: invalid json for part #${pos + 1} (${e.message})`);\n }\n}\n","import { jwtDecode } from \"jwt-decode\";\nimport type { RedactoJwtPayload } from \"../api/types\";\n\n/**\n * Decode JWT with error handling — returns null on failure.\n */\nexport function decodeTokenSafely(token: string): RedactoJwtPayload | null {\n try {\n return jwtDecode(token) as RedactoJwtPayload;\n } catch (error) {\n console.warn(\"Failed to decode JWT token:\", error);\n return null;\n }\n}\n","/**\n * Sandbox-mode auth primitives for the consent PoC.\n *\n * In sandbox mode the SDK talks to the consent-server with a pasted static\n * token and an explicit test subject, bypassing the JWT entirely. Org/workspace\n * UUIDs come from options (they still build the `/public/organisations/{org}/\n * workspaces/{ws}/...` URL paths) instead of being decoded from a token.\n *\n * Auth is the single `X-Consent-Token` header carrying the static token; its\n * presence alone marks the request as `environment=test`. There is no subject\n * header. The acting identity (the test subject) rides the request's own\n * payload: query params (`primary_email` / `primary_mobile`) on GET/query reads,\n * and the body on POSTs. The server normalizes and namespaces it `test::`\n * server-side. Call sites resolve the credential via {@link buildAuthHeaders}\n * and the identity via {@link sandboxQueryIdentity} / {@link sandboxBodyIdentity}.\n *\n * This file exists so every JWT-decode / Authorization site resolves its\n * org/workspace UUIDs and builds its auth header through one place, keeping\n * sandbox vs. JWT branching from drifting across the fetch sites.\n */\nimport { decodeTokenSafely } from \"../core/jwt-decode\";\nimport type {\n ResolvedRequestAuth,\n SandboxAuth,\n SandboxIdentityPayload,\n SandboxOptions,\n} from \"./types\";\n\n/** HTTP header carrying the static sandbox token (the credential). */\nexport const SANDBOX_TOKEN_HEADER = \"X-Consent-Token\";\n\n/**\n * Resolve a {@link SandboxAuth} from sandbox options, or null when sandbox mode\n * is not active (no token).\n *\n * @throws Error when a sandbox token is provided but org/workspace or the acting\n * identity are incomplete — sandbox mode cannot build URLs or identify the\n * acting principal without them.\n */\nexport const resolveSandboxAuth = (\n options: SandboxOptions\n): SandboxAuth | null => {\n const token = options.token?.trim();\n if (!token) {\n return null;\n }\n\n const organisationUuid = options.organisationUuid?.trim();\n const workspaceUuid = options.workspaceUuid?.trim();\n const ucic = options.sandboxUcic?.trim();\n const email = options.sandboxEmail?.trim();\n const mobile = options.sandboxMobile?.trim();\n\n if (!organisationUuid || !workspaceUuid) {\n throw new Error(\n \"Sandbox mode requires organisationUuid and workspaceUuid\"\n );\n }\n if (!ucic && !email && !mobile) {\n throw new Error(\"Sandbox mode requires a UCIC, email, or mobile\");\n }\n\n return { token, ucic, email, mobile, organisationUuid, workspaceUuid };\n};\n\n/**\n * Resolve org/workspace UUIDs plus the sandbox context for an authenticated\n * request. In sandbox mode these come from options; otherwise they are decoded\n * from the JWT (preserving the pre-sandbox error messages exactly).\n *\n * @throws Error when neither a valid sandbox config nor a decodable token with\n * org/workspace UUIDs is available.\n */\nexport const resolveRequestAuth = (\n accessToken: string | undefined,\n options: SandboxOptions\n): ResolvedRequestAuth => {\n const sandbox = resolveSandboxAuth(options);\n if (sandbox) {\n return {\n organisationUuid: sandbox.organisationUuid,\n workspaceUuid: sandbox.workspaceUuid,\n sandbox,\n };\n }\n\n const decodedToken = accessToken ? decodeTokenSafely(accessToken) : null;\n if (!decodedToken) {\n throw new Error(\"Invalid access token\");\n }\n const { organisation_uuid, workspace_uuid } = decodedToken;\n if (!organisation_uuid || !workspace_uuid) {\n throw new Error(\"Invalid token: missing organization or workspace UUID\");\n }\n return {\n organisationUuid: organisation_uuid,\n workspaceUuid: workspace_uuid,\n sandbox: null,\n };\n};\n\n/**\n * Build the request headers for an authenticated call. In sandbox mode this is\n * the single `X-Consent-Token` credential (its presence marks the request as\n * `environment=test`); otherwise the standard `Authorization: Bearer`. There is\n * no subject header — the acting identity travels in the request's own payload\n * (see {@link sandboxQueryIdentity} for reads, {@link sandboxBodyIdentity} for\n * POSTs).\n */\nexport const buildAuthHeaders = (\n accessToken: string | undefined,\n sandbox: SandboxAuth | null\n): Record<string, string> => {\n if (sandbox) {\n return { [SANDBOX_TOKEN_HEADER]: sandbox.token };\n }\n return { Authorization: `Bearer ${accessToken}` };\n};\n\n/**\n * The identity payload for the sandbox acting principal — every identifier the\n * host supplied (`org_user_id` / `primary_email` / `primary_mobile`), mirroring\n * a live JWT's `user_data`. The server keys the principal by precedence (UCIC >\n * email > mobile) and preserves the rest as the display-only sandbox contact, so\n * the contact shows on the dashboard/receipt just as it does for a live user.\n * Merge this into a JSON request body (POST) or into query params (GET).\n */\nexport const sandboxBodyIdentity = (\n sandbox: SandboxAuth\n): SandboxIdentityPayload => {\n const payload: SandboxIdentityPayload = {};\n if (sandbox.ucic) {\n payload.org_user_id = sandbox.ucic;\n }\n if (sandbox.email) {\n payload.primary_email = sandbox.email;\n }\n if (sandbox.mobile) {\n payload.primary_mobile = sandbox.mobile;\n }\n return payload;\n};\n\n/**\n * The identity query fragment for GET/query reads — the same full identity as\n * {@link sandboxBodyIdentity}. Append these to the request's query string so the\n * server can resolve the acting test principal (it reads `org_user_id` /\n * `primary_email` / `primary_mobile` query params on sandbox reads).\n */\nexport const sandboxQueryIdentity = (\n sandbox: SandboxAuth\n): SandboxIdentityPayload => sandboxBodyIdentity(sandbox);\n","export const CODE_BY_NAME = new Map<string, string>([\n [\"english\", \"en\"],\n [\"assamese\", \"as\"],\n [\"bengali\", \"bn\"],\n [\"bodo\", \"brx\"],\n [\"dogri\", \"doi\"],\n [\"goan konkani\", \"gom\"],\n [\"gujarati\", \"gu\"],\n [\"hindi\", \"hi\"],\n [\"kannada\", \"kn\"],\n [\"kashmiri\", \"ks\"],\n [\"maithili\", \"mai\"],\n [\"malayalam\", \"ml\"],\n [\"manipuri\", \"mni-Mtei\"],\n [\"marathi\", \"mr\"],\n [\"nepali\", \"ne\"],\n [\"odia\", \"or\"],\n [\"punjabi\", \"pa\"],\n [\"sanskrit\", \"sa\"],\n [\"santali\", \"sat\"],\n [\"sindhi\", \"sd\"],\n [\"tamil\", \"ta\"],\n [\"telugu\", \"te\"],\n [\"urdu\", \"ur\"],\n]);\n\nexport const CODE_BY_LOWER = new Map<string, string>(\n [...CODE_BY_NAME.values()].map((c) => [c.toLowerCase(), c])\n);\n","import { CODE_BY_LOWER, CODE_BY_NAME } from \"./constants\";\n\nexport function toLanguageCode(lang?: string | null): string | undefined {\n if (!lang) {\n return undefined;\n }\n const trimmed = lang.trim();\n if (!trimmed) {\n return undefined;\n }\n const lower = trimmed.toLowerCase();\n return CODE_BY_LOWER.get(lower) ?? CODE_BY_NAME.get(lower) ?? trimmed;\n}\n\nexport function resolveDisplayLanguage(\n requested: string | undefined,\n defaultLanguage: string | undefined,\n translations: Record<string, unknown> | undefined\n): string {\n const fallback = defaultLanguage || \"en\";\n const requestedCode = toLanguageCode(requested);\n if (!requestedCode) {\n return fallback;\n }\n\n for (const key of Object.keys(translations || {})) {\n if (toLanguageCode(key) === requestedCode) {\n return key;\n }\n }\n\n return fallback;\n}\n","import type { ConsentEventPayload, Purpose } from \"./types\";\n\nexport const toSubmitPurposes = (\n purposes: ReadonlyArray<Purpose>\n): ConsentEventPayload[\"purposes\"] =>\n purposes.map((purpose) => {\n if (!purpose.uuid) {\n throw new Error(\"Invalid purpose data: missing uuid\");\n }\n\n const dataElements = (purpose.data_elements || [])\n .filter((element) => element.enabled)\n .map((element) => ({\n uuid: element.uuid,\n selected: element.required ? true : Boolean(element.selected),\n }));\n\n return {\n purpose_uuid: purpose.uuid,\n ...(purpose.product_uuid ? { product_uuid: purpose.product_uuid } : {}),\n selected: Boolean(purpose.selected),\n data_elements: dataElements.length > 0 ? dataElements : undefined,\n };\n });\n","import type { ApiErrorBody, ApiErrorCodeLike, ApiErrorDetail } from \"./types\";\n\nexport class ApiError extends Error {\n readonly status: number;\n readonly code?: ApiErrorCodeLike;\n readonly shouldRequestNew?: boolean;\n\n constructor(opts: {\n status: number;\n code?: ApiErrorCodeLike;\n message: string;\n shouldRequestNew?: boolean;\n }) {\n super(opts.message);\n this.name = \"ApiError\";\n this.status = opts.status;\n this.code = opts.code;\n this.shouldRequestNew = opts.shouldRequestNew;\n Object.setPrototypeOf(this, ApiError.prototype);\n }\n}\n\nconst statusFallback = (status: number): string | undefined => {\n if (status === 401) {\n return \"Your session has expired. Please request a new access link.\";\n }\n if (status === 403) {\n return \"You do not have access to this resource.\";\n }\n if (status >= 500) {\n return \"Something went wrong on our end. Please try again later.\";\n }\n return undefined;\n};\n\nconst extractFromDetail = (\n detail: ApiErrorBody[\"detail\"]\n): { message?: string; code?: string | null } => {\n if (typeof detail === \"string\") {\n return { message: detail };\n }\n if (Array.isArray(detail)) {\n return {};\n }\n if (detail && typeof detail === \"object\") {\n const obj = detail as ApiErrorDetail;\n return { message: obj.message ?? obj.detail, code: obj.error_code };\n }\n return {};\n};\n\nexport const parseApiError = async (\n response: Response,\n fallbackMessage: string\n): Promise<ApiError> => {\n let body: ApiErrorBody | undefined;\n let parsedBody = false;\n try {\n body = (await response.json()) as ApiErrorBody;\n parsedBody = true;\n } catch {\n body = undefined;\n }\n\n const fromDetail = extractFromDetail(body?.detail);\n const serverMessage = body?.message ?? fromDetail.message;\n const message =\n serverMessage ??\n (parsedBody ? statusFallback(response.status) : undefined) ??\n fallbackMessage;\n const code = body?.error_code ?? fromDetail.code ?? undefined;\n\n return new ApiError({\n status: response.status,\n code,\n message,\n shouldRequestNew: body?.should_request_new,\n });\n};\n","import type { IdempotencySender, PendingKey, RandomSource } from \"./types\";\n\nconst HEADER = \"Idempotency-Key\";\n\nconst MAX_PENDING = 16;\n\nconst pending = new Map<string, PendingKey>();\n\nconst toHex = (bytes: Uint8Array): string =>\n Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n\nexport const mintIdempotencyKey = (\n source: RandomSource | undefined = (globalThis as { crypto?: RandomSource }).crypto\n): string => {\n if (source && typeof source.randomUUID === \"function\") {\n return source.randomUUID();\n }\n if (source && typeof source.getRandomValues === \"function\") {\n return toHex(source.getRandomValues(new Uint8Array(16)));\n }\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 14)}-${Math.random()\n .toString(36)\n .slice(2, 14)}`;\n};\n\nconst statusOf = (outcome: unknown): number | undefined => {\n if (typeof Response !== \"undefined\" && outcome instanceof Response) {\n return outcome.status;\n }\n if (outcome && typeof outcome === \"object\" && \"status\" in outcome) {\n const status = (outcome as { status?: unknown }).status;\n if (typeof status === \"number\") return status;\n }\n return undefined;\n};\n\nconst settledOnResolve = (result: unknown): boolean => {\n const status = statusOf(result);\n return status === undefined || status < 500;\n};\n\nconst settledOnReject = (error: unknown): boolean => {\n const status = statusOf(error);\n return status !== undefined && status < 500;\n};\n\nexport const withIdempotencyKey = async <T>(\n url: string,\n body: string,\n send: IdempotencySender<T>\n): Promise<T> => {\n const signature = `${url}\\n${body}`;\n\n let entry = pending.get(signature);\n if (!entry) {\n entry = { key: mintIdempotencyKey(), inFlight: 0, keep: false };\n if (pending.size >= MAX_PENDING) {\n const oldest = pending.keys().next().value;\n if (oldest !== undefined) pending.delete(oldest);\n }\n pending.set(signature, entry);\n } else if (entry.inFlight === 0) {\n entry.keep = false;\n }\n entry.inFlight += 1;\n\n const held = entry;\n const settle = (settled: boolean) => {\n held.inFlight -= 1;\n if (!settled) held.keep = true;\n if (held.inFlight === 0 && !held.keep) pending.delete(signature);\n };\n\n try {\n const result = await send({ [HEADER]: held.key });\n settle(settledOnResolve(result));\n return result;\n } catch (error) {\n settle(settledOnReject(error));\n throw error;\n }\n};\n\nexport const resetIdempotencyKeys = (): void => {\n pending.clear();\n};\n","import type {\n DpoInfoAudioKey,\n LogoPosition,\n PurposePreselection,\n SelectionControlType,\n} from \"./api/types\";\nimport type { NoticeFontEntry } from \"./types\";\n\n/**\n * The production consent API. Every default in this package resolves here, so\n * no entry point can ship a host of its own -- the public calls used to fall\n * back to a staging constant and wrote consent records there.\n */\nexport const DEFAULT_CONSENT_API_BASE_URL = \"https://api.redacto.io/consent\";\n\nexport const DEFAULT_LOGO_POSITION: LogoPosition = \"left\";\n\n/**\n * English fallbacks for the action buttons, used when the notice config omits\n * a label — an older consent-server, or a notice published before the\n * accept-all shortcut existed.\n */\nexport const DEFAULT_ACCEPT_ALL_BUTTON_TEXT = \"Accept All\";\nexport const DEFAULT_ACCEPT_SELECTED_BUTTON_TEXT = \"Accept Selected\";\nexport const DEFAULT_DECLINE_BUTTON_TEXT = \"Decline\";\n\n/**\n * DOM ids for the footer buttons. `confirm-button-text` and\n * `decline-button-text` predate the accept-all shortcut and are load-bearing\n * for the e2e suite and the TTS highlight sequence — do not rename them.\n */\nexport const ACCEPT_ALL_BUTTON_ID = \"accept-all-button-text\";\nexport const ACCEPT_SELECTED_BUTTON_ID = \"confirm-button-text\";\nexport const DECLINE_BUTTON_ID = \"decline-button-text\";\n\nexport const SUBMITTING_BUTTON_TEXT = \"Submitting...\";\n\n/**\n * `justify-content` for the logo row, keyed by the configured position. The row\n * is full width, so aligning it is the whole of the layout change.\n */\nexport const LOGO_POSITION_JUSTIFY: Record<LogoPosition, string> = {\n left: \"flex-start\",\n center: \"center\",\n right: \"flex-end\",\n};\n\n/** Glyph marking a required data element, and the purpose that carries one. */\nexport const REQUIRED_MARKER_GLYPH = \"*\";\n\nexport const REQUIRED_MARKER_ARIA_LABEL = \"required\";\n\nconst REQUIRED_MARKER_COLOR = \"red\";\n\n/** Gap between the label the marker annotates and the marker itself. */\nconst REQUIRED_MARKER_GAP = \"4px\";\n\nexport const REQUIRED_MARKER_STYLE: Readonly<Record<string, string>> = {\n color: REQUIRED_MARKER_COLOR,\n marginLeft: REQUIRED_MARKER_GAP,\n};\n\nexport const DPO_AUDIO_ELEMENT_MAP: ReadonlyArray<{\n audioKey: DpoInfoAudioKey;\n elementId: string;\n}> = [\n { audioKey: \"grievance_text_audio_url\", elementId: \"dpo-grievance-text\" },\n { audioKey: \"grievance_anchor_text_audio_url\", elementId: \"dpo-grievance-link\" },\n { audioKey: \"grievance_email_connector_text_audio_url\", elementId: \"dpo-grievance-email-connector\" },\n { audioKey: \"grievance_email_audio_url\", elementId: \"dpo-grievance-email\" },\n { audioKey: \"dp_board_text_audio_url\", elementId: \"dpo-dp-board-text\" },\n { audioKey: \"dp_board_anchor_text_audio_url\", elementId: \"dpo-dp-board-link\" },\n { audioKey: \"dpo_text_audio_url\", elementId: \"dpo-dpo-text\" },\n { audioKey: \"dpo_anchor_text_audio_url\", elementId: \"dpo-dpo-link\" },\n] as const;\n\nexport const PURPOSE_STATUS_ACTIVE = \"ACTIVE\";\n\nexport const PRODUCT_SECTION_COPY = {\n toggleSelection: (productName: string, purposeCount: number) =>\n `Toggle all ${purposeCount} purposes for ${productName}`,\n toggleRequired: (productName: string, purposeCount: number) =>\n `Toggle the ${purposeCount} required purposes for ${productName}`,\n settled: (productName: string) => `Already consented to ${productName}`,\n} as const;\n\nexport const CONFIRM_HINT_ID = \"redacto-confirm-hint\";\n\nexport const CONFIRM_HINT_COPY = {\n \"nothing-chosen\": \"Select at least one purpose to confirm.\",\n \"nothing-engaged\":\n \"Select or change a purpose for the product you are consenting to.\",\n \"required-outstanding\": \"Accept the required purposes to confirm.\",\n productsIncomplete: (productNames: string[]) =>\n `Accept the required purposes for ${productNames.join(\", \")} to confirm.`,\n} as const;\n\nexport const DEFAULT_PURPOSE_PRESELECTION: PurposePreselection = \"NONE\";\n\nexport const PURPOSE_STATUS_INACTIVE = \"INACTIVE\";\n\nexport const OTP_GATE_LENGTH = 6;\n\nexport const OTP_GATE_TITLE_ID = \"notice-otp-gate-title\";\n\nexport const OTP_GATE_COPY = {\n title: \"Enter the verification code\",\n description:\n \"Ask the customer to read out the code they were sent. Your selections are locked until it is confirmed.\",\n submit: \"Confirm code\",\n verifying: \"Verifying...\",\n failed: \"Could not verify that code.\",\n} as const;\n\nexport const PRODUCT_POLICIES_LABEL = \"Privacy policies:\";\n\nexport const DEFAULT_SELECTION_CONTROL: SelectionControlType = \"checkbox\";\n\nexport const SELECTION_CONTROL_ACCENT = \"#4f87ff\";\n\nexport const SELECTION_CONTROL_COPY = {\n onRecord: (answer: string) => `Saved answer: ${answer}`,\n mixed: \"Mixed\",\n options: [\n { label: \"Yes\", value: true },\n { label: \"No\", value: false },\n ],\n} as const;\n\nexport const CONFIRM_DIALOG_ID = \"redacto-confirm-dialog\";\nexport const CONFIRM_DIALOG_DETAIL_ID = \"redacto-confirm-dialog-detail\";\n\nexport const CONFIRM_DIALOG_COPY = {\n \"accept-all\": {\n title: \"Accept every purpose?\",\n detail:\n \"This agrees to all purposes on this notice, including any you left unselected.\",\n },\n \"accept-selected\": {\n title: \"Confirm your selections?\",\n detail:\n \"Only the purposes you selected are recorded as agreed. The rest are recorded as not agreed.\",\n },\n decline: {\n title: \"Decline this notice?\",\n detail:\n \"Nothing is recorded as agreed, including any purposes you selected.\",\n },\n confirm: \"Yes\",\n cancel: \"No\",\n} as const;\n\nexport const INHERIT_FONT_FAMILY = \"inherit\";\n\nexport const DEFAULT_NOTICE_FONT_ID = \"arial\";\n\nexport const NOTICE_FONT_GENERIC_FALLBACK = \", sans-serif\";\n\nexport const NOTICE_FONT_CATALOGUE: ReadonlyArray<NoticeFontEntry> = [\n {\n id: \"montserrat\",\n value: \"Montserrat\",\n stack: 'Montserrat, \"Trebuchet MS\", \"Segoe UI\", Arial, sans-serif',\n },\n { id: \"arial\", value: \"Arial\", stack: \"Arial, Helvetica, sans-serif\" },\n {\n id: \"georgia\",\n value: \"Georgia\",\n stack: 'Georgia, \"Times New Roman\", Times, serif',\n },\n {\n id: \"times new roman\",\n value: \"Times New Roman\",\n stack: '\"Times New Roman\", Times, serif',\n },\n {\n id: \"trebuchet ms\",\n value: \"Trebuchet MS\",\n stack: '\"Trebuchet MS\", \"Lucida Sans Unicode\", \"Lucida Grande\", sans-serif',\n },\n { id: \"verdana\", value: \"Verdana\", stack: \"Verdana, Geneva, sans-serif\" },\n];\n\nexport const CSS_FONT_KEYWORDS: ReadonlyArray<string> = [\n \"inherit\",\n \"initial\",\n \"revert\",\n \"revert-layer\",\n \"unset\",\n \"serif\",\n \"sans-serif\",\n \"monospace\",\n \"cursive\",\n \"fantasy\",\n \"system-ui\",\n \"ui-serif\",\n \"ui-sans-serif\",\n \"ui-monospace\",\n \"ui-rounded\",\n \"math\",\n \"emoji\",\n \"fangsong\",\n];\n\nexport const UNSAFE_FONT_CHARACTERS = /[\"';{}\\\\]/g;\n\nexport const NOTICE_FONT_ROOT_ATTRIBUTE = \"data-redacto-notice-font\";\n\nexport const NOTICE_FONT_STYLE_ID = \"redacto-notice-font-styles\";\n\nexport const NOTICE_FONT_CSS = `\n [${NOTICE_FONT_ROOT_ATTRIBUTE}] button,\n [${NOTICE_FONT_ROOT_ATTRIBUTE}] input,\n [${NOTICE_FONT_ROOT_ATTRIBUTE}] optgroup,\n [${NOTICE_FONT_ROOT_ATTRIBUTE}] option,\n [${NOTICE_FONT_ROOT_ATTRIBUTE}] select,\n [${NOTICE_FONT_ROOT_ATTRIBUTE}] textarea {\n font-family: inherit;\n }\n`;\n","import { clearApiCache, getCachedData, setCachedData } from \"../services/cache\";\nimport { decodeTokenSafely } from \"../core/jwt-decode\";\nimport {\n buildAuthHeaders,\n resolveRequestAuth,\n sandboxBodyIdentity,\n sandboxQueryIdentity,\n} from \"./sandbox\";\nimport { toLanguageCode } from \"./language\";\nimport { toSubmitPurposes } from \"./submit-payload\";\nimport { parseApiError } from \"../shared/api-errors\";\nimport { withIdempotencyKey } from \"../shared/idempotency\";\nimport type {\n ConsentContent,\n ConsentEventPayload,\n FetchConsentContentParams,\n FetchConsentContentPublicParams,\n FetchTTSAudioUrlsParams,\n InitiateGuardianVerificationParams,\n InitiateGuardianVerificationResponse,\n SubmitConsentEventParams,\n SubmitConsentEventPublicParams,\n TTSAudioUrlsResponse,\n VerifyGuardianStatusParams,\n VerifyGuardianStatusResponse,\n} from \"./types\";\nimport { DEFAULT_CONSENT_API_BASE_URL } from \"../constants\";\n\nconst BASE_URL = DEFAULT_CONSENT_API_BASE_URL;\n\n// ─── Modal: fetch notice (authenticated, JWT-decoded) ───\n\nexport const fetchConsentContent = async ({\n noticeId,\n accessToken,\n baseUrl,\n language = \"en\",\n specific_uuid,\n validate_against = \"all\",\n include_fully_consented_data = false,\n signal,\n ...sandboxParams\n}: FetchConsentContentParams & { signal?: AbortSignal }): Promise<ConsentContent> => {\n if (!noticeId || !validate_against) {\n throw new Error(\"noticeId is required\");\n }\n if (!accessToken && !sandboxParams.token) {\n throw new Error(\"accessToken or token is required\");\n }\n\n const { organisationUuid: ORG, workspaceUuid: WS, sandbox } = resolveRequestAuth(\n accessToken,\n sandboxParams\n );\n\n const apiBaseUrl = baseUrl || BASE_URL;\n\n // Include org + workspace in the sandbox cache identity so two sessions\n // sharing an identity but scoped to different orgs never collide.\n const cacheIdentity = sandbox\n ? `sandbox:${sandbox.organisationUuid}:${sandbox.workspaceUuid}:${sandbox.ucic || sandbox.email || sandbox.mobile}`\n : accessToken;\n const cacheKey = `${cacheIdentity}-${noticeId}-${validate_against}-${language}-${specific_uuid || \"\"}-${include_fully_consented_data}`;\n\n if (validate_against === \"all\" && !specific_uuid) {\n const cached = getCachedData(cacheKey);\n if (cached) return cached;\n }\n\n const url = new URL(`${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/notices/${noticeId}`);\n if (specific_uuid) url.searchParams.append(\"specific_uuid\", specific_uuid);\n url.searchParams.append(\"validate_against\", validate_against);\n if (include_fully_consented_data) url.searchParams.append(\"include_fully_consented_data\", \"true\");\n // Sandbox mode: the acting identity travels as query params\n // (primary_email / primary_mobile); the credential is the X-Consent-Token header.\n if (sandbox) {\n for (const [key, value] of Object.entries(sandboxQueryIdentity(sandbox))) {\n if (value) url.searchParams.append(key, value);\n }\n }\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n ...buildAuthHeaders(accessToken, sandbox),\n \"Accept-Language\": language,\n },\n signal,\n });\n\n if (!response.ok) {\n throw await parseApiError(response, \"Could not load the consent notice. Please try again.\");\n }\n\n const data: ConsentContent = await response.json();\n\n if (validate_against === \"all\" && !specific_uuid) {\n setCachedData(cacheKey, data);\n }\n\n return data;\n};\n\n// ─── Inline: fetch notice (public, no auth) ───\n\nexport const fetchConsentContentPublic = async ({\n org_uuid,\n workspace_uuid,\n notice_uuid,\n accessToken,\n baseUrl,\n language = \"en\",\n specific_uuid,\n}: FetchConsentContentPublicParams): Promise<ConsentContent> => {\n const apiBaseUrl = baseUrl || BASE_URL;\n const noticesUrl = `${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/notices`;\n\n const url = new URL(\n accessToken ? `${noticesUrl}/${notice_uuid}` : `${noticesUrl}/get-notice/${notice_uuid}`\n );\n if (specific_uuid) url.searchParams.append(\"specific_uuid\", specific_uuid);\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Accept-Language\": language,\n ...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}),\n },\n });\n\n if (!response.ok) {\n throw await parseApiError(response, \"Could not load the consent notice. Please try again.\");\n }\n\n return await response.json();\n};\n\n// ─── Modal: submit consent (JWT-decoded) ───\n\nexport const submitConsentEvent = async ({\n accessToken,\n baseUrl,\n ledgerBaseUrl,\n noticeUuid,\n purposes,\n declined,\n meta_data,\n guardianVerificationReference,\n selfDeclaredAdult,\n language,\n signal,\n ...sandboxParams\n}: SubmitConsentEventParams & { signal?: AbortSignal }): Promise<void> => {\n if (!noticeUuid || !Array.isArray(purposes)) {\n throw new Error(\"noticeUuid and purposes array are required\");\n }\n if (!accessToken && !sandboxParams.token) {\n throw new Error(\"accessToken or token is required\");\n }\n\n const { organisationUuid: ORG, workspaceUuid: WS, sandbox } = resolveRequestAuth(\n accessToken,\n sandboxParams\n );\n\n // Route the write to the Go ledger when configured; fall back to the consent\n // server so existing integrations that only pass baseUrl keep working.\n const apiBaseUrl = ledgerBaseUrl || baseUrl || BASE_URL;\n\n const payload: ConsentEventPayload = {\n notice_uuid: noticeUuid,\n purposes: toSubmitPurposes(purposes),\n select_all_mandatory: false,\n source: \"WEB\",\n declined: Boolean(declined),\n meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid, minor_age: meta_data.minor_age } : undefined,\n guardian_verification_reference: guardianVerificationReference,\n self_declared_adult: selfDeclaredAdult,\n language: toLanguageCode(language),\n };\n\n // Sandbox mode: merge the acting test identity into the body (the server has\n // no subject header; it namespaces this identity `test::`).\n const requestBody = sandbox ? { ...payload, ...sandboxBodyIdentity(sandbox) } : payload;\n\n const url = `${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/submit-consent`;\n const serialisedBody = JSON.stringify(requestBody);\n\n const response = await withIdempotencyKey(url, serialisedBody, (idempotencyHeaders) =>\n fetch(url, {\n method: \"POST\",\n headers: {\n ...buildAuthHeaders(accessToken, sandbox),\n \"Content-Type\": \"application/json\",\n ...idempotencyHeaders,\n },\n body: serialisedBody,\n signal,\n })\n );\n\n if (!response.ok) {\n throw await parseApiError(response, \"Could not submit your consent. Please try again.\");\n }\n\n clearApiCache();\n};\n\n// ─── Inline: submit consent (direct org/workspace) ───\n\nexport const submitConsentEventPublic = async ({\n org_uuid,\n workspace_uuid,\n accessToken,\n baseUrl,\n ledgerBaseUrl,\n noticeUuid,\n purposes,\n declined,\n meta_data,\n language,\n}: SubmitConsentEventPublicParams): Promise<void> => {\n // Route the write to the Go ledger when configured; fall back to the consent\n // server so existing integrations that only pass baseUrl keep working.\n const apiBaseUrl = ledgerBaseUrl || baseUrl || BASE_URL;\n\n const payload: ConsentEventPayload = {\n notice_uuid: noticeUuid,\n purposes: toSubmitPurposes(purposes),\n select_all_mandatory: false,\n source: \"WEB\",\n declined,\n meta_data,\n language: toLanguageCode(language),\n };\n\n const url = `${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/submit-consent`;\n const serialisedBody = JSON.stringify(payload);\n\n const response = await withIdempotencyKey(url, serialisedBody, (idempotencyHeaders) =>\n fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n ...idempotencyHeaders,\n },\n body: serialisedBody,\n })\n );\n\n if (!response.ok) {\n throw await parseApiError(response, \"Could not submit your consent. Please try again.\");\n }\n};\n\n// ─── TTS Audio ───\n\nexport const fetchTTSAudioUrls = async ({\n accessToken,\n baseUrl,\n ledgerBaseUrl,\n noticeUuid,\n language,\n signal,\n ...sandboxParams\n}: FetchTTSAudioUrlsParams & { signal?: AbortSignal }): Promise<TTSAudioUrlsResponse> => {\n if ((!accessToken && !sandboxParams.token) || !noticeUuid || !language) {\n throw new Error(\"accessToken (or token), noticeUuid, and language are required\");\n }\n\n const { organisationUuid: ORG, workspaceUuid: WS, sandbox } = resolveRequestAuth(\n accessToken,\n sandboxParams\n );\n\n // Prefer the Go ledger for audio, but a sandbox session never routes there:\n // the ledger's public reads are JWT-gated and don't support X-Consent-Token.\n // Without this a ledger-minted token is rejected by the consent server and\n // per-language audio silently disappears.\n const apiBaseUrl = (sandbox ? null : ledgerBaseUrl) || baseUrl || BASE_URL;\n const url = new URL(\n `${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/notices/${noticeUuid}/audio/${language}`\n );\n // Sandbox mode: the acting identity travels as query params\n // (primary_email / primary_mobile); the credential is the X-Consent-Token header.\n if (sandbox) {\n for (const [key, value] of Object.entries(sandboxQueryIdentity(sandbox))) {\n if (value) url.searchParams.append(key, value);\n }\n }\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n ...buildAuthHeaders(accessToken, sandbox),\n Accept: \"application/json\",\n },\n signal,\n });\n\n if (!response.ok) {\n throw await parseApiError(response, \"Could not load audio narration. Please try again.\");\n }\n\n return await response.json();\n};\n\n// ─── Guardian Verification ───\n\nexport const initiateGuardianVerification = async ({\n accessToken,\n baseUrl,\n guardianName,\n guardianContact,\n guardianRelationship,\n frontendCallbackUrl,\n metadata,\n signal,\n}: InitiateGuardianVerificationParams): Promise<InitiateGuardianVerificationResponse> => {\n // Guardian verification is JWT-only: sandbox sessions have no minor-notice /\n // guardian support (the server 403s them, and C1 blocks minor notices at\n // render), so no sandbox identity is wired through here.\n if (!accessToken) throw new Error(\"accessToken is required\");\n if (!guardianName?.trim()) throw new Error(\"Guardian name is required\");\n if (!guardianContact?.trim()) throw new Error(\"Guardian contact is required\");\n if (!guardianRelationship?.trim()) throw new Error(\"Guardian relationship is required\");\n\n const decodedToken = decodeTokenSafely(accessToken);\n if (!decodedToken) throw new Error(\"Invalid access token\");\n const { organisation_uuid: ORG, workspace_uuid: WS } = decodedToken;\n if (!ORG || !WS) throw new Error(\"Invalid token: missing organization or workspace UUID\");\n\n const apiBaseUrl = baseUrl || BASE_URL;\n\n const payload: Record<string, any> = {\n guardian_name: guardianName.trim(),\n guardian_contact: guardianContact.trim(),\n guardian_relationship: guardianRelationship.trim(),\n };\n if (frontendCallbackUrl) payload.frontend_callback_url = frontendCallbackUrl;\n if (metadata) payload.metadata = metadata;\n\n const response = await fetch(\n `${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/guardian/initiate-verification`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(payload),\n signal,\n }\n );\n\n if (!response.ok) {\n throw await parseApiError(response, \"Could not start guardian verification. Please try again.\");\n }\n\n const responseData = await response.json();\n const detail = responseData.detail || responseData;\n\n if (detail.already_verified) {\n return {\n success: true,\n guardian_info_uuid: detail.guardian_info_uuid,\n already_verified: true,\n verification_reference: detail.verification_reference,\n };\n }\n\n if (!detail.session_token || !detail.digilocker_redirect_url) {\n throw new Error(\"Invalid response: missing session_token or digilocker_redirect_url\");\n }\n\n return {\n success: detail.success ?? true,\n guardian_info_uuid: detail.guardian_info_uuid,\n already_verified: false,\n session_token: detail.session_token,\n digilocker_redirect_url: detail.digilocker_redirect_url,\n expires_at: detail.expires_at,\n };\n};\n\nexport const verifyGuardianStatus = async ({\n accessToken,\n baseUrl,\n sessionToken,\n signal,\n}: VerifyGuardianStatusParams): Promise<VerifyGuardianStatusResponse> => {\n // Guardian verification is JWT-only: sandbox sessions have no minor-notice /\n // guardian support (the server 403s them, and C1 blocks minor notices at\n // render), so no sandbox identity is wired through here.\n if (!accessToken || !sessionToken) {\n throw new Error(\"accessToken and sessionToken are required\");\n }\n\n const decodedToken = decodeTokenSafely(accessToken);\n if (!decodedToken) throw new Error(\"Invalid access token\");\n const { organisation_uuid: ORG, workspace_uuid: WS } = decodedToken;\n if (!ORG || !WS) throw new Error(\"Invalid token: missing organization or workspace UUID\");\n\n const apiBaseUrl = baseUrl || BASE_URL;\n\n const response = await fetch(\n `${apiBaseUrl}/public/organisations/${ORG}/workspaces/${WS}/guardian/verify-status`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ session_token: sessionToken }),\n signal,\n }\n );\n\n if (!response.ok) {\n throw await parseApiError(response, \"Could not check verification status. Please try again.\");\n }\n\n const responseData = await response.json();\n const detail = responseData.detail || responseData;\n\n return {\n status: detail.status ?? \"in_progress\",\n guardian_info_uuid: detail.guardian_info_uuid ?? null,\n verification_reference: detail.verification_reference ?? null,\n guardian_details: detail.guardian_details ?? null,\n error: detail.error ?? null,\n error_code: detail.error_code ?? null,\n can_retry: detail.can_retry ?? true,\n };\n};\n","import { decodeTokenSafely } from \"../core/jwt-decode\";\nimport type {\n ConsentContent,\n DataElementSelection,\n FetchNoticeConsentStatusForScopeParams,\n FetchNoticeConsentStatusParams,\n LedgerConsentOverlay,\n NoticeConsentStatusResponse,\n PurposeSelection,\n} from \"./types\";\n\n/**\n * Go-ledger notice `check-consent` read.\n *\n * Post-cutover, consent records live in the Go ledger, so Python's notice\n * validation (which powered the 409 CONSENT_ALREADY_PROVIDED and the\n * `purpose_selections` / `reconsent_required` overlay) reads an empty consent\n * DB. When a `ledgerBaseUrl` is configured, the modal and the inline embed ask\n * the ledger directly instead.\n *\n * Every failure mode (no ledger configured, undecodable token, non-OK\n * response, network/abort/parse error) degrades to `null` so callers fall\n * back to the legacy Python-driven flow.\n */\n\n/**\n * Fetch the principal's current consent status for a notice from the Go\n * ledger (`check-consent`), with org/workspace supplied explicitly. The\n * principal resolves from the bearer token server-side, so the body is empty.\n * Returns null on any failure so the caller can fall back to the legacy flow.\n */\nexport const fetchNoticeConsentStatusForScope = async ({\n accessToken,\n ledgerBaseUrl,\n organisationUuid,\n workspaceUuid,\n noticeUuid,\n signal,\n}: FetchNoticeConsentStatusForScopeParams): Promise<NoticeConsentStatusResponse | null> => {\n if (!accessToken || !ledgerBaseUrl || !organisationUuid || !workspaceUuid || !noticeUuid) {\n return null;\n }\n\n try {\n const response = await fetch(\n `${ledgerBaseUrl}/public/organisations/${organisationUuid}/workspaces/${workspaceUuid}/notices/${noticeUuid}/check-consent`,\n {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: \"{}\",\n signal,\n }\n );\n\n if (!response.ok) return null;\n\n const data = (await response.json()) as\n | NoticeConsentStatusResponse\n | { detail?: NoticeConsentStatusResponse };\n // The ledger returns the response directly; tolerate a {detail} envelope too.\n const body =\n data && typeof data === \"object\" && \"detail\" in data && data.detail\n ? data.detail\n : (data as NoticeConsentStatusResponse);\n\n if (!body || !Array.isArray(body.purposes)) return null;\n return body;\n } catch {\n // Network / abort / parse failure — degrade to the legacy Python flow.\n return null;\n }\n};\n\n/**\n * Same read, resolving org/workspace by decoding the JWT (the modal's tokens\n * carry them). Returns null on any failure.\n */\nexport const fetchNoticeConsentStatus = async ({\n accessToken,\n ledgerBaseUrl,\n noticeUuid,\n signal,\n}: FetchNoticeConsentStatusParams): Promise<NoticeConsentStatusResponse | null> => {\n if (!accessToken || !ledgerBaseUrl || !noticeUuid) return null;\n\n const decodedToken = decodeTokenSafely(accessToken);\n if (!decodedToken) return null;\n\n const { organisation_uuid: ORG, workspace_uuid: WS } = decodedToken;\n if (!ORG || !WS) return null;\n\n return fetchNoticeConsentStatusForScope({\n accessToken,\n ledgerBaseUrl,\n organisationUuid: ORG,\n workspaceUuid: WS,\n noticeUuid,\n signal,\n });\n};\n\n/**\n * Whether the principal has already fully consented to this notice with no\n * reconsent needed — the ledger equivalent of Python's 409\n * `CONSENT_ALREADY_PROVIDED`. Requires an active consent record with every\n * mandatory purpose still ACTIVE.\n */\nexport const isNoticeFullyConsented = (status: NoticeConsentStatusResponse): boolean =>\n status.consented && status.all_mandatory_active;\n\n/**\n * Translate the ledger's notice consent status into the\n * `{ purpose_selections, reconsent_required }` shape the modal already\n * consumes, so prior-consent pre-fill and reconsent categorization work off\n * the ledger. Returns null for a first-time principal (no consent record —\n * every purpose INACTIVE), preserving the normal first-time consent flow.\n *\n * `needs_reconsent` is derived from `status` (anything not ACTIVE needs\n * reconsent: expired / withdrawn / declined / inactive). NOTE: notice-version\n * reconsent is NOT covered — the ledger's check-consent has no version\n * awareness yet, so a republished-notice version bump won't re-prompt until\n * that lands on the ledger (tracked fast-follow).\n */\nexport const buildLedgerConsentOverlay = (\n status: NoticeConsentStatusResponse,\n configPurposes: ConsentContent[\"detail\"][\"active_config\"][\"purposes\"]\n): LedgerConsentOverlay | null => {\n const byUuid = new Map(status.purposes.map((p) => [p.uuid, p]));\n const hasHistory = status.purposes.some((p) => (p.status || \"INACTIVE\") !== \"INACTIVE\");\n if (!hasHistory) return null;\n\n const purpose_selections: Record<string, PurposeSelection> = {};\n for (const cp of configPurposes) {\n const lp = byUuid.get(cp.uuid);\n const purposeStatus = lp?.status || \"INACTIVE\";\n const selectedByUuid = new Map((lp?.data_elements || []).map((de) => [de.uuid, de.selected]));\n const data_elements: Record<string, DataElementSelection> = {};\n for (const de of cp.data_elements) {\n data_elements[de.uuid] = {\n selected: selectedByUuid.get(de.uuid) ?? false,\n enabled: de.enabled,\n required: de.required,\n };\n }\n purpose_selections[cp.uuid] = {\n selected: lp?.selected ?? false,\n status: purposeStatus,\n needs_reconsent: purposeStatus !== \"ACTIVE\",\n data_elements: purposeStatus === \"INACTIVE\" ? {} : data_elements,\n };\n }\n\n const reconsent_required = configPurposes.some(\n (cp) => (purpose_selections[cp.uuid]?.status || \"INACTIVE\") !== \"ACTIVE\"\n );\n return { reconsent_required, purpose_selections };\n};\n","const STYLE_ID = \"redacto-consent-checkbox-styles\";\n\nconst STYLE_CONTENT = `\n /* Redacto Consent SDK Checkbox Styles */\n .redacto-checkbox-large {\n appearance: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n height: 20px !important;\n width: 20px !important;\n border: 2px solid #d0d5dd !important;\n border-radius: 5px !important;\n background-color: transparent !important;\n cursor: pointer !important;\n position: relative !important;\n box-sizing: border-box !important;\n flex-shrink: 0 !important;\n margin: 0 !important;\n padding: 4px !important;\n }\n\n .redacto-checkbox-medium {\n appearance: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n height: 17px !important;\n width: 17px !important;\n border: 2px solid #d0d5dd !important;\n border-radius: 5px !important;\n background-color: transparent !important;\n cursor: pointer !important;\n position: relative !important;\n box-sizing: border-box !important;\n flex-shrink: 0 !important;\n margin: 0 !important;\n padding: 4px !important;\n }\n\n .redacto-checkbox-small {\n appearance: none !important;\n -webkit-appearance: none !important;\n -moz-appearance: none !important;\n height: 16px !important;\n width: 16px !important;\n border: 2px solid #d0d5dd !important;\n border-radius: 5px !important;\n background-color: transparent !important;\n cursor: pointer !important;\n position: relative !important;\n box-sizing: border-box !important;\n flex-shrink: 0 !important;\n margin: 0 !important;\n padding: 4px !important;\n }\n\n .redacto-checkbox-large:checked {\n background-color: #4f87ff !important;\n border-color: #4f87ff !important;\n }\n\n .redacto-checkbox-medium:checked {\n background-color: #4f87ff !important;\n border-color: #4f87ff !important;\n }\n\n .redacto-checkbox-small:checked {\n background-color: #4f87ff !important;\n border-color: #4f87ff !important;\n }\n\n .redacto-checkbox-large:checked::after,\n .redacto-checkbox-medium:checked::after {\n content: '' !important;\n position: absolute !important;\n left: 50% !important;\n top: 50% !important;\n transform: translate(-50%, -50%) rotate(45deg) !important;\n width: 4px !important;\n height: 8px !important;\n border: solid white !important;\n border-width: 0 2px 2px 0 !important;\n box-sizing: border-box !important;\n }\n\n .redacto-checkbox-small:checked::after {\n content: '' !important;\n position: absolute !important;\n left: 50% !important;\n top: 50% !important;\n transform: translate(-50%, -50%) rotate(45deg) !important;\n width: 3px !important;\n height: 6px !important;\n border: solid white !important;\n border-width: 0 1.5px 1.5px 0 !important;\n box-sizing: border-box !important;\n }\n\n .redacto-checkbox-large:indeterminate {\n background-color: #4f87ff !important;\n border-color: #4f87ff !important;\n }\n\n .redacto-checkbox-large:indeterminate::after {\n content: '' !important;\n position: absolute !important;\n left: 50% !important;\n top: 50% !important;\n transform: translate(-50%, -50%) !important;\n width: 8px !important;\n height: 2px !important;\n background-color: white !important;\n }\n\n .redacto-checkbox-large:focus,\n .redacto-checkbox-medium:focus {\n outline: 2px solid #4f87ff !important;\n outline-offset: 2px !important;\n }\n\n .redacto-checkbox-small:focus {\n outline: 2px solid #4f87ff !important;\n outline-offset: 2px !important;\n }\n\n /* TTS Highlight Styles */\n .redacto-tts-highlight {\n position: relative !important;\n transition: background-color 0.3s ease, outline 0.3s ease !important;\n }\n\n h2.redacto-tts-highlight,\n h3.redacto-tts-highlight {\n background-color: #FFF9C4 !important;\n border-radius: 3px !important;\n padding: 2px 4px !important;\n margin: -2px -4px !important;\n }\n\n span.redacto-tts-highlight,\n a.redacto-tts-highlight {\n background-color: #FFF9C4 !important;\n border-radius: 3px !important;\n padding: 2px 4px !important;\n margin: -2px -4px !important;\n }\n\n p.redacto-tts-highlight {\n background-color: #FFF9C4 !important;\n border-radius: 3px !important;\n padding: 2px 4px !important;\n margin: -2px -4px !important;\n }\n\n button.redacto-tts-highlight {\n outline: 3px solid #FFF9C4 !important;\n outline-offset: 2px !important;\n }\n\n /* Overlay fade-in */\n @keyframes overlayFadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n\n /* Spinner animation */\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n\n /* DigiLocker callback retry button hover */\n .redacto-dl-retry-btn:hover {\n background-color: #2563eb !important;\n }\n `;\n\n/**\n * Inject the checkbox / TTS / animation stylesheet into the given root.\n *\n * - When called with a `Document`, the style tag is placed in `document.head`.\n * - When called with a `ShadowRoot`, the style tag is placed inside the shadow\n * so it only applies within that shadow tree (full CSS isolation from the\n * host page).\n *\n * No-ops if the stylesheet is already present in the target root.\n */\nexport const injectCheckboxStyles = (\n root: Document | ShadowRoot\n): void => {\n if (typeof document === \"undefined\") return;\n\n // Skip if already injected into this root.\n const existing =\n root instanceof Document\n ? root.getElementById(STYLE_ID)\n : root.querySelector(`#${STYLE_ID}`);\n if (existing) return;\n\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = STYLE_CONTENT;\n\n if (root instanceof Document) {\n root.head.appendChild(style);\n } else {\n root.appendChild(style);\n }\n};\n","export const styles = {\n overlay: {\n position: \"fixed\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n backgroundColor: \"rgba(0, 0, 0, 0.5)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n zIndex: 999,\n animation: \"overlayFadeIn 0.2s cubic-bezier(0.16, 1, 0.3, 1)\",\n pointerEvents: \"all\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n modal: {\n position: \"fixed\",\n top: \"50%\",\n left: \"50%\",\n transform: \"translate(-50%, -50%)\",\n width: \"700px\",\n borderRadius: \"8px\",\n backgroundColor: \"#ffffff\",\n boxShadow: \"4px 0px 4px 0px #00000040\",\n border: \"none\",\n display: \"flex\",\n flexDirection: \"column\",\n maxHeight: \"90vh\",\n zIndex: 1000,\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n fontFamily: \"inherit\",\n },\n\n content: {\n margin: \"22px\",\n display: \"flex\",\n flexDirection: \"column\",\n flexGrow: 1,\n overflow: \"hidden\",\n minHeight: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n topSection: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"flex-start\",\n gap: \"10px\",\n paddingBottom: \"15px\",\n borderBottom: \"none\",\n backgroundColor: \"#ffffff\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n topLeft: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n flex: \"1 1 0\",\n minWidth: 0,\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n // The main notice header is two stacked rows: the logo alone on row 1,\n // aligned per active_config.logo_position, then the title and the\n // TTS/language controls on row 2. `topSection` and `topLeft` above keep their\n // single-row shape for the age-verification, guardian and verification\n // screens, which have no controls to place and share those styles.\n // Mirrors consent-sdk-react/src/RedactoNoticeConsent/styles.ts.\n headerStack: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"stretch\",\n gap: \"10px\",\n paddingBottom: \"15px\",\n borderBottom: \"none\",\n backgroundColor: \"#ffffff\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n logoRow: {\n display: \"flex\",\n alignItems: \"center\",\n width: \"100%\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n headerRow: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"10px\",\n width: \"100%\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n logo: {\n height: \"32px\",\n width: \"auto\",\n maxWidth: \"140px\",\n objectFit: \"contain\",\n flexShrink: 0,\n margin: 0,\n padding: 0,\n display: \"block\",\n },\n\n title: {\n fontSize: \"18px\",\n fontWeight: 700,\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n verticalAlign: \"middle\",\n color: \"#101828\",\n flex: \"1 1 auto\",\n minWidth: 0,\n wordBreak: \"normal\",\n overflowWrap: \"anywhere\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n topRight: {\n borderRadius: \"8px\",\n padding: \"3px 9px\",\n border: \"1px solid #d0d5dd\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flexShrink: 0,\n fontWeight: 400,\n fontSize: \"12px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n verticalAlign: \"middle\",\n color: \"#344054\",\n gap: \"5px\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n cursor: \"pointer\",\n backgroundColor: \"#ffffff\",\n },\n\n middleSection: {\n margin: \"0px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"12px\",\n flexGrow: 1,\n overflowY: \"auto\",\n minHeight: 0,\n paddingRight: \"15px\",\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n privacyText: {\n fontSize: \"16px\",\n fontWeight: 400,\n lineHeight: \"150%\",\n color: \"#344054\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n link: {\n color: \"#4f87ff\",\n textDecoration: \"none\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n subTitle: {\n fontWeight: 600,\n fontSize: \"16px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#101828\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n optionsContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"10px\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionItem: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionLeft: {\n display: \"flex\",\n gap: \"12px\",\n alignItems: \"center\",\n cursor: \"pointer\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionTextContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionTitle: {\n fontWeight: 500,\n fontSize: \"16px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#101828\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n optionDescription: {\n fontWeight: 400,\n fontSize: \"12px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#475467\",\n verticalAlign: \"middle\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n checkboxLarge: {\n height: \"20px\",\n width: \"20px\",\n padding: \"4px\",\n borderRadius: \"5px\",\n border: \"2px solid #d0d5dd\",\n margin: 0,\n boxSizing: \"border-box\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n MozAppearance: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n backgroundColor: \"transparent\",\n },\n\n dataElementsContainer: {\n marginLeft: \"27px\",\n display: \"flex\",\n flexDirection: \"column\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n paddingLeft: \"22px\",\n },\n\n dataElementItem: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n justifyContent: \"space-between\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n minHeight: \"24px\",\n },\n\n dataElementText: {\n fontWeight: 400,\n fontSize: \"14px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#344054\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n checkboxSmall: {\n height: \"16px\",\n width: \"16px\",\n padding: \"4px\",\n borderRadius: \"5px\",\n border: \"2px solid #d0d5dd\",\n margin: 0,\n boxSizing: \"border-box\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n MozAppearance: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n backgroundColor: \"transparent\",\n },\n\n bottomSection: {\n display: \"flex\",\n justifyContent: \"space-between\",\n gap: \"29px\",\n paddingTop: \"15px\",\n borderTop: \"none\",\n backgroundColor: \"#ffffff\",\n margin: 0,\n boxSizing: \"border-box\",\n },\n\n /**\n * The main notice footer. Wide: one row with decline pushed left and the\n * accepts grouped right. Narrow: a full-width stack. Review mode keeps\n * `bottomSection` — it collapses to a single button.\n */\n actionButtonRow: {\n display: \"flex\",\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: \"12px\",\n paddingTop: \"15px\",\n borderTop: \"none\",\n backgroundColor: \"#ffffff\",\n margin: 0,\n boxSizing: \"border-box\",\n },\n\n actionButtonStack: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"12px\",\n paddingTop: \"15px\",\n borderTop: \"none\",\n backgroundColor: \"#ffffff\",\n margin: 0,\n boxSizing: \"border-box\",\n },\n\n button: {\n width: \"100%\",\n borderRadius: \"8px\",\n padding: \"9px 45px\",\n fontWeight: 400,\n fontSize: \"16px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n cursor: \"pointer\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"center\",\n },\n\n acceptButton: {\n backgroundColor: \"#4f87ff\",\n border: \"none\",\n color: \"#ffffff\",\n },\n\n cancelButton: {\n border: \"1px solid #d0d5dd\",\n backgroundColor: \"#ffffff\",\n color: \"#000000\",\n },\n\n languageSelectorContainer: {\n position: \"relative\",\n // Shares `headerRow` with the title, which grows; without this a long\n // heading squeezes the language button instead of wrapping itself.\n flexShrink: 0,\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n languageDropdown: {\n position: \"absolute\",\n top: \"100%\",\n right: 0,\n backgroundColor: \"#ffffff\",\n border: \"1px solid #d0d5dd\",\n borderRadius: \"4px\",\n boxShadow: \"0px 2px 4px rgba(0, 0, 0, 0.1)\",\n zIndex: 10,\n width: \"max-content\",\n maxHeight: \"200px\",\n overflowY: \"auto\",\n marginTop: \"4px\",\n padding: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n languageItem: {\n padding: \"8px 12px\",\n cursor: \"pointer\",\n fontSize: \"12px\",\n color: \"#344054\",\n backgroundColor: \"#ffffff\",\n borderBottom: \"1px solid #e5e7eb\",\n margin: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n },\n\n selectedLanguageItem: {\n backgroundColor: \"#f3f4f6\",\n fontWeight: 600,\n },\n\n loadingContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"2rem\",\n minHeight: \"200px\",\n margin: 0,\n boxSizing: \"border-box\",\n },\n\n loadingSpinner: {\n width: \"40px\",\n height: \"40px\",\n border: \"4px solid #f3f3f3\",\n borderTop: \"4px solid #3498db\",\n borderRadius: \"50%\",\n animation: \"spin 1s linear infinite\",\n marginBottom: \"1rem\",\n boxSizing: \"border-box\",\n },\n\n sectionHeader: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n margin: \"0 0 8px\",\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n sectionBody: {\n paddingLeft: \"18px\",\n margin: \"0 0 14px\",\n boxSizing: \"border-box\",\n },\n\n sectionTitle: {\n fontWeight: 600,\n fontSize: \"17px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n chevronButton: {\n background: \"none\",\n border: \"none\",\n padding: 0,\n margin: 0,\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n },\n\n confirmHint: {\n fontSize: \"13px\",\n lineHeight: \"18px\",\n color: \"#6b6b6b\",\n margin: 0,\n paddingTop: \"12px\",\n boxSizing: \"border-box\",\n },\n} as const;\n","import { el } from \"./dom\";\nimport {\n REQUIRED_MARKER_ARIA_LABEL,\n REQUIRED_MARKER_GLYPH,\n REQUIRED_MARKER_STYLE,\n} from \"../constants\";\nimport type { PurposeItemData } from \"../api/types\";\n\n/**\n * The red `*` that marks something the data subject cannot opt out of — a\n * required data element, or a purpose that carries one.\n *\n * Callers append this to the label element; append *after* any\n * `textContent` assignment, which replaces every existing child.\n */\nexport function createRequiredMarker(\n label: string = REQUIRED_MARKER_ARIA_LABEL\n): HTMLElement {\n return el(\n \"span\",\n { style: REQUIRED_MARKER_STYLE, \"aria-label\": label },\n REQUIRED_MARKER_GLYPH\n );\n}\n\n/**\n * Whether a purpose carries at least one required data element — the condition\n * for marking the purpose itself as required in the notice UI.\n *\n * Deliberately does not also test `enabled`: this drives a visual marker, and\n * it must agree with the per-element markers actually on screen.\n */\nexport function hasRequiredDataElement(purpose: PurposeItemData): boolean {\n return purpose.data_elements.some((element) => element.required);\n}\n","import type { ProductLike, ProductPurposeGroup, PurposeLike } from \"../types\";\n\nexport const productPurposeKey = (\n productUuid: string | undefined,\n purposeUuid: string,\n) => (productUuid ? `${productUuid}:${purposeUuid}` : purposeUuid);\n\nexport const purposeCoversProduct = (\n purpose: PurposeLike,\n productUuid: string,\n): boolean => {\n const scope = purpose.product_uuids;\n if (!scope || scope.length === 0) return true;\n return scope.includes(productUuid);\n};\n\nexport const isMultiProduct = (products: ProductLike[] | undefined): boolean =>\n Boolean(products && products.length > 1);\n\nexport const purposeNamesProduct = (\n purpose: PurposeLike,\n productUuid: string,\n): boolean => Boolean(purpose.product_uuids?.includes(productUuid));\n\nexport const noticeScopesPurposes = (purposes: PurposeLike[]): boolean =>\n purposes.some((purpose) => (purpose.product_uuids?.length ?? 0) > 0);\n\nexport const serverMarksMandatoryProducts = (\n products: ProductLike[] | undefined,\n): boolean =>\n Boolean(\n products &&\n products.length > 0 &&\n products.every((product) => product.mandatory !== undefined),\n );\n\nexport const gatedProductUuids = (\n products: ProductLike[] | undefined,\n): Set<string> =>\n new Set(\n (products ?? [])\n .filter((product) => product.mandatory === true)\n .map((product) => product.uuid),\n );\n\nexport const rowProductUuid = (\n row: { productUuid?: string },\n products: ProductLike[] | undefined,\n): string | undefined =>\n row.productUuid ?? (products?.length === 1 ? products[0].uuid : undefined);\n\nexport const rowsUnderGate = <R extends { productUuid?: string }>(\n rows: R[],\n products: ProductLike[] | undefined,\n): R[] => {\n const gated = gatedProductUuids(products);\n if (gated.size === 0) return [];\n\n return rows.filter((row) => {\n const productUuid = rowProductUuid(row, products);\n return productUuid !== undefined && gated.has(productUuid);\n });\n};\n\nexport const mandatoryProductsFirst = <P extends ProductLike>(\n products: P[],\n): P[] => {\n const mandatory = products.filter((product) => product.mandatory === true);\n if (mandatory.length === 0 || mandatory.length === products.length) {\n return products;\n }\n return [\n ...mandatory,\n ...products.filter((product) => product.mandatory !== true),\n ];\n};\n\nexport const groupPurposesByProduct = <\n P extends ProductLike,\n U extends PurposeLike,\n>(\n products: P[] | undefined,\n purposes: U[],\n order?: Record<string, string[]>,\n): ProductPurposeGroup<P, U>[] => {\n if (!products || products.length === 0) return [];\n\n return mandatoryProductsFirst(products)\n .map((product) => {\n const covered = purposes.filter((purpose) =>\n purposeCoversProduct(purpose, product.uuid),\n );\n\n const saved = order?.[product.uuid];\n if (!saved || saved.length === 0) return { product, purposes: covered };\n\n const byUuid = new Map(covered.map((p) => [p.uuid, p]));\n const ordered: U[] = [];\n for (const uuid of saved) {\n const found = byUuid.get(uuid);\n if (found) ordered.push(found);\n }\n const rest = covered.filter((p) => !saved.includes(p.uuid));\n return { product, purposes: [...ordered, ...rest] };\n })\n .filter((group) => group.purposes.length > 0);\n};\n\nexport const expandPurposesByProduct = <\n P extends ProductLike,\n U extends PurposeLike,\n>(\n products: P[] | undefined,\n purposes: U[],\n order?: Record<string, string[]>,\n): Array<{ product: P; purpose: U }> => {\n if (!isMultiProduct(products)) return [];\n\n const rows: Array<{ product: P; purpose: U }> = [];\n for (const group of groupPurposesByProduct(products, purposes, order)) {\n for (const purpose of group.purposes) {\n rows.push({ product: group.product, purpose });\n }\n }\n return rows;\n};\n\nexport const noticePurposeRows = <P extends ProductLike, U extends PurposeLike>(\n products: P[] | undefined,\n purposes: U[],\n order?: Record<string, string[]>,\n): Array<{ purpose: U; productUuid?: string }> => {\n if (!isMultiProduct(products)) {\n return purposes.map((purpose) => ({ purpose, productUuid: undefined }));\n }\n\n return expandPurposesByProduct(products, purposes, order).map((row) => ({\n purpose: row.purpose,\n productUuid: row.product.uuid,\n }));\n};\n","import type {\n AcceptMode,\n SelectablePurpose,\n SelectionState,\n} from \"../types\";\nimport { productPurposeKey } from \"../core/productMatrix\";\n\n/**\n * Composite key for a data element's checkbox state — a data element uuid is\n * only unique within its purpose, since the same element can be attached to\n * several purposes on one notice.\n */\nexport const dataElementKey = (\n purposeUuid: string,\n elementUuid: string,\n productUuid?: string\n) => `${productPurposeKey(productUuid, purposeUuid)}-${elementUuid}`;\n\n/**\n * Resolves the checkbox state that a given accept button should submit.\n *\n * - `all` selects every purpose and every enabled data element.\n * - `selected` is the user's own ticks, returned untouched.\n */\nexport const buildSelectionForMode = (\n rows: ReadonlyArray<{\n purpose: SelectablePurpose;\n productUuid?: string;\n }>,\n mode: AcceptMode,\n current: SelectionState\n): SelectionState => {\n if (mode === \"selected\") {\n return current;\n }\n\n const selectedPurposes: Record<string, boolean> = {};\n const selectedDataElements: Record<string, boolean> = {};\n\n rows.forEach(({ purpose, productUuid }) => {\n selectedPurposes[productPurposeKey(productUuid, purpose.uuid)] = true;\n\n purpose.data_elements.forEach((element) => {\n selectedDataElements[\n dataElementKey(purpose.uuid, element.uuid, productUuid)\n ] = element.enabled;\n });\n });\n\n return { selectedPurposes, selectedDataElements };\n};\n\nexport const isBlockingRequiredElement = (element: {\n enabled: boolean;\n required: boolean;\n}): boolean => element.required && element.enabled;\n\nexport const hasRequiredDataElement = (purpose: SelectablePurpose): boolean =>\n purpose.data_elements.some(isBlockingRequiredElement);\n","import { el, svg } from \"../core/dom\";\nimport {\n SELECTION_CONTROL_ACCENT,\n SELECTION_CONTROL_COPY,\n} from \"../constants\";\nimport type {\n SelectionControlProps,\n SelectionControlRefs,\n SelectionControlSize,\n} from \"../types\";\n\nconst SIZES = {\n large: {\n option: { fontSize: \"14px\", fontWeight: \"500\" },\n radio: { width: \"17px\", height: \"17px\" },\n select: { fontSize: \"13px\", padding: \"6px 8px\", fontWeight: \"500\" },\n slot: \"68px\",\n gap: \"10px\",\n tick: { box: 20, glyph: 12 },\n },\n small: {\n option: { fontSize: \"12px\", fontWeight: \"400\" },\n radio: { width: \"13px\", height: \"13px\" },\n select: { fontSize: \"12px\", padding: \"5px 8px\", fontWeight: \"400\" },\n slot: \"62px\",\n gap: \"8px\",\n tick: { box: 17, glyph: 10 },\n },\n} as const;\n\nconst groupStyle = {\n display: \"flex\",\n alignItems: \"center\",\n flexShrink: \"0\",\n};\n\nconst optionStyle = {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n cursor: \"pointer\",\n whiteSpace: \"nowrap\",\n};\n\nconst dropdownWrapStyle = {\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"flex-end\",\n flexShrink: \"0\",\n};\n\nconst settledAnswerStyle = {\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"flex-end\",\n color: \"#667085\",\n whiteSpace: \"nowrap\",\n};\n\nconst selectStyle = {\n border: \"1px solid #d0d5dd\",\n borderRadius: \"6px\",\n lineHeight: \"18px\",\n boxSizing: \"border-box\",\n cursor: \"pointer\",\n backgroundColor: \"#ffffff\",\n color: \"#344054\",\n flexShrink: \"0\",\n};\n\nconst lockedBadgeStyle = (box: number) => ({\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: `${box}px`,\n height: `${box}px`,\n borderRadius: \"50%\",\n flexShrink: \"0\",\n boxSizing: \"border-box\",\n backgroundColor: \"#10B981\",\n marginLeft: \"12px\",\n});\n\nconst lockedTick = (label: string | undefined, box: number, glyph: number) =>\n el(\n \"div\",\n { role: \"img\", \"aria-label\": label, style: lockedBadgeStyle(box) },\n svg(\n \"svg\",\n {\n width: String(glyph),\n height: String(glyph),\n viewBox: \"0 0 12 12\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", {\n d: \"M4 6L5.5 7.5L8.5 4.5\",\n stroke: \"white\",\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n })\n )\n );\n\nconst checkboxClass = (size: SelectionControlSize, className?: string) =>\n className ??\n (size === \"small\" ? \"redacto-checkbox-medium\" : \"redacto-checkbox-large\");\n\nexport function renderSelectionControl(\n props: SelectionControlProps\n): SelectionControlRefs {\n const {\n control,\n onSelect,\n label,\n groupName,\n className,\n locked = false,\n lockedLabel,\n recordedAnswer,\n size = \"large\",\n } = props;\n const scale = SIZES[size];\n let checked = props.checked;\n let indeterminate = props.indeterminate ?? false;\n\n const select = (next: boolean) => {\n if (indeterminate || next !== checked) onSelect(next);\n };\n\n const held = (value: boolean) =>\n locked ? value : !indeterminate && checked === value;\n\n const optionLabel = (text: string, value: boolean) =>\n recordedAnswer === value\n ? `${text} ${SELECTION_CONTROL_COPY.onRecord(text)}`\n : text;\n\n if (locked && control === \"checkbox\") {\n return {\n element: lockedTick(lockedLabel, scale.tick.box, scale.tick.glyph),\n setChecked: () => {},\n };\n }\n\n if (control === \"radio\") {\n const paintRadios = () => {\n radios.forEach((radio) => {\n radio.input.checked = held(radio.value);\n });\n };\n const radios = SELECTION_CONTROL_COPY.options.map((option) => ({\n value: option.value,\n input: el(\"input\", {\n type: \"radio\",\n name: groupName,\n checked: held(option.value),\n disabled: locked,\n \"aria-label\": optionLabel(option.label, option.value),\n style: { accentColor: SELECTION_CONTROL_ACCENT, ...scale.radio },\n onChange: () => {\n select(option.value);\n paintRadios();\n },\n }) as HTMLInputElement,\n label: option.label,\n }));\n\n const element = el(\n \"div\",\n {\n role: \"radiogroup\",\n \"aria-label\": locked ? lockedLabel : label,\n style: { ...groupStyle, gap: scale.gap },\n },\n ...radios.map((radio) =>\n el(\n \"label\",\n { style: { ...optionStyle, ...scale.option } },\n radio.input,\n radio.label\n )\n )\n );\n\n return {\n element,\n setChecked: (next: boolean, nextIndeterminate = false) => {\n if (locked) return;\n checked = next;\n indeterminate = nextIndeterminate;\n paintRadios();\n },\n };\n }\n\n if (control === \"dropdown\") {\n if (locked) {\n return {\n element: el(\n \"span\",\n {\n role: \"img\",\n \"aria-label\": lockedLabel,\n style: { ...settledAnswerStyle, ...scale.select, width: scale.slot },\n },\n SELECTION_CONTROL_COPY.options[0].label\n ),\n setChecked: () => {},\n };\n }\n\n const mixedOption = el(\n \"option\",\n { value: \"\", disabled: true },\n SELECTION_CONTROL_COPY.mixed\n ) as HTMLOptionElement;\n\n const selectEl = el(\n \"select\",\n {\n \"aria-label\": label,\n style: { ...selectStyle, ...scale.select, width: \"100%\" },\n onChange: () => {\n select(selectEl.value === \"true\");\n paint();\n },\n },\n ...SELECTION_CONTROL_COPY.options.map((option) =>\n el(\"option\", { value: String(option.value) }, option.label)\n )\n ) as HTMLSelectElement;\n\n const paint = () => {\n if (indeterminate && mixedOption.parentNode !== selectEl) {\n selectEl.insertBefore(mixedOption, selectEl.firstChild);\n }\n if (!indeterminate && mixedOption.parentNode === selectEl) {\n selectEl.removeChild(mixedOption);\n }\n selectEl.value = indeterminate ? \"\" : String(held(true));\n };\n paint();\n\n return {\n element: el(\n \"span\",\n { style: { ...dropdownWrapStyle, width: scale.slot } },\n selectEl\n ),\n setChecked: (next: boolean, nextIndeterminate = false) => {\n checked = next;\n indeterminate = nextIndeterminate;\n paint();\n },\n };\n }\n\n const checkbox = el(\"input\", {\n className: checkboxClass(size, className),\n type: \"checkbox\",\n checked,\n \"aria-label\": label,\n onChange: () => {\n select(!checked);\n checkbox.checked = checked;\n checkbox.indeterminate = indeterminate;\n },\n }) as HTMLInputElement;\n checkbox.indeterminate = indeterminate;\n\n return {\n element: checkbox,\n setChecked: (next: boolean, nextIndeterminate = false) => {\n checked = next;\n indeterminate = nextIndeterminate;\n checkbox.checked = next;\n checkbox.indeterminate = nextIndeterminate;\n },\n };\n}\n","import { el, svg } from \"../core/dom\";\nimport { createRequiredMarker } from \"../core/required-marker\";\nimport { productPurposeKey } from \"../core/productMatrix\";\nimport { styles } from \"../styles/modal\";\nimport { DEFAULT_SELECTION_CONTROL } from \"../constants\";\nimport {\n hasRequiredDataElement,\n isBlockingRequiredElement,\n} from \"./consentSelection\";\nimport type { PurposeItemData, Settings } from \"../api/types\";\nimport type { SelectionControlRefs } from \"../types\";\nimport { renderSelectionControl } from \"./selection-control\";\n\nexport type ModalPurposeRefs = {\n container: HTMLElement;\n checkboxes: Map<string, HTMLInputElement>;\n purposeControls: Map<string, SelectionControlRefs>;\n collapseButtons: Map<string, HTMLElement>;\n dataElementContainers: Map<string, HTMLElement>;\n chevrons: Map<string, SVGElement>;\n titleElements: Map<string, HTMLElement>;\n descriptionElements: Map<string, HTMLElement>;\n dataElementLabels: Map<string, HTMLElement>;\n};\n\nexport function renderModalPurposes(\n purposes: PurposeItemData[],\n options: {\n selectedPurposes: Record<string, boolean>;\n collapsedPurposes: Record<string, boolean>;\n selectedDataElements: Record<string, boolean>;\n initialDataElementSelections?: Record<string, boolean>;\n recordedAnswers?: Record<string, boolean>;\n settings?: Partial<Settings>;\n isMobile: boolean;\n isAlreadyConsented: boolean;\n productUuid?: string;\n isRowLocked?: (purposeUuid: string) => boolean;\n getTranslatedText: (key: string, defaultText: string, itemId?: string) => string;\n onPurposeToggle: (purposeUuid: string, productUuid?: string) => void;\n onPurposeCollapse: (purposeUuid: string, productUuid?: string) => void;\n onDataElementToggle: (elementUuid: string, purposeUuid: string, productUuid?: string) => void;\n }\n): ModalPurposeRefs {\n const {\n selectedPurposes,\n collapsedPurposes,\n selectedDataElements,\n initialDataElementSelections = {},\n recordedAnswers = {},\n settings,\n isMobile,\n isAlreadyConsented,\n productUuid,\n isRowLocked,\n getTranslatedText,\n onPurposeToggle,\n onPurposeCollapse,\n onDataElementToggle,\n } = options;\n\n const checkboxes = new Map<string, HTMLInputElement>();\n const purposeControls = new Map<string, SelectionControlRefs>();\n const collapseButtons = new Map<string, HTMLElement>();\n const dataElementContainers = new Map<string, HTMLElement>();\n const chevrons = new Map<string, SVGElement>();\n const titleElements = new Map<string, HTMLElement>();\n const descriptionElements = new Map<string, HTMLElement>();\n const dataElementLabels = new Map<string, HTMLElement>();\n\n const headingColor = settings?.headingColor || \"#323B4B\";\n const textColor = settings?.textColor || \"#344054\";\n const font = settings?.font || \"inherit\";\n\n const container = el(\"div\", { style: styles.optionsContainer });\n\n for (const purpose of purposes) {\n const purposeWrapper = el(\"div\");\n const stateKey = productPurposeKey(productUuid, purpose.uuid);\n const locked = isRowLocked ? isRowLocked(purpose.uuid) : isAlreadyConsented;\n\n // Chevron\n const chevron = svg(\n \"svg\",\n {\n width: \"7\",\n height: \"12\",\n viewBox: \"0 0 7 12\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n stroke: headingColor,\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n style: {\n transform: !collapsedPurposes[stateKey] ? \"rotate(90deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.3s ease\",\n },\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", { d: \"M1 1L6 6L1 11\" })\n );\n chevrons.set(stateKey, chevron);\n\n const chevronContainer = el(\n \"div\",\n { style: { display: \"flex\", alignItems: \"center\", justifyContent: \"center\", marginLeft: \"5px\" } },\n chevron\n );\n\n // Title\n const titleEl = el(\"h2\", {\n id: `purpose-name-${stateKey}`,\n style: {\n ...styles.optionTitle,\n fontSize: isMobile ? \"14px\" : \"16px\",\n color: headingColor,\n fontFamily: font,\n },\n });\n // Appended after `textContent`, which replaces every existing child.\n titleEl.textContent = getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid);\n if (hasRequiredDataElement(purpose)) {\n titleEl.appendChild(createRequiredMarker());\n }\n titleElements.set(stateKey, titleEl);\n\n // Description\n const descEl = el(\"h3\", {\n id: `purpose-description-${stateKey}`,\n style: {\n ...styles.optionDescription,\n fontSize: isMobile ? \"11px\" : \"12px\",\n color: textColor,\n fontFamily: font,\n },\n });\n descEl.textContent = getTranslatedText(\"purposes.description\", purpose.description, purpose.uuid);\n descriptionElements.set(stateKey, descEl);\n\n const textContainer = el(\"div\", { style: styles.optionTextContainer }, titleEl, descEl);\n\n // Collapse button\n const collapseBtn = el(\"div\", {\n style: styles.optionLeft,\n role: \"button\",\n tabIndex: \"0\",\n \"aria-expanded\": String(!collapsedPurposes[stateKey]),\n \"aria-controls\": `purpose-${stateKey}`,\n \"aria-label\": `${collapsedPurposes[stateKey] ? \"Expand\" : \"Collapse\"} ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)} details`,\n onClick: () => onPurposeCollapse(purpose.uuid, productUuid),\n onKeydown: (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onPurposeCollapse(purpose.uuid, productUuid);\n }\n },\n }, chevronContainer, textContainer);\n collapseButtons.set(stateKey, collapseBtn);\n\n // Purpose checkbox or green checkmark\n const purposeName = getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid);\n const purposeControl = renderSelectionControl({\n control: settings?.selectionControl ?? DEFAULT_SELECTION_CONTROL,\n checked: selectedPurposes[stateKey] || false,\n onSelect: () => onPurposeToggle(purpose.uuid, productUuid),\n label: `Select all data elements for ${purposeName}`,\n groupName: `redacto-purpose-${stateKey}`,\n recordedAnswer: recordedAnswers[stateKey],\n size: \"small\",\n locked,\n lockedLabel: `Already consented to ${purposeName}`,\n });\n if (!locked) {\n purposeControls.set(stateKey, purposeControl);\n }\n const rightElement = purposeControl.element;\n\n const optionRow = el(\"div\", { style: styles.optionItem }, collapseBtn, rightElement);\n\n // Data elements\n const deContainer = el(\"div\", {\n id: `purpose-${stateKey}`,\n style: styles.dataElementsContainer,\n });\n\n if (purpose.data_elements?.length > 0) {\n for (const dataElement of purpose.data_elements) {\n const combinedId = `${stateKey}-${dataElement.uuid}`;\n\n const labelSpan = el(\"span\", {\n id: `data-element-${stateKey}-${dataElement.uuid}`,\n style: {\n ...styles.dataElementText,\n fontSize: isMobile ? \"12px\" : \"14px\",\n color: textColor,\n fontFamily: font,\n },\n });\n labelSpan.textContent = getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid);\n dataElementLabels.set(combinedId, labelSpan);\n\n if (isBlockingRequiredElement(dataElement)) {\n labelSpan.appendChild(createRequiredMarker());\n }\n\n let deRightElement: HTMLElement;\n if (!locked) {\n const deCheckbox = el(\"input\", {\n className: \"redacto-checkbox-small\",\n type: \"checkbox\",\n checked: selectedDataElements[combinedId] || false,\n \"aria-label\": `Select ${getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid)}${isBlockingRequiredElement(dataElement) ? \" (required)\" : \"\"}`,\n onChange: () => onDataElementToggle(dataElement.uuid, purpose.uuid, productUuid),\n }) as HTMLInputElement;\n checkboxes.set(combinedId, deCheckbox);\n deRightElement = deCheckbox;\n } else {\n const wasSelected = initialDataElementSelections[combinedId] || false;\n if (wasSelected) {\n deRightElement = createGreenCheckmark(\n 16,\n `Consented to ${getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid)}`\n );\n } else {\n deRightElement = el(\"div\", {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"16px\",\n height: \"16px\",\n borderRadius: \"50%\",\n border: \"2px solid #d0d5dd\",\n backgroundColor: \"transparent\",\n },\n \"aria-label\": `Not consented to ${getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid)}`,\n });\n }\n }\n\n const deRow = el(\"div\", { style: styles.dataElementItem }, labelSpan, deRightElement);\n deContainer.appendChild(deRow);\n }\n }\n\n dataElementContainers.set(stateKey, deContainer);\n deContainer.style.display = !collapsedPurposes[stateKey] && purpose.data_elements?.length > 0 ? \"flex\" : \"none\";\n\n purposeWrapper.appendChild(optionRow);\n purposeWrapper.appendChild(deContainer);\n container.appendChild(purposeWrapper);\n }\n\n return {\n container,\n checkboxes,\n purposeControls,\n collapseButtons,\n dataElementContainers,\n chevrons,\n titleElements,\n descriptionElements,\n dataElementLabels,\n };\n}\n\nexport function createGreenCheckmark(size: number, ariaLabel: string): HTMLElement {\n const svgSize = size === 20 ? 12 : 10;\n const strokeWidth = size === 20 ? \"2\" : \"1.5\";\n const pathD = size === 20 ? \"M4 6L5.5 7.5L8.5 4.5\" : \"M3 5L4.5 6.5L7.5 3.5\";\n\n const checkSvg = svg(\n \"svg\",\n {\n width: String(svgSize),\n height: String(svgSize),\n viewBox: `0 0 ${svgSize} ${svgSize}`,\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", {\n d: pathD,\n stroke: \"white\",\n \"stroke-width\": strokeWidth,\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n })\n );\n\n return el(\"div\", {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: `${size}px`,\n height: `${size}px`,\n borderRadius: \"50%\",\n backgroundColor: \"#10B981\",\n },\n \"aria-label\": ariaLabel,\n }, checkSvg);\n}\n","import { el, svg, applyStyles } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { Settings } from \"../api/types\";\n\nconst LANGUAGE_NATIVE_LABELS: Record<string, string> = {\n English: \"English\",\n Assamese: \"অসমীয়া (Assamese)\",\n Bengali: \"বাংলা (Bengali)\",\n Bodo: \"बड़ो (Bodo)\",\n Dogri: \"डोगरी (Dogri)\",\n \"Goan Konkani\": \"कोंकणी (Goan Konkani)\",\n Gujarati: \"ગુજરાતી (Gujarati)\",\n Hindi: \"हिन्दी (Hindi)\",\n Kannada: \"ಕನ್ನಡ (Kannada)\",\n Kashmiri: \"كٲشُر (Kashmiri)\",\n Maithili: \"मैथिली (Maithili)\",\n Malayalam: \"മലയാളം (Malayalam)\",\n Manipuri: \"ꯃꯩꯇꯩꯂꯣꯟ (Manipuri)\",\n Marathi: \"मराठी (Marathi)\",\n Nepali: \"नेपाली (Nepali)\",\n Odia: \"ଓଡ଼ିଆ (Odia)\",\n Punjabi: \"ਪੰਜਾਬੀ (Punjabi)\",\n Sanskrit: \"संस्कृतम् (Sanskrit)\",\n Santali: \"ᱥᱟᱱᱛᱟᱲᱤ (Santali)\",\n Sindhi: \"سنڌي (Sindhi)\",\n Tamil: \"தமிழ் (Tamil)\",\n Telugu: \"తెలుగు (Telugu)\",\n Urdu: \"اردو (Urdu)\",\n};\n\nconst toNativeLabel = (name: string): string => LANGUAGE_NATIVE_LABELS[name] ?? name;\n\nexport type LanguageSelectorRefs = {\n container: HTMLElement;\n button: HTMLElement;\n dropdown: HTMLElement;\n buttonText: HTMLElement;\n close: () => void;\n};\n\nexport function renderLanguageSelector(options: {\n languages: string[];\n selectedLanguage: string;\n settings?: Partial<Settings>;\n onSelect: (lang: string) => void;\n /**\n * Where the dropdown panel itself is appended. We append it as a sibling of\n * the modal (rather than inside `container`) so it can escape the modal's\n * `transform: translate(...)` stacking context. Pass the shadow root when\n * the modal is rendered inside a shadow boundary; otherwise pass\n * `document.body`.\n */\n dropdownContainer: HTMLElement | ShadowRoot;\n}): LanguageSelectorRefs {\n const { languages, selectedLanguage, settings, onSelect, dropdownContainer } = options;\n\n let isOpen = false;\n\n const buttonText = el(\"span\");\n buttonText.textContent = toNativeLabel(selectedLanguage);\n\n const chevronSvg = svg(\n \"svg\",\n {\n width: \"8\",\n height: \"5\",\n viewBox: \"0 0 8 5\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n },\n svg(\"path\", {\n d: \"M1 1L4 4L7 1\",\n stroke: settings?.button?.language?.textColor || \"#344054\",\n \"stroke-width\": \"1.5\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n })\n );\n\n const buttonStyle: Record<string, any> = { ...styles.topRight };\n if (settings?.button?.language) {\n buttonStyle.backgroundColor = settings.button.language.backgroundColor;\n buttonStyle.color = settings.button.language.textColor;\n }\n\n const button = el(\"div\", {\n style: buttonStyle,\n role: \"button\",\n tabIndex: \"0\",\n \"aria-haspopup\": \"listbox\",\n \"aria-expanded\": \"false\",\n \"aria-label\": `Language selector, current: ${toNativeLabel(selectedLanguage)}`,\n onClick: () => toggleDropdown(),\n onKeydown: (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n toggleDropdown();\n } else if (e.key === \"Escape\") {\n closeDropdown();\n }\n },\n }, buttonText, chevronSvg);\n\n // Dropdown — uses position:fixed to escape modal's transform stacking context\n const dropdown = el(\"div\", {\n style: {\n position: \"fixed\",\n backgroundColor: \"#ffffff\",\n border: \"1px solid #d0d5dd\",\n borderRadius: \"4px\",\n boxShadow: \"0px 4px 12px rgba(0, 0, 0, 0.15)\",\n zIndex: 2147483647, // max int — always on top\n minWidth: \"140px\",\n maxHeight: \"200px\",\n overflowY: \"auto\",\n padding: 0,\n boxSizing: \"border-box\",\n textAlign: \"left\",\n display: \"none\",\n },\n role: \"listbox\",\n \"aria-label\": \"Select language\",\n });\n\n for (const lang of languages) {\n const isSelected = lang === selectedLanguage;\n const itemStyle = isSelected\n ? { ...styles.languageItem, ...styles.selectedLanguageItem }\n : { ...styles.languageItem };\n\n if (settings?.button?.language) {\n if (isSelected && settings.button.language.selectedBackgroundColor) {\n itemStyle.backgroundColor = settings.button.language.selectedBackgroundColor;\n }\n if (isSelected && settings.button.language.selectedTextColor) {\n itemStyle.color = settings.button.language.selectedTextColor;\n }\n }\n\n const item = el(\"div\", {\n style: itemStyle,\n role: \"option\",\n \"aria-selected\": String(isSelected),\n onClick: () => {\n onSelect(lang);\n closeDropdown();\n },\n onMouseenter: (e: Event) => {\n (e.target as HTMLElement).style.backgroundColor = \"#f3f4f6\";\n },\n onMouseleave: (e: Event) => {\n (e.target as HTMLElement).style.backgroundColor = isSelected ? \"#f3f4f6\" : \"#ffffff\";\n },\n });\n item.textContent = toNativeLabel(lang);\n dropdown.appendChild(item);\n }\n\n // Container only holds the button — dropdown is appended to its container\n // (shadow root in the modal flow, body for non-shadow callers) so it can\n // escape the modal's transform stacking context.\n const container = el(\"div\", { style: styles.languageSelectorContainer }, button);\n\n dropdownContainer.appendChild(dropdown);\n\n function positionDropdown() {\n const rect = button.getBoundingClientRect();\n dropdown.style.top = `${rect.bottom + 4}px`;\n dropdown.style.right = `${window.innerWidth - rect.right}px`;\n dropdown.style.left = \"auto\";\n }\n\n // Click outside handler. When the modal is inside a shadow root the click\n // event's `target` is retargeted to the shadow host for listeners on the\n // document. `composedPath()` returns the real path through the shadow tree\n // so we can correctly detect whether the click originated inside the\n // selector or its dropdown.\n const clickOutsideHandler = (e: Event) => {\n const path = (e as Event & { composedPath?: () => EventTarget[] }).composedPath?.() ?? [];\n if (path.includes(container) || path.includes(dropdown)) return;\n\n // Fallback for environments without composedPath()\n if (path.length === 0) {\n const target = e.target as Node;\n if (container.contains(target) || dropdown.contains(target)) return;\n }\n closeDropdown();\n };\n\n // Reposition on scroll/resize while open\n const repositionHandler = () => {\n if (isOpen) positionDropdown();\n };\n\n function toggleDropdown() {\n isOpen ? closeDropdown() : openDropdown();\n }\n\n function openDropdown() {\n isOpen = true;\n positionDropdown();\n dropdown.style.display = \"block\";\n button.setAttribute(\"aria-expanded\", \"true\");\n setTimeout(() => {\n document.addEventListener(\"click\", clickOutsideHandler);\n }, 0);\n window.addEventListener(\"scroll\", repositionHandler, true);\n window.addEventListener(\"resize\", repositionHandler);\n }\n\n function closeDropdown() {\n isOpen = false;\n dropdown.style.display = \"none\";\n button.setAttribute(\"aria-expanded\", \"false\");\n document.removeEventListener(\"click\", clickOutsideHandler);\n window.removeEventListener(\"scroll\", repositionHandler, true);\n window.removeEventListener(\"resize\", repositionHandler);\n }\n\n return { container, button, dropdown, buttonText, close: closeDropdown };\n}\n","/**\n * Focus trap + keyboard navigation for the modal.\n */\n\nexport type KeyboardTrapCleanup = () => void;\n\nexport function setupKeyboardTrap(\n modalEl: HTMLElement,\n onEscape: () => void\n): KeyboardTrapCleanup {\n const handler = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n onEscape();\n return;\n }\n\n if (e.key === \"Tab\") {\n const focusableElements = modalEl.querySelectorAll<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n const focusable = Array.from(focusableElements).filter(\n (el) => !el.hasAttribute(\"disabled\") && el.offsetParent !== null\n );\n\n if (focusable.length === 0) {\n e.preventDefault();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n // When the modal lives inside a shadow root, document.activeElement\n // returns the shadow host rather than the actually focused element.\n // Read activeElement from the modal's own root for a correct answer.\n const root = modalEl.getRootNode() as Document | ShadowRoot;\n const active =\n (root as ShadowRoot).activeElement ?? document.activeElement;\n\n if (e.shiftKey) {\n if (active === first) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (active === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n };\n\n document.addEventListener(\"keydown\", handler);\n\n // Auto-focus first focusable element\n requestAnimationFrame(() => {\n const firstFocusable = modalEl.querySelector<HTMLElement>(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n firstFocusable?.focus();\n });\n\n return () => {\n document.removeEventListener(\"keydown\", handler);\n };\n}\n","import type { PersistedConsentState } from \"../api/types\";\n\nconst STORAGE_KEY = \"redacto_consent_sdk_state\";\nconst STATE_EXPIRY_MS = 30 * 60 * 1000; // 30 minutes\n\nconst isBrowser = (): boolean => {\n return typeof window !== \"undefined\" && typeof window.sessionStorage !== \"undefined\";\n};\n\nexport const saveConsentState = (state: PersistedConsentState): void => {\n if (!isBrowser()) {\n console.warn(\"SessionStorage not available - state not persisted\");\n return;\n }\n\n try {\n const stateWithTimestamp = {\n ...state,\n timestamp: new Date().toISOString(),\n };\n sessionStorage.setItem(STORAGE_KEY, JSON.stringify(stateWithTimestamp));\n } catch (error) {\n console.error(\"Failed to save consent state:\", error);\n }\n};\n\nexport const getConsentState = (): PersistedConsentState | null => {\n if (!isBrowser()) return null;\n\n try {\n const savedState = sessionStorage.getItem(STORAGE_KEY);\n if (!savedState) return null;\n\n const parsed: PersistedConsentState = JSON.parse(savedState);\n\n const stateAge = Date.now() - new Date(parsed.timestamp).getTime();\n if (stateAge > STATE_EXPIRY_MS) {\n clearConsentState();\n return null;\n }\n\n return parsed;\n } catch (error) {\n console.error(\"Failed to get consent state:\", error);\n return null;\n }\n};\n\nexport const clearConsentState = (): void => {\n if (!isBrowser()) return;\n\n try {\n sessionStorage.removeItem(STORAGE_KEY);\n } catch (error) {\n console.error(\"Failed to clear consent state:\", error);\n }\n};\n\nexport const updateConsentState = (updates: Partial<PersistedConsentState>): void => {\n const currentState = getConsentState();\n if (currentState) {\n saveConsentState({\n ...currentState,\n ...updates,\n timestamp: new Date().toISOString(),\n });\n }\n};\n\nexport const hasPendingVerification = (): boolean => {\n const state = getConsentState();\n return state !== null && state.flowState === \"digilocker-pending\";\n};\n\nexport const getVerificationResult = (): \"pending\" | \"verified\" | \"failed\" | \"in_progress\" | \"expired\" | null => {\n const state = getConsentState();\n return state?.verificationResult ?? null;\n};\n\nexport const getVerificationReference = (): string | null => {\n const state = getConsentState();\n return state?.verificationReference ?? null;\n};\n","import { fetchTTSAudioUrls } from \"../api\";\nimport {\n ACCEPT_ALL_BUTTON_ID,\n ACCEPT_SELECTED_BUTTON_ID,\n DECLINE_BUTTON_ID,\n DPO_AUDIO_ELEMENT_MAP,\n} from \"../constants\";\nimport type {\n ActiveConfig,\n SandboxOptions,\n TTSAudioUrlsResponse,\n} from \"../api/types\";\nimport type { TTSAudioFetcher } from \"../shared/types\";\n\nexport class TTSManager {\n private audioUrls: TTSAudioUrlsResponse[\"detail\"] | null = null;\n private audioSequence: string[] = [];\n private elementIdSequence: string[] = [];\n private currentAudio: HTMLAudioElement | null = null;\n private currentIndex = 0;\n private _isPlaying = false;\n private _isPaused = false;\n private _isAvailable = false;\n private highlightedElementId: string | null = null;\n private abortController: AbortController | null = null;\n private onStateChange: () => void;\n private root: Document | ShadowRoot;\n private fetchAudio: TTSAudioFetcher;\n\n /**\n * @param onStateChange Invoked whenever playback state changes so the host\n * can refresh its UI (e.g. swap the play/pause icon).\n * @param root The root in which to look up highlightable elements by id.\n * When the modal is rendered inside a shadow root, pass that shadow root\n * so queries stay scoped to the SDK's tree (and don't accidentally hit\n * element ids that the host page also defines).\n */\n constructor(\n onStateChange: () => void,\n root: Document | ShadowRoot,\n fetchAudio: TTSAudioFetcher = fetchTTSAudioUrls\n ) {\n this.onStateChange = onStateChange;\n this.root = root;\n this.fetchAudio = fetchAudio;\n }\n\n get isPlaying(): boolean { return this._isPlaying; }\n get isPaused(): boolean { return this._isPaused; }\n get isAvailable(): boolean { return this._isAvailable; }\n get currentElementId(): string | null { return this.highlightedElementId; }\n\n async fetchAudioUrls(params: SandboxOptions & {\n accessToken?: string;\n baseUrl?: string;\n ledgerBaseUrl?: string;\n noticeUuid: string;\n language: string;\n content: ActiveConfig;\n }): Promise<void> {\n // Reset availability + sequences SYNCHRONOUSLY before notifying. The\n // language can change while a previous language's URLs are still loaded;\n // if we don't clear here, a click on the speaker icon (or the in-flight\n // stop()) would either keep the icon showing or replay the previous\n // language's audio. We then fire a single onStateChange() so the UI hides\n // the icon while the new language's audio is being fetched.\n this.stopInternal();\n this._isAvailable = false;\n this.audioUrls = null;\n this.audioSequence = [];\n this.elementIdSequence = [];\n this.onStateChange();\n\n this.abortController?.abort();\n this.abortController = new AbortController();\n\n try {\n const response = await this.fetchAudio({\n accessToken: params.accessToken,\n baseUrl: params.baseUrl,\n ledgerBaseUrl: params.ledgerBaseUrl,\n noticeUuid: params.noticeUuid,\n language: params.language,\n signal: this.abortController.signal,\n token: params.token,\n sandboxUcic: params.sandboxUcic,\n sandboxEmail: params.sandboxEmail,\n sandboxMobile: params.sandboxMobile,\n organisationUuid: params.organisationUuid,\n workspaceUuid: params.workspaceUuid,\n });\n\n this.audioUrls = response.detail;\n this.buildSequences(params.content);\n // Only mark TTS as available if the backend actually returned playable\n // audio for this language. Some languages (e.g. Santali) come back with\n // a 200 but empty / partial fields — surfacing the speaker icon in that\n // case would let users click it and replay the previous language.\n this._isAvailable = this.audioSequence.length > 0;\n this.onStateChange();\n } catch (error) {\n if ((error as Error).name !== \"AbortError\") {\n this._isAvailable = false;\n this.audioUrls = null;\n this.audioSequence = [];\n this.elementIdSequence = [];\n this.onStateChange();\n }\n }\n }\n\n private buildSequences(content: ActiveConfig): void {\n if (!this.audioUrls) return;\n const urls = this.audioUrls;\n\n const audioSeq: string[] = [];\n const elementSeq: string[] = [];\n\n const push = (url: string | undefined, elementId: string) => {\n if (url) {\n audioSeq.push(url);\n elementSeq.push(elementId);\n }\n };\n\n // 1. Notice banner heading\n push(urls.notice_banner_heading_audio_url, \"privacy-notice-title\");\n // 2. Notice text\n push(urls.notice_text_audio_url, \"privacy-notice-text\");\n // 3. Privacy policy prefix text\n push(urls.privacy_policy_prefix_text_audio_url, \"privacy-policy-text\");\n // 4. Privacy policy anchor text\n push(urls.privacy_policy_anchor_text_audio_url, \"privacy-policy-link\");\n // 5. Purpose section heading\n push(urls.purpose_section_heading_audio_url, \"purpose-section-heading\");\n\n // 6. For each purpose: name, description, data elements\n for (const purpose of content.purposes) {\n const purposeAudio = urls.purposes_audio?.[purpose.uuid];\n if (purposeAudio) {\n push(purposeAudio.name_audio_url, `purpose-name-${purpose.uuid}`);\n push(purposeAudio.description_audio_url, `purpose-description-${purpose.uuid}`);\n }\n\n for (const de of purpose.data_elements) {\n const deAudio = urls.data_elements_audio?.[de.uuid];\n if (deAudio) {\n push(deAudio.name_audio_url, `data-element-${purpose.uuid}-${de.uuid}`);\n }\n }\n }\n\n // 7. Additional text\n push(urls.additional_text_audio_url, \"additional-text\");\n // 8. Privacy center anchor text\n push(urls.privacy_center_anchor_text_audio_url, \"privacy-center-link\");\n\n // 9. DPO info audio\n if (urls.dpo_info_audio) {\n for (const mapping of DPO_AUDIO_ELEMENT_MAP) {\n const audioUrl = urls.dpo_info_audio[mapping.audioKey];\n push(audioUrl, mapping.elementId);\n }\n }\n\n // 10. Action buttons, read in the order they are laid out.\n push(urls.accept_all_button_text_audio_url, ACCEPT_ALL_BUTTON_ID);\n push(urls.confirm_button_text_audio_url, ACCEPT_SELECTED_BUTTON_ID);\n push(urls.decline_button_text_audio_url, DECLINE_BUTTON_ID);\n\n this.audioSequence = audioSeq;\n this.elementIdSequence = elementSeq;\n }\n\n toggle(): void {\n this._isPlaying ? this.pause() : this.play();\n }\n\n play(): void {\n if (this.audioSequence.length === 0) return;\n\n if (this._isPaused && this.currentAudio) {\n this.currentAudio.play()\n .then(() => {\n this._isPlaying = true;\n this._isPaused = false;\n this.onStateChange();\n })\n .catch(() => {});\n } else {\n const startIndex = this._isPlaying ? this.currentIndex : 0;\n this.playNextAudio(startIndex);\n }\n }\n\n pause(): void {\n if (this.currentAudio && this._isPlaying) {\n this.currentAudio.pause();\n this._isPlaying = false;\n this._isPaused = true;\n this.onStateChange();\n }\n }\n\n stop(): void {\n this.stopInternal();\n this.onStateChange();\n }\n\n /**\n * Internal stop used by code paths (like fetchAudioUrls) that will fire\n * their own onStateChange after composing a richer state update — we don't\n * want the intermediate notification to flicker the UI based on a half-set\n * state (e.g. _isAvailable still true from the previous language).\n */\n private stopInternal(): void {\n if (this.currentAudio) {\n this.currentAudio.pause();\n this.currentAudio.currentTime = 0;\n this.currentAudio = null;\n }\n this._isPlaying = false;\n this._isPaused = false;\n this.currentIndex = 0;\n this.removeHighlights();\n this.highlightedElementId = null;\n }\n\n destroy(): void {\n this.abortController?.abort();\n this.stop();\n }\n\n private playNextAudio(index: number): void {\n if (index >= this.audioSequence.length) {\n this.stop();\n return;\n }\n\n if (this.currentAudio) {\n this.currentAudio.pause();\n this.currentAudio = null;\n }\n\n const audio = new Audio(this.audioSequence[index]);\n this.currentAudio = audio;\n this.currentIndex = index;\n this._isPlaying = true;\n this._isPaused = false;\n\n // Highlight\n const elementId = this.elementIdSequence[index];\n if (elementId) {\n this.highlightElement(elementId);\n }\n\n audio.onended = () => this.playNextAudio(index + 1);\n audio.onerror = () => {\n console.warn(`Failed to load audio at index ${index}`);\n this.playNextAudio(index + 1);\n };\n\n audio.play().catch((error) => {\n console.warn(`Failed to play audio at index ${index}:`, error);\n this._isPlaying = false;\n this.onStateChange();\n });\n\n this.onStateChange();\n }\n\n private highlightElement(elementId: string): void {\n this.removeHighlights();\n this.highlightedElementId = elementId;\n\n setTimeout(() => {\n // ShadowRoot has getElementById in modern browsers; fall back to\n // querySelector with CSS.escape for safety.\n const element =\n \"getElementById\" in this.root\n ? (this.root as Document | ShadowRoot & { getElementById(id: string): HTMLElement | null }).getElementById(elementId)\n : (this.root as ShadowRoot).querySelector<HTMLElement>(`#${CSS.escape(elementId)}`);\n if (element) {\n element.classList.add(\"redacto-tts-highlight\");\n\n const rect = element.getBoundingClientRect();\n const isVisible =\n rect.top >= 0 &&\n rect.left >= 0 &&\n rect.bottom <= window.innerHeight &&\n rect.right <= window.innerWidth;\n\n if (!isVisible) {\n element.scrollIntoView({\n behavior: \"smooth\",\n block: \"center\",\n inline: \"nearest\",\n });\n }\n }\n }, 50);\n }\n\n private removeHighlights(): void {\n this.root.querySelectorAll(\".redacto-tts-highlight\").forEach((el) => {\n el.classList.remove(\"redacto-tts-highlight\");\n });\n }\n}\n","import { el, svg } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { Settings } from \"../api/types\";\nimport type { ResolvedColors } from \"./colors\";\n\nexport type AgeVerificationRefs = {\n container: HTMLElement;\n};\n\nexport function renderAgeVerification(options: {\n settings?: Partial<Settings>;\n colors: ResolvedColors;\n isMobile: boolean;\n logoUrl: string;\n onYes: () => void;\n onNo: () => void;\n onClose: () => void;\n}): AgeVerificationRefs {\n const { settings, colors, isMobile, logoUrl, onYes, onNo, onClose } = options;\n\n const headingColor = settings?.headingColor || \"#101828\";\n const textColor = colors.text;\n const font = colors.font;\n\n // ─── Top Section (matches React: logo+title left, X button right) ───\n const logo = el(\"img\", { src: logoUrl, style: styles.logo, alt: \"Redacto Logo\" });\n\n const title = el(\"h2\", {\n id: \"age-verification-title\",\n style: {\n ...styles.title,\n fontSize: isMobile ? \"16px\" : \"18px\",\n color: headingColor,\n fontFamily: font,\n },\n });\n title.textContent = \"Age Verification Required\";\n\n const topLeft = el(\"div\", { style: styles.topLeft }, logo, title);\n\n const closeBtn = el(\"button\", {\n style: {\n background: \"none\",\n border: \"none\",\n color: headingColor,\n cursor: \"pointer\",\n padding: isMobile ? \"2px\" : \"4px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n type: \"button\",\n \"aria-label\": \"Close modal\",\n onClick: onClose,\n });\n const closeSvg = svg(\n \"svg\",\n {\n width: isMobile ? \"18\" : \"20\",\n height: isMobile ? \"18\" : \"20\",\n viewBox: \"0 0 20 20\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", {\n d: \"M15 5L5 15M5 5L15 15\",\n stroke: \"currentColor\",\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n })\n );\n closeBtn.appendChild(closeSvg);\n\n const topSection = el(\"div\", {\n style: { ...styles.topSection, color: textColor, fontFamily: font },\n }, topLeft, closeBtn);\n\n // ─── Middle Section ───\n const description = el(\"p\", {\n style: {\n ...styles.privacyText,\n fontSize: isMobile ? \"14px\" : \"16px\",\n color: textColor,\n fontFamily: font,\n marginBottom: \"16px\",\n },\n });\n description.textContent = \"To proceed with this consent form, we need to verify your age.\";\n\n const question = el(\"p\", {\n style: {\n ...styles.subTitle,\n color: textColor,\n fontFamily: font,\n marginBottom: \"24px\",\n textAlign: \"left\",\n },\n });\n question.textContent = \"Are you 18 years of age or older?\";\n\n const middleSection = el(\"div\", {\n style: { ...styles.middleSection, color: textColor, fontFamily: font },\n }, description, question);\n\n // ─── Bottom Section (Yes first, No second — matches React) ───\n const btnBase = {\n ...styles.button,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n const yesBtn = el(\"button\", {\n style: {\n ...btnBase,\n ...styles.acceptButton,\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderRadius: colors.borderRadius,\n },\n type: \"button\",\n \"aria-label\": \"Confirm that I am 18 years of age or older\",\n onClick: onYes,\n });\n yesBtn.textContent = \"Yes, I am 18 or older\";\n\n const noBtn = el(\"button\", {\n style: {\n ...btnBase,\n ...styles.cancelButton,\n backgroundColor: colors.declineBg,\n color: colors.declineText,\n borderColor: colors.declineBorder,\n borderRadius: colors.borderRadius,\n },\n type: \"button\",\n \"aria-label\": \"Indicate that I am under 18 years of age\",\n onClick: onNo,\n });\n noBtn.textContent = \"No, I am under 18\";\n\n const bottomSection = el(\"div\", {\n style: { ...styles.bottomSection, color: textColor, fontFamily: font },\n }, yesBtn, noBtn);\n\n // ─── Assemble (wrapped in content div like modal) ───\n const container = el(\"div\", { style: styles.content }, topSection, middleSection, bottomSection);\n\n return { container };\n}\n","import { el, svg } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { Settings } from \"../api/types\";\nimport type { ResolvedColors } from \"./colors\";\n\nconst RELATIONSHIP_OPTIONS = [\n { value: \"Father\", label: \"Father\" },\n { value: \"Mother\", label: \"Mother\" },\n { value: \"Legal Guardian\", label: \"Legal Guardian\" },\n { value: \"Grandparent\", label: \"Grandparent\" },\n];\n\nexport type GuardianFormData = {\n guardianName: string;\n guardianContact: string;\n guardianRelationship: string;\n};\n\nexport type GuardianFormRefs = {\n container: HTMLElement;\n nameInput: HTMLInputElement;\n contactInput: HTMLInputElement;\n relationshipDisplay: HTMLElement;\n nameError: HTMLElement;\n contactError: HTMLElement;\n relationshipError: HTMLElement;\n submitBtn: HTMLButtonElement;\n generalError: HTMLElement;\n};\n\nexport function renderGuardianForm(options: {\n formData: GuardianFormData;\n settings?: Partial<Settings>;\n colors: ResolvedColors;\n isMobile: boolean;\n logoUrl: string;\n isSubmitting: boolean;\n onSubmit: () => void;\n onCancel: () => void;\n onFieldChange: (field: keyof GuardianFormData, value: string) => void;\n}): GuardianFormRefs {\n const { formData, settings, colors, isMobile, logoUrl, isSubmitting, onSubmit, onCancel, onFieldChange } = options;\n\n const headingColor = settings?.headingColor || \"#101828\";\n const textColor = colors.text;\n const borderColor = colors.declineBorder;\n const bgColor = settings?.backgroundColor || \"#ffffff\";\n const radius = colors.borderRadius;\n const font = colors.font;\n const accentColor = colors.acceptBg;\n\n const inputStyle: Record<string, any> = {\n width: \"100%\",\n padding: \"10px 12px\",\n border: `1px solid ${borderColor}`,\n borderRadius: radius,\n fontSize: \"13px\",\n fontFamily: font,\n color: textColor,\n backgroundColor: bgColor,\n marginBottom: \"2px\",\n boxSizing: \"border-box\",\n outline: \"none\",\n };\n\n const errorStyle: Record<string, any> = {\n color: \"#DC2626\",\n fontSize: \"11px\",\n marginTop: \"4px\",\n marginBottom: \"0px\",\n display: \"none\",\n };\n\n const labelStyle: Record<string, any> = {\n fontSize: \"13px\",\n fontWeight: 500,\n color: textColor,\n fontFamily: font,\n marginBottom: \"4px\",\n display: \"block\",\n };\n\n const hintStyle: Record<string, any> = {\n fontSize: \"11px\",\n color: \"#667085\",\n marginTop: \"2px\",\n marginBottom: \"0px\",\n lineHeight: \"1.4\",\n };\n\n // ─── Top Section ───\n const logo = el(\"img\", { src: logoUrl, style: styles.logo, alt: \"Logo\" });\n const title = el(\"h2\", {\n id: \"guardian-form-title\",\n style: {\n ...styles.title,\n fontSize: \"16px\",\n fontWeight: 600,\n color: headingColor,\n fontFamily: font,\n },\n });\n title.textContent = \"Guardian Verification\";\n\n const topLeft = el(\"div\", { style: styles.topLeft }, logo, title);\n const topSection = el(\"div\", {\n style: { ...styles.topSection, color: textColor, fontFamily: font },\n }, topLeft);\n\n // ─── Middle Section ───\n const subtitle = el(\"p\", {\n style: {\n ...styles.privacyText,\n fontSize: \"13px\",\n lineHeight: \"1.5\",\n color: textColor,\n fontFamily: font,\n marginBottom: \"12px\",\n },\n });\n subtitle.textContent = \"Since you are under the age of consent, a legal guardian must verify their identity via DigiLocker before you can proceed.\";\n\n // Info banner with SVG icon\n const infoIcon = svg(\n \"svg\",\n {\n width: \"16\", height: \"16\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: \"#2563EB\", \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"circle\", { cx: \"12\", cy: \"12\", r: \"10\" }),\n svg(\"line\", { x1: \"12\", y1: \"16\", x2: \"12\", y2: \"12\" }),\n svg(\"line\", { x1: \"12\", y1: \"8\", x2: \"12.01\", y2: \"8\" })\n );\n (infoIcon as unknown as HTMLElement).style.cssText = \"flex-shrink:0;margin-top:1px\";\n\n const infoText = el(\"span\");\n infoText.textContent = \"The guardian's name will be matched against their DigiLocker identity document (e.g. Aadhaar). Please enter the name exactly as it appears on the document.\";\n\n const infoBanner = el(\"div\", {\n style: {\n display: \"flex\",\n alignItems: \"flex-start\",\n gap: \"8px\",\n padding: \"10px 12px\",\n backgroundColor: \"#EFF6FF\",\n border: \"1px solid #BFDBFE\",\n borderRadius: radius,\n marginBottom: \"16px\",\n fontSize: \"12px\",\n lineHeight: \"1.5\",\n color: \"#1E40AF\",\n },\n }, infoIcon, infoText);\n\n // ─── Name field ───\n const nameLabel = el(\"label\", { for: \"guardianName\", style: labelStyle });\n nameLabel.innerHTML = `Guardian's Full Name <span style=\"color:#DC2626\">*</span>`;\n\n const nameInput = el(\"input\", {\n id: \"guardianName\",\n type: \"text\",\n style: inputStyle,\n value: formData.guardianName,\n placeholder: \"e.g. Rajesh Kumar\",\n autoComplete: \"name\",\n \"aria-describedby\": \"guardianName-hint\",\n onInput: (e: Event) => onFieldChange(\"guardianName\", (e.target as HTMLInputElement).value),\n }) as HTMLInputElement;\n\n const nameHint = el(\"p\", { id: \"guardianName-hint\", style: hintStyle });\n nameHint.textContent = \"Enter the full name as per government ID (Aadhaar, PAN, etc.)\";\n\n const nameError = el(\"div\", { style: errorStyle, role: \"alert\" });\n const nameGroup = el(\"div\", null, nameLabel, nameInput, nameHint, nameError);\n\n // ─── Contact field ───\n const contactLabel = el(\"label\", { for: \"guardianContact\", style: labelStyle });\n contactLabel.innerHTML = `Guardian's Phone Number <span style=\"color:#DC2626\">*</span>`;\n\n const contactInput = el(\"input\", {\n id: \"guardianContact\",\n type: \"tel\",\n inputMode: \"tel\",\n style: inputStyle,\n value: formData.guardianContact,\n placeholder: \"e.g. 9876543210\",\n autoComplete: \"tel\",\n \"aria-describedby\": \"guardianContact-hint\",\n onInput: (e: Event) => onFieldChange(\"guardianContact\", (e.target as HTMLInputElement).value),\n }) as HTMLInputElement;\n\n const contactHint = el(\"p\", { id: \"guardianContact-hint\", style: hintStyle });\n contactHint.textContent = \"Mobile number linked to guardian's Aadhaar\";\n\n const contactError = el(\"div\", { style: errorStyle, role: \"alert\" });\n const contactGroup = el(\"div\", null, contactLabel, contactInput, contactHint, contactError);\n\n // ─── Relationship dropdown ───\n const relLabel = el(\"label\", { id: \"guardianRelationship-label\", style: labelStyle });\n relLabel.innerHTML = `Relationship <span style=\"color:#DC2626\">*</span>`;\n\n const selectedLabel = RELATIONSHIP_OPTIONS.find((o) => o.value === formData.guardianRelationship)?.label;\n\n const chevronSvg = svg(\n \"svg\",\n {\n width: \"14\", height: \"14\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: \"#667085\", \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"polyline\", { points: \"6 9 12 15 18 9\" })\n );\n (chevronSvg as unknown as HTMLElement).style.cssText = \"flex-shrink:0;margin-left:8px;transition:transform 0.2s\";\n\n const selectedSpan = el(\"span\", {\n style: { overflow: \"hidden\", textOverflow: \"ellipsis\", whiteSpace: \"nowrap\" },\n });\n selectedSpan.textContent = selectedLabel || \"Select relationship\";\n\n const relationshipDisplay = el(\"div\", {\n role: \"combobox\",\n \"aria-expanded\": \"false\",\n \"aria-haspopup\": \"listbox\",\n \"aria-labelledby\": \"guardianRelationship-label\",\n tabIndex: \"0\",\n style: {\n ...inputStyle,\n color: selectedLabel ? textColor : \"#9CA3AF\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n userSelect: \"none\",\n transition: \"border-color 0.15s, box-shadow 0.15s\",\n },\n }, selectedSpan, chevronSvg);\n\n // Dropdown list\n const dropdownList = el(\"div\", {\n id: \"guardianRelationship-listbox\",\n role: \"listbox\",\n \"aria-labelledby\": \"guardianRelationship-label\",\n style: {\n position: \"absolute\",\n top: \"calc(100% + 4px)\",\n left: 0,\n right: 0,\n backgroundColor: bgColor,\n border: `1px solid ${borderColor}`,\n borderRadius: radius,\n boxShadow: \"0 4px 12px rgba(0,0,0,0.1), 0 1px 3px rgba(0,0,0,0.06)\",\n zIndex: 50,\n overflow: \"hidden\",\n padding: \"4px 0\",\n maxHeight: \"220px\",\n overflowY: \"auto\",\n display: \"none\",\n },\n });\n\n for (let i = 0; i < RELATIONSHIP_OPTIONS.length; i++) {\n const option = RELATIONSHIP_OPTIONS[i];\n const isSelected = formData.guardianRelationship === option.value;\n\n const optionEl = el(\"div\", {\n id: `guardianRelationship-option-${i}`,\n role: \"option\",\n \"aria-selected\": String(isSelected),\n style: {\n padding: \"9px 12px\",\n fontSize: \"13px\",\n fontFamily: font,\n color: isSelected ? accentColor : textColor,\n backgroundColor: \"transparent\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n transition: \"background-color 0.1s\",\n },\n onClick: () => {\n onFieldChange(\"guardianRelationship\", option.value);\n selectedSpan.textContent = option.label;\n relationshipDisplay.style.color = textColor;\n doClose();\n },\n onMouseenter: (e: Event) => { (e.target as HTMLElement).style.backgroundColor = \"#F3F4F6\"; },\n onMouseleave: (e: Event) => { (e.target as HTMLElement).style.backgroundColor = \"transparent\"; },\n });\n\n const label = el(\"span\");\n label.textContent = option.label;\n optionEl.appendChild(label);\n\n if (isSelected) {\n const checkSvg = svg(\n \"svg\",\n {\n width: \"14\", height: \"14\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: accentColor, \"stroke-width\": \"2.5\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"polyline\", { points: \"20 6 9 17 4 12\" })\n );\n (checkSvg as unknown as HTMLElement).style.flexShrink = \"0\";\n optionEl.appendChild(checkSvg);\n }\n\n dropdownList.appendChild(optionEl);\n }\n\n let dropdownOpen = false;\n\n const relContainer = el(\"div\", { style: { position: \"relative\" } });\n\n const handleClickOutside = (e: Event) => {\n if (!relContainer.contains(e.target as Node)) {\n doClose();\n }\n };\n\n function doOpen() {\n dropdownOpen = true;\n dropdownList.style.display = \"block\";\n relationshipDisplay.setAttribute(\"aria-expanded\", \"true\");\n (chevronSvg as unknown as HTMLElement).style.transform = \"rotate(180deg)\";\n relationshipDisplay.style.borderColor = accentColor;\n relationshipDisplay.style.boxShadow = `0 0 0 1px ${accentColor}`;\n\n // Determine direction: open upward if not enough space below\n const rect = relContainer.getBoundingClientRect();\n const spaceBelow = window.innerHeight - rect.bottom;\n const dropdownHeight = 220;\n const shouldOpenUpward = spaceBelow < dropdownHeight && rect.top > dropdownHeight;\n\n if (shouldOpenUpward) {\n dropdownList.style.top = \"auto\";\n dropdownList.style.bottom = \"calc(100% + 4px)\";\n dropdownList.style.boxShadow = \"0 -4px 12px rgba(0,0,0,0.1), 0 -1px 3px rgba(0,0,0,0.06)\";\n } else {\n dropdownList.style.top = \"calc(100% + 4px)\";\n dropdownList.style.bottom = \"auto\";\n dropdownList.style.boxShadow = \"0 4px 12px rgba(0,0,0,0.1), 0 1px 3px rgba(0,0,0,0.06)\";\n }\n\n // Scroll the dropdown into view\n requestAnimationFrame(() => {\n dropdownList.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n });\n\n // Listen for clicks outside (next tick so current click doesn't trigger it)\n setTimeout(() => document.addEventListener(\"mousedown\", handleClickOutside), 0);\n }\n\n function doClose() {\n dropdownOpen = false;\n dropdownList.style.display = \"none\";\n relationshipDisplay.setAttribute(\"aria-expanded\", \"false\");\n (chevronSvg as unknown as HTMLElement).style.transform = \"rotate(0deg)\";\n relationshipDisplay.style.borderColor = borderColor;\n relationshipDisplay.style.boxShadow = \"none\";\n document.removeEventListener(\"mousedown\", handleClickOutside);\n }\n\n relationshipDisplay.addEventListener(\"click\", () => {\n dropdownOpen ? doClose() : doOpen();\n });\n\n relationshipDisplay.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \" || e.key === \"ArrowDown\") {\n e.preventDefault();\n if (!dropdownOpen) doOpen();\n } else if (e.key === \"Escape\" || e.key === \"Tab\") {\n doClose();\n }\n });\n\n const relationshipError = el(\"div\", { style: errorStyle, role: \"alert\" });\n\n relContainer.appendChild(relLabel);\n relContainer.appendChild(relationshipDisplay);\n relContainer.appendChild(dropdownList);\n relContainer.appendChild(relationshipError);\n\n // General error\n const generalError = el(\"div\", {\n role: \"alert\",\n style: {\n color: \"#DC2626\",\n fontSize: \"13px\",\n marginTop: \"16px\",\n padding: \"12px\",\n borderRadius: \"6px\",\n border: \"1px solid #FCA5A5\",\n backgroundColor: \"#FEF2F2\",\n textAlign: \"center\",\n display: \"none\",\n },\n });\n\n const fieldsContainer = el(\"div\", {\n style: { display: \"flex\", flexDirection: \"column\", gap: \"14px\" },\n }, nameGroup, contactGroup, relContainer);\n\n const middleSection = el(\"div\", {\n style: { ...styles.middleSection, overflow: \"visible\", color: textColor, fontFamily: font },\n }, subtitle, infoBanner, fieldsContainer, generalError);\n\n // ─── Bottom Section (Verify first, Cancel second — matches React) ───\n const btnBase = {\n ...styles.button,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n const submitBtn = el(\"button\", {\n style: {\n ...btnBase,\n ...styles.acceptButton,\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderRadius: colors.borderRadius,\n },\n type: \"button\",\n disabled: isSubmitting,\n \"aria-label\": isSubmitting ? \"Verifying guardian identity\" : \"Proceed to guardian verification\",\n onClick: onSubmit,\n }) as HTMLButtonElement;\n submitBtn.textContent = isSubmitting ? \"Verifying...\" : \"Verify via DigiLocker\";\n\n const cancelBtn = el(\"button\", {\n style: {\n ...btnBase,\n ...styles.cancelButton,\n backgroundColor: colors.declineBg,\n color: colors.declineText,\n borderColor: colors.declineBorder,\n borderRadius: colors.borderRadius,\n },\n type: \"button\",\n \"aria-label\": \"Cancel\",\n onClick: onCancel,\n });\n cancelBtn.textContent = \"Cancel\";\n\n const bottomSection = el(\"div\", {\n style: { ...styles.bottomSection, paddingTop: \"12px\", color: textColor, fontFamily: font },\n }, submitBtn, cancelBtn);\n\n // ─── Assemble ───\n const container = el(\"div\", { style: { ...styles.content, overflow: \"visible\" } }, topSection, middleSection, bottomSection);\n\n return {\n container,\n nameInput,\n contactInput,\n relationshipDisplay,\n nameError,\n contactError,\n relationshipError,\n submitBtn,\n generalError,\n };\n}\n\nexport function validateGuardianForm(data: GuardianFormData): Record<string, string> {\n const errors: Record<string, string> = {};\n if (!data.guardianName.trim()) errors.guardianName = \"Guardian name is required\";\n if (!data.guardianContact.trim()) errors.guardianContact = \"Guardian contact is required\";\n if (!data.guardianRelationship.trim()) errors.guardianRelationship = \"Relationship to guardian is required\";\n return errors;\n}\n","import { el, svg } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport type { Settings, GuardianVerificationErrorCode } from \"../api/types\";\nimport type { ResolvedColors } from \"./colors\";\n\nexport type VerificationScreenRefs = {\n container: HTMLElement;\n};\n\nexport function getVerificationErrorMessage(\n errorCode: string | null,\n fallbackError: string | null\n): string {\n switch (errorCode) {\n case \"GUARDIAN_UNDER_18\":\n return \"The guardian must be 18 years or older. Please provide details of a different guardian.\";\n case \"TOKEN_FAILED\":\n return \"DigiLocker verification could not be completed. Please try again.\";\n case \"DIGILOCKER_AUTH_FAILED\":\n return \"DigiLocker authorization was cancelled or failed. Please try again.\";\n case \"NO_AUTH_CODE\":\n return \"DigiLocker did not return an authorization code. Please try again.\";\n case \"SESSION_EXPIRED\":\n return \"Verification session has expired. Please try again.\";\n default:\n return fallbackError || \"Verification failed. Please try again.\";\n }\n}\n\nexport function renderVerificationScreen(options: {\n settings?: Partial<Settings>;\n colors: ResolvedColors;\n isMobile: boolean;\n logoUrl: string;\n isInitiating: boolean;\n isPolling: boolean;\n isComplete: boolean;\n isAutoTransitioning?: boolean;\n error: string | null;\n errorCode: string | null;\n canRetry: boolean;\n onContinue: () => void;\n onBack: (clearName?: boolean) => void;\n}): VerificationScreenRefs {\n const {\n settings, colors, isMobile, logoUrl,\n isInitiating, isPolling, isComplete, isAutoTransitioning,\n error, errorCode, canRetry,\n onContinue, onBack,\n } = options;\n\n const headingColor = settings?.headingColor || \"#101828\";\n const textColor = colors.text;\n const font = colors.font;\n const accentColor = colors.acceptBg;\n\n // ─── Top Section ───\n const logo = el(\"img\", { src: logoUrl, style: styles.logo, alt: \"Logo\" });\n const title = el(\"h2\", {\n id: \"verification-title\",\n style: {\n ...styles.title,\n fontSize: \"16px\",\n fontWeight: 600,\n color: headingColor,\n fontFamily: font,\n },\n });\n title.textContent = \"Guardian Verification\";\n\n const topLeft = el(\"div\", { style: styles.topLeft }, logo, title);\n const topSection = el(\"div\", {\n style: { ...styles.topSection, color: textColor, fontFamily: font },\n }, topLeft);\n\n // ─── Middle Section ───\n const middleSection = el(\"div\", {\n style: {\n ...styles.middleSection,\n color: textColor,\n fontFamily: font,\n textAlign: \"center\",\n },\n });\n\n if (isComplete && !error) {\n // Success state: green checkmark circle\n const successCircle = el(\"div\", {\n style: {\n width: \"64px\",\n height: \"64px\",\n borderRadius: \"50%\",\n backgroundColor: \"#D1FAE5\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n });\n const checkSvg = svg(\n \"svg\",\n {\n width: \"32\", height: \"32\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: \"#059669\", \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"polyline\", { points: \"20 6 9 17 4 12\" })\n );\n successCircle.appendChild(checkSvg);\n\n const successText = el(\"p\", {\n style: {\n color: headingColor,\n fontFamily: font,\n fontSize: \"16px\",\n fontWeight: 600,\n lineHeight: \"1.5\",\n marginTop: \"12px\",\n marginBottom: \"24px\",\n },\n });\n successText.textContent = \"Verification Completed\";\n\n const wrapper = el(\"div\", {\n style: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n flex: \"1\",\n },\n }, successCircle, successText);\n middleSection.appendChild(wrapper);\n\n } else if ((isInitiating || isPolling) && !error) {\n // Polling state: spinner + status message\n const spinner = el(\"div\", {\n style: {\n width: \"48px\",\n height: \"48px\",\n border: \"4px solid #e5e7eb\",\n borderTopColor: accentColor,\n borderRadius: \"50%\",\n animation: \"spin 1s linear infinite\",\n margin: \"24px auto\",\n },\n });\n\n const statusMsg = el(\"div\", {\n style: {\n color: \"#059669\",\n fontSize: \"14px\",\n marginTop: \"16px\",\n padding: \"12px\",\n borderRadius: \"6px\",\n border: \"1px solid #A7F3D0\",\n backgroundColor: \"#D1FAE5\",\n textAlign: \"center\",\n },\n });\n statusMsg.textContent = isInitiating\n ? \"Opening DigiLocker in a new tab...\"\n : \"Please complete the verification in the DigiLocker tab. This page will update automatically when verification is complete.\";\n\n middleSection.appendChild(spinner);\n middleSection.appendChild(statusMsg);\n }\n\n if (error) {\n // Error state: red X circle + error text\n const errorCircle = el(\"div\", {\n style: {\n width: \"64px\",\n height: \"64px\",\n borderRadius: \"50%\",\n backgroundColor: \"#fee2e2\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n margin: \"24px auto\",\n },\n });\n const xSvg = svg(\n \"svg\",\n {\n width: \"32\", height: \"32\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: \"#dc2626\", \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n },\n svg(\"line\", { x1: \"18\", y1: \"6\", x2: \"6\", y2: \"18\" }),\n svg(\"line\", { x1: \"6\", y1: \"6\", x2: \"18\", y2: \"18\" })\n );\n errorCircle.appendChild(xSvg);\n\n const failedText = el(\"p\", {\n style: {\n ...styles.privacyText,\n color: textColor,\n fontFamily: font,\n fontSize: \"14px\",\n lineHeight: \"1.5\",\n marginBottom: \"12px\",\n },\n });\n failedText.textContent = \"Verification failed\";\n\n const errorBox = el(\"div\", {\n style: {\n color: \"#DC2626\",\n fontSize: \"14px\",\n marginTop: \"16px\",\n padding: \"12px\",\n borderRadius: \"6px\",\n border: \"1px solid #FCA5A5\",\n backgroundColor: \"#FEF2F2\",\n textAlign: \"center\",\n },\n });\n errorBox.textContent = error;\n\n middleSection.appendChild(errorCircle);\n middleSection.appendChild(failedText);\n middleSection.appendChild(errorBox);\n }\n\n // ─── Bottom Section ───\n const btnBase = {\n ...styles.button,\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: isMobile ? \"10px 20px\" : \"9px 45px\",\n };\n\n const bottomSection = el(\"div\", {\n style: {\n ...styles.bottomSection,\n paddingTop: \"12px\",\n display: \"flex\",\n gap: \"12px\",\n justifyContent: \"center\",\n color: textColor,\n fontFamily: font,\n },\n });\n\n const acceptBtnStyle = {\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderRadius: colors.borderRadius,\n };\n const declineBtnStyle = {\n backgroundColor: colors.declineBg,\n color: colors.declineText,\n borderColor: colors.declineBorder,\n borderRadius: colors.borderRadius,\n };\n\n // Hide bottom section during auto-transition\n if (!isAutoTransitioning) {\n if (isComplete && !error) {\n const continueBtn = el(\"button\", {\n style: { ...btnBase, ...acceptBtnStyle },\n type: \"button\",\n \"aria-label\": \"Continue to consent form\",\n onClick: onContinue,\n });\n continueBtn.textContent = \"Continue\";\n bottomSection.appendChild(continueBtn);\n } else if (error && canRetry) {\n const retryBtn = el(\"button\", {\n style: { ...btnBase, ...styles.acceptButton, ...acceptBtnStyle },\n type: \"button\",\n \"aria-label\": errorCode === \"GUARDIAN_UNDER_18\" ? \"Change guardian details\" : \"Try verification again\",\n onClick: () => onBack(errorCode === \"GUARDIAN_UNDER_18\"),\n });\n retryBtn.textContent = errorCode === \"GUARDIAN_UNDER_18\" ? \"Change Guardian\" : \"Try Again\";\n bottomSection.appendChild(retryBtn);\n } else if (error) {\n const goBackBtn = el(\"button\", {\n style: { ...btnBase, ...styles.cancelButton, ...declineBtnStyle },\n type: \"button\",\n \"aria-label\": \"Go back\",\n onClick: () => onBack(false),\n });\n goBackBtn.textContent = \"Go Back\";\n bottomSection.appendChild(goBackBtn);\n } else {\n // Polling state — show cancel\n const cancelBtn = el(\"button\", {\n style: { ...btnBase, ...styles.cancelButton, ...declineBtnStyle },\n type: \"button\",\n \"aria-label\": \"Cancel verification\",\n onClick: () => onBack(false),\n });\n cancelBtn.textContent = \"Cancel\";\n bottomSection.appendChild(cancelBtn);\n }\n }\n\n // ─── Assemble ───\n const container = el(\"div\", { style: styles.content }, topSection, middleSection, bottomSection);\n\n return { container };\n}\n","import type { ActiveConfig, Settings } from \"../api/types\";\n\nexport type ResolvedColors = {\n acceptBg: string;\n acceptText: string;\n /** The \"accept all\" shortcut. */\n acceptShortcutBg: string;\n acceptShortcutText: string;\n acceptShortcutBorder: string;\n declineBg: string;\n declineText: string;\n declineBorder: string;\n link: string;\n heading: string;\n text: string;\n font: string;\n borderRadius: string;\n primaryColor: string;\n secondaryColor: string;\n};\n\n/**\n * Resolves colors using the React SDK's fallback chain:\n * settings → API active_config → hardcoded default\n */\nexport function resolveColors(\n settings: Partial<Settings> | undefined,\n activeConfig: ActiveConfig | null | undefined\n): ResolvedColors {\n const primaryColor = activeConfig?.primary_color || \"#4f87ff\";\n const secondaryColor = activeConfig?.secondary_color || \"#4f87ff\";\n\n return {\n acceptBg: settings?.button?.accept?.backgroundColor || primaryColor,\n acceptText: settings?.button?.accept?.textColor || \"#ffffff\",\n acceptShortcutBg: settings?.button?.acceptAll?.backgroundColor || \"#ffffff\",\n acceptShortcutText: settings?.button?.acceptAll?.textColor || primaryColor,\n acceptShortcutBorder: primaryColor,\n declineBg: settings?.button?.decline?.backgroundColor || \"#ffffff\",\n declineText: settings?.button?.decline?.textColor || \"#000000\",\n declineBorder: settings?.borderColor || \"#d0d5dd\",\n link: settings?.link || secondaryColor,\n heading: settings?.headingColor || \"#323B4B\",\n text: settings?.textColor || \"#344054\",\n font: settings?.font || \"inherit\",\n borderRadius: settings?.borderRadius || \"8px\",\n primaryColor,\n secondaryColor,\n };\n}\n","import type { NoticeProduct, PurposeSelection } from \"../api/types\";\nimport { CONFIRM_HINT_COPY, PURPOSE_STATUS_ACTIVE } from \"../constants\";\nimport type {\n ConfirmVerdict,\n PurposeRow,\n RecordedLookup,\n ScopedPurpose,\n SelectablePurpose,\n SelectionState,\n SubmissionPurpose,\n} from \"../types\";\nimport {\n gatedProductUuids,\n noticeScopesPurposes,\n productPurposeKey,\n purposeNamesProduct,\n rowProductUuid,\n serverMarksMandatoryProducts,\n} from \"../core/productMatrix\";\nimport {\n dataElementKey,\n hasRequiredDataElement,\n isBlockingRequiredElement,\n} from \"./consentSelection\";\n\nconst rowKey = (row: PurposeRow) =>\n productPurposeKey(row.productUuid, row.purpose.uuid);\n\nexport const recordedSelectionLookup =\n (\n purposeSelections: Record<string, PurposeSelection> | undefined,\n productPurposeSelections:\n | Record<string, Record<string, PurposeSelection>>\n | undefined,\n ): RecordedLookup =>\n (purposeUuid, productUuid) => {\n const perProduct = productUuid\n ? productPurposeSelections?.[productUuid]?.[purposeUuid]\n : undefined;\n return perProduct ?? purposeSelections?.[purposeUuid];\n };\n\nexport const seedSelection = (\n rows: ReadonlyArray<PurposeRow>,\n recordedFor: RecordedLookup,\n): SelectionState => {\n const selectedPurposes: Record<string, boolean> = {};\n const selectedDataElements: Record<string, boolean> = {};\n\n rows.forEach((row) => {\n const recorded = recordedFor(row.purpose.uuid, row.productUuid);\n selectedPurposes[rowKey(row)] = recorded ? recorded.selected : false;\n row.purpose.data_elements.forEach((element) => {\n selectedDataElements[\n dataElementKey(row.purpose.uuid, element.uuid, row.productUuid)\n ] = recorded?.data_elements?.[element.uuid]?.selected ?? false;\n });\n });\n\n return { selectedPurposes, selectedDataElements };\n};\n\nexport const collapseEveryRow = (\n rows: ReadonlyArray<PurposeRow>,\n): Record<string, boolean> =>\n rows.reduce((acc: Record<string, boolean>, row) => {\n acc[rowKey(row)] = true;\n return acc;\n }, {});\n\nexport const initialCollapsedProducts = (\n groups: ReadonlyArray<{ product: { uuid: string } }>,\n defaultOpenProducts?: ReadonlyArray<string>,\n): Record<string, boolean> => {\n const openByDefault = new Set(defaultOpenProducts ?? []);\n const soleSection = groups.length === 1;\n return groups.reduce((acc: Record<string, boolean>, group) => {\n acc[group.product.uuid] =\n !soleSection && !openByDefault.has(group.product.uuid);\n return acc;\n }, {});\n};\n\nexport const recordedBaseline = (\n rows: ReadonlyArray<PurposeRow>,\n recordedFor: RecordedLookup,\n): Record<string, boolean> =>\n rows.reduce((acc: Record<string, boolean>, row) => {\n const recorded = recordedFor(row.purpose.uuid, row.productUuid);\n acc[rowKey(row)] =\n recorded?.selected === true &&\n (!recorded.status || recorded.status === PURPOSE_STATUS_ACTIVE) &&\n recorded.needs_reconsent !== true;\n return acc;\n }, {});\n\nexport const settleProducts = (\n rows: ReadonlyArray<PurposeRow>,\n products: ReadonlyArray<NoticeProduct> | undefined,\n recordedFor: RecordedLookup,\n): {\n consentedProducts: Record<string, boolean>;\n consentedPurposes: Record<string, boolean>;\n} => {\n const productList = products ? [...products] : undefined;\n const isSettled = (row: PurposeRow) => {\n const recorded = recordedFor(row.purpose.uuid, row.productUuid);\n return recorded?.selected === true && recorded.needs_reconsent !== true;\n };\n\n const consentedPurposes: Record<string, boolean> = {};\n const rowsByProduct = new Map<string, PurposeRow[]>();\n rows.forEach((row) => {\n const resolved = rowProductUuid(row, productList);\n if (!resolved) return;\n consentedPurposes[rowKey(row)] = isSettled(row);\n const group = rowsByProduct.get(resolved) ?? [];\n group.push(row);\n rowsByProduct.set(resolved, group);\n });\n\n const consentedProducts: Record<string, boolean> = {};\n rowsByProduct.forEach((group, productUuid) => {\n const mandatory = group.filter((row) => hasRequiredDataElement(row.purpose));\n const deciding = mandatory.length > 0 ? mandatory : group;\n consentedProducts[productUuid] = deciding.every(isSettled);\n });\n\n return { consentedProducts, consentedPurposes };\n};\n\nexport const isFullyConsented = (\n rows: ReadonlyArray<PurposeRow>,\n recordedFor: RecordedLookup,\n): boolean =>\n rows.every((row) => {\n const recorded = recordedFor(row.purpose.uuid, row.productUuid);\n return Boolean(recorded?.selected && !recorded?.needs_reconsent);\n });\n\nexport const productBoxPurposes = <P extends SelectablePurpose>(\n purposes: ReadonlyArray<P>,\n): P[] => {\n const required = purposes.filter(hasRequiredDataElement);\n return required.length > 0 ? required : [...purposes];\n};\n\nexport const purposeToggle = (\n purpose: SelectablePurpose,\n productUuid: string | undefined,\n selectedPurposes: Record<string, boolean>,\n): SelectionState => {\n const key = productPurposeKey(productUuid, purpose.uuid);\n const nextState = !selectedPurposes[key];\n const selectedDataElements: Record<string, boolean> = {};\n purpose.data_elements.forEach((element) => {\n selectedDataElements[`${key}-${element.uuid}`] = element.enabled\n ? nextState\n : false;\n });\n return { selectedPurposes: { [key]: nextState }, selectedDataElements };\n};\n\nexport const sectionToggle = (\n sectionPurposes: ReadonlyArray<SelectablePurpose>,\n keyProductUuid: string | undefined,\n selectedPurposes: Record<string, boolean>,\n next?: boolean,\n): SelectionState => {\n const nextState =\n next ??\n !sectionPurposes.every(\n (purpose) => selectedPurposes[productPurposeKey(keyProductUuid, purpose.uuid)],\n );\n const purposeOverrides: Record<string, boolean> = {};\n const elementOverrides: Record<string, boolean> = {};\n sectionPurposes.forEach((purpose) => {\n const key = productPurposeKey(keyProductUuid, purpose.uuid);\n purposeOverrides[key] = nextState;\n purpose.data_elements.forEach((element) => {\n elementOverrides[`${key}-${element.uuid}`] = element.enabled\n ? nextState\n : false;\n });\n });\n return {\n selectedPurposes: purposeOverrides,\n selectedDataElements: elementOverrides,\n };\n};\n\nexport const purposeCheckedFromElements = (\n purpose: SelectablePurpose,\n productUuid: string | undefined,\n selectedDataElements: Record<string, boolean>,\n): boolean => {\n const key = productPurposeKey(productUuid, purpose.uuid);\n const requiredElements = purpose.data_elements.filter(isBlockingRequiredElement);\n return requiredElements.length > 0\n ? requiredElements.every((element) => selectedDataElements[`${key}-${element.uuid}`])\n : purpose.data_elements.some((element) => selectedDataElements[`${key}-${element.uuid}`]);\n};\n\nexport const confirmVerdict = ({\n products,\n purposes,\n rows,\n selectedPurposes,\n recordedPurposeSelections,\n}: {\n products: ReadonlyArray<NoticeProduct> | undefined;\n purposes: ReadonlyArray<ScopedPurpose>;\n rows: ReadonlyArray<PurposeRow>;\n selectedPurposes: Record<string, boolean>;\n recordedPurposeSelections: Record<string, boolean>;\n}): ConfirmVerdict => {\n if (rows.length === 0) return { ok: true, reason: \"ok\", blocking: [] };\n\n const productList = products ? [...products] : undefined;\n const isSelected = (row: PurposeRow) => Boolean(selectedPurposes[rowKey(row)]);\n const wasRecorded = (row: PurposeRow) =>\n Boolean(recordedPurposeSelections[rowKey(row)]);\n const isMandatory = (row: PurposeRow) => hasRequiredDataElement(row.purpose);\n const satisfies = (group: ReadonlyArray<PurposeRow>) =>\n group.filter(isMandatory).every(isSelected);\n const touched = (group: ReadonlyArray<PurposeRow>) =>\n group.some(isSelected) &&\n group.some((row) => isSelected(row) !== wasRecorded(row));\n\n const rowsByProduct = new Map<string, PurposeRow[]>();\n const unresolved: PurposeRow[] = [];\n rows.forEach((row) => {\n const productUuid = rowProductUuid(row, productList);\n if (productUuid === undefined) {\n unresolved.push(row);\n return;\n }\n const group = rowsByProduct.get(productUuid);\n if (group) {\n group.push(row);\n } else {\n rowsByProduct.set(productUuid, [row]);\n }\n });\n\n if (!serverMarksMandatoryProducts(productList)) {\n const groups = [...rowsByProduct.values()];\n if (unresolved.length > 0) groups.push(unresolved);\n const everyProductHasMandatory = groups.every((group) => group.some(isMandatory));\n const baseline = everyProductHasMandatory ? groups.some(satisfies) : satisfies(rows);\n const blocking = [...rowsByProduct.entries()]\n .filter(([, group]) => touched(group) && !satisfies(group))\n .map(([productUuid]) => productUuid);\n const ok = baseline && blocking.length === 0;\n return {\n ok,\n reason: ok\n ? \"ok\"\n : blocking.length > 0\n ? \"product-incomplete\"\n : \"required-outstanding\",\n blocking,\n };\n }\n\n if (unresolved.length > 0 && rowsByProduct.size === 0) {\n const ok = satisfies(unresolved);\n return { ok, reason: ok ? \"ok\" : \"required-outstanding\", blocking: [] };\n }\n\n const gated = gatedProductUuids(productList);\n const scoped = noticeScopesPurposes([...purposes]);\n const engagingRows = (group: PurposeRow[], productUuid: string) =>\n scoped\n ? group.filter((row) => purposeNamesProduct(row.purpose, productUuid))\n : group;\n\n const engaged: string[] = [];\n rowsByProduct.forEach((group, productUuid) => {\n if (gated.has(productUuid)) {\n engaged.push(productUuid);\n return;\n }\n if (touched(engagingRows(group, productUuid))) engaged.push(productUuid);\n });\n\n if (engaged.length === 0) {\n return {\n ok: false,\n reason: rows.some(isSelected) ? \"nothing-engaged\" : \"nothing-chosen\",\n blocking: [],\n };\n }\n\n const blocking = engaged.filter(\n (productUuid) => !satisfies(rowsByProduct.get(productUuid) ?? []),\n );\n\n return {\n ok: blocking.length === 0,\n reason: blocking.length === 0 ? \"ok\" : \"product-incomplete\",\n blocking,\n };\n};\n\nexport const confirmHint = (\n verdict: ConfirmVerdict,\n products: ReadonlyArray<NoticeProduct> | undefined,\n productName: (product: NoticeProduct) => string,\n): string | null => {\n if (verdict.ok || verdict.reason === \"ok\") return null;\n if (verdict.reason !== \"product-incomplete\") {\n return CONFIRM_HINT_COPY[verdict.reason];\n }\n const byUuid = new Map((products ?? []).map((product) => [product.uuid, product]));\n const names = verdict.blocking.map((uuid) => {\n const product = byUuid.get(uuid);\n return product ? productName(product) : uuid;\n });\n return CONFIRM_HINT_COPY.productsIncomplete(names);\n};\n\nexport const submissionPurposes = <P extends ScopedPurpose>(\n rows: ReadonlyArray<PurposeRow<P>>,\n selection: SelectionState,\n): SubmissionPurpose<P>[] =>\n rows.map(({ purpose, productUuid }) => {\n const key = productPurposeKey(productUuid, purpose.uuid);\n return {\n ...purpose,\n ...(productUuid ? { product_uuid: productUuid } : {}),\n selected: selection.selectedPurposes[key] || false,\n data_elements: purpose.data_elements.map((element) => ({\n ...element,\n selected: selection.selectedDataElements[`${key}-${element.uuid}`] || false,\n })),\n };\n });\n","import type { NoticeProduct } from \"../api/types\";\nimport type {\n ConfirmVerdict,\n ProductConfig,\n ProductSeed,\n ProductSeedInput,\n PurposeRow,\n ScopedPurpose,\n} from \"../types\";\nimport {\n gatedProductUuids,\n groupPurposesByProduct,\n isMultiProduct,\n noticePurposeRows,\n serverMarksMandatoryProducts,\n} from \"../core/productMatrix\";\nimport {\n collapseEveryRow,\n confirmVerdict,\n initialCollapsedProducts,\n isFullyConsented,\n recordedBaseline,\n recordedSelectionLookup,\n seedSelection,\n settleProducts,\n} from \"./productConsent\";\n\nexport const rowsOf = <P extends ScopedPurpose>(\n config: ProductConfig & { purposes: P[] },\n): PurposeRow<P>[] =>\n noticePurposeRows(config.products, config.purposes, config.product_purpose_order);\n\nexport const groupsOf = <P extends ScopedPurpose>(\n config: ProductConfig & { purposes: P[] },\n) => groupPurposesByProduct(config.products, config.purposes, config.product_purpose_order);\n\nexport const seedProductState = <P extends ScopedPurpose>({\n config,\n purposeSelections,\n productPurposeSelections,\n defaultOpenProducts,\n includeFullyConsentedData,\n}: ProductSeedInput<P>): ProductSeed<P> => {\n const rows = rowsOf(config);\n const recordedFor = recordedSelectionLookup(purposeSelections, productPurposeSelections);\n const hasRecord = Boolean(purposeSelections || productPurposeSelections);\n const settled = hasRecord\n ? settleProducts(rows, config.products, recordedFor)\n : { consentedProducts: {}, consentedPurposes: {} };\n\n const seed: ProductSeed<P> = {\n collapsedProducts: initialCollapsedProducts(groupsOf(config), defaultOpenProducts),\n recordedPurposeSelections: recordedBaseline(rows, recordedFor),\n consentedProducts: settled.consentedProducts,\n consentedPurposes: settled.consentedPurposes,\n };\n if (!isMultiProduct(config.products)) return seed;\n\n const seeded = seedSelection(rows, recordedFor);\n return {\n ...seed,\n collapsedPurposes: collapseEveryRow(rows),\n selectedPurposes: seeded.selectedPurposes,\n selectedDataElements: seeded.selectedDataElements,\n initialDataElementSelections: seeded.selectedDataElements,\n needsConsentPurposes: config.purposes,\n alreadyConsentedPurposes: [],\n isFullyConsentedReviewMode: Boolean(\n includeFullyConsentedData &&\n hasRecord &&\n rows.length > 0 &&\n isFullyConsented(rows, recordedFor),\n ),\n };\n};\n\nexport const productIsRequired = (\n products: ReadonlyArray<NoticeProduct> | undefined,\n productUuid: string,\n): boolean | undefined => {\n const list = products ? [...products] : undefined;\n if (!serverMarksMandatoryProducts(list)) return undefined;\n return gatedProductUuids(list).has(productUuid);\n};\n\nexport const noticeConfirmVerdict = <P extends ScopedPurpose>(\n config: ProductConfig & { purposes: P[] },\n selectedPurposes: Record<string, boolean>,\n recordedPurposeSelections: Record<string, boolean>,\n): ConfirmVerdict =>\n confirmVerdict({\n products: config.products,\n purposes: config.purposes,\n rows: rowsOf(config),\n selectedPurposes,\n recordedPurposeSelections,\n });\n","import { el, svg } from \"../core/dom\";\nimport { createRequiredMarker } from \"../core/required-marker\";\nimport { productPurposeKey } from \"../core/productMatrix\";\nimport {\n CONFIRM_HINT_ID,\n DEFAULT_SELECTION_CONTROL,\n PRODUCT_SECTION_COPY,\n} from \"../constants\";\nimport { styles } from \"../styles/modal\";\nimport type {\n ProductGroupsOptions,\n ProductSectionOptions,\n ProductSectionRefs,\n SelectablePurpose,\n} from \"../types\";\nimport { renderModalPurposes, type ModalPurposeRefs } from \"./purposes\";\nimport { renderSelectionControl } from \"./selection-control\";\nimport { productBoxPurposes } from \"./productConsent\";\nimport { productIsRequired } from \"./productState\";\n\nconst CHEVRON_OPEN = \"rotate(90deg)\";\nconst CHEVRON_CLOSED = \"rotate(0deg)\";\n\nconst sectionTally = (\n boxPurposes: ReadonlyArray<SelectablePurpose>,\n keyProductUuid: string | undefined,\n selectedPurposes: Record<string, boolean>\n) => {\n const selectedCount = boxPurposes.filter(\n (purpose) => selectedPurposes[productPurposeKey(keyProductUuid, purpose.uuid)]\n ).length;\n return {\n allSelected: boxPurposes.length > 0 && selectedCount === boxPurposes.length,\n someSelected: selectedCount > 0,\n };\n};\n\nexport function renderProductSection(options: ProductSectionOptions): ProductSectionRefs {\n const {\n product,\n purposes,\n keyProductUuid,\n selectedPurposes,\n collapsed,\n locked,\n isRequired,\n settings,\n isMobile,\n getTranslatedText,\n onToggleCollapse,\n onToggleSelect,\n } = options;\n\n const name = getTranslatedText(\"products.name\", product.name, product.uuid);\n const headingColor = settings?.headingColor || \"#323B4B\";\n const boxPurposes = productBoxPurposes(purposes);\n\n const chevron = svg(\n \"svg\",\n {\n width: \"7\",\n height: \"12\",\n viewBox: \"0 0 7 12\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n stroke: headingColor,\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n style: {\n transform: collapsed ? CHEVRON_CLOSED : CHEVRON_OPEN,\n transition: \"transform 0.3s ease\",\n },\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", { d: \"M1 1L6 6L1 11\" })\n );\n\n const collapseButton = el(\n \"button\",\n {\n type: \"button\",\n style: styles.chevronButton,\n \"aria-expanded\": String(!collapsed),\n \"aria-controls\": `product-${product.uuid}`,\n \"aria-labelledby\": `product-name-${product.uuid}`,\n onClick: () => onToggleCollapse(product.uuid),\n },\n el(\n \"div\",\n { style: { display: \"flex\", alignItems: \"center\", justifyContent: \"center\", marginLeft: \"5px\" } },\n chevron\n )\n );\n\n const title = el(\"h2\", {\n id: `product-name-${product.uuid}`,\n style: {\n ...styles.sectionTitle,\n fontSize: isMobile ? \"14px\" : \"16px\",\n color: headingColor,\n fontFamily: settings?.font || \"inherit\",\n },\n });\n title.textContent = name;\n if (isRequired) {\n title.appendChild(createRequiredMarker());\n }\n\n const tally = sectionTally(boxPurposes, keyProductUuid, selectedPurposes);\n const selection = renderSelectionControl({\n control: settings?.selectionControl ?? DEFAULT_SELECTION_CONTROL,\n checked: tally.allSelected,\n indeterminate: tally.someSelected && !tally.allSelected,\n onSelect: (next) => onToggleSelect(product.uuid, next),\n label:\n boxPurposes.length < purposes.length\n ? PRODUCT_SECTION_COPY.toggleRequired(name, boxPurposes.length)\n : PRODUCT_SECTION_COPY.toggleSelection(name, boxPurposes.length),\n groupName: `redacto-product-${product.uuid}`,\n size: \"large\",\n locked,\n lockedLabel: PRODUCT_SECTION_COPY.settled(name),\n });\n const control = selection.element;\n\n const header = el(\n \"div\",\n { style: styles.sectionHeader },\n el(\n \"div\",\n { style: styles.optionLeft },\n collapseButton,\n el(\"div\", { style: styles.optionTextContainer }, title)\n ),\n control\n );\n\n const body = el(\"div\", { id: `product-${product.uuid}`, style: styles.sectionBody });\n body.hidden = collapsed;\n\n return {\n productUuid: product.uuid,\n keyProductUuid,\n boxPurposes,\n container: el(\"div\", null, header, body),\n body,\n collapseButton,\n chevron,\n control: locked ? null : selection,\n };\n}\n\nexport function renderProductGroups(options: ProductGroupsOptions): {\n container: HTMLElement;\n purposeRefs: ModalPurposeRefs;\n sections: ProductSectionRefs[];\n} {\n const container = el(\"div\", { style: styles.optionsContainer });\n const sections: ProductSectionRefs[] = [];\n const parts: ModalPurposeRefs[] = [];\n\n for (const group of options.groups) {\n const productUuid = group.product.uuid;\n const section = renderProductSection({\n product: group.product,\n purposes: group.purposes,\n keyProductUuid: productUuid,\n selectedPurposes: options.selectedPurposes,\n collapsed: options.collapsedProducts[productUuid] || false,\n locked: options.consentedProducts[productUuid] ?? false,\n isRequired: productIsRequired(options.products, productUuid),\n settings: options.settings,\n isMobile: options.isMobile,\n getTranslatedText: options.getTranslatedText,\n onToggleCollapse: options.onToggleCollapse,\n onToggleSelect: options.onToggleSelect,\n });\n const rows = renderModalPurposes(group.purposes, {\n selectedPurposes: options.selectedPurposes,\n collapsedPurposes: options.collapsedPurposes,\n selectedDataElements: options.selectedDataElements,\n initialDataElementSelections: options.initialDataElementSelections,\n recordedAnswers: options.recordedAnswers,\n settings: options.settings,\n isMobile: options.isMobile,\n isAlreadyConsented: false,\n productUuid,\n isRowLocked: (purposeUuid) =>\n options.consentedPurposes[productPurposeKey(productUuid, purposeUuid)] ?? false,\n getTranslatedText: options.getTranslatedText,\n onPurposeToggle: options.onPurposeToggle,\n onPurposeCollapse: options.onPurposeCollapse,\n onDataElementToggle: options.onDataElementToggle,\n });\n section.body.appendChild(rows.container);\n container.appendChild(section.container);\n sections.push(section);\n parts.push(rows);\n }\n\n return { container, purposeRefs: mergePurposeRefs(container, parts), sections };\n}\n\nexport function updateProductSection(\n refs: ProductSectionRefs,\n selectedPurposes: Record<string, boolean>,\n collapsed: boolean\n): void {\n if (refs.control) {\n const tally = sectionTally(refs.boxPurposes, refs.keyProductUuid, selectedPurposes);\n refs.control.setChecked(tally.allSelected, tally.someSelected && !tally.allSelected);\n }\n refs.body.hidden = collapsed;\n refs.collapseButton.setAttribute(\"aria-expanded\", String(!collapsed));\n (refs.chevron as unknown as HTMLElement).style.transform = collapsed\n ? CHEVRON_CLOSED\n : CHEVRON_OPEN;\n}\n\nexport function mergePurposeRefs(\n container: HTMLElement,\n parts: ReadonlyArray<ModalPurposeRefs>\n): ModalPurposeRefs {\n const merge = <V>(pick: (refs: ModalPurposeRefs) => Map<string, V>) =>\n new Map<string, V>(parts.flatMap((refs) => [...pick(refs)]));\n return {\n container,\n checkboxes: merge((refs) => refs.checkboxes),\n purposeControls: merge((refs) => refs.purposeControls),\n collapseButtons: merge((refs) => refs.collapseButtons),\n dataElementContainers: merge((refs) => refs.dataElementContainers),\n chevrons: merge((refs) => refs.chevrons),\n titleElements: merge((refs) => refs.titleElements),\n descriptionElements: merge((refs) => refs.descriptionElements),\n dataElementLabels: merge((refs) => refs.dataElementLabels),\n };\n}\n\nexport function renderConfirmHint(): HTMLElement {\n return el(\"p\", { id: CONFIRM_HINT_ID, role: \"status\", style: styles.confirmHint });\n}\n\nexport function updateConfirmHint(\n hintEl: HTMLElement,\n anchor: HTMLElement,\n describedButton: HTMLElement | null,\n text: string | null\n): void {\n if (!text) {\n hintEl.remove();\n describedButton?.removeAttribute(\"aria-describedby\");\n return;\n }\n hintEl.textContent = text;\n if (hintEl.nextSibling !== anchor) {\n anchor.parentNode?.insertBefore(hintEl, anchor);\n }\n describedButton?.setAttribute(\"aria-describedby\", CONFIRM_HINT_ID);\n}\n","import type { LogoPosition } from \"../api/types\";\nimport { DEFAULT_LOGO_POSITION, LOGO_POSITION_JUSTIFY } from \"../constants\";\n\n/**\n * Resolves `active_config.logo_position` onto a position the header can lay out.\n *\n * The field is absent on notices published before it existed and on responses\n * from an older consent-server, so an unrecognised value is not an error — it\n * simply means \"the customer never chose\", which is the left-aligned default.\n *\n * Sibling of `resolveColors` in ./colors.ts: same config-then-default shape,\n * kept deliberately parallel with the React package's layout.ts.\n */\nexport function resolveLogoPosition(raw: string | undefined | null): LogoPosition {\n return raw === \"center\" || raw === \"right\" ? raw : DEFAULT_LOGO_POSITION;\n}\n\nexport function logoRowJustify(position: LogoPosition): string {\n return LOGO_POSITION_JUSTIFY[position];\n}\n","import { OTP_GATE_COPY, OTP_GATE_LENGTH } from \"../constants\";\nimport type {\n AcceptMode,\n OtpEntry,\n OtpGateOptions,\n OtpGateView,\n OtpVerifyResult,\n} from \"../types\";\n\nexport const shouldHoldForOtp = (\n gate: { required: boolean } | undefined,\n verified: boolean\n): boolean => Boolean(gate?.required) && !verified;\n\nexport const emptyOtpDigits = (length: number = OTP_GATE_LENGTH): string[] =>\n Array.from({ length }, () => \"\");\n\nexport const otpCodeOf = (digits: string[]): string => digits.join(\"\");\n\nexport const isOtpComplete = (digits: string[]): boolean =>\n digits.length > 0 && digits.every((digit) => /^[0-9]$/.test(digit));\n\nconst onlyDigits = (value: string): string => value.replace(/[^0-9]/g, \"\");\n\nconst withDigit = (digits: string[], index: number, digit: string): string[] =>\n digits.map((current, i) => (i === index ? digit : current));\n\nconst fillFromStart = (code: string, length: number): string[] =>\n Array.from({ length }, (_, i) => code[i] ?? \"\");\n\nconst typedOver = (text: string, previous: string): string => {\n if (!previous || text.length !== previous.length + 1) {\n return text;\n }\n if (text.startsWith(previous)) {\n return text.slice(previous.length);\n }\n if (text.endsWith(previous)) {\n return text.slice(0, text.length - previous.length);\n }\n return text;\n};\n\nconst withoutPrevious = (\n code: string,\n previous: string,\n length: number\n): string => {\n if (!previous || code.length <= length) {\n return code;\n }\n if (code.startsWith(previous)) {\n return code.slice(previous.length);\n }\n if (code.endsWith(previous)) {\n return code.slice(0, code.length - previous.length);\n }\n return code;\n};\n\nexport const applyOtpText = (\n digits: string[],\n index: number,\n text: string\n): OtpEntry | null => {\n const length = digits.length;\n const previous = digits[index] ?? \"\";\n\n if (text === \"\") {\n return { digits: withDigit(digits, index, \"\"), focus: null };\n }\n\n const typed = onlyDigits(typedOver(text, previous));\n if (!typed) {\n return null;\n }\n\n if (typed.length === 1) {\n return {\n digits: withDigit(digits, index, typed),\n focus: index + 1 < length ? index + 1 : null,\n };\n }\n\n const code = withoutPrevious(typed, previous, length).slice(0, length);\n return {\n digits: fillFromStart(code, length),\n focus: Math.min(code.length, length - 1),\n };\n};\n\nexport const applyOtpBackspace = (\n digits: string[],\n index: number\n): OtpEntry => {\n if (digits[index]) {\n return { digits: withDigit(digits, index, \"\"), focus: null };\n }\n if (index <= 0) {\n return { digits, focus: null };\n }\n return { digits: withDigit(digits, index - 1, \"\"), focus: index - 1 };\n};\n\nconst settleVerify = async (\n gate: OtpGateOptions,\n code: string\n): Promise<OtpVerifyResult> => {\n try {\n const result = await gate.onVerify(code);\n return result && result.ok ? result : { ok: false, message: result?.message };\n } catch {\n return { ok: false };\n }\n};\n\nexport class OtpGateSession {\n private verified = false;\n private pendingMode: AcceptMode | null = null;\n private acceptAfterToken: AcceptMode | null = null;\n private tokenAtVerify: string | undefined = undefined;\n private current: OtpGateView = {\n digits: emptyOtpDigits(),\n busy: false,\n error: null,\n };\n\n get isLocked(): boolean {\n return this.pendingMode !== null;\n }\n\n get view(): OtpGateView {\n return this.current;\n }\n\n hold(gate: OtpGateOptions | undefined, mode: AcceptMode): boolean {\n if (shouldHoldForOtp(gate, this.verified)) {\n this.pendingMode = mode;\n this.current = { ...this.current, error: null };\n return true;\n }\n this.acceptAfterToken = null;\n return false;\n }\n\n setDigits(digits: string[]): void {\n this.current = { ...this.current, digits };\n }\n\n async verify(\n gate: OtpGateOptions | undefined,\n token: string | undefined,\n onBusy: () => void\n ): Promise<boolean> {\n if (\n !gate ||\n this.pendingMode === null ||\n this.current.busy ||\n !isOtpComplete(this.current.digits)\n ) {\n return false;\n }\n\n this.current = { ...this.current, busy: true, error: null };\n onBusy();\n\n const result = await settleVerify(gate, otpCodeOf(this.current.digits));\n\n if (!result.ok) {\n this.current = {\n digits: emptyOtpDigits(),\n busy: false,\n error: result.message ?? OTP_GATE_COPY.failed,\n };\n return false;\n }\n\n const mode = this.pendingMode ?? \"selected\";\n this.verified = true;\n this.pendingMode = null;\n this.current = { digits: emptyOtpDigits(), busy: false, error: null };\n this.tokenAtVerify = token;\n this.acceptAfterToken = mode;\n return true;\n }\n\n dropStashedAccept(): void {\n this.acceptAfterToken = null;\n }\n\n takeStashedAccept(token: string | undefined): AcceptMode | null {\n if (this.acceptAfterToken === null || token === this.tokenAtVerify) {\n return null;\n }\n const mode = this.acceptAfterToken;\n this.acceptAfterToken = null;\n return mode;\n }\n}\n","import { el } from \"../core/dom\";\nimport { OTP_GATE_COPY, OTP_GATE_TITLE_ID } from \"../constants\";\nimport type {\n OtpEntry,\n OtpGatePanelOptions,\n OtpGatePanelRefs,\n OtpGateView,\n} from \"../types\";\nimport { applyOtpBackspace, applyOtpText, isOtpComplete } from \"./otpGate\";\n\nconst panelStyle = {\n margin: \"8px 0 4px\",\n padding: \"12px\",\n border: \"1px solid #e5e7eb\",\n borderRadius: \"8px\",\n background: \"#f9fafb\",\n};\n\nconst titleStyle = {\n margin: \"0\",\n fontSize: \"13px\",\n fontWeight: \"600\",\n color: \"#111827\",\n};\n\nconst descriptionStyle = {\n margin: \"4px 0 10px\",\n fontSize: \"12px\",\n lineHeight: \"1.4\",\n color: \"#6b7280\",\n};\n\nconst digitsStyle = {\n display: \"flex\",\n gap: \"8px\",\n justifyContent: \"space-between\",\n};\n\nconst digitStyle = {\n width: \"100%\",\n minWidth: \"0\",\n boxSizing: \"border-box\",\n padding: \"10px 0\",\n fontSize: \"18px\",\n fontWeight: \"600\",\n textAlign: \"center\",\n border: \"1px solid #d1d5db\",\n borderRadius: \"8px\",\n background: \"#ffffff\",\n};\n\nconst errorStyle = {\n margin: \"8px 0 0\",\n fontSize: \"12px\",\n color: \"#dc2626\",\n};\n\nconst buttonStyle = {\n width: \"100%\",\n marginTop: \"10px\",\n borderRadius: \"8px\",\n padding: \"9px 20px\",\n fontSize: \"14px\",\n lineHeight: \"150%\",\n border: \"none\",\n backgroundColor: \"#4f87ff\",\n color: \"#ffffff\",\n cursor: \"pointer\",\n boxSizing: \"border-box\",\n};\n\nexport function renderOtpGatePanel(\n options: OtpGatePanelOptions\n): OtpGatePanelRefs {\n let view: OtpGateView = options.view;\n const inputs: HTMLInputElement[] = [];\n\n const errorEl = el(\"p\", {\n role: \"alert\",\n style: { ...errorStyle, display: \"none\" },\n });\n\n const confirmButton = el(\"button\", {\n type: \"button\",\n style: { ...buttonStyle, ...options.buttonStyle },\n onClick: () => {\n if (view.busy || !isOtpComplete(view.digits)) return;\n options.onConfirm();\n },\n }) as HTMLButtonElement;\n\n const paint = () => {\n inputs.forEach((input, index) => {\n input.value = view.digits[index] ?? \"\";\n input.disabled = view.busy;\n });\n const blocked = view.busy || !isOtpComplete(view.digits);\n confirmButton.disabled = blocked;\n confirmButton.style.opacity = blocked ? \"0.5\" : \"1\";\n confirmButton.style.cursor = blocked ? \"not-allowed\" : \"pointer\";\n confirmButton.textContent = view.busy\n ? OTP_GATE_COPY.verifying\n : options.submitLabel;\n errorEl.textContent = view.error ?? \"\";\n errorEl.style.display = view.error ? \"block\" : \"none\";\n };\n\n const focusDigit = (index: number) => {\n inputs[index]?.focus();\n };\n\n const applyEntry = (entry: OtpEntry | null) => {\n if (!entry) {\n paint();\n return;\n }\n view = { ...view, digits: entry.digits };\n paint();\n options.onDigitsChange(entry.digits);\n if (entry.focus !== null) focusDigit(entry.focus);\n };\n\n const digitRow = el(\"div\", { style: digitsStyle });\n view.digits.forEach((_, index) => {\n const input = el(\"input\", {\n id: `notice-otp-digit-${index}`,\n type: \"text\",\n inputmode: \"numeric\",\n autocomplete: index === 0 ? \"one-time-code\" : \"off\",\n \"aria-label\": `Digit ${index + 1}`,\n style: digitStyle,\n onFocus: () => input.select(),\n onInput: () => applyEntry(applyOtpText(view.digits, index, input.value)),\n onKeydown: (event: KeyboardEvent) => {\n if (event.key !== \"Backspace\") return;\n event.preventDefault();\n applyEntry(applyOtpBackspace(view.digits, index));\n },\n onPaste: (event: ClipboardEvent) => {\n event.preventDefault();\n const text = event.clipboardData?.getData(\"text\") ?? \"\";\n applyEntry(applyOtpText(view.digits, index, text));\n },\n }) as HTMLInputElement;\n inputs.push(input);\n digitRow.appendChild(input);\n });\n\n const container = el(\n \"div\",\n {\n role: \"group\",\n \"aria-labelledby\": OTP_GATE_TITLE_ID,\n style: panelStyle,\n },\n el(\"h3\", { id: OTP_GATE_TITLE_ID, style: titleStyle }, options.title),\n el(\"p\", { style: descriptionStyle }, options.description),\n digitRow,\n errorEl,\n confirmButton\n );\n\n paint();\n\n return {\n container,\n render: (next: OtpGateView) => {\n view = next;\n paint();\n },\n focusDigit,\n };\n}\n\nexport function lockSelections(container: HTMLElement): void {\n container.setAttribute(\"inert\", \"\");\n container.setAttribute(\"aria-disabled\", \"true\");\n container.style.pointerEvents = \"none\";\n container.style.opacity = \"0.55\";\n container\n .querySelectorAll<HTMLInputElement | HTMLSelectElement | HTMLButtonElement>(\n \"input, select, button\"\n )\n .forEach((control) => {\n control.disabled = true;\n });\n container\n .querySelectorAll<HTMLElement>('[role=\"button\"]')\n .forEach((button) => {\n button.setAttribute(\"tabindex\", \"-1\");\n button.setAttribute(\"aria-disabled\", \"true\");\n });\n}\n","import { el } from \"../core/dom\";\nimport {\n CONFIRM_DIALOG_COPY,\n CONFIRM_DIALOG_DETAIL_ID,\n CONFIRM_DIALOG_ID,\n NOTICE_FONT_ROOT_ATTRIBUTE,\n} from \"../constants\";\nimport type { ConfirmDialogOptions, ConfirmDialogRefs } from \"../types\";\n\nconst overlayStyle = {\n position: \"fixed\",\n inset: \"0\",\n top: \"0\",\n left: \"0\",\n right: \"0\",\n bottom: \"0\",\n backgroundColor: \"rgba(16, 24, 40, 0.45)\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"24px\",\n zIndex: \"2147483647\",\n};\n\nconst panelStyle = {\n backgroundColor: \"#ffffff\",\n borderRadius: \"12px\",\n padding: \"24px\",\n maxWidth: \"380px\",\n width: \"100%\",\n boxShadow: \"0 12px 32px rgba(16, 24, 40, 0.18)\",\n boxSizing: \"border-box\",\n};\n\nconst titleStyle = {\n margin: \"0 0 8px\",\n fontSize: \"16px\",\n lineHeight: \"24px\",\n fontWeight: \"600\",\n color: \"#101828\",\n};\n\nconst detailStyle = {\n margin: \"0 0 20px\",\n fontSize: \"14px\",\n lineHeight: \"20px\",\n color: \"#475467\",\n};\n\nconst actionsStyle = {\n display: \"flex\",\n gap: \"12px\",\n justifyContent: \"flex-end\",\n};\n\nconst buttonStyle = {\n borderRadius: \"8px\",\n padding: \"8px 20px\",\n fontSize: \"14px\",\n lineHeight: \"20px\",\n cursor: \"pointer\",\n border: \"1px solid #d0d5dd\",\n backgroundColor: \"#ffffff\",\n color: \"#344054\",\n};\n\nconst activeIn = (root: ShadowRoot | Document): Element | null =>\n root.activeElement ?? document.activeElement;\n\nexport function openConfirmDialog(\n options: ConfirmDialogOptions\n): ConfirmDialogRefs {\n const { root, action, onConfirm, onCancel, confirmStyle, fontFamily } =\n options;\n const opener = activeIn(root);\n let disposed = false;\n\n const dispose = () => {\n if (disposed) return;\n disposed = true;\n document.removeEventListener(\"keydown\", onKeyDown, true);\n overlay.parentNode?.removeChild(overlay);\n };\n\n const cancel = () => {\n dispose();\n onCancel();\n if (opener instanceof HTMLElement) opener.focus();\n };\n\n const confirm = () => {\n dispose();\n onConfirm();\n };\n\n const cancelButton = el(\n \"button\",\n { type: \"button\", style: buttonStyle, onClick: cancel },\n CONFIRM_DIALOG_COPY.cancel\n ) as HTMLButtonElement;\n\n const confirmButton = el(\n \"button\",\n {\n type: \"button\",\n style: { ...buttonStyle, ...confirmStyle },\n onClick: confirm,\n },\n CONFIRM_DIALOG_COPY.confirm\n ) as HTMLButtonElement;\n\n const panel = el(\n \"div\",\n {\n role: \"dialog\",\n \"aria-modal\": \"true\",\n \"aria-labelledby\": CONFIRM_DIALOG_ID,\n \"aria-describedby\": CONFIRM_DIALOG_DETAIL_ID,\n style: panelStyle,\n },\n el(\n \"p\",\n { id: CONFIRM_DIALOG_ID, style: titleStyle },\n CONFIRM_DIALOG_COPY[action].title\n ),\n el(\n \"p\",\n { id: CONFIRM_DIALOG_DETAIL_ID, style: detailStyle },\n CONFIRM_DIALOG_COPY[action].detail\n ),\n el(\"div\", { style: actionsStyle }, cancelButton, confirmButton)\n );\n\n const overlay = el(\n \"div\",\n {\n [NOTICE_FONT_ROOT_ATTRIBUTE]: \"\",\n style: { ...overlayStyle, fontFamily: fontFamily || \"inherit\" },\n },\n panel\n );\n\n function onKeyDown(event: KeyboardEvent) {\n if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n cancel();\n return;\n }\n if (event.key !== \"Tab\") return;\n event.stopPropagation();\n\n const active = activeIn(root);\n if (event.shiftKey && active === cancelButton) {\n event.preventDefault();\n confirmButton.focus();\n return;\n }\n if (!event.shiftKey && active === confirmButton) {\n event.preventDefault();\n cancelButton.focus();\n return;\n }\n if (active !== cancelButton && active !== confirmButton) {\n event.preventDefault();\n cancelButton.focus();\n }\n }\n\n document.addEventListener(\"keydown\", onKeyDown, true);\n (root instanceof Document ? root.body : root).appendChild(overlay);\n cancelButton.focus();\n\n return { element: overlay, dispose };\n}\n","import type { NoticeProduct } from \"../api/types\";\nimport type { ProductPolicyLink } from \"../types\";\n\nexport const getProductPolicyLinks = (\n products: ReadonlyArray<NoticeProduct> | null | undefined,\n policies: Record<string, string> | null | undefined\n): ProductPolicyLink[] => {\n if (!policies) {\n return [];\n }\n return (products ?? []).flatMap((product) => {\n const url = policies[product.uuid];\n return url ? [{ uuid: product.uuid, name: product.name, url }] : [];\n });\n};\n\nexport const shouldShowNoticePolicyLink = (\n products: ReadonlyArray<NoticeProduct> | null | undefined,\n links: ReadonlyArray<ProductPolicyLink>\n): boolean => {\n const productCount = products?.length ?? 0;\n if (links.length === 0 || productCount === 0) {\n return true;\n }\n return links.length < productCount;\n};\n","import { el } from \"../core/dom\";\nimport type { ProductPolicyLineOptions } from \"../types\";\n\nexport function renderProductPolicyLine({\n label,\n links,\n linkStyle,\n}: ProductPolicyLineOptions): HTMLElement {\n const line = el(\n \"span\",\n { id: \"product-privacy-policies\" },\n el(\"span\", { id: \"product-privacy-policies-label\" }, label),\n \" \"\n );\n links.forEach((link, index) => {\n if (index > 0) line.appendChild(document.createTextNode(\", \"));\n line.appendChild(\n el(\n \"a\",\n {\n id: `product-privacy-policy-${link.uuid}`,\n href: link.url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: linkStyle,\n },\n link.name\n )\n );\n });\n return line;\n}\n","import type {\n PurposeItemData,\n PurposePreselection,\n PurposeSelection,\n} from \"../api/types\";\nimport {\n DEFAULT_PURPOSE_PRESELECTION,\n PURPOSE_STATUS_INACTIVE,\n} from \"../constants\";\nimport { productPurposeKey } from \"../core/productMatrix\";\nimport type {\n OpeningSelection,\n PurposeRow,\n RecordedLookup,\n SelectablePurpose,\n SelectionState,\n} from \"../types\";\nimport { buildSelectionForMode, dataElementKey } from \"./consentSelection\";\n\nexport const resolvePurposePreselection = (\n raw: string | undefined | null\n): PurposePreselection =>\n raw === \"MANDATORY\" || raw === \"ALL\" ? raw : DEFAULT_PURPOSE_PRESELECTION;\n\nexport const hasRecordedPurposeState = (\n selection: PurposeSelection | undefined\n): selection is PurposeSelection => {\n if (!selection) {\n return false;\n }\n if (selection.status && selection.status !== PURPOSE_STATUS_INACTIVE) {\n return true;\n }\n return Object.keys(selection.data_elements ?? {}).length > 0;\n};\n\nexport const buildPreselection = (\n purposes: ReadonlyArray<SelectablePurpose>,\n mode: PurposePreselection\n): SelectionState => {\n if (mode === \"ALL\") {\n return buildSelectionForMode(\n purposes.map((purpose) => ({ purpose, productUuid: undefined })),\n \"all\",\n { selectedPurposes: {}, selectedDataElements: {} }\n );\n }\n\n const selectedPurposes: Record<string, boolean> = {};\n const selectedDataElements: Record<string, boolean> = {};\n\n purposes.forEach((purpose) => {\n let hasPreselectedElement = false;\n purpose.data_elements.forEach((element) => {\n const isPreselected =\n mode === \"MANDATORY\" && element.required && element.enabled;\n selectedDataElements[dataElementKey(purpose.uuid, element.uuid)] =\n isPreselected;\n hasPreselectedElement = hasPreselectedElement || isPreselected;\n });\n selectedPurposes[purpose.uuid] = hasPreselectedElement;\n });\n\n return { selectedPurposes, selectedDataElements };\n};\n\nexport const openingSelection = (\n purposes: ReadonlyArray<PurposeItemData>,\n preselection: string | undefined | null,\n recordedFor: RecordedLookup\n): OpeningSelection => {\n const hint = buildPreselection(\n purposes,\n resolvePurposePreselection(preselection)\n );\n const isRecorded = (purposeUuid: string, productUuid?: string) =>\n hasRecordedPurposeState(recordedFor(purposeUuid, productUuid));\n\n return {\n purpose: (purposeUuid, productUuid) =>\n !isRecorded(purposeUuid, productUuid) &&\n (hint.selectedPurposes[purposeUuid] ?? false),\n dataElement: (purposeUuid, elementUuid, productUuid) =>\n !isRecorded(purposeUuid, productUuid) &&\n (hint.selectedDataElements[dataElementKey(purposeUuid, elementUuid)] ??\n false),\n };\n};\n\nexport const applyPreselection = (\n rows: ReadonlyArray<PurposeRow<PurposeItemData>>,\n preselection: string | undefined | null,\n recordedFor: RecordedLookup,\n seeded: SelectionState\n): SelectionState => {\n const opening = openingSelection(\n rows.map((row) => row.purpose),\n preselection,\n recordedFor\n );\n const selectedPurposes = { ...seeded.selectedPurposes };\n const selectedDataElements = { ...seeded.selectedDataElements };\n\n rows.forEach(({ purpose, productUuid }) => {\n if (hasRecordedPurposeState(recordedFor(purpose.uuid, productUuid))) return;\n selectedPurposes[productPurposeKey(productUuid, purpose.uuid)] =\n opening.purpose(purpose.uuid, productUuid);\n purpose.data_elements.forEach((element) => {\n selectedDataElements[dataElementKey(purpose.uuid, element.uuid, productUuid)] =\n opening.dataElement(purpose.uuid, element.uuid, productUuid);\n });\n });\n\n return { selectedPurposes, selectedDataElements };\n};\n\nexport const recordedAnswersFor = (\n rows: ReadonlyArray<PurposeRow>,\n recordedFor: RecordedLookup\n): Record<string, boolean> =>\n rows.reduce((answers: Record<string, boolean>, { purpose, productUuid }) => {\n const selection = recordedFor(purpose.uuid, productUuid);\n if (hasRecordedPurposeState(selection)) {\n answers[productPurposeKey(productUuid, purpose.uuid)] =\n selection.selected === true;\n }\n return answers;\n }, {});\n","import {\n CSS_FONT_KEYWORDS,\n DEFAULT_NOTICE_FONT_ID,\n INHERIT_FONT_FAMILY,\n NOTICE_FONT_CATALOGUE,\n NOTICE_FONT_CSS,\n NOTICE_FONT_GENERIC_FALLBACK,\n NOTICE_FONT_STYLE_ID,\n UNSAFE_FONT_CHARACTERS,\n} from \"../constants\";\nimport type { NoticeFontEntry, NoticeFontSources } from \"../types\";\n\nconst entryById = (id: string): NoticeFontEntry | undefined =>\n NOTICE_FONT_CATALOGUE.find((entry) => entry.id === id);\n\nconst toFontFamilyValue = (value: string): string => {\n if (value.includes(\",\")) {\n return value;\n }\n const family = value.replace(UNSAFE_FONT_CHARACTERS, \"\").trim();\n if (!family) {\n return INHERIT_FONT_FAMILY;\n }\n const lowered = family.toLowerCase();\n if (CSS_FONT_KEYWORDS.includes(lowered)) {\n return lowered;\n }\n return entryById(lowered)?.stack ?? `\"${family}\"${NOTICE_FONT_GENERIC_FALLBACK}`;\n};\n\nconst toNoticeFontEntry = (\n fontPreference?: string\n): NoticeFontEntry | undefined => {\n const stored = fontPreference?.trim();\n if (!stored) {\n return undefined;\n }\n return entryById(stored.toLowerCase()) ?? entryById(DEFAULT_NOTICE_FONT_ID);\n};\n\nexport const resolveNoticeFontFamily = ({\n hostFont,\n noticeFont,\n}: NoticeFontSources): string => {\n const host = hostFont?.trim();\n if (host) {\n return toFontFamilyValue(host);\n }\n return toNoticeFontEntry(noticeFont)?.stack ?? INHERIT_FONT_FAMILY;\n};\n\nexport const injectNoticeFontStyles = (root: ShadowRoot | Document): void => {\n const existing =\n root instanceof Document\n ? root.getElementById(NOTICE_FONT_STYLE_ID)\n : root.querySelector(`#${NOTICE_FONT_STYLE_ID}`);\n if (existing) return;\n\n const style = document.createElement(\"style\");\n style.id = NOTICE_FONT_STYLE_ID;\n style.textContent = NOTICE_FONT_CSS;\n (root instanceof Document ? root.head : root).appendChild(style);\n};\n","import { Store } from \"../core/state\";\nimport { el, svg, clearElement } from \"../core/dom\";\nimport { createMediaQuery, type MediaQuerySubscription } from \"../core/media-query\";\nimport {\n fetchConsentContent,\n submitConsentEvent,\n fetchTTSAudioUrls,\n initiateGuardianVerification,\n verifyGuardianStatus,\n} from \"../api\";\nimport {\n buildLedgerConsentOverlay,\n fetchNoticeConsentStatus,\n} from \"../api/notice-consent-status\";\nimport { resolveDisplayLanguage } from \"../api/language\";\nimport { clearApiCache } from \"../services/cache\";\nimport { injectCheckboxStyles } from \"../styles/inject\";\nimport { styles } from \"../styles/modal\";\nimport { renderModalPurposes, type ModalPurposeRefs } from \"./purposes\";\nimport { renderLanguageSelector, type LanguageSelectorRefs } from \"./language-selector\";\nimport { setupKeyboardTrap, type KeyboardTrapCleanup } from \"./keyboard\";\nimport {\n saveConsentState,\n getConsentState,\n clearConsentState,\n updateConsentState,\n} from \"../services/storage\";\nimport { TTSManager } from \"./tts\";\nimport { renderAgeVerification } from \"./age-verification\";\nimport {\n renderGuardianForm,\n validateGuardianForm,\n type GuardianFormData,\n type GuardianFormRefs,\n} from \"./guardian-form\";\nimport {\n renderVerificationScreen,\n getVerificationErrorMessage,\n} from \"./verification-screen\";\nimport { resolveColors } from \"./colors\";\nimport { buildSelectionForMode } from \"./consentSelection\";\nimport { isMultiProduct, productPurposeKey } from \"../core/productMatrix\";\nimport {\n confirmHint,\n isFullyConsented,\n productBoxPurposes,\n purposeCheckedFromElements,\n purposeToggle,\n recordedSelectionLookup,\n sectionToggle,\n seedSelection,\n submissionPurposes,\n} from \"./productConsent\";\nimport {\n groupsOf,\n noticeConfirmVerdict,\n productIsRequired,\n rowsOf,\n seedProductState,\n} from \"./productState\";\nimport {\n renderConfirmHint,\n renderProductGroups,\n renderProductSection,\n updateConfirmHint,\n updateProductSection,\n} from \"./product-sections\";\nimport { logoRowJustify, resolveLogoPosition } from \"./layout\";\nimport { OtpGateSession } from \"./otpGate\";\nimport { lockSelections, renderOtpGatePanel } from \"./otp-gate-panel\";\nimport { openConfirmDialog } from \"./confirm-dialog\";\nimport { getProductPolicyLinks, shouldShowNoticePolicyLink } from \"./productPolicies\";\nimport { renderProductPolicyLine } from \"./product-policy-line\";\nimport { applyPreselection, recordedAnswersFor } from \"./preselection\";\nimport { injectNoticeFontStyles, resolveNoticeFontFamily } from \"./notice-font\";\nimport {\n ACCEPT_ALL_BUTTON_ID,\n ACCEPT_SELECTED_BUTTON_ID,\n DECLINE_BUTTON_ID,\n DEFAULT_ACCEPT_ALL_BUTTON_TEXT,\n DEFAULT_ACCEPT_SELECTED_BUTTON_TEXT,\n DEFAULT_DECLINE_BUTTON_TEXT,\n NOTICE_FONT_ROOT_ATTRIBUTE,\n OTP_GATE_COPY,\n PRODUCT_POLICIES_LABEL,\n SUBMITTING_BUTTON_TEXT,\n} from \"../constants\";\nimport type { SandboxOptions } from \"../api/types\";\nimport type {\n AcceptMode,\n ConfirmAction,\n ConfirmDialogRefs,\n ConfirmVerdict,\n ModalOptions,\n OtpGatePanelRefs,\n ProductSectionRefs,\n} from \"../types\";\nimport type {\n ActiveConfig,\n ConsentContent,\n PurposeItemData,\n PurposeSelection,\n Settings,\n TranslationObject,\n} from \"../api/types\";\n\ntype ModalState = {\n isLoading: boolean;\n isSubmitting: boolean;\n isSubmittingAccept: boolean;\n isSubmittingDecline: boolean;\n content: ConsentContent | null;\n selectedPurposes: Record<string, boolean>;\n selectedDataElements: Record<string, boolean>;\n initialDataElementSelections: Record<string, boolean>;\n recordedAnswers: Record<string, boolean>;\n collapsedPurposes: Record<string, boolean>;\n collapsedProducts: Record<string, boolean>;\n recordedPurposeSelections: Record<string, boolean>;\n consentedProducts: Record<string, boolean>;\n consentedPurposes: Record<string, boolean>;\n hasAlreadyConsented: boolean;\n isFullyConsentedReviewMode: boolean;\n selectedLanguage: string;\n errorMessage: string | null;\n fetchError: Error | null;\n needsConsentPurposes: PurposeItemData[];\n alreadyConsentedPurposes: PurposeItemData[];\n // Age/Guardian flow\n isMinorFlow: boolean;\n selfDeclaredAdult: boolean;\n showAgeVerification: boolean;\n showGuardianForm: boolean;\n showVerificationScreen: boolean;\n verificationReference: string | null;\n isVerificationComplete: boolean;\n isInitiatingVerification: boolean;\n isPollingStatus: boolean;\n verificationError: string | null;\n verificationErrorCode: string | null;\n canRetryVerification: boolean;\n guardianFormData: GuardianFormData;\n};\n\nexport class ModalController {\n private store: Store<ModalState>;\n private options: ModalOptions;\n private hostEl: HTMLElement | null = null;\n private shadowRoot: ShadowRoot | null = null;\n private previousBodyOverflow: string | null = null;\n private previousHtmlOverflow: string | null = null;\n private overlayEl: HTMLElement | null = null;\n private modalEl: HTMLElement | null = null;\n private mediaQuery: MediaQuerySubscription;\n private purposeRefs: ModalPurposeRefs | null = null;\n private alreadyConsentedPurposeRefs: ModalPurposeRefs | null = null;\n private productSections: ProductSectionRefs[] = [];\n private confirmHintEl: HTMLElement | null = null;\n private bottomSectionEl: HTMLElement | null = null;\n private langSelectorRefs: LanguageSelectorRefs | null = null;\n private keyboardCleanup: KeyboardTrapCleanup | null = null;\n private abortController: AbortController | null = null;\n private unsubscribe: (() => void) | null = null;\n private ttsManager: TTSManager | null = null;\n private guardianFormRefs: GuardianFormRefs | null = null;\n private statusPollTimeout: ReturnType<typeof setTimeout> | null = null;\n private popupCheckInterval: ReturnType<typeof setInterval> | null = null;\n private verificationPopup: Window | null = null;\n private verificationSessionToken: string | null = null;\n private visibilityChangeHandler: (() => void) | null = null;\n private otpSession = new OtpGateSession();\n private otpPanel: OtpGatePanelRefs | null = null;\n private selectionsEl: HTMLElement | null = null;\n private confirmDialog: ConfirmDialogRefs | null = null;\n\n // DOM refs for targeted updates\n private acceptBtn: HTMLButtonElement | null = null;\n private acceptAllBtn: HTMLButtonElement | null = null;\n private declineBtn: HTMLButtonElement | null = null;\n private middleSection: HTMLElement | null = null;\n private errorEl: HTMLElement | null = null;\n private noticeTitleEl: HTMLElement | null = null;\n private noticeTextEl: HTMLElement | null = null;\n private purposeHeadingEl: HTMLElement | null = null;\n private additionalTextEl: HTMLElement | null = null;\n private privacyPolicyLinkEl: HTMLAnchorElement | null = null;\n private privacyCenterLinkEl: HTMLAnchorElement | null = null;\n private ttsButton: HTMLElement | null = null;\n\n constructor(options: ModalOptions) {\n this.options = options;\n this.store = new Store<ModalState>({\n isLoading: true,\n isSubmitting: false,\n isSubmittingAccept: false,\n isSubmittingDecline: false,\n content: null,\n selectedPurposes: {},\n selectedDataElements: {},\n initialDataElementSelections: {},\n recordedAnswers: {},\n collapsedPurposes: {},\n collapsedProducts: {},\n recordedPurposeSelections: {},\n consentedProducts: {},\n consentedPurposes: {},\n hasAlreadyConsented: false,\n isFullyConsentedReviewMode: false,\n selectedLanguage: options.language || \"en\",\n errorMessage: null,\n fetchError: null,\n needsConsentPurposes: [],\n alreadyConsentedPurposes: [],\n isMinorFlow: false,\n selfDeclaredAdult: false,\n showAgeVerification: false,\n showGuardianForm: false,\n showVerificationScreen: false,\n verificationReference: null,\n isVerificationComplete: false,\n isInitiatingVerification: false,\n isPollingStatus: false,\n verificationError: null,\n verificationErrorCode: null,\n canRetryVerification: false,\n guardianFormData: { guardianName: \"\", guardianContact: \"\", guardianRelationship: \"\" },\n });\n this.mediaQuery = createMediaQuery(\"(max-width: 768px)\");\n // TTSManager is instantiated lazily in renderOverlayWithLoading() once the\n // shadow root exists, so it can scope its DOM queries inside the shadow.\n }\n\n async init(): Promise<void> {\n this.unsubscribe = this.store.subscribe((state, prevState) => {\n this.handleStateChange(state, prevState);\n });\n\n this.mediaQuery.subscribe(() => this.rebuildUI());\n\n // Render loading state\n this.renderOverlayWithLoading();\n\n // Fetch content\n await this.fetchNotice();\n }\n\n destroy(): void {\n this.abortController?.abort();\n this.keyboardCleanup?.();\n this.unsubscribe?.();\n this.mediaQuery.destroy();\n this.ttsManager?.destroy();\n this.stopPolling();\n this.confirmDialog?.dispose();\n this.confirmDialog = null;\n this.store.destroy();\n\n // Removing the shadow host nukes the entire shadow tree (overlay, modal,\n // language dropdown, injected stylesheet) in a single operation.\n if (this.hostEl && this.hostEl.parentNode) {\n this.hostEl.parentNode.removeChild(this.hostEl);\n }\n\n // Restore the host page's scroll lock to whatever it was before we opened.\n if (this.previousBodyOverflow !== null) {\n document.body.style.overflow = this.previousBodyOverflow;\n this.previousBodyOverflow = null;\n }\n if (this.previousHtmlOverflow !== null) {\n document.documentElement.style.overflow = this.previousHtmlOverflow;\n this.previousHtmlOverflow = null;\n }\n\n this.hostEl = null;\n this.shadowRoot = null;\n this.overlayEl = null;\n this.modalEl = null;\n this.purposeRefs = null;\n this.langSelectorRefs = null;\n }\n\n updateToken(accessToken: string): void {\n this.options = { ...this.options, accessToken };\n this.fireStashedAccept();\n }\n\n // ─── Private ───\n\n private fireStashedAccept(): void {\n if (!this.modalEl || this.confirmDialog) return;\n const mode = this.otpSession.takeStashedAccept(this.options.accessToken);\n if (mode) void this.handleAccept(mode);\n }\n\n private holdForOtp(mode: AcceptMode): boolean {\n const wasLocked = this.otpSession.isLocked;\n if (!this.otpSession.hold(this.options.otpGate, mode)) return false;\n if (wasLocked) {\n this.otpPanel?.render(this.otpSession.view);\n return true;\n }\n this.mountOtpGate();\n this.otpPanel?.focusDigit(0);\n this.otpPanel?.container.scrollIntoView?.({ block: \"nearest\" });\n return true;\n }\n\n private mountOtpGate(): void {\n this.otpPanel = null;\n const content = this.store.getState().content?.detail.active_config;\n if (!this.otpSession.isLocked || !this.selectionsEl || !content) return;\n lockSelections(this.selectionsEl);\n const gate = this.options.otpGate;\n const colors = resolveColors(this.options.settings, content);\n this.otpPanel = renderOtpGatePanel({\n title: gate?.title ?? OTP_GATE_COPY.title,\n description: gate?.description ?? OTP_GATE_COPY.description,\n submitLabel: gate?.submitLabel ?? OTP_GATE_COPY.submit,\n view: this.otpSession.view,\n buttonStyle: {\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderRadius: colors.borderRadius,\n },\n onDigitsChange: (digits) => this.otpSession.setDigits(digits),\n onConfirm: () => void this.handleOtpConfirm(),\n });\n this.selectionsEl.insertAdjacentElement(\"afterend\", this.otpPanel.container);\n }\n\n private async handleOtpConfirm(): Promise<void> {\n const verified = await this.otpSession.verify(\n this.options.otpGate,\n this.options.accessToken,\n () => this.otpPanel?.render(this.otpSession.view)\n );\n if (!this.modalEl) return;\n if (!verified) {\n this.otpPanel?.render(this.otpSession.view);\n this.otpPanel?.focusDigit(0);\n return;\n }\n this.rebuildUI();\n this.fireStashedAccept();\n }\n\n private confirmFirst(kind: ConfirmAction, action: () => void): void {\n this.otpSession.dropStashedAccept();\n const state = this.store.getState();\n if (\n !this.options.settings?.confirmBeforeSubmit ||\n state.isFullyConsentedReviewMode ||\n !this.shadowRoot\n ) {\n action();\n return;\n }\n if (this.confirmDialog || state.isSubmitting) return;\n if (kind === \"accept-selected\" && !this.confirmVerdict(state).ok) return;\n const colors = resolveColors(this.options.settings, state.content?.detail.active_config);\n this.confirmDialog = openConfirmDialog({\n root: this.shadowRoot,\n action: kind,\n onConfirm: () => {\n this.confirmDialog = null;\n action();\n },\n onCancel: () => {\n this.confirmDialog = null;\n },\n confirmStyle: {\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderColor: colors.acceptBg,\n },\n fontFamily: this.modalEl?.style.fontFamily,\n });\n }\n\n /**\n * Sandbox auth options to forward to every API call. When `token` is set the\n * API layer sends the single `X-Consent-Token` header, carries every supplied\n * identifier in each request's payload, and reads org/workspace from these\n * fields instead of decoding the JWT. Empty in the normal JWT flow.\n */\n private sandboxParams(): SandboxOptions {\n // Legacy `sandboxSubject` (deprecated): classify into email/mobile so an\n // existing caller that still passes it keeps working unchanged.\n const legacySubject = this.options.sandboxSubject?.trim();\n const legacyEmail = legacySubject?.includes(\"@\") ? legacySubject : undefined;\n const legacyMobile =\n legacySubject && !legacySubject.includes(\"@\") ? legacySubject : undefined;\n return {\n token: this.options.token,\n // The static token carries no identity; carry every supplied identifier\n // (ucic/email/mobile) so the server can pick the principal by precedence\n // (UCIC > email > mobile) and keep the rest as the sandbox contact.\n // sandboxUcic / sandboxEmail / sandboxMobile stay as fallbacks.\n sandboxUcic: this.options.ucic || this.options.sandboxUcic,\n sandboxEmail: this.options.email || this.options.sandboxEmail || legacyEmail,\n sandboxMobile:\n this.options.mobile || this.options.sandboxMobile || legacyMobile,\n organisationUuid: this.options.organisationUuid,\n workspaceUuid: this.options.workspaceUuid,\n };\n }\n\n private async fetchNotice(): Promise<void> {\n this.abortController = new AbortController();\n this.store.setState({ isLoading: true, fetchError: null });\n\n try {\n // Standard flow reads the notice from the Go ledger. The magic-link flow\n // (applicationId/specific_uuid) and sandbox sessions stay on the consent\n // server: the ledger notice read supports neither (no specific_uuid, no\n // X-Consent-Token auth). Without this a ledger-minted token is rejected\n // by the consent server and the modal renders with no content.\n const noticeBaseUrl =\n this.options.ledgerBaseUrl &&\n !this.options.applicationId &&\n !this.options.token\n ? this.options.ledgerBaseUrl\n : this.options.baseUrl;\n const data = await fetchConsentContent({\n noticeId: this.options.noticeId,\n accessToken: this.options.accessToken,\n refreshToken: this.options.refreshToken,\n baseUrl: noticeBaseUrl,\n language: this.options.language,\n specific_uuid: this.options.applicationId,\n validate_against: this.options.validateAgainst || \"all\",\n include_fully_consented_data: this.options.includeFullyConsentedData,\n signal: this.abortController.signal,\n ...this.sandboxParams(),\n });\n\n const activeConfig = data.detail.active_config;\n\n // Overlay the prior-consent / reconsent state from the Go ledger's\n // check-consent. Consents live in the ledger post-cutover, so Python's\n // notice-validation overlay is empty; the notice text/config still comes\n // from Python (above). Falls back to the Python-provided values when the\n // ledger is unavailable, and is skipped for the magic-link flow\n // (applicationId), which pre-fills from a specific event.\n let purposeSelections = data.detail.purpose_selections;\n let reconsentRequired = data.detail.reconsent_required;\n let ledgerOverlayApplied = false;\n if (this.options.ledgerBaseUrl && !this.options.applicationId) {\n const ledgerStatus = await fetchNoticeConsentStatus({\n accessToken: this.options.accessToken,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n noticeUuid: this.options.noticeId,\n signal: this.abortController.signal,\n });\n if (ledgerStatus) {\n const overlay = buildLedgerConsentOverlay(ledgerStatus, activeConfig.purposes);\n reconsentRequired = overlay?.reconsent_required ?? false;\n purposeSelections = overlay?.purpose_selections;\n ledgerOverlayApplied = Boolean(overlay);\n }\n }\n\n // Initialize state\n const initialCollapsed: Record<string, boolean> = {};\n const initialDataElementSelections: Record<string, boolean> = {};\n\n // Categorize purposes for reconsent. With a ledger overlay, categorize\n // whenever prior consent exists (even without reconsent needed) so a\n // fully-consented principal gets the already-consented presentation /\n // review mode instead of a fresh consent flow — the ledger-mode\n // equivalent of Python's 409-driven short-circuit.\n let needsConsentPurposes: PurposeItemData[] = [];\n let alreadyConsentedPurposes: PurposeItemData[] = [];\n let isFullyConsentedReviewMode = false;\n const recordedFor = recordedSelectionLookup(\n purposeSelections,\n data.detail.product_purpose_selections\n );\n const seedRows = rowsOf(activeConfig);\n const reviewsFullRecord = Boolean(\n this.options.includeFullyConsentedData &&\n seedRows.length > 0 &&\n isFullyConsented(seedRows, recordedFor)\n );\n\n if (purposeSelections && (reconsentRequired || ledgerOverlayApplied || reviewsFullRecord)) {\n for (const purpose of activeConfig.purposes) {\n const selection = purposeSelections[purpose.uuid];\n initialCollapsed[purpose.uuid] = true;\n\n if (selection && selection.selected && !selection.needs_reconsent) {\n alreadyConsentedPurposes.push(purpose);\n for (const de of purpose.data_elements) {\n const combinedId = `${purpose.uuid}-${de.uuid}`;\n const deSelection = selection.data_elements?.[de.uuid];\n initialDataElementSelections[combinedId] = deSelection?.selected || false;\n }\n } else {\n needsConsentPurposes.push(purpose);\n }\n }\n } else {\n needsConsentPurposes = activeConfig.purposes;\n for (const purpose of activeConfig.purposes) {\n initialCollapsed[purpose.uuid] = true;\n }\n }\n\n // Check if all purposes are already consented (review mode)\n if (\n this.options.includeFullyConsentedData &&\n needsConsentPurposes.length === 0 &&\n alreadyConsentedPurposes.length > 0\n ) {\n isFullyConsentedReviewMode = true;\n }\n\n const productSeed = seedProductState({\n config: activeConfig,\n purposeSelections,\n productPurposeSelections: data.detail.product_purpose_selections,\n defaultOpenProducts: this.options.defaultOpenProducts,\n includeFullyConsentedData: this.options.includeFullyConsentedData,\n });\n const productPreselection = applyPreselection(\n seedRows,\n activeConfig.purpose_preselection,\n recordedFor,\n productSeed.selectedPurposes && productSeed.selectedDataElements\n ? {\n selectedPurposes: productSeed.selectedPurposes,\n selectedDataElements: productSeed.selectedDataElements,\n }\n : seedSelection(seedRows, recordedFor)\n );\n\n const selectedLanguage = resolveDisplayLanguage(\n this.options.language,\n activeConfig.default_language,\n activeConfig.supported_languages_and_translations\n );\n\n // Check if minor flow is required, and restore in-progress verification\n // state from a previous session (e.g. user closed the SDK or returned\n // from a DigiLocker redirect mid-flow). Without this restoration, the\n // notice would be shown directly and guardian verification skipped.\n let isMinorFlow = false;\n let showAgeVerification = false;\n let restoreState: Partial<ModalState> = {};\n let pollingTokenToResume: string | null = null;\n if (data.detail.is_minor) {\n isMinorFlow = true;\n const persistedState = getConsentState();\n\n // Discard persisted state from a different notice\n if (persistedState?.noticeId && persistedState.noticeId !== this.options.noticeId) {\n clearConsentState();\n } else if (\n persistedState?.flowState === \"digilocker-pending\" &&\n persistedState.sessionToken\n ) {\n // User is mid-verification — resume the verification screen and polling\n restoreState = {\n showVerificationScreen: true,\n isPollingStatus: true,\n };\n pollingTokenToResume = persistedState.sessionToken;\n } else if (\n persistedState?.verificationResult === \"verified\" &&\n persistedState.verificationReference\n ) {\n // Verification completed during a redirect — show success state\n restoreState = {\n showVerificationScreen: true,\n isVerificationComplete: true,\n verificationReference: persistedState.verificationReference,\n };\n clearConsentState();\n } else if (\n persistedState?.verificationResult === \"failed\" ||\n persistedState?.verificationResult === \"expired\"\n ) {\n // Verification failed/expired during a redirect — show error\n restoreState = {\n showVerificationScreen: true,\n verificationError:\n persistedState.verificationResult === \"expired\"\n ? \"Verification session has expired. Please try again.\"\n : \"Verification failed. Please try again.\",\n canRetryVerification: true,\n };\n clearConsentState();\n } else {\n // No in-progress verification — start with age verification\n showAgeVerification = true;\n }\n }\n\n this.store.setState({\n content: data,\n isLoading: false,\n selectedLanguage,\n collapsedPurposes: initialCollapsed,\n initialDataElementSelections,\n recordedAnswers: recordedAnswersFor(seedRows, recordedFor),\n needsConsentPurposes,\n alreadyConsentedPurposes,\n isFullyConsentedReviewMode,\n ...productSeed,\n ...productPreselection,\n isMinorFlow,\n showAgeVerification,\n ...restoreState,\n });\n\n // Resume polling after state has been applied so the verification screen\n // is visible while polling runs.\n if (pollingTokenToResume) {\n this.startStatusPolling(pollingTokenToResume);\n }\n } catch (err: unknown) {\n if ((err as Error).name === \"AbortError\") return;\n const error = err as Error & { status?: number };\n if (error.status === 409) {\n this.store.setState({ hasAlreadyConsented: true, isLoading: false });\n this.options.onAccept();\n } else {\n this.store.setState({ fetchError: error, isLoading: false });\n this.options.onError?.(error);\n }\n }\n }\n\n private handleStateChange(state: ModalState, prevState: ModalState): void {\n // Loading → content loaded\n if (prevState.isLoading && !state.isLoading && state.content) {\n this.rebuildUI();\n return;\n }\n\n // Already consented → close\n if (state.hasAlreadyConsented && !prevState.hasAlreadyConsented) {\n this.destroy();\n return;\n }\n\n // Fetch error → show error\n if (state.fetchError && !prevState.fetchError) {\n this.renderError(state.fetchError.message);\n return;\n }\n\n // Screen transitions (age → guardian → verification → consent)\n if (state.showAgeVerification !== prevState.showAgeVerification ||\n state.showGuardianForm !== prevState.showGuardianForm ||\n state.showVerificationScreen !== prevState.showVerificationScreen) {\n this.rebuildUI();\n return;\n }\n\n // Verification screen state changes\n if (state.showVerificationScreen && (\n state.isVerificationComplete !== prevState.isVerificationComplete ||\n state.verificationError !== prevState.verificationError ||\n state.isPollingStatus !== prevState.isPollingStatus ||\n state.isInitiatingVerification !== prevState.isInitiatingVerification)) {\n this.rebuildUI();\n return;\n }\n\n // Checkbox changes\n if (\n state.selectedPurposes !== prevState.selectedPurposes ||\n state.selectedDataElements !== prevState.selectedDataElements\n ) {\n this.updateCheckboxes(state);\n }\n\n // Collapse changes\n if (state.collapsedPurposes !== prevState.collapsedPurposes) {\n this.updateCollapseState(state);\n }\n\n if (state.collapsedProducts !== prevState.collapsedProducts) {\n this.updateProductSections(state);\n }\n\n // Error message\n if (state.errorMessage !== prevState.errorMessage) {\n this.updateErrorMessage(state);\n }\n\n // Submitting state\n if (state.isSubmittingAccept !== prevState.isSubmittingAccept ||\n state.isSubmittingDecline !== prevState.isSubmittingDecline) {\n this.updateButtonStates(state);\n }\n }\n\n private renderOverlayWithLoading(): void {\n // Mount a single host <div> on document.body and attach an open shadow\n // root. All overlay, modal, and stylesheet content lives inside the shadow\n // so the host page's CSS cannot bleed in (and vice versa). This is what\n // makes the SDK render identically across customer sites and WordPress\n // installs that ship aggressive global stylesheets / accessibility plugins.\n this.hostEl = document.createElement(\"div\");\n this.hostEl.setAttribute(\"data-redacto-consent\", \"\");\n // Lock the host to a zero-size, fixed-position box so it cannot perturb a\n // flex / grid body layout. We deliberately DO NOT reset inherited text\n // properties (font-family, color, line-height) — those flow through the\n // shadow boundary so the modal picks up the host page's font, matching\n // how the React SDK renders.\n this.hostEl.style.position = \"fixed\";\n this.hostEl.style.top = \"0\";\n this.hostEl.style.left = \"0\";\n this.hostEl.style.width = \"0\";\n this.hostEl.style.height = \"0\";\n this.hostEl.style.zIndex = \"2147483646\";\n document.body.appendChild(this.hostEl);\n this.shadowRoot = this.hostEl.attachShadow({ mode: \"open\" });\n\n // Lock background scroll on the host page while the modal is open. We\n // capture the previous values so destroy() can restore exactly what was\n // there (including the empty string, which means \"use stylesheet rule\").\n this.previousBodyOverflow = document.body.style.overflow;\n this.previousHtmlOverflow = document.documentElement.style.overflow;\n document.body.style.overflow = \"hidden\";\n document.documentElement.style.overflow = \"hidden\";\n\n // Inject SDK stylesheet into the shadow root (not document.head).\n injectCheckboxStyles(this.shadowRoot);\n injectNoticeFontStyles(this.shadowRoot);\n\n // Lazy-instantiate TTSManager now that we have a root for it to query.\n this.ttsManager = new TTSManager(\n () => this.updateTTSButton(),\n this.shadowRoot\n );\n\n const blockUI = this.options.blockUI !== false;\n\n if (blockUI) {\n this.overlayEl = el(\"div\", {\n style: styles.overlay,\n role: \"presentation\",\n });\n this.shadowRoot.appendChild(this.overlayEl);\n }\n\n const settingsObj = this.options.settings;\n const modalStyle = { ...styles.modal } as Record<string, any>;\n if (settingsObj?.backgroundColor) modalStyle.backgroundColor = settingsObj.backgroundColor;\n if (settingsObj?.borderRadius) modalStyle.borderRadius = settingsObj.borderRadius;\n if (settingsObj?.borderColor) modalStyle.border = `1px solid ${settingsObj.borderColor}`;\n if (settingsObj?.font) modalStyle.fontFamily = settingsObj.font;\n if (this.mediaQuery.matches) {\n modalStyle.width = \"90%\";\n modalStyle.maxWidth = \"90%\";\n }\n\n this.modalEl = el(\"div\", {\n style: modalStyle,\n role: \"dialog\",\n \"aria-modal\": \"true\",\n \"aria-label\": \"Privacy consent\",\n [NOTICE_FONT_ROOT_ATTRIBUTE]: \"\",\n });\n\n // Loading content\n const loadingEl = el(\n \"div\",\n { style: styles.loadingContainer },\n el(\"div\", { style: styles.loadingSpinner }),\n el(\"p\", { style: { ...styles.privacyText, color: settingsObj?.textColor || \"#344054\" } }, \"Loading...\")\n );\n\n const contentEl = el(\"div\", { style: styles.content }, loadingEl);\n this.modalEl.appendChild(contentEl);\n this.shadowRoot.appendChild(this.modalEl);\n }\n\n private rebuildUI(): void {\n const state = this.store.getState();\n if (!state.content || !this.modalEl) return;\n\n const activeConfig = state.content.detail.active_config;\n const settingsObj = this.options.settings;\n const isMobile = this.mediaQuery.matches;\n const colors = resolveColors(settingsObj, activeConfig);\n this.modalEl.style.fontFamily = resolveNoticeFontFamily({\n hostFont: settingsObj?.font,\n noticeFont: activeConfig.font_preference,\n });\n\n // ─── Age Verification Screen ───\n if (state.showAgeVerification) {\n clearElement(this.modalEl);\n const ageRefs = renderAgeVerification({\n settings: settingsObj,\n colors,\n isMobile,\n logoUrl: activeConfig.logo_url,\n onYes: () => this.handleAgeVerificationYes(),\n onNo: () => this.handleAgeVerificationNo(),\n onClose: () => this.handleDecline(),\n });\n this.modalEl.appendChild(ageRefs.container);\n this.keyboardCleanup?.();\n this.keyboardCleanup = setupKeyboardTrap(this.modalEl, () => this.handleDecline());\n return;\n }\n\n // ─── Guardian Form Screen ───\n if (state.showGuardianForm) {\n clearElement(this.modalEl);\n this.guardianFormRefs = renderGuardianForm({\n formData: state.guardianFormData,\n settings: settingsObj,\n colors,\n isMobile,\n logoUrl: activeConfig.logo_url,\n isSubmitting: state.isInitiatingVerification,\n onSubmit: () => this.handleGuardianFormSubmit(),\n onCancel: () => this.handleDecline(),\n onFieldChange: (field, value) => {\n const s = this.store.getState();\n this.store.setState({\n guardianFormData: { ...s.guardianFormData, [field]: value },\n });\n },\n });\n this.modalEl.appendChild(this.guardianFormRefs.container);\n this.keyboardCleanup?.();\n this.keyboardCleanup = setupKeyboardTrap(this.modalEl, () => this.handleDecline());\n return;\n }\n\n // ─── Verification Screen ───\n if (state.showVerificationScreen) {\n clearElement(this.modalEl);\n const verRefs = renderVerificationScreen({\n settings: settingsObj,\n colors,\n isMobile,\n logoUrl: activeConfig.logo_url,\n isInitiating: state.isInitiatingVerification,\n isPolling: state.isPollingStatus,\n isComplete: state.isVerificationComplete,\n error: state.verificationError,\n errorCode: state.verificationErrorCode,\n canRetry: state.canRetryVerification,\n onContinue: () => this.handleVerificationContinue(),\n onBack: (clearName?: boolean) => {\n if (clearName) {\n this.handleChangeGuardian();\n } else if (state.verificationError && state.canRetryVerification) {\n this.handleVerificationRetry();\n } else {\n this.handleDecline();\n }\n },\n });\n this.modalEl.appendChild(verRefs.container);\n this.keyboardCleanup?.();\n this.keyboardCleanup = setupKeyboardTrap(this.modalEl, () => {});\n return;\n }\n\n // Clear modal content\n clearElement(this.modalEl);\n\n const headingColor = settingsObj?.headingColor || \"#101828\";\n const textColor = colors.text;\n const linkColor = colors.link;\n const font = colors.font;\n\n // ─── Top Section ───\n const logoImg = activeConfig.logo_url\n ? el(\"img\", {\n src: activeConfig.logo_url,\n style: {\n ...styles.logo,\n maxWidth: isMobile ? \"96px\" : \"140px\",\n maxHeight: isMobile ? \"28px\" : \"32px\",\n },\n alt: \"Logo\",\n })\n : null;\n\n this.noticeTitleEl = el(\"span\", {\n id: \"privacy-notice-title\",\n style: { ...styles.title, color: headingColor, fontFamily: font, fontSize: isMobile ? \"16px\" : \"18px\" },\n });\n this.noticeTitleEl.textContent = this.getTranslatedText(\"notice_banner_heading\", activeConfig.notice_banner_heading);\n\n // Clean up previous language dropdown (since rebuildUI re-creates it).\n // The dropdown lives inside the shadow root (sibling of the modal) so we\n // remove it from there.\n if (\n this.langSelectorRefs?.dropdown &&\n this.shadowRoot &&\n this.langSelectorRefs.dropdown.parentNode === this.shadowRoot\n ) {\n this.shadowRoot.removeChild(this.langSelectorRefs.dropdown);\n }\n\n // Language selector\n const supportedLangs = Object.keys(activeConfig.supported_languages_and_translations || {});\n const allLanguages = [activeConfig.default_language || \"English\", ...supportedLangs.filter((l) => l !== activeConfig.default_language)];\n\n this.langSelectorRefs = renderLanguageSelector({\n languages: allLanguages,\n selectedLanguage: state.selectedLanguage,\n settings: settingsObj,\n onSelect: (lang) => this.handleLanguageSelect(lang),\n dropdownContainer: this.shadowRoot!,\n });\n\n // TTS button with SVG speaker icon (matches React)\n const ttsStrokeColor = settingsObj?.button?.language?.textColor || \"currentColor\";\n const speakerSvg = svg(\n \"svg\",\n {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"16\",\n height: \"16\",\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: ttsStrokeColor,\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n \"aria-hidden\": \"true\",\n },\n svg(\"polygon\", { points: \"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" }),\n svg(\"path\", { d: \"M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07\" })\n );\n\n this.ttsButton = el(\"button\", {\n style: {\n ...styles.topRight,\n display: \"none\",\n padding: \"3px 9px\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n type: \"button\",\n \"aria-label\": \"Start audio playback\",\n title: \"Start Talkback\",\n onClick: () => this.ttsManager?.toggle(),\n });\n this.ttsButton.appendChild(speakerSvg);\n\n // Fetch TTS audio (the API uses \"English\" for English, not \"en\")\n this.ttsManager?.fetchAudioUrls({\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n noticeUuid: activeConfig.notice_uuid,\n language: this.getLanguageCode(state.selectedLanguage),\n content: activeConfig,\n ...this.sandboxParams(),\n });\n\n // TTS button on LEFT, language selector on RIGHT (matches React)\n const topRight = el(\"div\", {\n style: { display: \"flex\", alignItems: \"center\", gap: \"8px\", flexShrink: 0 },\n }, this.ttsButton, this.langSelectorRefs.container);\n\n // Two stacked rows at every breakpoint: the logo alone on row 1, aligned\n // per the admin-chosen position, then title + controls on row 2.\n const logoPosition = resolveLogoPosition(activeConfig.logo_position);\n const headerRows: HTMLElement[] = [];\n // Row 1 only exists when there is a logo. This package has no bundled\n // fallback (unlike React), so rendering it regardless would leave nothing\n // but the headerStack gap — a phantom band above the title.\n if (logoImg) {\n headerRows.push(\n el(\n \"div\",\n { style: { ...styles.logoRow, justifyContent: logoRowJustify(logoPosition) } },\n logoImg\n )\n );\n }\n headerRows.push(el(\"div\", { style: styles.headerRow }, this.noticeTitleEl, topRight));\n\n const topSection = el(\n \"div\",\n { style: { ...styles.headerStack, gap: isMobile ? \"12px\" : \"10px\" } },\n ...headerRows\n );\n\n // ─── Middle Section ───\n this.middleSection = el(\"div\", { style: styles.middleSection });\n\n const baseTextStyle = { ...styles.privacyText, color: textColor, fontFamily: font, fontSize: isMobile ? \"14px\" : \"16px\" };\n\n // Notice text + Privacy policy in ONE <p> (matches React: single <p> with <br>)\n const noticeTextSpan = el(\"span\", { id: \"privacy-notice-text\" });\n noticeTextSpan.textContent = this.getTranslatedText(\"notice_text\", activeConfig.notice_text);\n\n const policyPrefixText = this.getTranslatedText(\"privacy_policy_prefix_text\", activeConfig.privacy_policy_prefix_text);\n const policyAnchorText = this.getTranslatedText(\"privacy_policy_anchor_text\", activeConfig.privacy_policy_anchor_text);\n\n this.privacyPolicyLinkEl = el(\"a\", {\n id: \"privacy-policy-link\",\n href: activeConfig.privacy_policy_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n \"aria-label\": \"Privacy Policy (opens in new tab)\",\n }) as HTMLAnchorElement;\n this.privacyPolicyLinkEl.textContent = policyAnchorText;\n\n const policySpan = el(\"span\", { id: \"privacy-policy-text\" },\n `${policyPrefixText} `,\n this.privacyPolicyLinkEl\n );\n\n const productPolicyLinks = getProductPolicyLinks(\n activeConfig.products,\n activeConfig.product_privacy_policies\n );\n const showNoticePolicyLink = shouldShowNoticePolicyLink(\n activeConfig.products,\n productPolicyLinks\n );\n\n const noticeAndPolicyP = el(\"p\", { style: baseTextStyle },\n noticeTextSpan,\n showNoticePolicyLink && el(\"br\"),\n showNoticePolicyLink && policySpan\n );\n\n // Purpose section heading\n this.purposeHeadingEl = el(\"h2\", {\n id: \"purpose-section-heading\",\n style: { ...styles.subTitle, color: headingColor, fontFamily: font },\n });\n this.purposeHeadingEl.textContent = this.getTranslatedText(\"purpose_section_heading\", activeConfig.purpose_section_heading);\n\n this.middleSection.appendChild(noticeAndPolicyP);\n this.middleSection.appendChild(this.purposeHeadingEl);\n this.selectionsEl = el(\"div\");\n this.middleSection.appendChild(this.selectionsEl);\n\n this.productSections = [];\n this.alreadyConsentedPurposeRefs = null;\n const soleSection = this.renderSoleProductSection(state, isMobile);\n const purposesHost = soleSection ? soleSection.body : this.selectionsEl;\n if (soleSection) this.selectionsEl.appendChild(soleSection.container);\n\n if (isMultiProduct(activeConfig.products)) {\n const grouped = renderProductGroups({\n groups: groupsOf(activeConfig),\n products: activeConfig.products,\n selectedPurposes: state.selectedPurposes,\n selectedDataElements: state.selectedDataElements,\n collapsedPurposes: state.collapsedPurposes,\n collapsedProducts: state.collapsedProducts,\n consentedProducts: state.consentedProducts,\n consentedPurposes: state.consentedPurposes,\n initialDataElementSelections: state.initialDataElementSelections,\n recordedAnswers: state.recordedAnswers,\n settings: settingsObj,\n isMobile,\n getTranslatedText: (key, defaultText, itemId) => this.getTranslatedText(key, defaultText, itemId),\n onPurposeToggle: (uuid, productUuid) => this.handlePurposeCheckboxChange(uuid, productUuid),\n onPurposeCollapse: (uuid, productUuid) => this.togglePurposeCollapse(uuid, productUuid),\n onDataElementToggle: (euuid, puuid, productUuid) =>\n this.handleDataElementCheckboxChange(euuid, puuid, productUuid),\n onToggleCollapse: (productUuid) => this.toggleProductCollapse(productUuid),\n onToggleSelect: (productUuid, choice) => this.handleProductCheckboxChange(productUuid, choice),\n });\n this.purposeRefs = grouped.purposeRefs;\n this.productSections = grouped.sections;\n this.selectionsEl.appendChild(grouped.container);\n } else if (state.needsConsentPurposes.length > 0) {\n this.purposeRefs = renderModalPurposes(state.needsConsentPurposes, {\n selectedPurposes: state.selectedPurposes,\n collapsedPurposes: state.collapsedPurposes,\n selectedDataElements: state.selectedDataElements,\n recordedAnswers: state.recordedAnswers,\n settings: settingsObj,\n isMobile,\n isAlreadyConsented: false,\n getTranslatedText: (key, defaultText, itemId) => this.getTranslatedText(key, defaultText, itemId),\n onPurposeToggle: (uuid) => this.handlePurposeCheckboxChange(uuid),\n onPurposeCollapse: (uuid) => this.togglePurposeCollapse(uuid),\n onDataElementToggle: (euuid, puuid) => this.handleDataElementCheckboxChange(euuid, puuid),\n });\n purposesHost.appendChild(this.purposeRefs.container);\n }\n\n // Render already-consented purposes\n if (!isMultiProduct(activeConfig.products) && state.alreadyConsentedPurposes.length > 0) {\n this.alreadyConsentedPurposeRefs = renderModalPurposes(state.alreadyConsentedPurposes, {\n selectedPurposes: state.selectedPurposes,\n collapsedPurposes: state.collapsedPurposes,\n selectedDataElements: state.selectedDataElements,\n initialDataElementSelections: state.initialDataElementSelections,\n settings: settingsObj,\n isMobile,\n isAlreadyConsented: true,\n getTranslatedText: (key, defaultText, itemId) => this.getTranslatedText(key, defaultText, itemId),\n onPurposeToggle: () => {},\n onPurposeCollapse: (uuid) => this.togglePurposeCollapse(uuid),\n onDataElementToggle: () => {},\n });\n purposesHost.appendChild(this.alreadyConsentedPurposeRefs.container);\n }\n\n this.mountOtpGate();\n\n // Additional text + Privacy Center + DPO Info in ONE block (matches React layout)\n if (activeConfig.privacy_center_url || activeConfig.dpo_info || productPolicyLinks.length > 0) {\n const footerDiv = el(\"div\", {\n style: {\n ...baseTextStyle,\n fontSize: isMobile ? \"13px\" : \"14px\",\n lineHeight: \"1.4\",\n borderTop: \"1px solid rgba(152, 162, 179, 0.3)\",\n paddingTop: \"12px\",\n marginTop: \"12px\",\n },\n });\n\n const footerP = el(\"p\", { style: { margin: \"0\", opacity: \"0.6\" } });\n\n // Privacy Center section: \"additional_text Privacy Center.\"\n if (activeConfig.privacy_center_url) {\n if (activeConfig.additional_text) {\n const addlSpan = el(\"span\", { id: \"additional-text\" });\n addlSpan.textContent = this.getTranslatedText(\"additional_text\", activeConfig.additional_text);\n footerP.appendChild(addlSpan);\n footerP.appendChild(document.createTextNode(\" \"));\n }\n\n const pcAnchorText = this.getTranslatedText(\"privacy_center_anchor_text\", activeConfig.privacy_center_anchor_text || \"Privacy Center\");\n this.privacyCenterLinkEl = el(\"a\", {\n id: \"privacy-center-link\",\n href: activeConfig.privacy_center_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n }) as HTMLAnchorElement;\n this.privacyCenterLinkEl.textContent = pcAnchorText;\n footerP.appendChild(this.privacyCenterLinkEl);\n footerP.appendChild(document.createTextNode(\".\"));\n }\n\n if (productPolicyLinks.length > 0) {\n if (activeConfig.privacy_center_url) {\n footerP.appendChild(el(\"br\"));\n }\n footerP.appendChild(\n renderProductPolicyLine({\n label: this.getTranslatedText(\"product_privacy_policies_label\", PRODUCT_POLICIES_LABEL),\n links: productPolicyLinks,\n linkStyle: { ...styles.link, color: linkColor, fontFamily: font },\n })\n );\n }\n\n // DPO Info section (all inline with <br> separators, matching React)\n if (activeConfig.dpo_info) {\n const dpo = activeConfig.dpo_info;\n\n if (activeConfig.privacy_center_url || productPolicyLinks.length > 0) {\n footerP.appendChild(el(\"br\"));\n }\n\n // Grievance line\n if (dpo.grievance_text) {\n const gText = el(\"span\", { id: \"dpo-grievance-text\" });\n gText.textContent = this.getTranslatedDpoText(\"grievance_text\", dpo.grievance_text);\n footerP.appendChild(gText);\n footerP.appendChild(document.createTextNode(\" \"));\n\n if (dpo.grievance_url) {\n const gLink = el(\"a\", {\n id: \"dpo-grievance-link\",\n href: dpo.grievance_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n });\n gLink.textContent = this.getTranslatedDpoText(\"grievance_anchor_text\", dpo.grievance_anchor_text);\n footerP.appendChild(gLink);\n }\n\n if (dpo.grievance_email) {\n footerP.appendChild(document.createTextNode(\" \"));\n const connectorSpan = el(\"span\", { id: \"dpo-grievance-email-connector\" });\n connectorSpan.textContent = this.getTranslatedDpoText(\n \"grievance_email_connector_text\",\n dpo.grievance_email_connector_text || \"or email to\"\n );\n footerP.appendChild(connectorSpan);\n footerP.appendChild(document.createTextNode(\" \"));\n\n const emailLink = el(\"a\", {\n id: \"dpo-grievance-email\",\n href: `mailto:${dpo.grievance_email}`,\n style: { ...styles.link, color: linkColor, fontFamily: font },\n });\n emailLink.textContent = dpo.grievance_email;\n footerP.appendChild(emailLink);\n }\n }\n\n // DP Board line\n if (dpo.dp_board_text) {\n footerP.appendChild(el(\"br\"));\n const dpText = el(\"span\", { id: \"dpo-dp-board-text\" });\n dpText.textContent = this.getTranslatedDpoText(\"dp_board_text\", dpo.dp_board_text);\n footerP.appendChild(dpText);\n footerP.appendChild(document.createTextNode(\" \"));\n\n if (dpo.dp_board_url) {\n const dpLink = el(\"a\", {\n id: \"dpo-dp-board-link\",\n href: dpo.dp_board_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n });\n dpLink.textContent = this.getTranslatedDpoText(\"dp_board_anchor_text\", dpo.dp_board_anchor_text);\n footerP.appendChild(dpLink);\n }\n }\n\n // DPO line\n if (dpo.dpo_text) {\n footerP.appendChild(el(\"br\"));\n const dpoTextSpan = el(\"span\", { id: \"dpo-dpo-text\" });\n dpoTextSpan.textContent = this.getTranslatedDpoText(\"dpo_text\", dpo.dpo_text);\n footerP.appendChild(dpoTextSpan);\n footerP.appendChild(document.createTextNode(\" \"));\n\n if (dpo.dpo_url) {\n const dpoLink = el(\"a\", {\n id: \"dpo-dpo-link\",\n href: dpo.dpo_url,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: linkColor, fontFamily: font },\n });\n dpoLink.textContent = this.getTranslatedDpoText(\"dpo_anchor_text\", dpo.dpo_anchor_text);\n footerP.appendChild(dpoLink);\n }\n }\n }\n\n footerDiv.appendChild(footerP);\n this.middleSection.appendChild(footerDiv);\n }\n\n // Error message\n this.errorEl = el(\"div\", {\n role: \"alert\",\n style: {\n backgroundColor: \"#FEE2E2\",\n color: \"#DC2626\",\n padding: \"12px\",\n borderRadius: \"6px\",\n fontSize: \"14px\",\n border: \"1px solid #FCA5A5\",\n display: \"none\",\n },\n });\n\n // ─── Bottom Section: three actions (matches React) ───\n // wide: [Decline] <-- gap --> [Accept Selected] [Accept All]\n // narrow: [Accept All] / [Accept Selected] / [Decline], stacked\n const acceptBtnText = state.isFullyConsentedReviewMode\n ? (this.options.reviewModeButtonText || \"Continue\")\n : this.getTranslatedText(\n \"confirm_button_text\",\n activeConfig.confirm_button_text || DEFAULT_ACCEPT_SELECTED_BUTTON_TEXT\n );\n\n // Three buttons share the footer width, so the single-button horizontal\n // padding would clip long translated labels. Let them wrap instead.\n // `width: auto` undoes `styles.button`'s `width: 100%` -- in the wide row\n // each button must size to its own label or the left/right split collapses.\n const gridButtonBox: Record<string, any> = {\n fontSize: isMobile ? \"14px\" : \"16px\",\n padding: state.isFullyConsentedReviewMode\n ? (isMobile ? \"10px 20px\" : \"9px 45px\")\n : \"9px 20px\",\n width:\n state.isFullyConsentedReviewMode || isMobile ? \"100%\" : \"auto\",\n whiteSpace: \"normal\",\n wordBreak: \"break-word\",\n };\n\n // \"Accept selected\" is outlined in the accent colour on the notice step --\n // subordinate to the filled Accept All. Review mode keeps it filled, since\n // it is then the only button.\n const acceptStyle: Record<string, any> = {\n ...styles.button,\n ...(state.isFullyConsentedReviewMode\n ? { ...styles.acceptButton, backgroundColor: colors.acceptBg, color: colors.acceptText }\n : {\n ...styles.cancelButton,\n backgroundColor: \"#ffffff\",\n color: colors.acceptShortcutText,\n borderColor: colors.acceptShortcutBorder,\n }),\n borderRadius: colors.borderRadius,\n ...gridButtonBox,\n };\n\n this.acceptBtn = el(\"button\", {\n id: ACCEPT_SELECTED_BUTTON_ID,\n style: acceptStyle,\n type: \"button\",\n onClick: () => this.confirmFirst(\"accept-selected\", () => this.handleAccept(\"selected\")),\n }) as HTMLButtonElement;\n this.acceptBtn.textContent = acceptBtnText;\n\n // Accept All is the filled primary -- the one-click path, in the far-right\n // slot -- so it carries the brand colour.\n const shortcutStyle: Record<string, any> = {\n ...styles.button,\n ...styles.acceptButton,\n backgroundColor: colors.acceptBg,\n color: colors.acceptText,\n borderRadius: colors.borderRadius,\n ...gridButtonBox,\n };\n\n this.acceptAllBtn = el(\"button\", {\n id: ACCEPT_ALL_BUTTON_ID,\n style: shortcutStyle,\n type: \"button\",\n onClick: () => this.confirmFirst(\"accept-all\", () => this.handleAccept(\"all\")),\n }) as HTMLButtonElement;\n this.acceptAllBtn.textContent = this.getTranslatedText(\n \"accept_all_button_text\",\n activeConfig.accept_all_button_text || DEFAULT_ACCEPT_ALL_BUTTON_TEXT\n );\n\n const declineBtnText = this.getTranslatedText(\n \"decline_button_text\",\n activeConfig.decline_button_text || DEFAULT_DECLINE_BUTTON_TEXT\n );\n const declineStyle: Record<string, any> = {\n ...styles.button,\n ...styles.cancelButton,\n backgroundColor: colors.declineBg,\n color: colors.declineText,\n borderColor: colors.declineBorder,\n borderRadius: colors.borderRadius,\n ...gridButtonBox,\n // Pushes everything after decline to the right edge, which is the whole\n // of the wide layout. Inert in the stack and in review mode.\n marginRight:\n state.isFullyConsentedReviewMode || isMobile ? \"0\" : \"auto\",\n };\n\n this.declineBtn = el(\"button\", {\n id: DECLINE_BUTTON_ID,\n style: declineStyle,\n type: \"button\",\n onClick: () => this.confirmFirst(\"decline\", () => this.handleDecline()),\n }) as HTMLButtonElement;\n\n if (!state.isFullyConsentedReviewMode) {\n this.declineBtn.textContent = declineBtnText;\n }\n\n // Review mode collapses to the single host-supplied continue button.\n const bottomSection = el(\"div\", {\n style: state.isFullyConsentedReviewMode\n ? styles.bottomSection\n : isMobile\n ? styles.actionButtonStack\n : styles.actionButtonRow,\n });\n if (state.isFullyConsentedReviewMode) {\n bottomSection.appendChild(this.acceptBtn);\n } else if (isMobile) {\n // Appended in a different order per breakpoint rather than reordered with\n // CSS, so focus order follows visual order (WCAG 2.4.3).\n bottomSection.appendChild(this.acceptAllBtn);\n bottomSection.appendChild(this.acceptBtn);\n bottomSection.appendChild(this.declineBtn);\n } else {\n bottomSection.appendChild(this.declineBtn);\n bottomSection.appendChild(this.acceptBtn);\n bottomSection.appendChild(this.acceptAllBtn);\n }\n\n // Assemble modal\n const contentWrapper = el(\n \"div\",\n { style: styles.content },\n topSection,\n this.errorEl,\n this.middleSection,\n bottomSection\n );\n\n this.modalEl.appendChild(contentWrapper);\n this.bottomSectionEl = bottomSection;\n this.confirmHintEl = renderConfirmHint();\n\n // Set initial accept button disabled state\n this.updateAcceptButtonState(state);\n\n // Setup keyboard trap\n this.keyboardCleanup?.();\n this.keyboardCleanup = setupKeyboardTrap(this.modalEl, () => this.handleDecline());\n }\n\n private getLanguageCode(displayLanguage: string): string {\n const content = this.store.getState().content?.detail.active_config;\n if (!content) return \"English\";\n\n // English maps to \"English\" for audio API\n if (displayLanguage === \"English\" || displayLanguage === \"en\" || displayLanguage === \"EN\") {\n return \"English\";\n }\n\n // If display language exists in translations, use it directly\n if (content.supported_languages_and_translations?.[displayLanguage]) {\n return displayLanguage;\n }\n\n // Fallback to default language or English\n return content.default_language === \"en\" || content.default_language === \"EN\"\n ? \"English\"\n : content.default_language || \"English\";\n }\n\n private getTranslatedDpoText(key: string, defaultText: string): string {\n const state = this.store.getState();\n const content = state.content?.detail.active_config;\n if (!content) return defaultText;\n\n const lang = state.selectedLanguage;\n if (lang === \"English\" || lang === \"en\" || lang === \"EN\") return defaultText;\n\n const translations = content.supported_languages_and_translations;\n if (!translations) return defaultText;\n\n const translationMap = translations[lang];\n if (!translationMap?.dpo_info) return defaultText;\n\n const value = (translationMap.dpo_info as any)[key];\n return typeof value === \"string\" && value ? value : defaultText;\n }\n\n private renderError(message: string): void {\n if (!this.modalEl) return;\n\n clearElement(this.modalEl);\n\n const errorContent = el(\n \"div\",\n { style: { ...styles.content, alignItems: \"center\", justifyContent: \"center\" } },\n el(\"div\", {\n role: \"alert\",\n style: {\n backgroundColor: \"#FEE2E2\",\n color: \"#DC2626\",\n padding: \"16px\",\n borderRadius: \"8px\",\n fontSize: \"14px\",\n border: \"1px solid #FCA5A5\",\n textAlign: \"center\",\n maxWidth: \"400px\",\n },\n }, message)\n );\n\n this.modalEl.appendChild(errorContent);\n }\n\n private getTranslatedText(key: string, defaultText: string, itemId?: string): string {\n const state = this.store.getState();\n const content = state.content?.detail.active_config;\n if (!content) return defaultText;\n\n const lang = state.selectedLanguage;\n if (lang === \"English\" || lang === \"en\" || lang === \"EN\") {\n if (key === \"privacy_policy_anchor_text\" && content.privacy_policy_anchor_text) {\n return content.privacy_policy_anchor_text;\n }\n return defaultText;\n }\n\n const translations = content.supported_languages_and_translations;\n if (!translations) return defaultText;\n\n const translationMap = translations[lang] as TranslationObject | undefined;\n if (!translationMap) return defaultText;\n\n if (itemId) {\n if (key === \"purposes.name\" || key === \"purposes.description\") {\n const purposeData = translationMap.purposes?.[itemId];\n if (purposeData) {\n if (typeof purposeData === \"string\") {\n return key === \"purposes.name\" ? purposeData : defaultText;\n }\n return key === \"purposes.name\"\n ? purposeData.name || defaultText\n : purposeData.description || defaultText;\n }\n return defaultText;\n }\n if (key === \"products.name\" || key === \"products.description\") {\n const productData = translationMap.products?.[itemId];\n if (productData) {\n if (typeof productData === \"string\") {\n return key === \"products.name\" ? productData : defaultText;\n }\n return key === \"products.name\"\n ? productData.name || defaultText\n : productData.description || defaultText;\n }\n return defaultText;\n }\n if (key.startsWith(\"data_elements.\")) {\n return translationMap.data_elements?.[itemId] || defaultText;\n }\n }\n\n const value = (translationMap as any)[key];\n if (typeof value === \"string\" && value) return value;\n return defaultText;\n }\n\n private handleLanguageSelect(lang: string): void {\n this.store.setState({ selectedLanguage: lang });\n // Rebuild UI to update all translations\n this.rebuildUI();\n }\n\n private togglePurposeCollapse(purposeUuid: string, productUuid?: string): void {\n const state = this.store.getState();\n const key = productPurposeKey(productUuid, purposeUuid);\n this.store.setState({\n collapsedPurposes: {\n ...state.collapsedPurposes,\n [key]: !state.collapsedPurposes[key],\n },\n });\n }\n\n private handlePurposeCheckboxChange(purposeUuid: string, productUuid?: string): void {\n this.otpSession.dropStashedAccept();\n const state = this.store.getState();\n const content = state.content?.detail.active_config;\n if (!content) return;\n\n const purpose = content.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose) return;\n\n const next = purposeToggle(purpose, productUuid, state.selectedPurposes);\n this.store.setState({\n selectedPurposes: { ...state.selectedPurposes, ...next.selectedPurposes },\n selectedDataElements: { ...state.selectedDataElements, ...next.selectedDataElements },\n });\n }\n\n private handleDataElementCheckboxChange(\n elementUuid: string,\n purposeUuid: string,\n productUuid?: string\n ): void {\n this.otpSession.dropStashedAccept();\n const state = this.store.getState();\n const content = state.content?.detail.active_config;\n if (!content) return;\n\n const purpose = content.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose) return;\n\n const key = productPurposeKey(productUuid, purposeUuid);\n const combinedId = `${key}-${elementUuid}`;\n const newDataElements = {\n ...state.selectedDataElements,\n [combinedId]: !state.selectedDataElements[combinedId],\n };\n\n this.store.setState({\n selectedDataElements: newDataElements,\n selectedPurposes: {\n ...state.selectedPurposes,\n [key]: purposeCheckedFromElements(purpose, productUuid, newDataElements),\n },\n });\n }\n\n private toggleProductCollapse(productUuid: string): void {\n const state = this.store.getState();\n this.store.setState({\n collapsedProducts: {\n ...state.collapsedProducts,\n [productUuid]: !state.collapsedProducts[productUuid],\n },\n });\n }\n\n private isRowLocked(state: ModalState, purposeUuid: string, productUuid?: string): boolean {\n if (isMultiProduct(state.content?.detail.active_config.products)) {\n return state.consentedPurposes[productPurposeKey(productUuid, purposeUuid)] ?? false;\n }\n return state.alreadyConsentedPurposes.some((purpose) => purpose.uuid === purposeUuid);\n }\n\n private handleProductCheckboxChange(productUuid: string, choice?: boolean): void {\n this.otpSession.dropStashedAccept();\n const state = this.store.getState();\n const section = this.productSections.find((refs) => refs.productUuid === productUuid);\n if (!section) return;\n\n const editable = section.boxPurposes.filter(\n (purpose) => !this.isRowLocked(state, purpose.uuid, section.keyProductUuid)\n );\n if (editable.length === 0) return;\n\n const next = sectionToggle(editable, section.keyProductUuid, state.selectedPurposes, choice);\n this.store.setState({\n selectedPurposes: { ...state.selectedPurposes, ...next.selectedPurposes },\n selectedDataElements: { ...state.selectedDataElements, ...next.selectedDataElements },\n });\n }\n\n private renderSoleProductSection(state: ModalState, isMobile: boolean): ProductSectionRefs | null {\n const content = state.content?.detail.active_config;\n const products = content?.products;\n if (!content || !products || products.length !== 1) return null;\n\n const product = products[0];\n const section = renderProductSection({\n product,\n purposes: content.purposes,\n selectedPurposes: state.selectedPurposes,\n collapsed: state.collapsedProducts[product.uuid] || false,\n locked: state.consentedProducts[product.uuid] ?? state.isFullyConsentedReviewMode,\n isRequired: productIsRequired(products, product.uuid),\n settings: this.options.settings,\n isMobile,\n getTranslatedText: (key, defaultText, itemId) => this.getTranslatedText(key, defaultText, itemId),\n onToggleCollapse: (productUuid) => this.toggleProductCollapse(productUuid),\n onToggleSelect: (productUuid, choice) => this.handleProductCheckboxChange(productUuid, choice),\n });\n this.productSections = [section];\n return section;\n }\n\n private updateProductSections(state: ModalState): void {\n for (const section of this.productSections) {\n updateProductSection(\n section,\n state.selectedPurposes,\n state.collapsedProducts[section.productUuid] || false\n );\n }\n }\n\n /**\n * Shared by all three accept buttons. The mode only decides which\n * purposes/data elements are submitted — everything downstream, including\n * the host's `onAccept` callback, is identical.\n */\n private async handleAccept(mode: AcceptMode = \"selected\"): Promise<void> {\n const state = this.store.getState();\n if (state.isSubmitting) return;\n\n // Review mode — just close\n if (state.isFullyConsentedReviewMode) {\n this.options.onAccept();\n this.destroy();\n return;\n }\n\n // Block submission for minors who have not completed guardian verification\n if (state.isMinorFlow && !state.verificationReference && !state.selfDeclaredAdult) {\n this.store.setState({\n errorMessage: \"Guardian verification is required before consent can be submitted.\",\n });\n return;\n }\n\n const content = state.content?.detail.active_config;\n if (!content) return;\n\n if (mode === \"selected\" && !this.confirmVerdict(state).ok) return;\n\n const rows = rowsOf(content);\n const selection = buildSelectionForMode(rows, mode, {\n selectedPurposes: state.selectedPurposes,\n selectedDataElements: state.selectedDataElements,\n });\n // Reflect the shortcut's selection in the checkboxes so the notice shows\n // what was sent if the request fails and it stays open.\n if (mode !== \"selected\") {\n this.store.setState({\n selectedPurposes: selection.selectedPurposes,\n selectedDataElements: selection.selectedDataElements,\n });\n }\n\n if (this.holdForOtp(mode)) return;\n\n this.abortController = new AbortController();\n this.store.setState({ isSubmitting: true, isSubmittingAccept: true, errorMessage: null });\n\n try {\n const purposes = submissionPurposes(rows, selection);\n\n await submitConsentEvent({\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n noticeUuid: state.content!.detail.uuid,\n purposes,\n declined: false,\n meta_data: this.options.applicationId ? { specific_uuid: this.options.applicationId } : undefined,\n guardianVerificationReference: state.verificationReference || undefined,\n selfDeclaredAdult: state.selfDeclaredAdult || undefined,\n language: state.selectedLanguage,\n signal: this.abortController.signal,\n ...this.sandboxParams(),\n });\n\n this.options.onAccept();\n this.destroy();\n } catch (err) {\n if ((err as Error).name === \"AbortError\") return;\n const error = err as Error;\n const message = error.message || \"Failed to submit consent. Please try again.\";\n this.store.setState({ errorMessage: message, isSubmitting: false, isSubmittingAccept: false });\n this.options.onError?.(error);\n }\n }\n\n private handleDecline(): void {\n this.otpSession.dropStashedAccept();\n const state = this.store.getState();\n if (state.isSubmitting) return;\n\n // Stop any in-flight verification polling and clear the persisted\n // DigiLocker session so the next open starts the flow from scratch\n // (age verification → guardian form → verification screen).\n this.stopPolling();\n clearConsentState();\n\n this.options.onDecline();\n this.destroy();\n }\n\n private updateCheckboxes(state: ModalState): void {\n if (this.purposeRefs) {\n for (const [key, control] of this.purposeRefs.purposeControls) {\n control.setChecked(state.selectedPurposes[key] || false);\n }\n for (const [key, checkbox] of this.purposeRefs.checkboxes) {\n if (key in state.selectedPurposes) {\n checkbox.checked = state.selectedPurposes[key] || false;\n } else {\n checkbox.checked = state.selectedDataElements[key] || false;\n }\n }\n }\n this.updateProductSections(state);\n // Update accept button disabled state\n this.updateAcceptButtonState(state);\n }\n\n private confirmVerdict(state: ModalState): ConfirmVerdict {\n const content = state.content?.detail.active_config;\n if (!content) return { ok: false, reason: \"nothing-chosen\", blocking: [] };\n return noticeConfirmVerdict(\n content,\n state.selectedPurposes,\n state.recordedPurposeSelections\n );\n }\n\n private updateConfirmHint(state: ModalState, verdict: ConfirmVerdict): void {\n if (!this.confirmHintEl || !this.bottomSectionEl) return;\n const submitting = state.isSubmittingAccept || state.isSubmittingDecline;\n const text =\n submitting || state.isFullyConsentedReviewMode\n ? null\n : confirmHint(verdict, state.content?.detail.active_config.products, (product) =>\n this.getTranslatedText(\"products.name\", product.name, product.uuid)\n );\n updateConfirmHint(this.confirmHintEl, this.bottomSectionEl, this.acceptBtn, text);\n }\n\n private updateAcceptButtonState(state: ModalState): void {\n if (!this.acceptBtn || state.isFullyConsentedReviewMode) return;\n\n const submitting = state.isSubmittingAccept || state.isSubmittingDecline;\n const verdict = this.confirmVerdict(state);\n this.updateConfirmHint(state, verdict);\n // Only \"accept selected\" waits on the required boxes — sparing the two\n // shortcuts that gate is the point of the feature.\n const setDisabled = (btn: HTMLButtonElement | null, disabled: boolean) => {\n if (!btn) return;\n btn.disabled = disabled;\n btn.style.opacity = disabled ? \"0.5\" : \"1\";\n btn.style.cursor = disabled ? \"not-allowed\" : \"pointer\";\n };\n\n setDisabled(this.acceptBtn, !verdict.ok || submitting);\n setDisabled(this.acceptAllBtn, submitting);\n }\n\n private updateCollapseState(state: ModalState): void {\n const updateRefs = (refs: ModalPurposeRefs | null) => {\n if (!refs) return;\n for (const [purposeUuid, container] of refs.dataElementContainers) {\n const isCollapsed = state.collapsedPurposes[purposeUuid];\n\n container.style.display = !isCollapsed && container.childElementCount > 0 ? \"flex\" : \"none\";\n\n const chevron = refs.chevrons.get(purposeUuid);\n if (chevron) {\n (chevron as unknown as HTMLElement).style.transform = !isCollapsed ? \"rotate(90deg)\" : \"rotate(0deg)\";\n }\n\n const collapseBtn = refs.collapseButtons.get(purposeUuid);\n if (collapseBtn) {\n collapseBtn.setAttribute(\"aria-expanded\", String(!isCollapsed));\n }\n }\n };\n\n updateRefs(this.purposeRefs);\n updateRefs(this.alreadyConsentedPurposeRefs);\n }\n\n private updateErrorMessage(state: ModalState): void {\n if (!this.errorEl) return;\n if (state.errorMessage) {\n this.errorEl.textContent = state.errorMessage;\n this.errorEl.style.display = \"block\";\n } else {\n this.errorEl.style.display = \"none\";\n }\n }\n\n // ─── Age Verification Handlers ───\n\n private handleAgeVerificationYes(): void {\n this.store.setState({\n isMinorFlow: false,\n selfDeclaredAdult: true,\n showAgeVerification: false,\n });\n }\n\n private handleAgeVerificationNo(): void {\n this.store.setState({\n showAgeVerification: false,\n showGuardianForm: true,\n });\n }\n\n // ─── Guardian Form Handlers ───\n\n private async handleGuardianFormSubmit(): Promise<void> {\n const state = this.store.getState();\n const errors = validateGuardianForm(state.guardianFormData);\n if (Object.keys(errors).length > 0) {\n if (this.guardianFormRefs) {\n if (errors.guardianName) {\n this.guardianFormRefs.nameError.textContent = errors.guardianName;\n this.guardianFormRefs.nameError.style.display = \"block\";\n }\n if (errors.guardianContact) {\n this.guardianFormRefs.contactError.textContent = errors.guardianContact;\n this.guardianFormRefs.contactError.style.display = \"block\";\n }\n if (errors.guardianRelationship) {\n this.guardianFormRefs.relationshipError.textContent = errors.guardianRelationship;\n this.guardianFormRefs.relationshipError.style.display = \"block\";\n }\n }\n return;\n }\n\n this.store.setState({ isInitiatingVerification: true });\n\n const digilockerMode = this.options.digilockerMode || \"redirect\";\n const callbackUrl = digilockerMode === \"popup\"\n ? new URL(this.options.digilockerCallbackUrl || \"/digilocker-callback\", window.location.origin).href\n : undefined;\n\n try {\n const response = await initiateGuardianVerification({\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n guardianName: state.guardianFormData.guardianName,\n guardianContact: state.guardianFormData.guardianContact,\n guardianRelationship: state.guardianFormData.guardianRelationship,\n frontendCallbackUrl: callbackUrl,\n });\n\n if (response.already_verified && response.verification_reference) {\n this.store.setState({\n verificationReference: response.verification_reference,\n showGuardianForm: false,\n showVerificationScreen: true,\n isInitiatingVerification: false,\n isVerificationComplete: true,\n });\n // Auto-transition to consent form after 1s\n setTimeout(() => {\n this.store.setState({\n showVerificationScreen: false,\n isVerificationComplete: false,\n });\n }, 1000);\n return;\n }\n\n // Save state for redirect flow\n saveConsentState({\n flowState: \"digilocker-pending\",\n sessionToken: response.session_token,\n guardianInfoUuid: response.guardian_info_uuid,\n selectedPurposes: state.selectedPurposes,\n selectedDataElements: state.selectedDataElements,\n timestamp: new Date().toISOString(),\n originalUrl: window.location.href,\n noticeId: this.options.noticeId,\n baseUrl: this.options.baseUrl,\n });\n\n // Show verification screen with \"Opening DigiLocker...\" state\n this.store.setState({\n showGuardianForm: false,\n showVerificationScreen: true,\n isInitiatingVerification: true,\n isPollingStatus: false,\n });\n\n if (digilockerMode === \"popup\" && response.digilocker_redirect_url) {\n const popup = window.open(\n response.digilocker_redirect_url,\n \"digilocker_verification\",\n \"width=600,height=700,scrollbars=yes,resizable=yes\"\n );\n if (popup) {\n this.verificationPopup = popup;\n this.startPopupMonitoring(popup);\n } else {\n this.store.setState({\n isInitiatingVerification: false,\n verificationError: \"Popup blocked. Please allow popups for this site.\",\n canRetryVerification: true,\n });\n return;\n }\n } else if (response.digilocker_redirect_url) {\n const openedWindow = window.open(response.digilocker_redirect_url, \"_blank\");\n if (!openedWindow) {\n this.store.setState({\n isInitiatingVerification: false,\n verificationError: \"Unable to open DigiLocker. Please allow popups.\",\n canRetryVerification: true,\n });\n return;\n }\n try { openedWindow.opener = null; } catch {}\n }\n\n // Switch to polling state (spinner + \"Please complete verification...\" message)\n this.store.setState({\n isInitiatingVerification: false,\n isPollingStatus: true,\n });\n this.startStatusPolling(response.session_token!);\n } catch (error) {\n this.store.setState({ isInitiatingVerification: false });\n const err = error as Error & { status?: number };\n if (this.guardianFormRefs) {\n this.guardianFormRefs.generalError.textContent = err.message || \"Failed to initiate verification.\";\n this.guardianFormRefs.generalError.style.display = \"block\";\n }\n }\n }\n\n // ─── Verification Polling ───\n\n private startStatusPolling(token: string): void {\n this.verificationSessionToken = token;\n let attempts = 0;\n let consecutiveErrors = 0;\n let paused = false;\n const MAX_ATTEMPTS = 40;\n const MAX_CONSECUTIVE_ERRORS = 3;\n const POLL_INTERVAL = 3000;\n\n const poll = async () => {\n if (paused) return;\n attempts++;\n\n if (attempts > MAX_ATTEMPTS) {\n this.stopPolling();\n this.store.setState({\n verificationError: \"Verification is taking longer than expected. Please try again.\",\n verificationErrorCode: \"SESSION_EXPIRED\",\n canRetryVerification: true,\n isPollingStatus: false,\n });\n return;\n }\n\n try {\n const response = await verifyGuardianStatus({\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n sessionToken: token,\n });\n\n consecutiveErrors = 0;\n\n if (response.status === \"verified\") {\n this.stopPolling();\n const ref = response.verification_reference || response.guardian_details?.verification_reference;\n if (!ref) {\n this.store.setState({\n verificationError: \"Verification completed but no reference received. Please try again.\",\n canRetryVerification: true,\n isPollingStatus: false,\n });\n return;\n }\n this.store.setState({\n verificationReference: ref,\n isVerificationComplete: true,\n isPollingStatus: false,\n });\n clearConsentState();\n return;\n }\n\n if (response.status === \"failed\" || response.status === \"expired\") {\n this.stopPolling();\n this.store.setState({\n verificationError: getVerificationErrorMessage(response.error_code, response.error),\n verificationErrorCode: response.error_code,\n canRetryVerification: response.can_retry,\n isPollingStatus: false,\n });\n return;\n }\n\n if (!paused) {\n this.statusPollTimeout = setTimeout(poll, POLL_INTERVAL);\n }\n } catch (error) {\n const err = error as Error & { status?: number };\n if (err.status === 404 || err.status === 410) {\n this.stopPolling();\n this.store.setState({\n verificationError: \"Verification session not found or expired.\",\n verificationErrorCode: \"SESSION_EXPIRED\",\n canRetryVerification: true,\n isPollingStatus: false,\n });\n return;\n }\n\n consecutiveErrors++;\n if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) {\n this.stopPolling();\n this.store.setState({\n verificationError: err.message || \"Unable to check verification status.\",\n canRetryVerification: true,\n isPollingStatus: false,\n });\n return;\n }\n\n this.statusPollTimeout = setTimeout(poll, POLL_INTERVAL);\n }\n };\n\n // Pause when tab hidden, resume on return\n this.visibilityChangeHandler = () => {\n if (document.hidden) {\n paused = true;\n if (this.statusPollTimeout) {\n clearTimeout(this.statusPollTimeout);\n this.statusPollTimeout = null;\n }\n } else {\n paused = false;\n poll();\n }\n };\n document.addEventListener(\"visibilitychange\", this.visibilityChangeHandler);\n\n this.statusPollTimeout = setTimeout(poll, POLL_INTERVAL);\n }\n\n private stopPolling(): void {\n if (this.statusPollTimeout) {\n clearTimeout(this.statusPollTimeout);\n this.statusPollTimeout = null;\n }\n if (this.popupCheckInterval) {\n clearInterval(this.popupCheckInterval);\n this.popupCheckInterval = null;\n }\n if (this.visibilityChangeHandler) {\n document.removeEventListener(\"visibilitychange\", this.visibilityChangeHandler);\n this.visibilityChangeHandler = null;\n }\n this.verificationPopup?.close();\n this.verificationPopup = null;\n }\n\n private startPopupMonitoring(popup: Window): void {\n this.popupCheckInterval = setInterval(() => {\n if (popup.closed) {\n if (this.popupCheckInterval) {\n clearInterval(this.popupCheckInterval);\n this.popupCheckInterval = null;\n }\n }\n }, 500);\n }\n\n // ─── Verification Screen Handlers ───\n\n private handleVerificationContinue(): void {\n this.store.setState({\n showVerificationScreen: false,\n isVerificationComplete: false,\n });\n }\n\n private handleVerificationRetry(): void {\n this.store.setState({\n showVerificationScreen: false,\n showGuardianForm: true,\n verificationError: null,\n verificationErrorCode: null,\n canRetryVerification: false,\n isVerificationComplete: false,\n });\n }\n\n private handleChangeGuardian(): void {\n this.store.setState({\n showVerificationScreen: false,\n showGuardianForm: true,\n verificationError: null,\n verificationErrorCode: null,\n canRetryVerification: false,\n isVerificationComplete: false,\n guardianFormData: { guardianName: \"\", guardianContact: \"\", guardianRelationship: \"\" },\n });\n }\n\n // ─── TTS ───\n\n private updateTTSButton(): void {\n if (!this.ttsButton || !this.ttsManager) return;\n\n // When the current language has no TTS audio (e.g. Santali in some\n // configs), hide the speaker icon entirely. Without this branch the\n // button would keep whatever display value it had from the previous\n // language and clicking it would replay the previous language's audio.\n if (!this.ttsManager.isAvailable) {\n this.ttsButton.style.display = \"none\";\n return;\n }\n\n this.ttsButton.style.display = \"flex\";\n\n // Swap SVG: speaker icon vs pause icon\n clearElement(this.ttsButton);\n const strokeColor = this.options.settings?.button?.language?.textColor || \"currentColor\";\n\n if (this.ttsManager.isPlaying) {\n // Pause icon\n const pauseSvg = svg(\n \"svg\",\n {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"16\", height: \"16\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: strokeColor, \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n \"aria-hidden\": \"true\",\n },\n svg(\"rect\", { x: \"6\", y: \"4\", width: \"4\", height: \"16\" }),\n svg(\"rect\", { x: \"14\", y: \"4\", width: \"4\", height: \"16\" })\n );\n this.ttsButton.appendChild(pauseSvg);\n this.ttsButton.setAttribute(\"aria-label\", \"Pause audio playback\");\n this.ttsButton.setAttribute(\"title\", \"Pause Talkback\");\n } else {\n // Speaker icon\n const speakerSvg = svg(\n \"svg\",\n {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: \"16\", height: \"16\", viewBox: \"0 0 24 24\",\n fill: \"none\", stroke: strokeColor, \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\", \"stroke-linejoin\": \"round\",\n \"aria-hidden\": \"true\",\n },\n svg(\"polygon\", { points: \"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" }),\n svg(\"path\", { d: \"M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07\" })\n );\n this.ttsButton.appendChild(speakerSvg);\n this.ttsButton.setAttribute(\"aria-label\", this.ttsManager.isPaused ? \"Resume audio playback\" : \"Start audio playback\");\n this.ttsButton.setAttribute(\"title\", this.ttsManager.isPaused ? \"Resume Talkback\" : \"Start Talkback\");\n }\n }\n\n private updateButtonStates(state: ModalState): void {\n const content = state.content?.detail.active_config;\n\n // All three accept buttons submit through the same path, so a submission\n // in flight busies every one of them.\n const applySubmittingState = (\n btn: HTMLButtonElement | null,\n idleLabel: string\n ) => {\n if (!btn) return;\n btn.textContent = state.isSubmittingAccept\n ? SUBMITTING_BUTTON_TEXT\n : idleLabel;\n btn.disabled = state.isSubmittingAccept;\n btn.style.opacity = state.isSubmittingAccept ? \"0.7\" : \"1\";\n btn.style.cursor = state.isSubmittingAccept ? \"not-allowed\" : \"pointer\";\n };\n\n applySubmittingState(\n this.acceptBtn,\n state.isFullyConsentedReviewMode\n ? this.options.reviewModeButtonText || \"Continue\"\n : this.getTranslatedText(\n \"confirm_button_text\",\n content?.confirm_button_text || DEFAULT_ACCEPT_SELECTED_BUTTON_TEXT\n )\n );\n applySubmittingState(\n this.acceptAllBtn,\n this.getTranslatedText(\n \"accept_all_button_text\",\n content?.accept_all_button_text || DEFAULT_ACCEPT_ALL_BUTTON_TEXT\n )\n );\n\n if (this.declineBtn) {\n this.declineBtn.disabled = state.isSubmitting;\n this.declineBtn.style.opacity = state.isSubmitting ? \"0.7\" : \"1\";\n this.declineBtn.style.cursor = state.isSubmitting ? \"not-allowed\" : \"pointer\";\n }\n\n // Re-apply the required-elements gate, which `applySubmittingState` above\n // deliberately does not know about.\n this.updateAcceptButtonState(state);\n }\n}\n","export const inlineStyles = {\n optionItem: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionLeft: {\n display: \"flex\",\n gap: \"12px\",\n alignItems: \"center\",\n cursor: \"pointer\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionTextContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n },\n\n optionTitle: {\n fontWeight: 500,\n fontSize: \"16px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#101828\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n optionDescription: {\n fontWeight: 400,\n fontSize: \"12px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#475467\",\n verticalAlign: \"middle\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n checkboxLarge: {\n height: \"20px\",\n width: \"20px\",\n padding: \"4px\",\n borderRadius: \"5px\",\n border: \"2px solid #d0d5dd\",\n margin: 0,\n boxSizing: \"border-box\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n MozAppearance: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n backgroundColor: \"transparent\",\n },\n\n dataElementsContainer: {\n marginLeft: \"27px\",\n display: \"flex\",\n flexDirection: \"column\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n paddingLeft: \"22px\",\n },\n\n dataElementItem: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n justifyContent: \"space-between\",\n margin: 0,\n padding: 0,\n boxSizing: \"border-box\",\n minHeight: \"24px\",\n },\n\n dataElementText: {\n fontWeight: 400,\n fontSize: \"14px\",\n lineHeight: \"150%\",\n letterSpacing: \"0.2px\",\n color: \"#344054\",\n margin: 0,\n padding: 0,\n textAlign: \"left\",\n },\n\n checkboxSmall: {\n height: \"16px\",\n width: \"16px\",\n padding: \"4px\",\n borderRadius: \"5px\",\n border: \"2px solid #d0d5dd\",\n margin: 0,\n boxSizing: \"border-box\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n MozAppearance: \"none\",\n cursor: \"pointer\",\n position: \"relative\",\n backgroundColor: \"transparent\",\n },\n\n loadingContainer: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"2rem\",\n minHeight: \"200px\",\n margin: 0,\n boxSizing: \"border-box\",\n },\n\n loadingSpinner: {\n width: \"40px\",\n height: \"40px\",\n border: \"4px solid #f3f3f3\",\n borderTop: \"4px solid #3498db\",\n borderRadius: \"50%\",\n animation: \"spin 1s linear infinite\",\n marginBottom: \"1rem\",\n boxSizing: \"border-box\",\n },\n} as const;\n","import { isBlockingRequiredElement } from \"../modal/consentSelection\";\nimport { noticePurposeRows, productPurposeKey } from \"../core/productMatrix\";\nimport type { ProductLike } from \"../types\";\nimport type { Purpose } from \"../api/types\";\nimport type {\n InlineElementFlags,\n InlineNoticePurpose,\n InlinePurposeRow,\n InlineSelectablePurpose,\n InlineSelection,\n} from \"./types\";\n\nexport { isBlockingRequiredElement };\n\nexport const hasBlockingRequiredElement = (purpose: {\n data_elements: Array<{ enabled: boolean; required: boolean }>;\n}): boolean => purpose.data_elements.some(isBlockingRequiredElement);\n\nexport const inlineElementKey = (\n productUuid: string | undefined,\n purposeUuid: string,\n elementUuid: string\n): string => `${productPurposeKey(productUuid, purposeUuid)}-${elementUuid}`;\n\nexport const inlinePurposeRows = <P extends ProductLike, U extends InlineSelectablePurpose>(config: {\n products?: P[];\n purposes: U[];\n product_purpose_order?: Record<string, string[]>;\n}): InlinePurposeRow<U>[] =>\n noticePurposeRows(config.products, config.purposes, config.product_purpose_order);\n\nexport const initialCollapsedPurposes = <U extends InlineSelectablePurpose>(\n rows: InlinePurposeRow<U>[]\n): Record<string, boolean> =>\n rows.reduce<Record<string, boolean>>((acc, row) => {\n acc[productPurposeKey(row.productUuid, row.purpose.uuid)] = true;\n return acc;\n }, {});\n\nexport const initialSelection = <U extends InlineSelectablePurpose>(\n rows: InlinePurposeRow<U>[]\n): InlineSelection => {\n const selectedPurposes: Record<string, boolean> = {};\n const selectedDataElements: Record<string, boolean> = {};\n rows.forEach(({ purpose, productUuid }) => {\n selectedPurposes[productPurposeKey(productUuid, purpose.uuid)] = false;\n purpose.data_elements.forEach((element) => {\n selectedDataElements[inlineElementKey(productUuid, purpose.uuid, element.uuid)] = false;\n });\n });\n return { selectedPurposes, selectedDataElements };\n};\n\nexport const allRequiredElementsChecked = <U extends InlineSelectablePurpose>(\n rows: InlinePurposeRow<U>[],\n selectedDataElements: Record<string, boolean>\n): boolean =>\n rows.every(({ purpose, productUuid }) =>\n purpose.data_elements\n .filter(isBlockingRequiredElement)\n .every((element) =>\n Boolean(selectedDataElements[inlineElementKey(productUuid, purpose.uuid, element.uuid)])\n )\n );\n\nexport const withPurposeElements = (\n purpose: InlineSelectablePurpose,\n productUuid: string | undefined,\n selected: boolean,\n selectedDataElements: Record<string, boolean>\n): Record<string, boolean> => {\n const updated = { ...selectedDataElements };\n purpose.data_elements.forEach((element) => {\n updated[inlineElementKey(productUuid, purpose.uuid, element.uuid)] =\n selected && element.enabled;\n });\n return updated;\n};\n\nexport const toggleDataElement = (\n purpose: InlineSelectablePurpose,\n elementUuid: string,\n productUuid: string | undefined,\n selectedDataElements: Record<string, boolean>\n): { selectedDataElements: Record<string, boolean>; purposeSelected: boolean } => {\n const combinedId = inlineElementKey(productUuid, purpose.uuid, elementUuid);\n const next = { ...selectedDataElements, [combinedId]: !selectedDataElements[combinedId] };\n const isTicked = (element: InlineElementFlags) =>\n Boolean(next[inlineElementKey(productUuid, purpose.uuid, element.uuid)]);\n const requiredElements = purpose.data_elements.filter(isBlockingRequiredElement);\n const purposeSelected =\n requiredElements.length > 0\n ? requiredElements.every(isTicked)\n : purpose.data_elements.some(isTicked);\n return { selectedDataElements: next, purposeSelected };\n};\n\nexport const buildInlineSubmitPurposes = (\n rows: InlinePurposeRow<InlineNoticePurpose>[],\n { selectedPurposes, selectedDataElements }: InlineSelection\n): Purpose[] =>\n rows.map(({ purpose, productUuid }) => {\n const key = productPurposeKey(productUuid, purpose.uuid);\n const isTicked = (elementUuid: string) =>\n selectedDataElements[`${key}-${elementUuid}`] || false;\n const hasSelectedRequiredElement = purpose.data_elements.some(\n (element) => element.required && isTicked(element.uuid)\n );\n const hasSelectedDataElement = purpose.data_elements.some((element) =>\n isTicked(element.uuid)\n );\n const purposeSelected =\n selectedPurposes[key] || hasSelectedRequiredElement || hasSelectedDataElement;\n return {\n ...purpose,\n ...(productUuid ? { product_uuid: productUuid } : {}),\n selected: purposeSelected,\n data_elements: purpose.data_elements.map((element) => ({\n ...element,\n selected: isTicked(element.uuid),\n })),\n };\n });\n\nexport const inlineSubmissionKey = (\n accessToken: string | undefined,\n configUuid: string | undefined,\n { selectedPurposes, selectedDataElements }: InlineSelection\n): string =>\n JSON.stringify([accessToken ?? null, configUuid ?? null, selectedPurposes, selectedDataElements]);\n\nexport const isRetryableFailure = (error: unknown): boolean => {\n const status = (error as { status?: unknown } | null)?.status;\n return typeof status !== \"number\" || status >= 500;\n};\n","import { el, svg, applyStyles } from \"../core/dom\";\nimport { createRequiredMarker } from \"../core/required-marker\";\nimport { inlineStyles } from \"../styles/inline\";\nimport {\n groupPurposesByProduct,\n isMultiProduct,\n productPurposeKey,\n} from \"../core/productMatrix\";\nimport { hasBlockingRequiredElement, isBlockingRequiredElement } from \"./selection\";\nimport type { PurposeItemData } from \"../api/types\";\nimport type { InlinePurposeRenderOptions } from \"./types\";\n\nexport type PurposeRenderRefs = {\n container: HTMLElement;\n checkboxes: Map<string, HTMLInputElement>; // purposeUuid or \"purposeUuid-elementUuid\"\n collapseButtons: Map<string, HTMLElement>;\n dataElementContainers: Map<string, HTMLElement>;\n chevrons: Map<string, SVGElement>;\n titleElements: Map<string, HTMLElement>;\n descriptionElements: Map<string, HTMLElement>;\n dataElementLabels: Map<string, HTMLElement>;\n};\n\nexport function renderInlinePurposes(\n purposes: PurposeItemData[],\n options: InlinePurposeRenderOptions\n): PurposeRenderRefs {\n const {\n selectedPurposes,\n collapsedPurposes,\n selectedDataElements,\n products,\n productPurposeOrder,\n settings,\n isMobile,\n getTranslatedText,\n onPurposeToggle,\n onPurposeCollapse,\n onDataElementToggle,\n } = options;\n\n const checkboxes = new Map<string, HTMLInputElement>();\n const collapseButtons = new Map<string, HTMLElement>();\n const dataElementContainers = new Map<string, HTMLElement>();\n const chevrons = new Map<string, SVGElement>();\n const titleElements = new Map<string, HTMLElement>();\n const descriptionElements = new Map<string, HTMLElement>();\n const dataElementLabels = new Map<string, HTMLElement>();\n\n const headingColor = settings?.headingColor || \"#101828\";\n const textColor = settings?.textColor || \"#344054\";\n\n const container = el(\"div\", {\n style: { display: \"flex\", flexDirection: \"column\", gap: \"16px\" },\n });\n\n const renderPurpose = (purpose: PurposeItemData, productUuid?: string): HTMLElement => {\n const stateKey = productPurposeKey(productUuid, purpose.uuid);\n const purposeWrapper = el(\"div\");\n\n // Chevron SVG\n const chevron = svg(\n \"svg\",\n {\n width: \"7\",\n height: \"12\",\n viewBox: \"0 0 7 12\",\n fill: \"none\",\n xmlns: \"http://www.w3.org/2000/svg\",\n stroke: settings?.headingColor || \"#323B4B\",\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n style: {\n transform: !collapsedPurposes[stateKey] ? \"rotate(90deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.3s ease\",\n },\n \"aria-hidden\": \"true\",\n },\n svg(\"path\", { d: \"M1 1L6 6L1 11\" })\n );\n chevrons.set(stateKey, chevron);\n\n const chevronContainer = el(\n \"div\",\n {\n style: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n marginLeft: \"5px\",\n },\n },\n chevron\n );\n\n // Title\n const titleEl = el(\"h2\", {\n style: {\n ...inlineStyles.optionTitle,\n fontSize: isMobile ? \"14px\" : \"16px\",\n color: headingColor,\n },\n });\n // Appended after `textContent`, which replaces every existing child.\n titleEl.textContent = getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid);\n if (hasBlockingRequiredElement(purpose)) {\n titleEl.appendChild(createRequiredMarker());\n }\n titleElements.set(stateKey, titleEl);\n\n // Description\n const descEl = el(\"h3\", {\n style: {\n ...inlineStyles.optionDescription,\n fontSize: isMobile ? \"11px\" : \"12px\",\n color: textColor,\n },\n });\n descEl.textContent = getTranslatedText(\"purposes.description\", purpose.description, purpose.uuid);\n descriptionElements.set(stateKey, descEl);\n\n const textContainer = el(\"div\", { style: inlineStyles.optionTextContainer }, titleEl, descEl);\n\n // Collapse button\n const collapseBtn = el(\"div\", {\n style: inlineStyles.optionLeft,\n role: \"button\",\n tabIndex: \"0\",\n \"aria-expanded\": String(!collapsedPurposes[stateKey]),\n \"aria-controls\": `purpose-${stateKey}`,\n \"aria-label\": `${collapsedPurposes[stateKey] ? \"Expand\" : \"Collapse\"} ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)} details`,\n onClick: () => onPurposeCollapse(purpose.uuid, productUuid),\n onKeydown: (e: KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onPurposeCollapse(purpose.uuid, productUuid);\n }\n },\n }, chevronContainer, textContainer);\n collapseButtons.set(stateKey, collapseBtn);\n\n // Purpose checkbox\n const purposeCheckbox = el(\"input\", {\n type: \"checkbox\",\n checked: selectedPurposes[stateKey] || false,\n \"aria-label\": `Select all data elements for ${getTranslatedText(\"purposes.name\", purpose.name, purpose.uuid)}`,\n onChange: () => onPurposeToggle(purpose.uuid, productUuid),\n }) as HTMLInputElement;\n checkboxes.set(stateKey, purposeCheckbox);\n\n const optionRow = el(\"div\", { style: inlineStyles.optionItem }, collapseBtn, purposeCheckbox);\n\n // Data elements container\n const deContainer = el(\"div\", {\n id: `purpose-${stateKey}`,\n style: inlineStyles.dataElementsContainer,\n });\n\n if (purpose.data_elements && purpose.data_elements.length > 0) {\n for (const dataElement of purpose.data_elements) {\n const combinedId = `${stateKey}-${dataElement.uuid}`;\n\n const labelSpan = el(\"span\", {\n style: {\n ...inlineStyles.dataElementText,\n fontSize: isMobile ? \"12px\" : \"14px\",\n color: textColor,\n },\n });\n labelSpan.textContent = getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid);\n dataElementLabels.set(combinedId, labelSpan);\n\n if (isBlockingRequiredElement(dataElement)) {\n labelSpan.appendChild(createRequiredMarker());\n }\n\n const deCheckbox = el(\"input\", {\n type: \"checkbox\",\n checked: selectedDataElements[combinedId] || false,\n \"aria-label\": `Select ${getTranslatedText(\"data_elements.name\", dataElement.name, dataElement.uuid)}${isBlockingRequiredElement(dataElement) ? \" (required)\" : \"\"}`,\n onChange: () => onDataElementToggle(dataElement.uuid, purpose.uuid, productUuid),\n }) as HTMLInputElement;\n checkboxes.set(combinedId, deCheckbox);\n\n const deRow = el(\"div\", { style: inlineStyles.dataElementItem }, labelSpan, deCheckbox);\n deContainer.appendChild(deRow);\n }\n }\n\n dataElementContainers.set(stateKey, deContainer);\n\n // Show/hide data elements based on collapse state\n if (!collapsedPurposes[stateKey] && purpose.data_elements?.length > 0) {\n deContainer.style.display = \"flex\";\n } else {\n deContainer.style.display = \"none\";\n }\n\n purposeWrapper.appendChild(optionRow);\n purposeWrapper.appendChild(deContainer);\n return purposeWrapper;\n };\n\n if (!isMultiProduct(products)) {\n for (const purpose of purposes) {\n container.appendChild(renderPurpose(purpose));\n }\n } else {\n for (const group of groupPurposesByProduct(products, purposes, productPurposeOrder)) {\n const heading = el(\"div\", { style: { ...inlineStyles.optionTitle, color: headingColor } });\n heading.textContent = getTranslatedText(\"products.name\", group.product.name, group.product.uuid);\n const section = el(\n \"div\",\n { style: { display: \"flex\", flexDirection: \"column\", gap: \"16px\" } },\n heading\n );\n for (const purpose of group.purposes) {\n section.appendChild(renderPurpose(purpose, group.product.uuid));\n }\n container.appendChild(section);\n }\n }\n\n return {\n container,\n checkboxes,\n collapseButtons,\n dataElementContainers,\n chevrons,\n titleElements,\n descriptionElements,\n dataElementLabels,\n };\n}\n","import { Store } from \"../core/state\";\nimport { createMediaQuery, type MediaQuerySubscription } from \"../core/media-query\";\nimport { el, applyStyles, clearElement } from \"../core/dom\";\nimport { fetchConsentContentPublic, submitConsentEventPublic } from \"../api\";\nimport { resolveDisplayLanguage } from \"../api/language\";\nimport {\n fetchNoticeConsentStatusForScope,\n isNoticeFullyConsented,\n} from \"../api/notice-consent-status\";\nimport { injectCheckboxStyles } from \"../styles/inject\";\nimport { inlineStyles } from \"../styles/inline\";\nimport { renderInlinePurposes, type PurposeRenderRefs } from \"./purposes\";\nimport { productPurposeKey } from \"../core/productMatrix\";\nimport {\n allRequiredElementsChecked,\n buildInlineSubmitPurposes,\n initialCollapsedPurposes,\n initialSelection,\n inlinePurposeRows,\n inlineSubmissionKey,\n isRetryableFailure,\n toggleDataElement,\n withPurposeElements,\n} from \"./selection\";\nimport type { InlineOptions } from \"../types\";\nimport type { ActiveConfig, TranslationObject } from \"../api/types\";\n\ntype InlineState = {\n content: ActiveConfig | null;\n isLoading: boolean;\n isSubmitting: boolean;\n selectedLanguage: string;\n collapsedPurposes: Record<string, boolean>;\n selectedPurposes: Record<string, boolean>;\n selectedDataElements: Record<string, boolean>;\n hasAlreadyConsented: boolean;\n // Blocks auto-submit while the Go ledger check-consent read is in flight,\n // so an already-consented principal is not re-submitted post-cutover.\n isCheckingConsent: boolean;\n fetchError: Error | null;\n errorMessage: string | null;\n};\n\nexport class InlineController {\n private store: Store<InlineState>;\n private options: InlineOptions;\n private targetEl: HTMLElement | null = null;\n private hostEl: HTMLElement | null = null;\n private shadowRoot: ShadowRoot | null = null;\n private rootEl: HTMLElement | null = null;\n private mediaQuery: MediaQuerySubscription;\n private purposeRefs: PurposeRenderRefs | null = null;\n private errorEl: HTMLElement | null = null;\n private hasSubmitted = false;\n private lastSubmissionKey: string | null = null;\n private hasCheckedLedgerConsent = false;\n private fetchedWithToken = false;\n private fetchGeneration = 0;\n private unsubscribe: (() => void) | null = null;\n private abortController: AbortController | null = null;\n\n constructor(options: InlineOptions) {\n this.options = options;\n this.store = new Store<InlineState>({\n content: null,\n isLoading: true,\n isSubmitting: false,\n selectedLanguage: options.language || \"en\",\n collapsedPurposes: {},\n selectedPurposes: {},\n selectedDataElements: {},\n hasAlreadyConsented: false,\n isCheckingConsent: false,\n fetchError: null,\n errorMessage: null,\n });\n this.mediaQuery = createMediaQuery(\"(max-width: 768px)\");\n }\n\n async init(): Promise<void> {\n this.abortController = new AbortController();\n\n // Resolve target element\n if (typeof this.options.target === \"string\") {\n this.targetEl = document.querySelector(this.options.target);\n if (!this.targetEl) {\n throw new Error(`Target element not found: ${this.options.target}`);\n }\n } else {\n this.targetEl = this.options.target;\n }\n\n // Mount the inline form inside an open shadow root attached to a host\n // <div> within the user's target container. This matches the modal's\n // isolation strategy so host-page CSS cannot bleed into the inline form\n // either.\n this.hostEl = document.createElement(\"div\");\n this.hostEl.setAttribute(\"data-redacto-consent-inline\", \"\");\n // Block-level, but no `all: initial` — we want font / color / line-height\n // to inherit from the user's page so the inline form blends in like the\n // React SDK does.\n this.hostEl.style.display = \"block\";\n this.targetEl.appendChild(this.hostEl);\n this.shadowRoot = this.hostEl.attachShadow({ mode: \"open\" });\n injectCheckboxStyles(this.shadowRoot);\n\n // Subscribe to state changes\n this.unsubscribe = this.store.subscribe((state, prevState) => {\n this.handleStateChange(state, prevState);\n });\n\n // Subscribe to media query changes\n this.mediaQuery.subscribe(() => this.rebuildUI());\n\n // Render loading state\n this.renderLoading();\n\n // Fetch content\n await this.fetchNotice();\n }\n\n destroy(): void {\n // Cancels the in-flight ledger read and marks the controller torn down, so\n // late-resolving work cannot fire host callbacks or submit consent.\n this.abortController?.abort();\n this.unsubscribe?.();\n this.mediaQuery.destroy();\n this.store.destroy();\n // Removing the host div tears down the shadow tree (and the rootEl\n // inside it) in one step.\n if (this.hostEl && this.hostEl.parentNode) {\n this.hostEl.parentNode.removeChild(this.hostEl);\n }\n this.hostEl = null;\n this.shadowRoot = null;\n this.rootEl = null;\n this.purposeRefs = null;\n }\n\n updateToken(accessToken: string): void {\n this.options = { ...this.options, accessToken };\n if (accessToken && !this.fetchedWithToken) {\n void this.fetchNotice();\n return;\n }\n // A late-arriving token is the first chance to run the ledger\n // check-consent read; it gates auto-submit synchronously before trying.\n if (this.shouldCheckLedgerConsent()) {\n void this.checkLedgerConsent();\n return;\n }\n this.tryAutoSubmit();\n }\n\n // ─── Private ───\n\n // destroy() aborts the controller, so an aborted signal is the marker that\n // teardown has happened and async continuations must not touch the host.\n private isDestroyed(): boolean {\n return Boolean(this.abortController?.signal.aborted);\n }\n\n private async fetchNotice(): Promise<void> {\n const generation = ++this.fetchGeneration;\n this.fetchedWithToken = Boolean(this.options.accessToken);\n this.store.setState({ isLoading: true, fetchError: null, hasAlreadyConsented: false });\n try {\n const data = await fetchConsentContentPublic({\n org_uuid: this.options.org_uuid,\n workspace_uuid: this.options.workspace_uuid,\n notice_uuid: this.options.notice_uuid,\n accessToken: this.options.accessToken,\n baseUrl: this.options.baseUrl,\n language: this.options.language,\n specific_uuid: this.options.applicationId,\n });\n\n if (this.isDestroyed() || generation !== this.fetchGeneration) {\n return;\n }\n\n const activeConfig = data.detail.active_config;\n const rows = inlinePurposeRows(activeConfig);\n const selection = initialSelection(rows);\n\n // Post-cutover, consent records live in the Go ledger, so Python's\n // get-notice no longer 409s for an already-consented principal. Kick off\n // the ledger check BEFORE the content state lands: its synchronous\n // prologue raises isCheckingConsent, so the content state change below\n // cannot auto-submit until the read settles.\n void this.checkLedgerConsent();\n\n this.store.setState({\n content: activeConfig,\n isLoading: false,\n selectedLanguage: resolveDisplayLanguage(\n this.options.language,\n activeConfig.default_language,\n activeConfig.supported_languages_and_translations\n ),\n collapsedPurposes: initialCollapsedPurposes(rows),\n selectedPurposes: selection.selectedPurposes,\n selectedDataElements: selection.selectedDataElements,\n });\n } catch (err: unknown) {\n if (this.isDestroyed() || generation !== this.fetchGeneration) {\n return;\n }\n const error = err as Error & { status?: number };\n if (error.status === 409) {\n this.store.setState({ hasAlreadyConsented: true, isLoading: false });\n this.options.onAccept?.();\n } else {\n this.store.setState({ fetchError: error, isLoading: false });\n this.options.onError?.(error);\n }\n }\n }\n\n private shouldCheckLedgerConsent(): boolean {\n return (\n Boolean(this.options.ledgerBaseUrl) &&\n !this.options.applicationId &&\n Boolean(this.options.accessToken) &&\n !this.hasCheckedLedgerConsent\n );\n }\n\n // Ask the Go ledger whether this principal has already fully consented —\n // the ledger equivalent of the legacy Python 409. Skipped without a ledger\n // (the 409 path governs) and for the magic-link applicationId flow. Any\n // failure returns null and falls through to the normal flow.\n private async checkLedgerConsent(): Promise<void> {\n if (!this.shouldCheckLedgerConsent()) return;\n this.hasCheckedLedgerConsent = true;\n this.store.setState({ isCheckingConsent: true });\n try {\n const status = await fetchNoticeConsentStatusForScope({\n accessToken: this.options.accessToken!,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n organisationUuid: this.options.org_uuid,\n workspaceUuid: this.options.workspace_uuid,\n noticeUuid: this.options.notice_uuid,\n signal: this.abortController?.signal,\n });\n if (this.isDestroyed()) {\n return;\n }\n if (status && isNoticeFullyConsented(status)) {\n this.store.setState({ hasAlreadyConsented: true });\n this.options.onAccept?.();\n }\n } finally {\n if (!this.isDestroyed()) {\n this.store.setState({ isCheckingConsent: false });\n // Re-run auto-submit now that the gate is down (no-op when already\n // consented or requirements are unmet).\n this.tryAutoSubmit();\n }\n }\n }\n\n private handleStateChange(state: InlineState, prevState: InlineState): void {\n // Loading → content loaded\n if (prevState.isLoading && !state.isLoading && state.content) {\n this.rebuildUI();\n }\n\n // Already consented or fetch error → hide\n if (state.hasAlreadyConsented || state.fetchError) {\n if (this.rootEl && this.shadowRoot && this.rootEl.parentNode === this.shadowRoot) {\n this.shadowRoot.removeChild(this.rootEl);\n this.rootEl = null;\n }\n return;\n }\n\n // Checkbox state changes → update checkboxes\n if (state.selectedPurposes !== prevState.selectedPurposes ||\n state.selectedDataElements !== prevState.selectedDataElements) {\n this.updateCheckboxes(state);\n this.notifyValidation(state);\n this.tryAutoSubmit();\n }\n\n // Collapse state changes\n if (state.collapsedPurposes !== prevState.collapsedPurposes) {\n this.updateCollapseState(state);\n }\n\n // Error message changes\n if (state.errorMessage !== prevState.errorMessage) {\n this.updateErrorMessage(state);\n }\n }\n\n private renderLoading(): void {\n if (!this.shadowRoot) return;\n\n const textColor = this.options.settings?.textColor || \"#344054\";\n\n this.rootEl = el(\n \"div\",\n { style: inlineStyles.loadingContainer },\n el(\"div\", { style: inlineStyles.loadingSpinner }),\n el(\"p\", { style: { fontSize: \"16px\", fontWeight: 400, color: textColor } }, \"Loading...\")\n );\n\n this.shadowRoot.appendChild(this.rootEl);\n }\n\n private rebuildUI(): void {\n const state = this.store.getState();\n if (!state.content || !this.shadowRoot) return;\n\n // Remove existing root\n if (this.rootEl && this.rootEl.parentNode === this.shadowRoot) {\n this.shadowRoot.removeChild(this.rootEl);\n }\n\n // Build error message element\n this.errorEl = el(\"div\", {\n role: \"alert\",\n style: {\n backgroundColor: \"#FEE2E2\",\n color: \"#DC2626\",\n padding: \"12px\",\n borderRadius: \"6px\",\n fontSize: \"14px\",\n border: \"1px solid #FCA5A5\",\n display: state.errorMessage ? \"block\" : \"none\",\n },\n });\n if (state.errorMessage) {\n this.errorEl.textContent = state.errorMessage;\n }\n\n // Build purposes\n this.purposeRefs = renderInlinePurposes(state.content.purposes, {\n selectedPurposes: state.selectedPurposes,\n collapsedPurposes: state.collapsedPurposes,\n selectedDataElements: state.selectedDataElements,\n products: state.content.products,\n productPurposeOrder: state.content.product_purpose_order,\n settings: this.options.settings,\n isMobile: this.mediaQuery.matches,\n getTranslatedText: (key, defaultText, itemId) =>\n this.getTranslatedText(key, defaultText, itemId),\n onPurposeToggle: (uuid, productUuid) => this.handlePurposeCheckboxChange(uuid, productUuid),\n onPurposeCollapse: (uuid, productUuid) => this.togglePurposeCollapse(uuid, productUuid),\n onDataElementToggle: (elementUuid, purposeUuid, productUuid) =>\n this.handleDataElementCheckboxChange(elementUuid, purposeUuid, productUuid),\n });\n\n this.rootEl = el(\n \"div\",\n { style: { display: \"flex\", flexDirection: \"column\", gap: \"16px\" } },\n this.errorEl,\n this.purposeRefs.container\n );\n\n this.shadowRoot.appendChild(this.rootEl);\n this.notifyValidation(state);\n }\n\n private getTranslatedText(key: string, defaultText: string, itemId?: string): string {\n const state = this.store.getState();\n const content = state.content;\n if (!content) return defaultText;\n\n const lang = state.selectedLanguage;\n if (lang === \"English\" || lang === \"en\" || lang === \"EN\") {\n if (key === \"privacy_policy_anchor_text\" && content.privacy_policy_anchor_text) {\n return content.privacy_policy_anchor_text;\n }\n return defaultText;\n }\n\n const translations = content.supported_languages_and_translations;\n if (!translations) return defaultText;\n\n const translationMap = translations[lang] as TranslationObject | undefined;\n if (!translationMap) return defaultText;\n\n if (itemId) {\n if (key === \"purposes.name\" || key === \"purposes.description\") {\n const purposeData = translationMap.purposes?.[itemId];\n if (purposeData) {\n if (typeof purposeData === \"string\") {\n return key === \"purposes.name\" ? purposeData : defaultText;\n }\n return key === \"purposes.name\"\n ? purposeData.name || defaultText\n : purposeData.description || defaultText;\n }\n return defaultText;\n }\n if (key === \"products.name\" || key === \"products.description\") {\n const productData = translationMap.products?.[itemId];\n if (productData) {\n if (typeof productData === \"string\") {\n return key === \"products.name\" ? productData : defaultText;\n }\n return key === \"products.name\"\n ? productData.name || defaultText\n : productData.description || defaultText;\n }\n return defaultText;\n }\n if (key.startsWith(\"data_elements.\")) {\n return translationMap.data_elements?.[itemId] || defaultText;\n }\n }\n\n const value = (translationMap as any)[key];\n if (typeof value === \"string\" && value) return value;\n return defaultText;\n }\n\n private togglePurposeCollapse(purposeUuid: string, productUuid?: string): void {\n const state = this.store.getState();\n const key = productPurposeKey(productUuid, purposeUuid);\n this.store.setState({\n collapsedPurposes: {\n ...state.collapsedPurposes,\n [key]: !state.collapsedPurposes[key],\n },\n });\n }\n\n private handlePurposeCheckboxChange(purposeUuid: string, productUuid?: string): void {\n const state = this.store.getState();\n const content = state.content;\n if (!content) return;\n\n const purpose = content.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose) return;\n\n const key = productPurposeKey(productUuid, purposeUuid);\n const newPurposeState = !state.selectedPurposes[key];\n\n this.store.setState({\n selectedPurposes: { ...state.selectedPurposes, [key]: newPurposeState },\n selectedDataElements: withPurposeElements(\n purpose,\n productUuid,\n newPurposeState,\n state.selectedDataElements\n ),\n });\n }\n\n private handleDataElementCheckboxChange(\n elementUuid: string,\n purposeUuid: string,\n productUuid?: string\n ): void {\n const state = this.store.getState();\n const content = state.content;\n if (!content) return;\n\n const purpose = content.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose) return;\n\n const next = toggleDataElement(purpose, elementUuid, productUuid, state.selectedDataElements);\n\n this.store.setState({\n selectedDataElements: next.selectedDataElements,\n selectedPurposes: {\n ...state.selectedPurposes,\n [productPurposeKey(productUuid, purposeUuid)]: next.purposeSelected,\n },\n });\n }\n\n private updateCheckboxes(state: InlineState): void {\n if (!this.purposeRefs) return;\n\n for (const [key, checkbox] of this.purposeRefs.checkboxes) {\n if (key in state.selectedPurposes) {\n checkbox.checked = state.selectedPurposes[key] || false;\n } else {\n checkbox.checked = state.selectedDataElements[key] || false;\n }\n }\n }\n\n private updateCollapseState(state: InlineState): void {\n if (!this.purposeRefs) return;\n\n const rows = state.content ? inlinePurposeRows(state.content) : [];\n const rowsByKey = new Map(\n rows.map((row) => [productPurposeKey(row.productUuid, row.purpose.uuid), row])\n );\n\n for (const [stateKey, container] of this.purposeRefs.dataElementContainers) {\n const purpose = rowsByKey.get(stateKey)?.purpose;\n const isCollapsed = state.collapsedPurposes[stateKey];\n\n container.style.display = !isCollapsed && purpose?.data_elements?.length ? \"flex\" : \"none\";\n\n const chevron = this.purposeRefs.chevrons.get(stateKey);\n if (chevron) {\n (chevron as unknown as HTMLElement).style.transform = !isCollapsed\n ? \"rotate(90deg)\"\n : \"rotate(0deg)\";\n }\n\n const collapseBtn = this.purposeRefs.collapseButtons.get(stateKey);\n if (collapseBtn) {\n collapseBtn.setAttribute(\"aria-expanded\", String(!isCollapsed));\n }\n }\n }\n\n private updateErrorMessage(state: InlineState): void {\n if (!this.errorEl) return;\n if (state.errorMessage) {\n this.errorEl.textContent = state.errorMessage;\n this.errorEl.style.display = \"block\";\n } else {\n this.errorEl.style.display = \"none\";\n }\n }\n\n private areAllRequiredElementsChecked(): boolean {\n const state = this.store.getState();\n const content = state.content;\n if (!content) return false;\n\n return allRequiredElementsChecked(inlinePurposeRows(content), state.selectedDataElements);\n }\n\n private notifyValidation(state: InlineState): void {\n const isValid = this.areAllRequiredElementsChecked();\n this.options.onValidationChange?.(isValid);\n }\n\n private async tryAutoSubmit(skipKey: string | null = null): Promise<void> {\n // A submit is a network write — never start one after teardown.\n if (this.isDestroyed()) {\n return;\n }\n\n const state = this.store.getState();\n const accessToken = this.options.accessToken;\n\n if (\n accessToken &&\n state.content &&\n this.areAllRequiredElementsChecked() &&\n !state.isSubmitting &&\n !state.isCheckingConsent &&\n !state.hasAlreadyConsented &&\n !this.hasSubmitted\n ) {\n const submissionKey = inlineSubmissionKey(accessToken, state.content.uuid, state);\n if (submissionKey === this.lastSubmissionKey || submissionKey === skipKey) {\n return;\n }\n this.hasSubmitted = true;\n this.lastSubmissionKey = submissionKey;\n try {\n await this.handleSubmit(accessToken);\n } catch (err) {\n this.hasSubmitted = false;\n this.options.onError?.(err as Error);\n if (isRetryableFailure(err)) {\n this.lastSubmissionKey = null;\n void this.tryAutoSubmit(submissionKey);\n return;\n }\n }\n void this.tryAutoSubmit();\n }\n }\n\n private async handleSubmit(tokenToUse: string): Promise<void> {\n const state = this.store.getState();\n const content = state.content;\n if (!tokenToUse || !content) {\n this.store.setState({ errorMessage: \"Unable to submit consent. Please try again.\" });\n throw new Error(\"Access token or content not available\");\n }\n\n try {\n this.store.setState({ isSubmitting: true, errorMessage: null });\n\n await submitConsentEventPublic({\n org_uuid: this.options.org_uuid,\n workspace_uuid: this.options.workspace_uuid,\n accessToken: tokenToUse,\n baseUrl: this.options.baseUrl,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n noticeUuid: content.notice_uuid,\n purposes: buildInlineSubmitPurposes(inlinePurposeRows(content), state),\n declined: false,\n meta_data: this.options.applicationId\n ? { specific_uuid: this.options.applicationId }\n : undefined,\n language: state.selectedLanguage,\n });\n\n this.options.onAccept?.();\n this.hasSubmitted = false;\n } catch (error) {\n const err = error as Error;\n const message = err.message || \"Failed to submit consent. Please try again.\";\n this.store.setState({ errorMessage: message });\n this.hasSubmitted = false;\n throw error;\n } finally {\n this.store.setState({ isSubmitting: false });\n }\n }\n}\n","import type { PurposePreselection } from \"./types\";\nimport { DEFAULT_CONSENT_API_BASE_URL } from \"../constants\";\n\nexport const ASSISTED_BASE_URL = DEFAULT_CONSENT_API_BASE_URL;\n\nexport const ASSISTED_CONFIG = {\n otpLength: 6,\n resendSeconds: 30,\n dialCode: \"+91\",\n channel: \"sms\",\n emailChannel: \"email\",\n otpPurpose: \"login\",\n mobileDigits: 10,\n} as const;\n\nexport const EMAIL_REGEX = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nexport const DEFAULT_PURPOSE_PRESELECTION: PurposePreselection = \"NONE\";\n\nexport const ASSISTED_FALLBACK_MESSAGES = {\n notice: \"Could not load the consent notice. Please try again.\",\n createOtp: \"Could not send the OTP. Please try again.\",\n verifyOtp: \"Could not verify the OTP. Please try again.\",\n submit: \"Could not submit your consent. Please try again.\",\n audio: \"Could not load audio narration. Please try again.\",\n} as const;\n\nexport const ASSISTED_HOST_ATTRIBUTE = \"data-redacto-consent-assisted\";\n\nexport const ASSISTED_IDS = {\n mobileInput: \"redacto-assisted-mobile\",\n emailInput: \"redacto-assisted-email\",\n otpInputPrefix: \"redacto-assisted-otp-\",\n verifyPanel: \"redacto-assisted-verify\",\n purposeContainerPrefix: \"redacto-assisted-purpose-\",\n resend: \"redacto-assisted-resend\",\n speakerSlot: \"redacto-assisted-speaker\",\n} as const;\n\nexport const FOCUS_KEY_ATTRIBUTE = \"data-focus-key\";\n\nexport const FOCUS_KEYS = {\n language: \"language\",\n speaker: \"speaker\",\n acceptAll: \"accept-all\",\n primary: \"primary\",\n decline: \"decline\",\n editSelections: \"edit-selections\",\n switchMethod: \"switch-method\",\n changeContact: \"change-contact\",\n resend: \"resend\",\n close: \"close\",\n purpose: (purposeUuid: string) => `purpose:${purposeUuid}`,\n collapse: (purposeUuid: string) => `collapse:${purposeUuid}`,\n element: (purposeUuid: string, elementUuid: string) => `element:${purposeUuid}:${elementUuid}`,\n} as const;\n\nexport const ASSISTED_DEFAULT_PRIMARY_COLOR = \"#4f87ff\";\n\nexport const ASSISTED_STYLE_ID = \"redacto-assisted-styles\";\n\nexport const MOBILE_QUERY = \"(max-width: 768px)\";\n","import { parseApiError } from \"../shared/api-errors\";\nimport { withIdempotencyKey } from \"../shared/idempotency\";\nimport { toSubmitPurposes } from \"../api/submit-payload\";\nimport { toLanguageCode } from \"../api/language\";\nimport type { TTSAudioUrlsResponse } from \"../api/types\";\nimport { ASSISTED_BASE_URL, ASSISTED_FALLBACK_MESSAGES } from \"./constants\";\nimport type {\n AssistedNoticeResponse,\n CreateOtpDetail,\n CreateOtpParams,\n CreateOtpResponse,\n FetchAssistedNoticeParams,\n FetchAssistedTTSAudioUrlsParams,\n SubmitAssistedConsentParams,\n VerifyOtpDetail,\n VerifyOtpParams,\n VerifyOtpResponse,\n} from \"./types\";\n\nconst publicScope = (\n baseUrl: string | undefined,\n organisationUuid: string,\n workspaceUuid: string\n): string =>\n `${baseUrl || ASSISTED_BASE_URL}/public/organisations/${organisationUuid}/workspaces/${workspaceUuid}`;\n\nexport const fetchAssistedNotice = async ({\n organisationUuid,\n workspaceUuid,\n noticeUuid,\n baseUrl,\n signal,\n}: FetchAssistedNoticeParams): Promise<AssistedNoticeResponse> => {\n if (!organisationUuid || !workspaceUuid || !noticeUuid) {\n throw new Error(\"organisationUuid, workspaceUuid and noticeUuid are required\");\n }\n\n const url = `${publicScope(baseUrl, organisationUuid, workspaceUuid)}/notices/get-notice/${noticeUuid}`;\n\n const response = await fetch(url, {\n method: \"GET\",\n headers: { accept: \"application/json\" },\n signal,\n });\n\n if (!response.ok) {\n throw await parseApiError(response, ASSISTED_FALLBACK_MESSAGES.notice);\n }\n\n return (await response.json()) as AssistedNoticeResponse;\n};\n\nexport const createOtp = async ({\n organisationUuid,\n workspaceUuid,\n to,\n channel,\n baseUrl,\n signal,\n}: CreateOtpParams): Promise<CreateOtpDetail> => {\n if (!organisationUuid || !workspaceUuid || !to) {\n throw new Error(\"organisationUuid, workspaceUuid and to are required\");\n }\n\n const url = `${publicScope(baseUrl, organisationUuid, workspaceUuid)}/otp/create`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ to, channel }),\n signal,\n });\n\n if (!response.ok) {\n throw await parseApiError(response, ASSISTED_FALLBACK_MESSAGES.createOtp);\n }\n\n const data = (await response.json()) as CreateOtpResponse;\n return data.detail;\n};\n\nexport const verifyOtp = async ({\n organisationUuid,\n workspaceUuid,\n uuid,\n otp,\n purpose,\n baseUrl,\n signal,\n}: VerifyOtpParams): Promise<VerifyOtpDetail> => {\n if (!organisationUuid || !workspaceUuid || !uuid || !otp) {\n throw new Error(\"organisationUuid, workspaceUuid, uuid and otp are required\");\n }\n\n const url = `${publicScope(baseUrl, organisationUuid, workspaceUuid)}/otp/verify`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ uuid, otp, purpose }),\n signal,\n });\n\n if (!response.ok) {\n throw await parseApiError(response, ASSISTED_FALLBACK_MESSAGES.verifyOtp);\n }\n\n const data = (await response.json()) as VerifyOtpResponse;\n return data.detail;\n};\n\nexport const submitAssistedConsent = async ({\n accessToken,\n organisationUuid,\n workspaceUuid,\n baseUrl,\n ledgerBaseUrl,\n noticeUuid,\n purposes,\n language,\n signal,\n}: SubmitAssistedConsentParams): Promise<Record<string, unknown> | null> => {\n if (!accessToken || !noticeUuid || !Array.isArray(purposes)) {\n throw new Error(\"accessToken, noticeUuid and purposes array are required\");\n }\n\n const payload = {\n notice_uuid: noticeUuid,\n purposes: toSubmitPurposes(purposes),\n select_all_mandatory: false,\n source: \"WEB\",\n declined: false,\n language: toLanguageCode(language),\n };\n\n const url = `${publicScope(ledgerBaseUrl || baseUrl, organisationUuid, workspaceUuid)}/submit-consent`;\n const serialisedBody = JSON.stringify(payload);\n\n const response = await withIdempotencyKey(url, serialisedBody, (idempotencyHeaders) =>\n fetch(url, {\n method: \"POST\",\n headers: {\n accept: \"application/json\",\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n ...idempotencyHeaders,\n },\n body: serialisedBody,\n signal,\n })\n );\n\n if (!response.ok) {\n throw await parseApiError(response, ASSISTED_FALLBACK_MESSAGES.submit);\n }\n\n const text = await response.text();\n if (!text) return null;\n try {\n return JSON.parse(text) as Record<string, unknown>;\n } catch {\n return null;\n }\n};\n\nexport const fetchAssistedTTSAudioUrls = async ({\n organisationUuid,\n workspaceUuid,\n noticeUuid,\n language,\n baseUrl,\n signal,\n}: FetchAssistedTTSAudioUrlsParams): Promise<TTSAudioUrlsResponse> => {\n if (!organisationUuid || !workspaceUuid || !noticeUuid || !language) {\n throw new Error(\"organisationUuid, workspaceUuid, noticeUuid and language are required\");\n }\n\n const url = `${publicScope(baseUrl, organisationUuid, workspaceUuid)}/notices/${noticeUuid}/audio/${language}`;\n\n const response = await fetch(url, {\n method: \"GET\",\n headers: { accept: \"application/json\" },\n signal,\n });\n\n if (!response.ok) {\n throw await parseApiError(response, ASSISTED_FALLBACK_MESSAGES.audio);\n }\n\n return (await response.json()) as TTSAudioUrlsResponse;\n};\n","import type { StaticKey, StaticStrings, StaticVars } from \"./types\";\n\nconst en: StaticStrings = {\n useEmailInstead: \"Use email instead\",\n useMobileInstead: \"Use mobile instead\",\n emailAddress: \"Email address\",\n otpHelperEmail: \"We'll send a one-time password to this email.\",\n changeEmail: \"Change Email\",\n expandDetails: \"Expand {name} details\",\n collapseDetails: \"Collapse {name} details\",\n selectAllFor: \"Select all data elements for {name}\",\n selectElement: \"Select {name}\",\n selectElementRequired: \"Select {name} (required)\",\n required: \"required\",\n logoAlt: \"Logo\",\n selectLanguage: \"Select language\",\n selectLanguageCurrent: \"Select language. Current language: {lang}\",\n opensInNewTab: \"opens in new tab\",\n audioStart: \"Start audio playback\",\n audioPause: \"Pause audio playback\",\n talkbackStart: \"Start Talkback\",\n talkbackPause: \"Pause Talkback\",\n mobileNumber: \"Mobile number\",\n otpHelper: \"We'll send a one-time password to this number.\",\n otpSentTo: \"OTP sent to\",\n changeMobile: \"Change Mobile Number\",\n enterNDigitOtp: \"Enter {count}-digit OTP\",\n otpDigit: \"OTP digit {index}\",\n resendIn: \"Resend OTP in {seconds}s\",\n sending: \"Sending…\",\n resendOtp: \"Resend OTP\",\n getOtp: \"Get OTP\",\n verifying: \"Verifying…\",\n verifyOtp: \"Verify OTP\",\n sendOtp: \"Send OTP\",\n confirmOtp: \"Confirm OTP\",\n verifyWithOtp: \"Verify with OTP\",\n editSelections: \"Edit selections\",\n otpIncorrect:\n \"The verification code you entered is incorrect. Please check and try again.\",\n otpExpired: \"Your verification code has expired. Please request a new code.\",\n otpNotFound: \"Verification code not found. Please request a new code.\",\n otpVerifyFailed: \"Could not verify the OTP. Please try again.\",\n otpSendFailed: \"Could not send the OTP. Please try again.\",\n consentConfirmed: \"Consent confirmed\",\n recordedUnder: \"OTP verified · recorded under {regulation}\",\n recordedUnderAt: \"OTP verified · recorded under {regulation} at {time}\",\n consentReferenceId: \"Consent reference id\",\n proceed: \"Proceed\",\n loadingNotice: \"Loading notice\",\n loadFailedTitle: \"Couldn't load the consent notice\",\n tryAgain: \"Please try again.\",\n close: \"Close\",\n};\n\nconst hi: StaticStrings = {\n useEmailInstead: \"ईमेल इस्तेमाल करें\",\n useMobileInstead: \"मोबाइल इस्तेमाल करें\",\n emailAddress: \"ईमेल पता\",\n otpHelperEmail: \"हम इस ईमेल पर एक वन-टाइम पासवर्ड भेजेंगे.\",\n changeEmail: \"ईमेल बदलें\",\n expandDetails: \"{name} का विवरण विस्तृत करें\",\n collapseDetails: \"{name} का विवरण संक्षिप्त करें\",\n selectAllFor: \"{name} के लिए सभी डेटा तत्व चुनें\",\n selectElement: \"{name} चुनें\",\n selectElementRequired: \"{name} चुनें (आवश्यक)\",\n required: \"आवश्यक\",\n logoAlt: \"लोगो\",\n selectLanguage: \"भाषा चुनें\",\n selectLanguageCurrent: \"भाषा चुनें. वर्तमान भाषा: {lang}\",\n opensInNewTab: \"नए टैब में खुलता है\",\n audioStart: \"ऑडियो प्लेबैक शुरू करें\",\n audioPause: \"ऑडियो प्लेबैक रोकें\",\n talkbackStart: \"टॉकबैक शुरू करें\",\n talkbackPause: \"टॉकबैक रोकें\",\n mobileNumber: \"मोबाइल नंबर\",\n otpHelper: \"हम इस नंबर पर एक वन-टाइम पासवर्ड भेजेंगे.\",\n otpSentTo: \"ओटीपी (OTP) भेजा गया\",\n changeMobile: \"मोबाइल नंबर बदलें\",\n enterNDigitOtp: \"{count}-अंकों का ओटीपी (OTP) दर्ज करें\",\n otpDigit: \"ओटीपी (OTP) अंक {index}\",\n resendIn: \"{seconds} सेकंड में ओटीपी (OTP) पुनः भेजें\",\n sending: \"भेजा जा रहा है…\",\n resendOtp: \"ओटीपी (OTP) पुनः भेजें\",\n getOtp: \"ओटीपी (OTP) प्राप्त करें\",\n verifying: \"सत्यापित किया जा रहा है…\",\n verifyOtp: \"ओटीपी (OTP) सत्यापित करें\",\n sendOtp: \"ओटीपी (OTP) भेजें\",\n confirmOtp: \"ओटीपी (OTP) की पुष्टि करें\",\n verifyWithOtp: \"ओटीपी (OTP) से सत्यापित करें\",\n editSelections: \"चयन संपादित करें\",\n otpIncorrect:\n \"आपके द्वारा दर्ज किया गया सत्यापन कोड गलत है. कृपया जाँचें और पुनः प्रयास करें.\",\n otpExpired: \"आपके सत्यापन कोड की अवधि समाप्त हो गई है. कृपया नया कोड माँगें.\",\n otpNotFound: \"सत्यापन कोड नहीं मिला. कृपया नया कोड माँगें.\",\n otpVerifyFailed: \"ओटीपी (OTP) सत्यापित नहीं हो सका. कृपया पुनः प्रयास करें.\",\n otpSendFailed: \"ओटीपी (OTP) नहीं भेजा जा सका. कृपया पुनः प्रयास करें.\",\n consentConfirmed: \"सहमति की पुष्टि हुई\",\n recordedUnder: \"ओटीपी (OTP) सत्यापित · {regulation} के तहत दर्ज किया गया\",\n recordedUnderAt:\n \"ओटीपी (OTP) सत्यापित · {regulation} के तहत {time} पर दर्ज किया गया\",\n consentReferenceId: \"सहमति संदर्भ आईडी\",\n proceed: \"आगे बढ़ें\",\n loadingNotice: \"नोटिस लोड हो रहा है\",\n loadFailedTitle: \"सहमति नोटिस लोड नहीं हो सका\",\n tryAgain: \"कृपया पुनः प्रयास करें.\",\n close: \"बंद करें\",\n};\n\nconst bn: StaticStrings = {\n useEmailInstead: \"ইমেইল ব্যবহার করুন\",\n useMobileInstead: \"মোবাইল ব্যবহার করুন\",\n emailAddress: \"ইমেইল ঠিকানা\",\n otpHelperEmail: \"আমরা এই ইমেইলে একটি ওয়ান-টাইম পাসওয়ার্ড পাঠাব।\",\n changeEmail: \"ইমেইল পরিবর্তন করুন\",\n expandDetails: \"{name} এর বিবরণ প্রসারিত করুন\",\n collapseDetails: \"{name} এর বিবরণ সংকুচিত করুন\",\n selectAllFor: \"{name} এর জন্য সমস্ত ডেটা উপাদান নির্বাচন করুন\",\n selectElement: \"{name} নির্বাচন করুন\",\n selectElementRequired: \"{name} নির্বাচন করুন (আবশ্যক)\",\n required: \"আবশ্যক\",\n logoAlt: \"লোগো\",\n selectLanguage: \"ভাষা নির্বাচন করুন\",\n selectLanguageCurrent: \"ভাষা নির্বাচন করুন। বর্তমান ভাষা: {lang}\",\n opensInNewTab: \"নতুন ট্যাবে খোলে\",\n audioStart: \"অডিও প্লেব্যাক শুরু করুন\",\n audioPause: \"অডিও প্লেব্যাক বিরতি দিন\",\n talkbackStart: \"টকব্যাক শুরু করুন\",\n talkbackPause: \"টকব্যাক বিরতি দিন\",\n mobileNumber: \"মোবাইল নম্বর\",\n otpHelper: \"আমরা এই নম্বরে একটি ওয়ান-টাইম পাসওয়ার্ড পাঠাব।\",\n otpSentTo: \"ওটিপি (OTP) পাঠানো হয়েছে\",\n changeMobile: \"মোবাইল নম্বর পরিবর্তন করুন\",\n enterNDigitOtp: \"{count}-সংখ্যার ওটিপি (OTP) লিখুন\",\n otpDigit: \"ওটিপি (OTP) সংখ্যা {index}\",\n resendIn: \"{seconds} সেকেন্ডে ওটিপি (OTP) পুনরায় পাঠান\",\n sending: \"পাঠানো হচ্ছে…\",\n resendOtp: \"ওটিপি (OTP) পুনরায় পাঠান\",\n getOtp: \"ওটিপি (OTP) পান\",\n verifying: \"যাচাই করা হচ্ছে…\",\n verifyOtp: \"ওটিপি (OTP) যাচাই করুন\",\n sendOtp: \"ওটিপি (OTP) পাঠান\",\n confirmOtp: \"ওটিপি (OTP) নিশ্চিত করুন\",\n verifyWithOtp: \"ওটিপি (OTP) দিয়ে যাচাই করুন\",\n editSelections: \"নির্বাচন সম্পাদনা করুন\",\n otpIncorrect:\n \"আপনি যে যাচাইকরণ কোডটি লিখেছেন তা ভুল। অনুগ্রহ করে যাচাই করে আবার চেষ্টা করুন।\",\n otpExpired:\n \"আপনার যাচাইকরণ কোডের মেয়াদ শেষ হয়ে গেছে। অনুগ্রহ করে একটি নতুন কোড চান।\",\n otpNotFound: \"যাচাইকরণ কোড পাওয়া যায়নি। অনুগ্রহ করে একটি নতুন কোড চান।\",\n otpVerifyFailed:\n \"ওটিপি (OTP) যাচাই করা যায়নি। অনুগ্রহ করে আবার চেষ্টা করুন।\",\n otpSendFailed: \"ওটিপি (OTP) পাঠানো যায়নি। অনুগ্রহ করে আবার চেষ্টা করুন।\",\n consentConfirmed: \"সম্মতি নিশ্চিত হয়েছে\",\n recordedUnder: \"ওটিপি (OTP) যাচাই হয়েছে · {regulation} এর অধীনে নথিভুক্ত\",\n recordedUnderAt:\n \"ওটিপি (OTP) যাচাই হয়েছে · {regulation} এর অধীনে {time} এ নথিভুক্ত\",\n consentReferenceId: \"সম্মতি রেফারেন্স আইডি\",\n proceed: \"এগিয়ে যান\",\n loadingNotice: \"নোটিশ লোড হচ্ছে\",\n loadFailedTitle: \"সম্মতি নোটিশ লোড করা যায়নি\",\n tryAgain: \"অনুগ্রহ করে আবার চেষ্টা করুন।\",\n close: \"বন্ধ করুন\",\n};\n\nconst gu: StaticStrings = {\n useEmailInstead: \"ઇમેલ વાપરો\",\n useMobileInstead: \"મોબાઇલ વાપરો\",\n emailAddress: \"ઇમેલ સરનામું\",\n otpHelperEmail: \"અમે આ ઇમેલ પર વન-ટાઇમ પાસવર્ડ મોકલીશું.\",\n changeEmail: \"ઇમેલ બદલો\",\n expandDetails: \"{name} ની વિગતો વિસ્તૃત કરો\",\n collapseDetails: \"{name} ની વિગતો સંકોચો\",\n selectAllFor: \"{name} માટે બધા ડેટા ઘટકો પસંદ કરો\",\n selectElement: \"{name} પસંદ કરો\",\n selectElementRequired: \"{name} પસંદ કરો (આવશ્યક)\",\n required: \"આવશ્યક\",\n logoAlt: \"લોગો\",\n selectLanguage: \"ભાષા પસંદ કરો\",\n selectLanguageCurrent: \"ભાષા પસંદ કરો. વર્તમાન ભાષા: {lang}\",\n opensInNewTab: \"નવી ટૅબમાં ખુલે છે\",\n audioStart: \"ઑડિયો પ્લેબેક શરૂ કરો\",\n audioPause: \"ઑડિયો પ્લેબેક થોભાવો\",\n talkbackStart: \"ટૉકબેક શરૂ કરો\",\n talkbackPause: \"ટૉકબેક થોભાવો\",\n mobileNumber: \"મોબાઇલ નંબર\",\n otpHelper: \"અમે આ નંબર પર વન-ટાઇમ પાસવર્ડ મોકલીશું.\",\n otpSentTo: \"ઓટીપી (OTP) મોકલ્યો\",\n changeMobile: \"મોબાઇલ નંબર બદલો\",\n enterNDigitOtp: \"{count}-અંકનો ઓટીપી (OTP) દાખલ કરો\",\n otpDigit: \"ઓટીપી (OTP) અંક {index}\",\n resendIn: \"{seconds} સેકન્ડમાં ઓટીપી (OTP) ફરી મોકલો\",\n sending: \"મોકલી રહ્યું છે…\",\n resendOtp: \"ઓટીપી (OTP) ફરી મોકલો\",\n getOtp: \"ઓટીપી (OTP) મેળવો\",\n verifying: \"ચકાસી રહ્યું છે…\",\n verifyOtp: \"ઓટીપી (OTP) ચકાસો\",\n sendOtp: \"ઓટીપી (OTP) મોકલો\",\n confirmOtp: \"ઓટીપી (OTP) ની પુષ્ટિ કરો\",\n verifyWithOtp: \"ઓટીપી (OTP) થી ચકાસો\",\n editSelections: \"પસંદગીઓ સંપાદિત કરો\",\n otpIncorrect:\n \"તમે દાખલ કરેલ ચકાસણી કોડ ખોટો છે. કૃપા કરીને તપાસો અને ફરી પ્રયાસ કરો.\",\n otpExpired: \"તમારા ચકાસણી કોડની મુદત પૂરી થઈ ગઈ છે. કૃપા કરીને નવો કોડ માગો.\",\n otpNotFound: \"ચકાસણી કોડ મળ્યો નથી. કૃપા કરીને નવો કોડ માગો.\",\n otpVerifyFailed: \"ઓટીપી (OTP) ચકાસી શકાયો નથી. કૃપા કરીને ફરી પ્રયાસ કરો.\",\n otpSendFailed: \"ઓટીપી (OTP) મોકલી શકાયો નથી. કૃપા કરીને ફરી પ્રયાસ કરો.\",\n consentConfirmed: \"સંમતિની પુષ્ટિ થઈ\",\n recordedUnder: \"ઓટીપી (OTP) ચકાસાયું · {regulation} હેઠળ નોંધાયું\",\n recordedUnderAt:\n \"ઓટીપી (OTP) ચકાસાયું · {regulation} હેઠળ {time} વાગ્યે નોંધાયું\",\n consentReferenceId: \"સંમતિ સંદર્ભ આઈડી\",\n proceed: \"આગળ વધો\",\n loadingNotice: \"નોટિસ લોડ થઈ રહ્યું છે\",\n loadFailedTitle: \"સંમતિ નોટિસ લોડ થઈ શકી નથી\",\n tryAgain: \"કૃપા કરીને ફરી પ્રયાસ કરો.\",\n close: \"બંધ કરો\",\n};\n\nconst kn: StaticStrings = {\n useEmailInstead: \"ಇಮೇಲ್ ಬಳಸಿ\",\n useMobileInstead: \"ಮೊಬೈಲ್ ಬಳಸಿ\",\n emailAddress: \"ಇಮೇಲ್ ವಿಳಾಸ\",\n otpHelperEmail: \"ನಾವು ಈ ಇಮೇಲ್‌ಗೆ ಒಂದು-ಬಾರಿಯ ಪಾಸ್‌ವರ್ಡ್ ಕಳುಹಿಸುತ್ತೇವೆ.\",\n changeEmail: \"ಇಮೇಲ್ ಬದಲಾಯಿಸಿ\",\n expandDetails: \"{name} ವಿವರಗಳನ್ನು ವಿಸ್ತರಿಸಿ\",\n collapseDetails: \"{name} ವಿವರಗಳನ್ನು ಸಂಕುಚಿಸಿ\",\n selectAllFor: \"{name} ಗಾಗಿ ಎಲ್ಲಾ ಡೇಟಾ ಅಂಶಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ\",\n selectElement: \"{name} ಆಯ್ಕೆಮಾಡಿ\",\n selectElementRequired: \"{name} ಆಯ್ಕೆಮಾಡಿ (ಅಗತ್ಯ)\",\n required: \"ಅಗತ್ಯ\",\n logoAlt: \"ಲೋಗೋ\",\n selectLanguage: \"ಭಾಷೆ ಆಯ್ಕೆಮಾಡಿ\",\n selectLanguageCurrent: \"ಭಾಷೆ ಆಯ್ಕೆಮಾಡಿ. ಪ್ರಸ್ತುತ ಭಾಷೆ: {lang}\",\n opensInNewTab: \"ಹೊಸ ಟ್ಯಾಬ್‌ನಲ್ಲಿ ತೆರೆಯುತ್ತದೆ\",\n audioStart: \"ಆಡಿಯೊ ಪ್ಲೇಬ್ಯಾಕ್ ಪ್ರಾರಂಭಿಸಿ\",\n audioPause: \"ಆಡಿಯೊ ಪ್ಲೇಬ್ಯಾಕ್ ವಿರಾಮಗೊಳಿಸಿ\",\n talkbackStart: \"ಟಾಕ್‌ಬ್ಯಾಕ್ ಪ್ರಾರಂಭಿಸಿ\",\n talkbackPause: \"ಟಾಕ್‌ಬ್ಯಾಕ್ ವಿರಾಮಗೊಳಿಸಿ\",\n mobileNumber: \"ಮೊಬೈಲ್ ಸಂಖ್ಯೆ\",\n otpHelper: \"ನಾವು ಈ ಸಂಖ್ಯೆಗೆ ಒಂದು-ಬಾರಿಯ ಪಾಸ್‌ವರ್ಡ್ ಕಳುಹಿಸುತ್ತೇವೆ.\",\n otpSentTo: \"ಓಟಿಪಿ (OTP) ಕಳುಹಿಸಲಾಗಿದೆ\",\n changeMobile: \"ಮೊಬೈಲ್ ಸಂಖ್ಯೆ ಬದಲಾಯಿಸಿ\",\n enterNDigitOtp: \"{count}-ಅಂಕಿಯ ಓಟಿಪಿ (OTP) ನಮೂದಿಸಿ\",\n otpDigit: \"ಓಟಿಪಿ (OTP) ಅಂಕಿ {index}\",\n resendIn: \"{seconds} ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಓಟಿಪಿ (OTP) ಮರುಕಳುಹಿಸಿ\",\n sending: \"ಕಳುಹಿಸಲಾಗುತ್ತಿದೆ…\",\n resendOtp: \"ಓಟಿಪಿ (OTP) ಮರುಕಳುಹಿಸಿ\",\n getOtp: \"ಓಟಿಪಿ (OTP) ಪಡೆಯಿರಿ\",\n verifying: \"ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ…\",\n verifyOtp: \"ಓಟಿಪಿ (OTP) ಪರಿಶೀಲಿಸಿ\",\n sendOtp: \"ಓಟಿಪಿ (OTP) ಕಳುಹಿಸಿ\",\n confirmOtp: \"ಓಟಿಪಿ (OTP) ದೃಢೀಕರಿಸಿ\",\n verifyWithOtp: \"ಓಟಿಪಿ (OTP) ಮೂಲಕ ಪರಿಶೀಲಿಸಿ\",\n editSelections: \"ಆಯ್ಕೆಗಳನ್ನು ಸಂಪಾದಿಸಿ\",\n otpIncorrect:\n \"ನೀವು ನಮೂದಿಸಿದ ಪರಿಶೀಲನಾ ಕೋಡ್ ತಪ್ಪಾಗಿದೆ. ದಯವಿಟ್ಟು ಪರಿಶೀಲಿಸಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ.\",\n otpExpired: \"ನಿಮ್ಮ ಪರಿಶೀಲನಾ ಕೋಡ್ ಅವಧಿ ಮೀರಿದೆ. ದಯವಿಟ್ಟು ಹೊಸ ಕೋಡ್ ಕೋರಿ.\",\n otpNotFound: \"ಪರಿಶೀಲನಾ ಕೋಡ್ ಕಂಡುಬಂದಿಲ್ಲ. ದಯವಿಟ್ಟು ಹೊಸ ಕೋಡ್ ಕೋರಿ.\",\n otpVerifyFailed: \"ಓಟಿಪಿ (OTP) ಪರಿಶೀಲಿಸಲಾಗಲಿಲ್ಲ. ದಯವಿಟ್ಟು ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ.\",\n otpSendFailed: \"ಓಟಿಪಿ (OTP) ಕಳುಹಿಸಲಾಗಲಿಲ್ಲ. ದಯವಿಟ್ಟು ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ.\",\n consentConfirmed: \"ಸಮ್ಮತಿ ದೃಢೀಕರಿಸಲಾಗಿದೆ\",\n recordedUnder:\n \"ಓಟಿಪಿ (OTP) ಪರಿಶೀಲಿಸಲಾಗಿದೆ · {regulation} ಅಡಿಯಲ್ಲಿ ದಾಖಲಿಸಲಾಗಿದೆ\",\n recordedUnderAt:\n \"ಓಟಿಪಿ (OTP) ಪರಿಶೀಲಿಸಲಾಗಿದೆ · {regulation} ಅಡಿಯಲ್ಲಿ {time} ಕ್ಕೆ ದಾಖಲಿಸಲಾಗಿದೆ\",\n consentReferenceId: \"ಸಮ್ಮತಿ ಉಲ್ಲೇಖ ಐಡಿ\",\n proceed: \"ಮುಂದುವರಿಯಿರಿ\",\n loadingNotice: \"ಸೂಚನೆ ಲೋಡ್ ಆಗುತ್ತಿದೆ\",\n loadFailedTitle: \"ಸಮ್ಮತಿ ಸೂಚನೆಯನ್ನು ಲೋಡ್ ಮಾಡಲಾಗಲಿಲ್ಲ\",\n tryAgain: \"ದಯವಿಟ್ಟು ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ.\",\n close: \"ಮುಚ್ಚಿ\",\n};\n\nconst ks: StaticStrings = {\n useEmailInstead: \"ای میل استعمال کرِو\",\n useMobileInstead: \"موبایل استعمال کرِو\",\n emailAddress: \"ای میل ایڈریس\",\n otpHelperEmail: \"أسؠ بھیجو اَتھ ای میلس پؠٹھ اکھ ون ٹایم پاسورڈ۔\",\n changeEmail: \"ای میل تبدیل کرِو\",\n expandDetails: \"{name} تفصیلات کھولِو\",\n collapseDetails: \"{name} تفصیلات بند کرِو\",\n selectAllFor: \"{name} خٲطرٕ سٲری ڈیٹا عناصر ژارٕو\",\n selectElement: \"{name} ژارٕو\",\n selectElementRequired: \"{name} ژارٕو (ضروری)\",\n required: \"ضروری\",\n logoAlt: \"لوگو\",\n selectLanguage: \"زبان ژارٕو\",\n selectLanguageCurrent: \"زبان ژارٕو۔ موجودٕ زبان: {lang}\",\n opensInNewTab: \"نٔو ٹیب منٛز کھولان\",\n audioStart: \"آڈیو پلے بیک شروٗع کرِو\",\n audioPause: \"آڈیو پلے بیک روکِو\",\n talkbackStart: \"ٹاک بیک شروٗع کرِو\",\n talkbackPause: \"ٹاک بیک روکِو\",\n mobileNumber: \"موبایل نمبر\",\n otpHelper: \"أسؠ بھیجو اَتھ نمبرس پؠٹھ اکھ ون ٹایم پاسورڈ۔\",\n otpSentTo: \"او ٹی پی (OTP) بھیجِو\",\n changeMobile: \"موبایل نمبر تبدیل کرِو\",\n enterNDigitOtp: \"{count}-ہندسن ہُنٛد او ٹی پی (OTP) دِیُت\",\n otpDigit: \"او ٹی پی (OTP) ہندسہ {index}\",\n resendIn: \"{seconds} سیکنڈن منٛز او ٹی پی (OTP) دوبارٕ بھیجِو\",\n sending: \"بھیجان آسؠ…\",\n resendOtp: \"او ٹی پی (OTP) دوبارٕ بھیجِو\",\n getOtp: \"او ٹی پی (OTP) حٲصِل کرِو\",\n verifying: \"تصدیق کران آسؠ…\",\n verifyOtp: \"او ٹی پی (OTP) تصدیق کرِو\",\n sendOtp: \"او ٹی پی (OTP) بھیجِو\",\n confirmOtp: \"او ٹی پی (OTP) پۄختہ کرِو\",\n verifyWithOtp: \"او ٹی پی (OTP) سٟتؠ تصدیق کرِو\",\n editSelections: \"ژارٕمٕژ تبدیل کرِو\",\n otpIncorrect:\n \"تُہند درج کرمُت تصدیقی کوڈ چھ غلط۔ مہربانی کرِتھ چیک کرِتھ دوبارٕ کوشش کریو۔\",\n otpExpired:\n \"تُہند تصدیقی کوڈ ہنٛد میعاد چھ ختم گژھمُت۔ مہربانی کرِتھ نٔو کوڈ طلب کریو۔\",\n otpNotFound: \"تصدیقی کوڈ آو نہ لبنہ۔ مہربانی کرِتھ نٔو کوڈ طلب کریو۔\",\n otpVerifyFailed:\n \"او ٹی پی (OTP) ہیوٚک نہ تصدیق کرنہ۔ مہربانی کرِتھ دوبارٕ کوشش کریو۔\",\n otpSendFailed:\n \"او ٹی پی (OTP) ہیوٚک نہ بھیجنہ۔ مہربانی کرِتھ دوبارٕ کوشش کریو۔\",\n consentConfirmed: \"رضامندی تصدیق آیہٕ\",\n recordedUnder: \"او ٹی پی (OTP) تصدیق · {regulation} تحت درج\",\n recordedUnderAt: \"او ٹی پی (OTP) تصدیق · {regulation} تحت {time} پؠٹھ درج\",\n consentReferenceId: \"رضامندی ریفرنس آی ڈی\",\n proceed: \"اگٕ بڑھِو\",\n loadingNotice: \"نوٹس لوڈ گژھان آسؠ\",\n loadFailedTitle: \"رضامندی نوٹس لوڈ کرِتھ ہیوٚک نہٕ\",\n tryAgain: \"مہربانی کرِتھ دوبارٕ کوشش کرِو۔\",\n close: \"بند کرِو\",\n};\n\nconst gom: StaticStrings = {\n useEmailInstead: \"ईमेल वापरात\",\n useMobileInstead: \"मोबायल वापरात\",\n emailAddress: \"ईमेल पत्तो\",\n otpHelperEmail: \"आमी ह्या ईमेलाचेर एक वेळचो पासवर्ड धाडटले.\",\n changeEmail: \"ईमेल बदलात\",\n expandDetails: \"{name} चो तपशील विस्तारीत करात\",\n collapseDetails: \"{name} चो तपशील संकुचित करात\",\n selectAllFor: \"{name} खातीर सगळे डेटा घटक निवडात\",\n selectElement: \"{name} निवडात\",\n selectElementRequired: \"{name} निवडात (गरजेचें)\",\n required: \"गरजेचें\",\n logoAlt: \"लोगो\",\n selectLanguage: \"भास निवडात\",\n selectLanguageCurrent: \"भास निवडात. सद्याची भास: {lang}\",\n opensInNewTab: \"नव्या टॅबांत उगडता\",\n audioStart: \"ऑडियो प्लेबॅक सुरू करात\",\n audioPause: \"ऑडियो प्लेबॅक थांबयात\",\n talkbackStart: \"टॉकबॅक सुरू करात\",\n talkbackPause: \"टॉकबॅक थांबयात\",\n mobileNumber: \"मोबायल क्रमांक\",\n otpHelper: \"आमी ह्या क्रमांकाचेर एक वेळचो पासवर्ड धाडटले.\",\n otpSentTo: \"ओटीपी (OTP) धाडलो\",\n changeMobile: \"मोबायल क्रमांक बदलात\",\n enterNDigitOtp: \"{count}-आंकडी ओटीपी (OTP) घालात\",\n otpDigit: \"ओटीपी (OTP) आंकडो {index}\",\n resendIn: \"{seconds} सेकंदांनी ओटीपी (OTP) परत धाडात\",\n sending: \"धाडटा…\",\n resendOtp: \"ओटीपी (OTP) परत धाडात\",\n getOtp: \"ओटीपी (OTP) मेळयात\",\n verifying: \"तपासता…\",\n verifyOtp: \"ओटीपी (OTP) तपासात\",\n sendOtp: \"ओटीपी (OTP) धाडात\",\n confirmOtp: \"ओटीपी (OTP) निश्चीत करात\",\n verifyWithOtp: \"ओटीपी (OTP) वरवीं तपासात\",\n editSelections: \"निवडी संपादित करात\",\n otpIncorrect:\n \"तुमी घाललो पडताळणी कोड चुकीचो आसा. उपकार करून तपासात आनी परत यत्न करात.\",\n otpExpired: \"तुमच्या पडताळणी कोडाची मुदत सोंपली. उपकार करून नवो कोड मागात.\",\n otpNotFound: \"पडताळणी कोड मेळूंक ना. उपकार करून नवो कोड मागात.\",\n otpVerifyFailed: \"ओटीपी (OTP) पडताळूंक जमलें ना. उपकार करून परत यत्न करात.\",\n otpSendFailed: \"ओटीपी (OTP) धाडूंक जमलें ना. उपकार करून परत यत्न करात.\",\n consentConfirmed: \"संमती निश्चीत जाली\",\n recordedUnder: \"ओटीपी (OTP) तपासलो · {regulation} खाला नोंद केली\",\n recordedUnderAt:\n \"ओटीपी (OTP) तपासलो · {regulation} खाला {time} वोरांचेर नोंद केली\",\n consentReferenceId: \"संमती संदर्भ आयडी\",\n proceed: \"फुडें वचात\",\n loadingNotice: \"नोटीस लोड जाता\",\n loadFailedTitle: \"संमती नोटीस लोड करूंक जमलें ना\",\n tryAgain: \"उपकार करून परत यत्न करात.\",\n close: \"बंद करात\",\n};\n\nconst mai: StaticStrings = {\n useEmailInstead: \"ईमेल उपयोग करू\",\n useMobileInstead: \"मोबाइल उपयोग करू\",\n emailAddress: \"ईमेल पता\",\n otpHelperEmail: \"हम एहि ईमेल पर एकटा वन-टाइम पासवर्ड पठाएब.\",\n changeEmail: \"ईमेल बदलू\",\n expandDetails: \"{name} क विवरण विस्तृत करू\",\n collapseDetails: \"{name} क विवरण संक्षिप्त करू\",\n selectAllFor: \"{name} लेल सभ डेटा तत्व चुनू\",\n selectElement: \"{name} चुनू\",\n selectElementRequired: \"{name} चुनू (आवश्यक)\",\n required: \"आवश्यक\",\n logoAlt: \"लोगो\",\n selectLanguage: \"भाषा चुनू\",\n selectLanguageCurrent: \"भाषा चुनू. वर्तमान भाषा: {lang}\",\n opensInNewTab: \"नव टैब मे खुजैत अछि\",\n audioStart: \"ऑडियो प्लेबैक शुरू करू\",\n audioPause: \"ऑडियो प्लेबैक रोकू\",\n talkbackStart: \"टॉकबैक शुरू करू\",\n talkbackPause: \"टॉकबैक रोकू\",\n mobileNumber: \"मोबाइल नंबर\",\n otpHelper: \"हम एहि नंबर पर एकटा वन-टाइम पासवर्ड पठाएब.\",\n otpSentTo: \"ओटीपी (OTP) पठाओल गेल\",\n changeMobile: \"मोबाइल नंबर बदलू\",\n enterNDigitOtp: \"{count}-अंक क ओटीपी (OTP) दर्ज करू\",\n otpDigit: \"ओटीपी (OTP) अंक {index}\",\n resendIn: \"{seconds} सेकंड मे ओटीपी (OTP) पुनः पठाउ\",\n sending: \"पठाओल जा रहल अछि…\",\n resendOtp: \"ओटीपी (OTP) पुनः पठाउ\",\n getOtp: \"ओटीपी (OTP) प्राप्त करू\",\n verifying: \"सत्यापित कैल जा रहल अछि…\",\n verifyOtp: \"ओटीपी (OTP) सत्यापित करू\",\n sendOtp: \"ओटीपी (OTP) पठाउ\",\n confirmOtp: \"ओटीपी (OTP) क पुष्टि करू\",\n verifyWithOtp: \"ओटीपी (OTP) सँ सत्यापित करू\",\n editSelections: \"चयन संपादित करू\",\n otpIncorrect:\n \"अहाँक दर्ज कएल सत्यापन कोड गलत अछि. कृपया जाँचू आ फेर प्रयास करू.\",\n otpExpired: \"अहाँक सत्यापन कोडक अवधि समाप्त भ' गेल. कृपया नव कोड मांगू.\",\n otpNotFound: \"सत्यापन कोड नहि भेटल. कृपया नव कोड मांगू.\",\n otpVerifyFailed: \"ओटीपी (OTP) सत्यापित नहि भ' सकल. कृपया फेर प्रयास करू.\",\n otpSendFailed: \"ओटीपी (OTP) पठाओल नहि जा सकल. कृपया फेर प्रयास करू.\",\n consentConfirmed: \"सहमति क पुष्टि भेल\",\n recordedUnder: \"ओटीपी (OTP) सत्यापित · {regulation} क अंतर्गत दर्ज\",\n recordedUnderAt:\n \"ओटीपी (OTP) सत्यापित · {regulation} क अंतर्गत {time} बजे दर्ज\",\n consentReferenceId: \"सहमति संदर्भ आईडी\",\n proceed: \"आगू बढ़ू\",\n loadingNotice: \"नोटिस लोड भ' रहल अछि\",\n loadFailedTitle: \"सहमति नोटिस लोड नहि भ' सकल\",\n tryAgain: \"कृपया पुनः प्रयास करू.\",\n close: \"बंद करू\",\n};\n\nconst ml: StaticStrings = {\n useEmailInstead: \"ഇമെയിൽ ഉപയോഗിക്കുക\",\n useMobileInstead: \"മൊബൈൽ ഉപയോഗിക്കുക\",\n emailAddress: \"ഇമെയിൽ വിലാസം\",\n otpHelperEmail: \"ഞങ്ങൾ ഈ ഇമെയിലിലേക്ക് ഒറ്റത്തവണ പാസ്‌വേഡ് അയയ്ക്കും.\",\n changeEmail: \"ഇമെയിൽ മാറ്റുക\",\n expandDetails: \"{name} വിശദാംശങ്ങൾ വികസിപ്പിക്കുക\",\n collapseDetails: \"{name} വിശദാംശങ്ങൾ ചുരുക്കുക\",\n selectAllFor: \"{name} എന്നതിനായി എല്ലാ ഡാറ്റ ഘടകങ്ങളും തിരഞ്ഞെടുക്കുക\",\n selectElement: \"{name} തിരഞ്ഞെടുക്കുക\",\n selectElementRequired: \"{name} തിരഞ്ഞെടുക്കുക (ആവശ്യമാണ്)\",\n required: \"ആവശ്യമാണ്\",\n logoAlt: \"ലോഗോ\",\n selectLanguage: \"ഭാഷ തിരഞ്ഞെടുക്കുക\",\n selectLanguageCurrent: \"ഭാഷ തിരഞ്ഞെടുക്കുക. നിലവിലെ ഭാഷ: {lang}\",\n opensInNewTab: \"പുതിയ ടാബിൽ തുറക്കുന്നു\",\n audioStart: \"ഓഡിയോ പ്ലേബാക്ക് ആരംഭിക്കുക\",\n audioPause: \"ഓഡിയോ പ്ലേബാക്ക് താൽക്കാലികമായി നിർത്തുക\",\n talkbackStart: \"ടോക്ക്ബാക്ക് ആരംഭിക്കുക\",\n talkbackPause: \"ടോക്ക്ബാക്ക് താൽക്കാലികമായി നിർത്തുക\",\n mobileNumber: \"മൊബൈൽ നമ്പർ\",\n otpHelper: \"ഞങ്ങൾ ഈ നമ്പറിലേക്ക് ഒറ്റത്തവണ പാസ്‌വേഡ് അയയ്ക്കും.\",\n otpSentTo: \"ഒടിപി (OTP) അയച്ചു\",\n changeMobile: \"മൊബൈൽ നമ്പർ മാറ്റുക\",\n enterNDigitOtp: \"{count}-അക്ക ഒടിപി (OTP) നൽകുക\",\n otpDigit: \"ഒടിപി (OTP) അക്കം {index}\",\n resendIn: \"{seconds} സെക്കൻഡിൽ ഒടിപി (OTP) വീണ്ടും അയയ്ക്കുക\",\n sending: \"അയയ്ക്കുന്നു…\",\n resendOtp: \"ഒടിപി (OTP) വീണ്ടും അയയ്ക്കുക\",\n getOtp: \"ഒടിപി (OTP) നേടുക\",\n verifying: \"പരിശോധിക്കുന്നു…\",\n verifyOtp: \"ഒടിപി (OTP) പരിശോധിക്കുക\",\n sendOtp: \"ഒടിപി (OTP) അയയ്ക്കുക\",\n confirmOtp: \"ഒടിപി (OTP) സ്ഥിരീകരിക്കുക\",\n verifyWithOtp: \"ഒടിപി (OTP) ഉപയോഗിച്ച് പരിശോധിക്കുക\",\n editSelections: \"തിരഞ്ഞെടുപ്പുകൾ എഡിറ്റ് ചെയ്യുക\",\n otpIncorrect:\n \"നിങ്ങൾ നൽകിയ പരിശോധനാ കോഡ് തെറ്റാണ്. ദയവായി പരിശോധിച്ച് വീണ്ടും ശ്രമിക്കുക.\",\n otpExpired:\n \"നിങ്ങളുടെ പരിശോധനാ കോഡിന്റെ കാലാവധി കഴിഞ്ഞു. ദയവായി പുതിയ കോഡ് അഭ്യർത്ഥിക്കുക.\",\n otpNotFound:\n \"പരിശോധനാ കോഡ് കണ്ടെത്തിയില്ല. ദയവായി പുതിയ കോഡ് അഭ്യർത്ഥിക്കുക.\",\n otpVerifyFailed: \"ഒടിപി (OTP) പരിശോധിക്കാനായില്ല. ദയവായി വീണ്ടും ശ്രമിക്കുക.\",\n otpSendFailed: \"ഒടിപി (OTP) അയയ്ക്കാനായില്ല. ദയവായി വീണ്ടും ശ്രമിക്കുക.\",\n consentConfirmed: \"സമ്മതം സ്ഥിരീകരിച്ചു\",\n recordedUnder: \"ഒടിപി (OTP) പരിശോധിച്ചു · {regulation} പ്രകാരം രേഖപ്പെടുത്തി\",\n recordedUnderAt:\n \"ഒടിപി (OTP) പരിശോധിച്ചു · {regulation} പ്രകാരം {time}-ന് രേഖപ്പെടുത്തി\",\n consentReferenceId: \"സമ്മത റഫറൻസ് ഐഡി\",\n proceed: \"തുടരുക\",\n loadingNotice: \"നോട്ടീസ് ലോഡ് ചെയ്യുന്നു\",\n loadFailedTitle: \"സമ്മത നോട്ടീസ് ലോഡ് ചെയ്യാനായില്ല\",\n tryAgain: \"ദയവായി വീണ്ടും ശ്രമിക്കുക.\",\n close: \"അടയ്ക്കുക\",\n};\n\nconst mniMtei: StaticStrings = {\n useEmailInstead: \"ইমেইল শিজিন্নবা\",\n useMobileInstead: \"মোবাইল শিজিন্নবা\",\n emailAddress: \"ইমেইল ঠিকানা\",\n otpHelperEmail: \"ঐখোয়না ইমেইল অসিদা অমুক্তং শিজিন্নবা পাসৱার্দ থাগনি।\",\n changeEmail: \"ইমেইল হোংদোকউ\",\n expandDetails: \"{name} গী অকুপ্পা ৱারোল ফোংদোকউ\",\n collapseDetails: \"{name} গী অকুপ্পা ৱারোল হুপশিনউ\",\n selectAllFor: \"{name} গীদমক ডেটা পুম্নমক খনগৎলু\",\n selectElement: \"{name} খনগৎলু\",\n selectElementRequired: \"{name} খনগৎলু (দরকার ওই)\",\n required: \"দরকার ওই\",\n logoAlt: \"লোগো\",\n selectLanguage: \"লোল খনগৎলু\",\n selectLanguageCurrent: \"লোল খনগৎলু। হৌজিক্কী লোল: {lang}\",\n opensInNewTab: \"অনৌবা টেবত হাংই\",\n audioStart: \"অডিও প্লেবেক হৌদোকউ\",\n audioPause: \"অডিও প্লেবেক লেপশিনউ\",\n talkbackStart: \"টোকবেক হৌদোকউ\",\n talkbackPause: \"টোকবেক লেপশিনউ\",\n mobileNumber: \"মোবাইল নম্বর\",\n otpHelper: \"ঐখোয়না নম্বর অসিদা অমুক্তং শিজিন্নবা পাসৱার্দ থাগনি।\",\n otpSentTo: \"ওটিপি (OTP) থাখ্রে\",\n changeMobile: \"মোবাইল নম্বর হোংদোকউ\",\n enterNDigitOtp: \"{count}-মশিংগী ওটিপি (OTP) চংশিল্লু\",\n otpDigit: \"ওটিপি (OTP) মশিং {index}\",\n resendIn: \"{seconds} সেকেন্দগী মনুংদা ওটিপি (OTP) অমুক হন্না থাউ\",\n sending: \"থারি…\",\n resendOtp: \"ওটিপি (OTP) অমুক হন্না থাউ\",\n getOtp: \"ওটিপি (OTP) ফংউ\",\n verifying: \"শোয়দনা য়েংলি…\",\n verifyOtp: \"ওটিপি (OTP) শোয়দনা য়েংউ\",\n sendOtp: \"ওটিপি (OTP) থাউ\",\n confirmOtp: \"ওটিপি (OTP) চপ চানা শেংদোকউ\",\n verifyWithOtp: \"ওটিপি (OTP) না শোয়দনা য়েংউ\",\n editSelections: \"খনগৎলবশিং শেমদোকউ\",\n otpIncorrect:\n \"নহাক্না চংশিল্লবা ভেরিফিকেসন কোদ অসি অরানবনি। চানবীদুনা য়েংশিল্লগা অমুক হন্না হোৎনবীয়ু।\",\n otpExpired:\n \"নহাক্কী ভেরিফিকেসন কোদ অসিগী মতম লোইখ্রে। চানবীদুনা অনৌবা কোদ অমা নিজবীয়ু।\",\n otpNotFound: \"ভেরিফিকেসন কোদ ফংদ্রে। চানবীদুনা অনৌবা কোদ অমা নিজবীয়ু।\",\n otpVerifyFailed:\n \"ওটিপি (OTP) শোয়দনা য়েংবা ঙমদ্রে। চানবীদুনা অমুক হন্না হোৎনবীয়ু।\",\n otpSendFailed: \"ওটিপি (OTP) থাবা ঙমদ্রে। চানবীদুনা অমুক হন্না হোৎনবীয়ু।\",\n consentConfirmed: \"অয়াবা চপ চানা শেংদোকখ্রে\",\n recordedUnder:\n \"ওটিপি (OTP) শোয়দনা য়েংলে · {regulation} গী মখাদা রেকর্ড তৌখ্রে\",\n recordedUnderAt:\n \"ওটিপি (OTP) শোয়দনা য়েংলে · {regulation} গী মখাদা {time} দা রেকর্ড তৌখ্রে\",\n consentReferenceId: \"অয়াবা রেফরেন্স আইদি\",\n proceed: \"মখা চৎথউ\",\n loadingNotice: \"নোতিস লোদ তৌরি\",\n loadFailedTitle: \"অয়াবা নোতিস লোদ তৌবা ঙমদে\",\n tryAgain: \"চানবীদুনা অমুক হন্না হোৎনবীয়ু।\",\n close: \"লোনশিনউ\",\n};\n\nconst mr: StaticStrings = {\n useEmailInstead: \"ईमेल वापरा\",\n useMobileInstead: \"मोबाइल वापरा\",\n emailAddress: \"ईमेल पत्ता\",\n otpHelperEmail: \"आम्ही या ईमेलवर एक-वेळचा पासवर्ड पाठवू.\",\n changeEmail: \"ईमेल बदला\",\n expandDetails: \"{name} चे तपशील विस्तृत करा\",\n collapseDetails: \"{name} चे तपशील संक्षिप्त करा\",\n selectAllFor: \"{name} साठी सर्व डेटा घटक निवडा\",\n selectElement: \"{name} निवडा\",\n selectElementRequired: \"{name} निवडा (आवश्यक)\",\n required: \"आवश्यक\",\n logoAlt: \"लोगो\",\n selectLanguage: \"भाषा निवडा\",\n selectLanguageCurrent: \"भाषा निवडा. सध्याची भाषा: {lang}\",\n opensInNewTab: \"नवीन टॅबमध्ये उघडते\",\n audioStart: \"ऑडिओ प्लेबॅक सुरू करा\",\n audioPause: \"ऑडिओ प्लेबॅक थांबवा\",\n talkbackStart: \"टॉकबॅक सुरू करा\",\n talkbackPause: \"टॉकबॅक थांबवा\",\n mobileNumber: \"मोबाइल नंबर\",\n otpHelper: \"आम्ही या नंबरवर एक-वेळचा पासवर्ड पाठवू.\",\n otpSentTo: \"ओटीपी (OTP) पाठवला\",\n changeMobile: \"मोबाइल नंबर बदला\",\n enterNDigitOtp: \"{count}-अंकी ओटीपी (OTP) प्रविष्ट करा\",\n otpDigit: \"ओटीपी (OTP) अंक {index}\",\n resendIn: \"{seconds} सेकंदात ओटीपी (OTP) पुन्हा पाठवा\",\n sending: \"पाठवत आहे…\",\n resendOtp: \"ओटीपी (OTP) पुन्हा पाठवा\",\n getOtp: \"ओटीपी (OTP) मिळवा\",\n verifying: \"पडताळत आहे…\",\n verifyOtp: \"ओटीपी (OTP) पडताळा\",\n sendOtp: \"ओटीपी (OTP) पाठवा\",\n confirmOtp: \"ओटीपी (OTP) ची पुष्टी करा\",\n verifyWithOtp: \"ओटीपी (OTP) ने पडताळा\",\n editSelections: \"निवडी संपादित करा\",\n otpIncorrect:\n \"तुम्ही प्रविष्ट केलेला पडताळणी कोड चुकीचा आहे. कृपया तपासा आणि पुन्हा प्रयत्न करा.\",\n otpExpired: \"तुमच्या पडताळणी कोडची मुदत संपली आहे. कृपया नवीन कोड मागवा.\",\n otpNotFound: \"पडताळणी कोड सापडला नाही. कृपया नवीन कोड मागवा.\",\n otpVerifyFailed: \"ओटीपी (OTP) पडताळता आला नाही. कृपया पुन्हा प्रयत्न करा.\",\n otpSendFailed: \"ओटीपी (OTP) पाठवता आला नाही. कृपया पुन्हा प्रयत्न करा.\",\n consentConfirmed: \"संमती निश्चित झाली\",\n recordedUnder: \"ओटीपी (OTP) पडताळला · {regulation} अंतर्गत नोंदवले\",\n recordedUnderAt:\n \"ओटीपी (OTP) पडताळला · {regulation} अंतर्गत {time} वाजता नोंदवले\",\n consentReferenceId: \"संमती संदर्भ आयडी\",\n proceed: \"पुढे जा\",\n loadingNotice: \"सूचना लोड होत आहे\",\n loadFailedTitle: \"संमती सूचना लोड करता आली नाही\",\n tryAgain: \"कृपया पुन्हा प्रयत्न करा.\",\n close: \"बंद करा\",\n};\n\nconst ne: StaticStrings = {\n useEmailInstead: \"इमेल प्रयोग गर्नुहोस्\",\n useMobileInstead: \"मोबाइल प्रयोग गर्नुहोस्\",\n emailAddress: \"इमेल ठेगाना\",\n otpHelperEmail: \"हामी यो इमेलमा एक-पटक प्रयोग हुने पासवर्ड पठाउनेछौं।\",\n changeEmail: \"इमेल परिवर्तन गर्नुहोस्\",\n expandDetails: \"{name} को विवरण विस्तार गर्नुहोस्\",\n collapseDetails: \"{name} को विवरण संक्षिप्त गर्नुहोस्\",\n selectAllFor: \"{name} का लागि सबै डेटा तत्वहरू चयन गर्नुहोस्\",\n selectElement: \"{name} चयन गर्नुहोस्\",\n selectElementRequired: \"{name} चयन गर्नुहोस् (आवश्यक)\",\n required: \"आवश्यक\",\n logoAlt: \"लोगो\",\n selectLanguage: \"भाषा चयन गर्नुहोस्\",\n selectLanguageCurrent: \"भाषा चयन गर्नुहोस्। हालको भाषा: {lang}\",\n opensInNewTab: \"नयाँ ट्याबमा खुल्छ\",\n audioStart: \"अडियो प्लेब्याक सुरु गर्नुहोस्\",\n audioPause: \"अडियो प्लेब्याक रोक्नुहोस्\",\n talkbackStart: \"टकब्याक सुरु गर्नुहोस्\",\n talkbackPause: \"टकब्याक रोक्नुहोस्\",\n mobileNumber: \"मोबाइल नम्बर\",\n otpHelper: \"हामी यो नम्बरमा एक-पटक प्रयोग हुने पासवर्ड पठाउनेछौं।\",\n otpSentTo: \"ओटीपी (OTP) पठाइयो\",\n changeMobile: \"मोबाइल नम्बर परिवर्तन गर्नुहोस्\",\n enterNDigitOtp: \"{count}-अङ्कको ओटीपी (OTP) प्रविष्ट गर्नुहोस्\",\n otpDigit: \"ओटीपी (OTP) अङ्क {index}\",\n resendIn: \"{seconds} सेकेन्डमा ओटीपी (OTP) पुनः पठाउनुहोस्\",\n sending: \"पठाउँदै…\",\n resendOtp: \"ओटीपी (OTP) पुनः पठाउनुहोस्\",\n getOtp: \"ओटीपी (OTP) प्राप्त गर्नुहोस्\",\n verifying: \"प्रमाणित गर्दै…\",\n verifyOtp: \"ओटीपी (OTP) प्रमाणित गर्नुहोस्\",\n sendOtp: \"ओटीपी (OTP) पठाउनुहोस्\",\n confirmOtp: \"ओटीपी (OTP) पुष्टि गर्नुहोस्\",\n verifyWithOtp: \"ओटीपी (OTP) मार्फत प्रमाणित गर्नुहोस्\",\n editSelections: \"चयनहरू सम्पादन गर्नुहोस्\",\n otpIncorrect:\n \"तपाईंले प्रविष्ट गर्नुभएको प्रमाणीकरण कोड गलत छ. कृपया जाँच गरी पुनः प्रयास गर्नुहोस्.\",\n otpExpired:\n \"तपाईंको प्रमाणीकरण कोडको म्याद सकिएको छ. कृपया नयाँ कोड अनुरोध गर्नुहोस्.\",\n otpNotFound: \"प्रमाणीकरण कोड फेला परेन. कृपया नयाँ कोड अनुरोध गर्नुहोस्.\",\n otpVerifyFailed:\n \"ओटीपी (OTP) प्रमाणित गर्न सकिएन. कृपया पुनः प्रयास गर्नुहोस्.\",\n otpSendFailed: \"ओटीपी (OTP) पठाउन सकिएन. कृपया पुनः प्रयास गर्नुहोस्.\",\n consentConfirmed: \"सहमति पुष्टि भयो\",\n recordedUnder: \"ओटीपी (OTP) प्रमाणित · {regulation} अन्तर्गत अभिलेख गरियो\",\n recordedUnderAt:\n \"ओटीपी (OTP) प्रमाणित · {regulation} अन्तर्गत {time} मा अभिलेख गरियो\",\n consentReferenceId: \"सहमति सन्दर्भ आईडी\",\n proceed: \"अगाडि बढ्नुहोस्\",\n loadingNotice: \"सूचना लोड हुँदै\",\n loadFailedTitle: \"सहमति सूचना लोड गर्न सकिएन\",\n tryAgain: \"कृपया पुनः प्रयास गर्नुहोस्।\",\n close: \"बन्द गर्नुहोस्\",\n};\n\nconst or: StaticStrings = {\n useEmailInstead: \"ଇମେଲ୍ ବ୍ୟବହାର କରନ୍ତୁ\",\n useMobileInstead: \"ମୋବାଇଲ୍ ବ୍ୟବହାର କରନ୍ତୁ\",\n emailAddress: \"ଇମେଲ୍ ଠିକଣା\",\n otpHelperEmail: \"ଆମେ ଏହି ଇମେଲକୁ ଗୋଟିଏ-ଥର ବ୍ୟବହାର ପାସୱର୍ଡ ପଠାଇବୁ।\",\n changeEmail: \"ଇମେଲ୍ ବଦଳାନ୍ତୁ\",\n expandDetails: \"{name} ର ବିବରଣୀ ବିସ୍ତାର କରନ୍ତୁ\",\n collapseDetails: \"{name} ର ବିବରଣୀ ସଙ୍କୁଚିତ କରନ୍ତୁ\",\n selectAllFor: \"{name} ପାଇଁ ସମସ୍ତ ଡାଟା ଉପାଦାନ ବାଛନ୍ତୁ\",\n selectElement: \"{name} ବାଛନ୍ତୁ\",\n selectElementRequired: \"{name} ବାଛନ୍ତୁ (ଆବଶ୍ୟକ)\",\n required: \"ଆବଶ୍ୟକ\",\n logoAlt: \"ଲୋଗୋ\",\n selectLanguage: \"ଭାଷା ବାଛନ୍ତୁ\",\n selectLanguageCurrent: \"ଭାଷା ବାଛନ୍ତୁ। ବର୍ତ୍ତମାନର ଭାଷା: {lang}\",\n opensInNewTab: \"ନୂଆ ଟ୍ୟାବରେ ଖୋଲେ\",\n audioStart: \"ଅଡିଓ ପ୍ଲେବ୍ୟାକ୍ ଆରମ୍ଭ କରନ୍ତୁ\",\n audioPause: \"ଅଡିଓ ପ୍ଲେବ୍ୟାକ୍ ବିରତ କରନ୍ତୁ\",\n talkbackStart: \"ଟକ୍‌ବ୍ୟାକ୍ ଆରମ୍ଭ କରନ୍ତୁ\",\n talkbackPause: \"ଟକ୍‌ବ୍ୟାକ୍ ବିରତ କରନ୍ତୁ\",\n mobileNumber: \"ମୋବାଇଲ୍ ନମ୍ବର\",\n otpHelper: \"ଆମେ ଏହି ନମ୍ବରକୁ ଗୋଟିଏ-ଥର ବ୍ୟବହାର ପାସୱର୍ଡ ପଠାଇବୁ।\",\n otpSentTo: \"ଓଟିପି (OTP) ପଠାଗଲା\",\n changeMobile: \"ମୋବାଇଲ୍ ନମ୍ବର ବଦଳାନ୍ତୁ\",\n enterNDigitOtp: \"{count}-ଅଙ୍କ ବିଶିଷ୍ଟ ଓଟିପି (OTP) ଭରନ୍ତୁ\",\n otpDigit: \"ଓଟିପି (OTP) ଅଙ୍କ {index}\",\n resendIn: \"{seconds} ସେକେଣ୍ଡରେ ଓଟିପି (OTP) ପୁନଃ ପଠାନ୍ତୁ\",\n sending: \"ପଠାଯାଉଛି…\",\n resendOtp: \"ଓଟିପି (OTP) ପୁନଃ ପଠାନ୍ତୁ\",\n getOtp: \"ଓଟିପି (OTP) ପାଆନ୍ତୁ\",\n verifying: \"ଯାଞ୍ଚ କରାଯାଉଛି…\",\n verifyOtp: \"ଓଟିପି (OTP) ଯାଞ୍ଚ କରନ୍ତୁ\",\n sendOtp: \"ଓଟିପି (OTP) ପଠାନ୍ତୁ\",\n confirmOtp: \"ଓଟିପି (OTP) ନିଶ୍ଚିତ କରନ୍ତୁ\",\n verifyWithOtp: \"ଓଟିପି (OTP) ମାଧ୍ୟମରେ ଯାଞ୍ଚ କରନ୍ତୁ\",\n editSelections: \"ଚୟନଗୁଡ଼ିକ ସମ୍ପାଦନ କରନ୍ତୁ\",\n otpIncorrect:\n \"ଆପଣ ଭରିଥିବା ଯାଞ୍ଚ କୋଡ୍ ଭୁଲ ଅଛି। ଦୟାକରି ଯାଞ୍ଚ କରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।\",\n otpExpired: \"ଆପଣଙ୍କ ଯାଞ୍ଚ କୋଡ୍‌ର ମିଆଦ ସରିଯାଇଛି। ଦୟାକରି ନୂଆ କୋଡ୍ ମାଗନ୍ତୁ।\",\n otpNotFound: \"ଯାଞ୍ଚ କୋଡ୍ ମିଳିଲା ନାହିଁ। ଦୟାକରି ନୂଆ କୋଡ୍ ମାଗନ୍ତୁ।\",\n otpVerifyFailed:\n \"ଓଟିପି (OTP) ଯାଞ୍ଚ କରାଯାଇପାରିଲା ନାହିଁ। ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।\",\n otpSendFailed: \"ଓଟିପି (OTP) ପଠାଯାଇପାରିଲା ନାହିଁ। ଦୟାକରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।\",\n consentConfirmed: \"ସମ୍ମତି ନିଶ୍ଚିତ ହେଲା\",\n recordedUnder: \"ଓଟିପି (OTP) ଯାଞ୍ଚ ହେଲା · {regulation} ଅଧୀନରେ ରେକର୍ଡ କରାଗଲା\",\n recordedUnderAt:\n \"ଓଟିପି (OTP) ଯାଞ୍ଚ ହେଲା · {regulation} ଅଧୀନରେ {time}ରେ ରେକର୍ଡ କରାଗଲା\",\n consentReferenceId: \"ସମ୍ମତି ରେଫରେନ୍ସ ଆଇଡି\",\n proceed: \"ଆଗକୁ ବଢ଼ନ୍ତୁ\",\n loadingNotice: \"ବିଜ୍ଞପ୍ତି ଲୋଡ୍ ହେଉଛି\",\n loadFailedTitle: \"ସମ୍ମତି ବିଜ୍ଞପ୍ତି ଲୋଡ୍ କରାଯାଇପାରିଲା ନାହିଁ\",\n tryAgain: \"ଦୟାକରି ପୁନଃ ଚେଷ୍ଟା କରନ୍ତୁ।\",\n close: \"ବନ୍ଦ କରନ୍ତୁ\",\n};\n\nconst pa: StaticStrings = {\n useEmailInstead: \"ਈਮੇਲ ਵਰਤੋ\",\n useMobileInstead: \"ਮੋਬਾਈਲ ਵਰਤੋ\",\n emailAddress: \"ਈਮੇਲ ਪਤਾ\",\n otpHelperEmail: \"ਅਸੀਂ ਇਸ ਈਮੇਲ 'ਤੇ ਇੱਕ ਵਾਰੀ ਵਰਤੋਂ ਵਾਲਾ ਪਾਸਵਰਡ ਭੇਜਾਂਗੇ।\",\n changeEmail: \"ਈਮੇਲ ਬਦਲੋ\",\n expandDetails: \"{name} ਦੇ ਵੇਰਵੇ ਫੈਲਾਓ\",\n collapseDetails: \"{name} ਦੇ ਵੇਰਵੇ ਸਮੇਟੋ\",\n selectAllFor: \"{name} ਲਈ ਸਾਰੇ ਡਾਟਾ ਤੱਤ ਚੁਣੋ\",\n selectElement: \"{name} ਚੁਣੋ\",\n selectElementRequired: \"{name} ਚੁਣੋ (ਲੋੜੀਂਦਾ)\",\n required: \"ਲੋੜੀਂਦਾ\",\n logoAlt: \"ਲੋਗੋ\",\n selectLanguage: \"ਭਾਸ਼ਾ ਚੁਣੋ\",\n selectLanguageCurrent: \"ਭਾਸ਼ਾ ਚੁਣੋ। ਮੌਜੂਦਾ ਭਾਸ਼ਾ: {lang}\",\n opensInNewTab: \"ਨਵੀਂ ਟੈਬ ਵਿੱਚ ਖੁੱਲ੍ਹਦਾ ਹੈ\",\n audioStart: \"ਆਡੀਓ ਪਲੇਬੈਕ ਸ਼ੁਰੂ ਕਰੋ\",\n audioPause: \"ਆਡੀਓ ਪਲੇਬੈਕ ਰੋਕੋ\",\n talkbackStart: \"ਟਾਕਬੈਕ ਸ਼ੁਰੂ ਕਰੋ\",\n talkbackPause: \"ਟਾਕਬੈਕ ਰੋਕੋ\",\n mobileNumber: \"ਮੋਬਾਈਲ ਨੰਬਰ\",\n otpHelper: \"ਅਸੀਂ ਇਸ ਨੰਬਰ 'ਤੇ ਇੱਕ ਵਾਰੀ ਵਰਤੋਂ ਵਾਲਾ ਪਾਸਵਰਡ ਭੇਜਾਂਗੇ।\",\n otpSentTo: \"ਓਟੀਪੀ (OTP) ਭੇਜਿਆ ਗਿਆ\",\n changeMobile: \"ਮੋਬਾਈਲ ਨੰਬਰ ਬਦਲੋ\",\n enterNDigitOtp: \"{count}-ਅੰਕਾਂ ਵਾਲਾ ਓਟੀਪੀ (OTP) ਦਰਜ ਕਰੋ\",\n otpDigit: \"ਓਟੀਪੀ (OTP) ਅੰਕ {index}\",\n resendIn: \"{seconds} ਸਕਿੰਟਾਂ ਵਿੱਚ ਓਟੀਪੀ (OTP) ਮੁੜ ਭੇਜੋ\",\n sending: \"ਭੇਜਿਆ ਜਾ ਰਿਹਾ ਹੈ…\",\n resendOtp: \"ਓਟੀਪੀ (OTP) ਮੁੜ ਭੇਜੋ\",\n getOtp: \"ਓਟੀਪੀ (OTP) ਪ੍ਰਾਪਤ ਕਰੋ\",\n verifying: \"ਪੁਸ਼ਟੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…\",\n verifyOtp: \"ਓਟੀਪੀ (OTP) ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ\",\n sendOtp: \"ਓਟੀਪੀ (OTP) ਭੇਜੋ\",\n confirmOtp: \"ਓਟੀਪੀ (OTP) ਦੀ ਤਸਦੀਕ ਕਰੋ\",\n verifyWithOtp: \"ਓਟੀਪੀ (OTP) ਨਾਲ ਤਸਦੀਕ ਕਰੋ\",\n editSelections: \"ਚੋਣਾਂ ਸੋਧੋ\",\n otpIncorrect:\n \"ਤੁਹਾਡੇ ਵੱਲੋਂ ਦਰਜ ਕੀਤਾ ਤਸਦੀਕ ਕੋਡ ਗਲਤ ਹੈ। ਕਿਰਪਾ ਕਰਕੇ ਜਾਂਚ ਕਰੋ ਅਤੇ ਮੁੜ ਕੋਸ਼ਿਸ਼ ਕਰੋ।\",\n otpExpired:\n \"ਤੁਹਾਡੇ ਤਸਦੀਕ ਕੋਡ ਦੀ ਮਿਆਦ ਖਤਮ ਹੋ ਗਈ ਹੈ। ਕਿਰਪਾ ਕਰਕੇ ਨਵਾਂ ਕੋਡ ਮੰਗੋ।\",\n otpNotFound: \"ਤਸਦੀਕ ਕੋਡ ਨਹੀਂ ਮਿਲਿਆ। ਕਿਰਪਾ ਕਰਕੇ ਨਵਾਂ ਕੋਡ ਮੰਗੋ।\",\n otpVerifyFailed:\n \"ਓਟੀਪੀ (OTP) ਦੀ ਤਸਦੀਕ ਨਹੀਂ ਹੋ ਸਕੀ। ਕਿਰਪਾ ਕਰਕੇ ਮੁੜ ਕੋਸ਼ਿਸ਼ ਕਰੋ।\",\n otpSendFailed: \"ਓਟੀਪੀ (OTP) ਨਹੀਂ ਭੇਜਿਆ ਜਾ ਸਕਿਆ। ਕਿਰਪਾ ਕਰਕੇ ਮੁੜ ਕੋਸ਼ਿਸ਼ ਕਰੋ।\",\n consentConfirmed: \"ਸਹਿਮਤੀ ਦੀ ਪੁਸ਼ਟੀ ਹੋਈ\",\n recordedUnder: \"ਓਟੀਪੀ (OTP) ਦੀ ਪੁਸ਼ਟੀ · {regulation} ਅਧੀਨ ਦਰਜ ਕੀਤਾ ਗਿਆ\",\n recordedUnderAt:\n \"ਓਟੀਪੀ (OTP) ਦੀ ਪੁਸ਼ਟੀ · {regulation} ਅਧੀਨ {time} ਵਜੇ ਦਰਜ ਕੀਤਾ ਗਿਆ\",\n consentReferenceId: \"ਸਹਿਮਤੀ ਰੈਫਰੈਂਸ ਆਈਡੀ\",\n proceed: \"ਅੱਗੇ ਵਧੋ\",\n loadingNotice: \"ਨੋਟਿਸ ਲੋਡ ਹੋ ਰਿਹਾ ਹੈ\",\n loadFailedTitle: \"ਸਹਿਮਤੀ ਨੋਟਿਸ ਲੋਡ ਨਹੀਂ ਹੋ ਸਕਿਆ\",\n tryAgain: \"ਕਿਰਪਾ ਕਰਕੇ ਮੁੜ ਕੋਸ਼ਿਸ਼ ਕਰੋ।\",\n close: \"ਬੰਦ ਕਰੋ\",\n};\n\nconst sa: StaticStrings = {\n useEmailInstead: \"ईमेल् उपयुज्यताम्\",\n useMobileInstead: \"चलदूरभाषः उपयुज्यताम्\",\n emailAddress: \"ईमेल्-पता\",\n otpHelperEmail: \"वयम् अस्मिन् ईमेल् एकवारप्रयोग-कूटशब्दं प्रेषयिष्यामः।\",\n changeEmail: \"ईमेल् परिवर्तयतु\",\n expandDetails: \"{name} इत्यस्य विवरणं विस्तारयतु\",\n collapseDetails: \"{name} इत्यस्य विवरणं संक्षिपतु\",\n selectAllFor: \"{name} कृते सर्वाणि दत्तांश-तत्त्वानि चिनोतु\",\n selectElement: \"{name} चिनोतु\",\n selectElementRequired: \"{name} चिनोतु (आवश्यकम्)\",\n required: \"आवश्यकम्\",\n logoAlt: \"प्रतीकचिह्नम्\",\n selectLanguage: \"भाषां चिनोतु\",\n selectLanguageCurrent: \"भाषां चिनोतु। वर्तमाना भाषा: {lang}\",\n opensInNewTab: \"नूतनपटले उद्घाटयति\",\n audioStart: \"श्रव्यप्रचारणम् आरभतु\",\n audioPause: \"श्रव्यप्रचारणं विरमयतु\",\n talkbackStart: \"टॉक्-बैक् आरभतु\",\n talkbackPause: \"टॉक्-बैक् विरमयतु\",\n mobileNumber: \"चलदूरभाष-सङ्ख्या\",\n otpHelper: \"वयम् अस्मिन् सङ्ख्यायां एकवारप्रयोग-कूटशब्दं प्रेषयिष्यामः।\",\n otpSentTo: \"ओटीपी (OTP) प्रेषितम्\",\n changeMobile: \"चलदूरभाष-सङ्ख्यां परिवर्तयतु\",\n enterNDigitOtp: \"{count}-अङ्कीयं ओटीपी (OTP) प्रविशतु\",\n otpDigit: \"ओटीपी (OTP) अङ्कः {index}\",\n resendIn: \"{seconds} सेकेण्ड्-काले ओटीपी (OTP) पुनः प्रेषयतु\",\n sending: \"प्रेष्यते…\",\n resendOtp: \"ओटीपी (OTP) पुनः प्रेषयतु\",\n getOtp: \"ओटीपी (OTP) प्राप्नोतु\",\n verifying: \"सत्यापयति…\",\n verifyOtp: \"ओटीपी (OTP) सत्यापयतु\",\n sendOtp: \"ओटीपी (OTP) प्रेषयतु\",\n confirmOtp: \"ओटीपी (OTP) सुनिश्चिनोतु\",\n verifyWithOtp: \"ओटीपी (OTP) द्वारा सत्यापयतु\",\n editSelections: \"चयनानि सम्पादयतु\",\n otpIncorrect:\n \"भवता प्रविष्टः सत्यापनसङ्केतः अशुद्धः अस्ति. कृपया परीक्ष्य पुनः प्रयतताम्.\",\n otpExpired:\n \"भवतः सत्यापनसङ्केतस्य अवधिः समाप्तः. कृपया नूतनं सङ्केतं प्रार्थयताम्.\",\n otpNotFound: \"सत्यापनसङ्केतः न प्राप्तः. कृपया नूतनं सङ्केतं प्रार्थयताम्.\",\n otpVerifyFailed: \"ओटीपी (OTP) सत्यापयितुं न शक्तम्. कृपया पुनः प्रयतताम्.\",\n otpSendFailed: \"ओटीपी (OTP) प्रेषयितुं न शक्तम्. कृपया पुनः प्रयतताम्.\",\n consentConfirmed: \"सम्मतिः सुनिश्चिता\",\n recordedUnder: \"ओटीपी (OTP) सत्यापितम् · {regulation} अन्तर्गतं लिखितम्\",\n recordedUnderAt:\n \"ओटीपी (OTP) सत्यापितम् · {regulation} अन्तर्गतं {time} समये लिखितम्\",\n consentReferenceId: \"सम्मति-सन्दर्भ-सङ्केतः\",\n proceed: \"अग्रे गच्छतु\",\n loadingNotice: \"सूचना आरोप्यते\",\n loadFailedTitle: \"सम्मति-सूचना आरोपयितुं न शक्यते\",\n tryAgain: \"कृपया पुनः प्रयत्नं करोतु।\",\n close: \"पिदधातु\",\n};\n\nconst sat: StaticStrings = {\n useEmailInstead: \"ᱤᱢᱮᱞ ᱵᱮᱵᱷᱟᱨ ᱢᱮ\",\n useMobileInstead: \"ᱢᱳᱵᱟᱭᱤᱞ ᱵᱮᱵᱷᱟᱨ ᱢᱮ\",\n emailAddress: \"ᱤᱢᱮᱞ ᱴᱷᱤᱠᱟᱱᱟ\",\n otpHelperEmail: \"ᱟᱞᱮ ᱱᱚᱣᱟ ᱤᱢᱮᱞ ᱨᱮ ᱢᱤᱫ ᱫᱷᱟᱣ ᱵᱮᱵᱷᱟᱨ ᱯᱟᱥᱣᱟᱰ ᱵᱷᱮᱡᱟᱣᱟ।\",\n changeEmail: \"ᱤᱢᱮᱞ ᱵᱚᱫᱚᱞ ᱢᱮ\",\n expandDetails: \"{name} ᱨᱮᱭᱟᱜ ᱵᱤᱵᱨᱚᱬ ᱯᱟᱥᱱᱟᱣ ᱢᱮ\",\n collapseDetails: \"{name} ᱨᱮᱭᱟᱜ ᱵᱤᱵᱨᱚᱬ ᱦᱩᱰᱤᱧ ᱢᱮ\",\n selectAllFor: \"{name} ᱞᱟᱹᱜᱤᱫ ᱡᱷᱚᱛᱚ ᱰᱟᱴᱟ ᱵᱟᱵᱚᱫ ᱵᱟᱪᱷᱟᱣ ᱢᱮ\",\n selectElement: \"{name} ᱵᱟᱪᱷᱟᱣ ᱢᱮ\",\n selectElementRequired: \"{name} ᱵᱟᱪᱷᱟᱣ ᱢᱮ (ᱫᱟᱨᱠᱟᱨ)\",\n required: \"ᱫᱟᱨᱠᱟᱨ\",\n logoAlt: \"ᱞᱚᱜᱚ\",\n selectLanguage: \"ᱯᱟᱹᱨᱥᱤ ᱵᱟᱪᱷᱟᱣ ᱢᱮ\",\n selectLanguageCurrent: \"ᱯᱟᱹᱨᱥᱤ ᱵᱟᱪᱷᱟᱣ ᱢᱮ। ᱱᱤᱛᱚᱜᱟᱜ ᱯᱟᱹᱨᱥᱤ: {lang}\",\n opensInNewTab: \"ᱱᱟᱣᱟ ᱴᱮᱵ ᱨᱮ ᱡᱷᱤᱡ ᱟᱠᱟᱱᱟ\",\n audioStart: \"ᱚᱰᱤᱭᱚ ᱯᱞᱮᱵᱮᱠ ᱮᱱᱮᱫ ᱢᱮ\",\n audioPause: \"ᱚᱰᱤᱭᱚ ᱯᱞᱮᱵᱮᱠ ᱛᱷᱟᱢᱟᱣ ᱢᱮ\",\n talkbackStart: \"ᱴᱚᱠᱵᱮᱠ ᱮᱱᱮᱫ ᱢᱮ\",\n talkbackPause: \"ᱴᱚᱠᱵᱮᱠ ᱛᱷᱟᱢᱟᱣ ᱢᱮ\",\n mobileNumber: \"ᱢᱳᱵᱟᱭᱤᱞ ᱱᱚᱢᱵᱚᱨ\",\n otpHelper: \"ᱟᱞᱮ ᱱᱚᱣᱟ ᱱᱚᱢᱵᱚᱨ ᱨᱮ ᱢᱤᱫ ᱫᱷᱟᱣ ᱵᱮᱵᱷᱟᱨ ᱯᱟᱥᱣᱟᱰ ᱵᱷᱮᱡᱟᱣᱟ।\",\n otpSentTo: \"ᱚᱴᱤᱯᱤ (OTP) ᱵᱷᱮᱡᱟᱣ ᱮᱱᱟ\",\n changeMobile: \"ᱢᱳᱵᱟᱭᱤᱞ ᱱᱚᱢᱵᱚᱨ ᱵᱚᱫᱚᱞ ᱢᱮ\",\n enterNDigitOtp: \"{count}-ᱴᱷᱮᱱ ᱟᱝᱠ ᱨᱮᱱᱟᱜ ᱚᱴᱤᱯᱤ (OTP) ᱟᱫᱮᱨ ᱢᱮ\",\n otpDigit: \"ᱚᱴᱤᱯᱤ (OTP) ᱟᱝᱠ {index}\",\n resendIn: \"{seconds} ᱥᱮᱠᱮᱱᱰ ᱨᱮ ᱚᱴᱤᱯᱤ (OTP) ᱫᱳᱦᱲᱟ ᱵᱷᱮᱡᱟ ᱢᱮ\",\n sending: \"ᱵᱷᱮᱡᱟᱣ ᱠᱟᱱᱟ…\",\n resendOtp: \"ᱚᱴᱤᱯᱤ (OTP) ᱫᱳᱦᱲᱟ ᱵᱷᱮᱡᱟ ᱢᱮ\",\n getOtp: \"ᱚᱴᱤᱯᱤ (OTP) ᱧᱟᱢ ᱢᱮ\",\n verifying: \"ᱯᱟᱨᱠᱷᱟ ᱠᱟᱱᱟ…\",\n verifyOtp: \"ᱚᱴᱤᱯᱤ (OTP) ᱯᱟᱨᱠᱷᱟ ᱢᱮ\",\n sendOtp: \"ᱚᱴᱤᱯᱤ (OTP) ᱵᱷᱮᱡᱟ ᱢᱮ\",\n confirmOtp: \"ᱚᱴᱤᱯᱤ (OTP) ᱯᱚᱠᱠᱟ ᱢᱮ\",\n verifyWithOtp: \"ᱚᱴᱤᱯᱤ (OTP) ᱛᱮ ᱯᱟᱨᱠᱷᱟ ᱢᱮ\",\n editSelections: \"ᱵᱟᱪᱷᱟᱣ ᱥᱟᱯᱲᱟᱣ ᱢᱮ\",\n otpIncorrect:\n \"ᱟᱢ ᱟᱫᱮᱨ ᱟᱠᱟᱱ ᱠᱳᱰ ᱵᱷᱩᱞ ᱠᱟᱱᱟ। ᱫᱟᱭᱟ ᱠᱟᱛᱮ ᱧᱮᱞ ᱠᱟᱛᱮ ᱫᱳᱦᱲᱟ ᱠᱩᱨᱩᱢᱩᱴᱩ ᱢᱮ।\",\n otpExpired: \"ᱟᱢᱟᱜ ᱠᱳᱰ ᱨᱮᱱᱟᱜ ᱚᱠᱛᱚ ᱢᱩᱪᱟᱫ ᱮᱱᱟ। ᱫᱟᱭᱟ ᱠᱟᱛᱮ ᱱᱟᱣᱟ ᱠᱳᱰ ᱢᱟᱸᱜ ᱢᱮ।\",\n otpNotFound: \"ᱠᱳᱰ ᱵᱟᱝ ᱧᱟᱢ ᱞᱮᱱᱟ। ᱫᱟᱭᱟ ᱠᱟᱛᱮ ᱱᱟᱣᱟ ᱠᱳᱰ ᱢᱟᱸᱜ ᱢᱮ।\",\n otpVerifyFailed:\n \"ᱚᱴᱤᱯᱤ (OTP) ᱵᱟᱝ ᱯᱟᱨᱠᱷᱟ ᱦᱩᱭ ᱞᱮᱱᱟ। ᱫᱟᱭᱟ ᱠᱟᱛᱮ ᱫᱳᱦᱲᱟ ᱠᱩᱨᱩᱢᱩᱴᱩ ᱢᱮ।\",\n otpSendFailed: \"ᱚᱴᱤᱯᱤ (OTP) ᱵᱟᱝ ᱵᱷᱮᱡᱟ ᱦᱩᱭ ᱞᱮᱱᱟ। ᱫᱟᱭᱟ ᱠᱟᱛᱮ ᱫᱳᱦᱲᱟ ᱠᱩᱨᱩᱢᱩᱴᱩ ᱢᱮ।\",\n consentConfirmed: \"ᱨᱟᱹᱡᱤ ᱯᱚᱠᱠᱟ ᱦᱩᱭ ᱮᱱᱟ\",\n recordedUnder:\n \"ᱚᱴᱤᱯᱤ (OTP) ᱯᱟᱨᱠᱷᱟ ᱦᱩᱭ ᱮᱱᱟ · {regulation} ᱞᱟᱛᱟᱨ ᱨᱮ ᱱᱚᱛ ᱦᱩᱭ ᱮᱱᱟ\",\n recordedUnderAt:\n \"ᱚᱴᱤᱯᱤ (OTP) ᱯᱟᱨᱠᱷᱟ ᱦᱩᱭ ᱮᱱᱟ · {regulation} ᱞᱟᱛᱟᱨ ᱨᱮ {time} ᱨᱮ ᱱᱚᱛ ᱦᱩᱭ ᱮᱱᱟ\",\n consentReferenceId: \"ᱨᱟᱹᱡᱤ ᱨᱮᱯᱷᱨᱮᱱᱥ ᱟᱭᱰᱤ\",\n proceed: \"ᱟᱭᱢᱟ ᱪᱟᱞᱟᱜ ᱢᱮ\",\n loadingNotice: \"ᱱᱳᱴᱤᱥ ᱞᱳᱰ ᱦᱩᱭ ᱠᱟᱱᱟ\",\n loadFailedTitle: \"ᱨᱟᱹᱡᱤ ᱱᱳᱴᱤᱥ ᱞᱳᱰ ᱵᱟᱝ ᱦᱩᱭ ᱞᱮᱱᱟ\",\n tryAgain: \"ᱫᱟᱭᱟ ᱠᱟᱛᱮ ᱫᱳᱦᱲᱟ ᱠᱩᱨᱩᱢᱩᱴᱩ ᱢᱮ।\",\n close: \"ᱵᱚᱸᱫᱚ ᱢᱮ\",\n};\n\nconst sd: StaticStrings = {\n useEmailInstead: \"اي ميل استعمال ڪريو\",\n useMobileInstead: \"موبائيل استعمال ڪريو\",\n emailAddress: \"اي ميل پتو\",\n otpHelperEmail: \"اسان هن اي ميل تي هڪ ڀيرو استعمال ٿيندڙ پاسورڊ موڪلينداسين.\",\n changeEmail: \"اي ميل تبديل ڪريو\",\n expandDetails: \"{name} جا تفصيل وڌايو\",\n collapseDetails: \"{name} جا تفصيل سُکيڙيو\",\n selectAllFor: \"{name} لاءِ سڀ ڊيٽا عنصر چونڊيو\",\n selectElement: \"{name} چونڊيو\",\n selectElementRequired: \"{name} چونڊيو (ضروري)\",\n required: \"ضروري\",\n logoAlt: \"لوگو\",\n selectLanguage: \"ٻولي چونڊيو\",\n selectLanguageCurrent: \"ٻولي چونڊيو. موجودہ ٻولي: {lang}\",\n opensInNewTab: \"نئين ٽيب ۾ کُلي ٿو\",\n audioStart: \"آڊيو پلے بيڪ شروع ڪريو\",\n audioPause: \"آڊيو پلے بيڪ روڪيو\",\n talkbackStart: \"ٽاڪ بيڪ شروع ڪريو\",\n talkbackPause: \"ٽاڪ بيڪ روڪيو\",\n mobileNumber: \"موبائيل نمبر\",\n otpHelper: \"اسان هن نمبر تي هڪ ڀيرو استعمال ٿيندڙ پاسورڊ موڪلينداسين.\",\n otpSentTo: \"او ٽي پي (OTP) موڪليو ويو\",\n changeMobile: \"موبائيل نمبر تبديل ڪريو\",\n enterNDigitOtp: \"{count}-عددن وارو او ٽي پي (OTP) داخل ڪريو\",\n otpDigit: \"او ٽي پي (OTP) عدد {index}\",\n resendIn: \"{seconds} سيڪنڊن ۾ او ٽي پي (OTP) ٻيهر موڪليو\",\n sending: \"موڪليو پيو وڃي…\",\n resendOtp: \"او ٽي پي (OTP) ٻيهر موڪليو\",\n getOtp: \"او ٽي پي (OTP) حاصل ڪريو\",\n verifying: \"تصديق ٿي رهي آهي…\",\n verifyOtp: \"او ٽي پي (OTP) جي تصديق ڪريو\",\n sendOtp: \"او ٽي پي (OTP) موڪليو\",\n confirmOtp: \"او ٽي پي (OTP) جي تصديق ڪريو\",\n verifyWithOtp: \"او ٽي پي (OTP) سان تصديق ڪريو\",\n editSelections: \"چونڊون تبديل ڪريو\",\n otpIncorrect:\n \"توهان داخل ڪيل تصديق ڪوڊ غلط آهي. مهرباني ڪري جانچيو ۽ ٻيهر ڪوشش ڪريو.\",\n otpExpired:\n \"توهان جي تصديق ڪوڊ جي مدت ختم ٿي وئي آهي. مهرباني ڪري نئون ڪوڊ گهرو.\",\n otpNotFound: \"تصديق ڪوڊ نه مليو. مهرباني ڪري نئون ڪوڊ گهرو.\",\n otpVerifyFailed:\n \"او ٽي پي (OTP) جي تصديق نه ٿي سگهي. مهرباني ڪري ٻيهر ڪوشش ڪريو.\",\n otpSendFailed: \"او ٽي پي (OTP) موڪلي نه سگهيو. مهرباني ڪري ٻيهر ڪوشش ڪريو.\",\n consentConfirmed: \"رضامندي جي تصديق ٿي\",\n recordedUnder: \"او ٽي پي (OTP) تصديق ٿيل · {regulation} تحت رڪارڊ ٿيل\",\n recordedUnderAt:\n \"او ٽي پي (OTP) تصديق ٿيل · {regulation} تحت {time} تي رڪارڊ ٿيل\",\n consentReferenceId: \"رضامندي ريفرنس آءِ ڊي\",\n proceed: \"اڳتي وڌو\",\n loadingNotice: \"نوٽيس لوڊ ٿي رهيو آهي\",\n loadFailedTitle: \"رضامندي نوٽيس لوڊ نه ٿي سگھيو\",\n tryAgain: \"مهرباني ڪري ٻيهر ڪوشش ڪريو.\",\n close: \"بند ڪريو\",\n};\n\nconst ta: StaticStrings = {\n useEmailInstead: \"மின்னஞ்சல் பயன்படுத்து\",\n useMobileInstead: \"மொபைல் பயன்படுத்து\",\n emailAddress: \"மின்னஞ்சல் முகவரி\",\n otpHelperEmail: \"இந்த மின்னஞ்சலுக்கு ஒரு முறை பயன்படுத்தும் கடவுச்சொல்லை அனுப்புவோம்.\",\n changeEmail: \"மின்னஞ்சலை மாற்று\",\n expandDetails: \"{name} விவரங்களை விரிவாக்கு\",\n collapseDetails: \"{name} விவரங்களை சுருக்கு\",\n selectAllFor: \"{name} க்கான அனைத்து தரவு கூறுகளையும் தேர்ந்தெடு\",\n selectElement: \"{name} தேர்ந்தெடு\",\n selectElementRequired: \"{name} தேர்ந்தெடு (தேவை)\",\n required: \"தேவை\",\n logoAlt: \"லோகோ\",\n selectLanguage: \"மொழியைத் தேர்ந்தெடு\",\n selectLanguageCurrent: \"மொழியைத் தேர்ந்தெடு. தற்போதைய மொழி: {lang}\",\n opensInNewTab: \"புதிய தாவலில் திறக்கிறது\",\n audioStart: \"ஆடியோ பிளேபேக்கைத் தொடங்கு\",\n audioPause: \"ஆடியோ பிளேபேக்கை இடைநிறுத்து\",\n talkbackStart: \"டாக்பேக்கைத் தொடங்கு\",\n talkbackPause: \"டாக்பேக்கை இடைநிறுத்து\",\n mobileNumber: \"மொபைல் எண்\",\n otpHelper: \"இந்த எண்ணுக்கு ஒரு முறை பயன்படுத்தும் கடவுச்சொல்லை அனுப்புவோம்.\",\n otpSentTo: \"ஓடிபி (OTP) அனுப்பப்பட்டது\",\n changeMobile: \"மொபைல் எண்ணை மாற்று\",\n enterNDigitOtp: \"{count}-இலக்க ஓடிபி (OTP) ஐ உள்ளிடவும்\",\n otpDigit: \"ஓடிபி (OTP) இலக்கம் {index}\",\n resendIn: \"{seconds} வினாடிகளில் ஓடிபி (OTP) ஐ மீண்டும் அனுப்பு\",\n sending: \"அனுப்புகிறது…\",\n resendOtp: \"ஓடிபி (OTP) ஐ மீண்டும் அனுப்பு\",\n getOtp: \"ஓடிபி (OTP) பெறு\",\n verifying: \"சரிபார்க்கிறது…\",\n verifyOtp: \"ஓடிபி (OTP) ஐ சரிபார்\",\n sendOtp: \"ஓடிபி (OTP) ஐ அனுப்பு\",\n confirmOtp: \"ஓடிபி (OTP) ஐ உறுதிப்படுத்து\",\n verifyWithOtp: \"ஓடிபி (OTP) மூலம் சரிபார்\",\n editSelections: \"தேர்வுகளைத் திருத்து\",\n otpIncorrect:\n \"நீங்கள் உள்ளிட்ட சரிபார்ப்புக் குறியீடு தவறானது. சரிபார்த்து மீண்டும் முயற்சிக்கவும்.\",\n otpExpired:\n \"உங்கள் சரிபார்ப்புக் குறியீட்டின் காலம் முடிந்தது. புதிய குறியீட்டைக் கோரவும்.\",\n otpNotFound:\n \"சரிபார்ப்புக் குறியீடு கிடைக்கவில்லை. புதிய குறியீட்டைக் கோரவும்.\",\n otpVerifyFailed:\n \"ஓடிபி (OTP) ஐ சரிபார்க்க முடியவில்லை. மீண்டும் முயற்சிக்கவும்.\",\n otpSendFailed: \"ஓடிபி (OTP) ஐ அனுப்ப முடியவில்லை. மீண்டும் முயற்சிக்கவும்.\",\n consentConfirmed: \"ஒப்புதல் உறுதி செய்யப்பட்டது\",\n recordedUnder:\n \"ஓடிபி (OTP) சரிபார்க்கப்பட்டது · {regulation} இன் கீழ் பதிவு செய்யப்பட்டது\",\n recordedUnderAt:\n \"ஓடிபி (OTP) சரிபார்க்கப்பட்டது · {regulation} இன் கீழ் {time} மணிக்கு பதிவு செய்யப்பட்டது\",\n consentReferenceId: \"ஒப்புதல் குறிப்பு ஐடி\",\n proceed: \"தொடரவும்\",\n loadingNotice: \"அறிவிப்பு ஏற்றப்படுகிறது\",\n loadFailedTitle: \"ஒப்புதல் அறிவிப்பை ஏற்ற முடியவில்லை\",\n tryAgain: \"மீண்டும் முயற்சிக்கவும்.\",\n close: \"மூடு\",\n};\n\nconst te: StaticStrings = {\n useEmailInstead: \"ఇమెయిల్ ఉపయోగించండి\",\n useMobileInstead: \"మొబైల్ ఉపయోగించండి\",\n emailAddress: \"ఇమెయిల్ చిరునామా\",\n otpHelperEmail: \"మేము ఈ ఇమెయిల్‌కు ఒక్కసారి ఉపయోగించే పాస్‌వర్డ్‌ను పంపుతాము.\",\n changeEmail: \"ఇమెయిల్ మార్చు\",\n expandDetails: \"{name} వివరాలను విస్తరించు\",\n collapseDetails: \"{name} వివరాలను కుదించు\",\n selectAllFor: \"{name} కోసం అన్ని డేటా అంశాలను ఎంచుకోండి\",\n selectElement: \"{name} ఎంచుకోండి\",\n selectElementRequired: \"{name} ఎంచుకోండి (అవసరం)\",\n required: \"అవసరం\",\n logoAlt: \"లోగో\",\n selectLanguage: \"భాష ఎంచుకోండి\",\n selectLanguageCurrent: \"భాష ఎంచుకోండి. ప్రస్తుత భాష: {lang}\",\n opensInNewTab: \"కొత్త ట్యాబ్‌లో తెరుచుకుంటుంది\",\n audioStart: \"ఆడియో ప్లేబ్యాక్ ప్రారంభించు\",\n audioPause: \"ఆడియో ప్లేబ్యాక్ నిలిపివేయి\",\n talkbackStart: \"టాక్‌బ్యాక్ ప్రారంభించు\",\n talkbackPause: \"టాక్‌బ్యాక్ నిలిపివేయి\",\n mobileNumber: \"మొబైల్ నంబర్\",\n otpHelper: \"మేము ఈ నంబర్‌కు ఒక్కసారి ఉపయోగించే పాస్‌వర్డ్‌ను పంపుతాము.\",\n otpSentTo: \"ఓటీపీ (OTP) పంపబడింది\",\n changeMobile: \"మొబైల్ నంబర్ మార్చు\",\n enterNDigitOtp: \"{count}-అంకెల ఓటీపీ (OTP) నమోదు చేయండి\",\n otpDigit: \"ఓటీపీ (OTP) అంకె {index}\",\n resendIn: \"{seconds} సెకన్లలో ఓటీపీ (OTP) మళ్లీ పంపు\",\n sending: \"పంపుతోంది…\",\n resendOtp: \"ఓటీపీ (OTP) మళ్లీ పంపు\",\n getOtp: \"ఓటీపీ (OTP) పొందండి\",\n verifying: \"ధృవీకరిస్తోంది…\",\n verifyOtp: \"ఓటీపీ (OTP) ధృవీకరించండి\",\n sendOtp: \"ఓటీపీ (OTP) పంపండి\",\n confirmOtp: \"ఓటీపీ (OTP) నిర్ధారించండి\",\n verifyWithOtp: \"ఓటీపీ (OTP) ద్వారా ధృవీకరించండి\",\n editSelections: \"ఎంపికలను సవరించండి\",\n otpIncorrect:\n \"మీరు నమోదు చేసిన ధృవీకరణ కోడ్ తప్పు. దయచేసి తనిఖీ చేసి మళ్లీ ప్రయత్నించండి.\",\n otpExpired: \"మీ ధృవీకరణ కోడ్ గడువు ముగిసింది. దయచేసి కొత్త కోడ్ అడగండి.\",\n otpNotFound: \"ధృవీకరణ కోడ్ కనుగొనబడలేదు. దయచేసి కొత్త కోడ్ అడగండి.\",\n otpVerifyFailed:\n \"ఓటీపీ (OTP) ధృవీకరించడం సాధ్యం కాలేదు. దయచేసి మళ్లీ ప్రయత్నించండి.\",\n otpSendFailed: \"ఓటీపీ (OTP) పంపడం సాధ్యం కాలేదు. దయచేసి మళ్లీ ప్రయత్నించండి.\",\n consentConfirmed: \"సమ్మతి నిర్ధారించబడింది\",\n recordedUnder:\n \"ఓటీపీ (OTP) ధృవీకరించబడింది · {regulation} కింద నమోదు చేయబడింది\",\n recordedUnderAt:\n \"ఓటీపీ (OTP) ధృవీకరించబడింది · {regulation} కింద {time}కి నమోదు చేయబడింది\",\n consentReferenceId: \"సమ్మతి సూచన ఐడీ\",\n proceed: \"కొనసాగించు\",\n loadingNotice: \"నోటీసు లోడ్ అవుతోంది\",\n loadFailedTitle: \"సమ్మతి నోటీసును లోడ్ చేయడం సాధ్యం కాలేదు\",\n tryAgain: \"దయచేసి మళ్లీ ప్రయత్నించండి.\",\n close: \"మూసివేయి\",\n};\n\nconst ur: StaticStrings = {\n useEmailInstead: \"ای میل استعمال کریں\",\n useMobileInstead: \"موبائل استعمال کریں\",\n emailAddress: \"ای میل پتہ\",\n otpHelperEmail: \"ہم اس ای میل پر ایک بار استعمال ہونے والا پاس ورڈ بھیجیں گے۔\",\n changeEmail: \"ای میل تبدیل کریں\",\n expandDetails: \"{name} کی تفصیلات پھیلائیں\",\n collapseDetails: \"{name} کی تفصیلات سمیٹیں\",\n selectAllFor: \"{name} کے لیے تمام ڈیٹا عناصر منتخب کریں\",\n selectElement: \"{name} منتخب کریں\",\n selectElementRequired: \"{name} منتخب کریں (لازمی)\",\n required: \"لازمی\",\n logoAlt: \"لوگو\",\n selectLanguage: \"زبان منتخب کریں\",\n selectLanguageCurrent: \"زبان منتخب کریں۔ موجودہ زبان: {lang}\",\n opensInNewTab: \"نئے ٹیب میں کھلتا ہے\",\n audioStart: \"آڈیو پلے بیک شروع کریں\",\n audioPause: \"آڈیو پلے بیک روکیں\",\n talkbackStart: \"ٹاک بیک شروع کریں\",\n talkbackPause: \"ٹاک بیک روکیں\",\n mobileNumber: \"موبائل نمبر\",\n otpHelper: \"ہم اس نمبر پر ایک بار استعمال ہونے والا پاس ورڈ بھیجیں گے۔\",\n otpSentTo: \"او ٹی پی (OTP) بھیج دیا گیا\",\n changeMobile: \"موبائل نمبر تبدیل کریں\",\n enterNDigitOtp: \"{count}-ہندسوں والا او ٹی پی (OTP) درج کریں\",\n otpDigit: \"او ٹی پی (OTP) ہندسہ {index}\",\n resendIn: \"{seconds} سیکنڈ میں او ٹی پی (OTP) دوبارہ بھیجیں\",\n sending: \"بھیجا جا رہا ہے…\",\n resendOtp: \"او ٹی پی (OTP) دوبارہ بھیجیں\",\n getOtp: \"او ٹی پی (OTP) حاصل کریں\",\n verifying: \"تصدیق ہو رہی ہے…\",\n verifyOtp: \"او ٹی پی (OTP) کی تصدیق کریں\",\n sendOtp: \"او ٹی پی (OTP) بھیجیں\",\n confirmOtp: \"او ٹی پی (OTP) کی تصدیق کریں\",\n verifyWithOtp: \"او ٹی پی (OTP) سے تصدیق کریں\",\n editSelections: \"انتخاب میں ترمیم کریں\",\n otpIncorrect:\n \"آپ کا درج کردہ توثیقی کوڈ غلط ہے۔ براہ کرم جانچیں اور دوبارہ کوشش کریں۔\",\n otpExpired:\n \"آپ کے توثیقی کوڈ کی میعاد ختم ہو گئی ہے۔ براہ کرم نیا کوڈ طلب کریں۔\",\n otpNotFound: \"توثیقی کوڈ نہیں ملا۔ براہ کرم نیا کوڈ طلب کریں۔\",\n otpVerifyFailed:\n \"او ٹی پی (OTP) کی تصدیق نہیں ہو سکی۔ براہ کرم دوبارہ کوشش کریں۔\",\n otpSendFailed: \"او ٹی پی (OTP) نہیں بھیجا جا سکا۔ براہ کرم دوبارہ کوشش کریں۔\",\n consentConfirmed: \"رضامندی کی تصدیق ہو گئی\",\n recordedUnder:\n \"او ٹی پی (OTP) تصدیق شدہ · {regulation} کے تحت ریکارڈ کیا گیا\",\n recordedUnderAt:\n \"او ٹی پی (OTP) تصدیق شدہ · {regulation} کے تحت {time} پر ریکارڈ کیا گیا\",\n consentReferenceId: \"رضامندی ریفرنس آئی ڈی\",\n proceed: \"آگے بڑھیں\",\n loadingNotice: \"نوٹس لوڈ ہو رہا ہے\",\n loadFailedTitle: \"رضامندی نوٹس لوڈ نہیں ہو سکا\",\n tryAgain: \"براہ کرم دوبارہ کوشش کریں۔\",\n close: \"بند کریں\",\n};\n\nconst as: StaticStrings = {\n useEmailInstead: \"ইমেইল ব্যৱহাৰ কৰক\",\n useMobileInstead: \"মোবাইল ব্যৱহাৰ কৰক\",\n emailAddress: \"ইমেইল ঠিকনা\",\n otpHelperEmail: \"আমি এই ইমেইললৈ এটা এবাৰ ব্যৱহাৰযোগ্য পাছৱৰ্ড পঠিয়াম।\",\n changeEmail: \"ইমেইল সলনি কৰক\",\n expandDetails: \"{name} ৰ বিৱৰণ বিস্তাৰ কৰক\",\n collapseDetails: \"{name} ৰ বিৱৰণ সংকোচন কৰক\",\n selectAllFor: \"{name} ৰ বাবে সকলো ডাটা উপাদান বাছনি কৰক\",\n selectElement: \"{name} বাছনি কৰক\",\n selectElementRequired: \"{name} বাছনি কৰক (আৱশ্যক)\",\n required: \"আৱশ্যক\",\n logoAlt: \"ল’গো\",\n selectLanguage: \"ভাষা বাছনি কৰক\",\n selectLanguageCurrent: \"ভাষা বাছনি কৰক। বৰ্তমানৰ ভাষা: {lang}\",\n opensInNewTab: \"নতুন টেবত খোলে\",\n audioStart: \"অডিঅ’ প্লেবেক আৰম্ভ কৰক\",\n audioPause: \"অডিঅ’ প্লেবেক বিৰতি দিয়ক\",\n talkbackStart: \"টকবেক আৰম্ভ কৰক\",\n talkbackPause: \"টকবেক বিৰতি দিয়ক\",\n mobileNumber: \"মোবাইল নম্বৰ\",\n otpHelper: \"আমি এই নম্বৰলৈ এটা এবাৰ ব্যৱহাৰযোগ্য পাছৱৰ্ড পঠিয়াম।\",\n otpSentTo: \"ওটিপি (OTP) পঠিওৱা হ’ল\",\n changeMobile: \"মোবাইল নম্বৰ সলনি কৰক\",\n enterNDigitOtp: \"{count}-অংকৰ ওটিপি (OTP) দিয়ক\",\n otpDigit: \"ওটিপি (OTP) অংক {index}\",\n resendIn: \"{seconds} ছেকেণ্ডত ওটিপি (OTP) পুনৰ পঠিয়াওক\",\n sending: \"পঠিওৱা হৈ আছে…\",\n resendOtp: \"ওটিপি (OTP) পুনৰ পঠিয়াওক\",\n getOtp: \"ওটিপি (OTP) লওক\",\n verifying: \"সত্যাপন কৰি আছে…\",\n verifyOtp: \"ওটিপি (OTP) সত্যাপন কৰক\",\n sendOtp: \"ওটিপি (OTP) পঠিয়াওক\",\n confirmOtp: \"ওটিপি (OTP) নিশ্চিত কৰক\",\n verifyWithOtp: \"ওটিপি (OTP) ৰে সত্যাপন কৰক\",\n editSelections: \"বাছনিসমূহ সম্পাদনা কৰক\",\n otpIncorrect:\n \"আপুনি দিয়া সত্যাপন ক'ড ভুল। অনুগ্ৰহ কৰি পৰীক্ষা কৰি পুনৰ চেষ্টা কৰক।\",\n otpExpired: \"আপোনাৰ সত্যাপন ক'ডৰ ম্যাদ উকলিল। অনুগ্ৰহ কৰি নতুন ক'ড বিচাৰক।\",\n otpNotFound: \"সত্যাপন ক'ড পোৱা নগ'ল। অনুগ্ৰহ কৰি নতুন ক'ড বিচাৰক।\",\n otpVerifyFailed:\n \"ওটিপি (OTP) সত্যাপন কৰিব পৰা নগ'ল। অনুগ্ৰহ কৰি পুনৰ চেষ্টা কৰক।\",\n otpSendFailed: \"ওটিপি (OTP) পঠিয়াব পৰা নগ'ল। অনুগ্ৰহ কৰি পুনৰ চেষ্টা কৰক।\",\n consentConfirmed: \"সন্মতি নিশ্চিত হ’ল\",\n recordedUnder: \"ওটিপি (OTP) সত্যাপিত · {regulation} ৰ অধীনত লিপিবদ্ধ কৰা হ’ল\",\n recordedUnderAt:\n \"ওটিপি (OTP) সত্যাপিত · {regulation} ৰ অধীনত {time} বজাত লিপিবদ্ধ কৰা হ’ল\",\n consentReferenceId: \"সন্মতি ৰেফাৰেন্স আইডি\",\n proceed: \"আগবাঢ়ক\",\n loadingNotice: \"জাননী ল’ড হৈ আছে\",\n loadFailedTitle: \"সন্মতি জাননী ল’ড কৰিব পৰা নগ’ল\",\n tryAgain: \"অনুগ্ৰহ কৰি পুনৰ চেষ্টা কৰক।\",\n close: \"বন্ধ কৰক\",\n};\n\nconst brx: StaticStrings = {\n useEmailInstead: \"इमेल बाहाय\",\n useMobileInstead: \"मबाइल बाहाय\",\n emailAddress: \"इमेल ठिकानाय\",\n otpHelperEmail: \"जों बे इमेलआव मोनसे थांखि बाहायनाय पासवार्ड दैथायगोन।\",\n changeEmail: \"इमेल सोलायहो\",\n expandDetails: \"{name} नि गुवारै बेखेवनाय खालामो\",\n collapseDetails: \"{name} नि गुवारै फुंखानाय खालामो\",\n selectAllFor: \"{name} नि थाखाय गासै डाटा बिथिं सायख\",\n selectElement: \"{name} सायख\",\n selectElementRequired: \"{name} सायख (गोनां)\",\n required: \"गोनां\",\n logoAlt: \"लोगो\",\n selectLanguage: \"राव सायख\",\n selectLanguageCurrent: \"राव सायख। दानि राव: {lang}\",\n opensInNewTab: \"गोदान टेबआव खेवनाय जायो\",\n audioStart: \"अडिअ' प्लेबेक जागायहो\",\n audioPause: \"अडिअ' प्लेबेक थिनाय खालामो\",\n talkbackStart: \"टकबेक जागायहो\",\n talkbackPause: \"टकबेक थिनाय खालामो\",\n mobileNumber: \"मबाइल नम्बर\",\n otpHelper: \"जों बे नम्बरआव मोनसे थांखि बाहायनाय पासवार्ड दैथायगोन।\",\n otpSentTo: \"ओटीपी (OTP) दैथायबाय\",\n changeMobile: \"मबाइल नम्बर सोलायहो\",\n enterNDigitOtp: \"{count}-अंकनि ओटीपी (OTP) हाबहो\",\n otpDigit: \"ओटीपी (OTP) अंक {index}\",\n resendIn: \"{seconds} सेकेन्डआव ओटीपी (OTP) फिन दैथाय\",\n sending: \"दैथायगासिनो दं…\",\n resendOtp: \"ओटीपी (OTP) फिन दैथाय\",\n getOtp: \"ओटीपी (OTP) मोनो\",\n verifying: \"रोखा खालामगासिनो दं…\",\n verifyOtp: \"ओटीपी (OTP) रोखा खालामो\",\n sendOtp: \"ओटीपी (OTP) दैथाय\",\n confirmOtp: \"ओटीपी (OTP) पोखा खालामो\",\n verifyWithOtp: \"ओटीपी (OTP) जों रोखा खालामो\",\n editSelections: \"सायखनायखौ सुजुहो\",\n otpIncorrect:\n \"नोंथाङा हाबहोनाय सत्यापन कोडआ गोरोबा नङा। अननानै नाजावनानै फिन नाजा।\",\n otpExpired: \"नोंथांनि सत्यापन कोडनि सम जोबबाय। अननानै गोदान कोड बिथां।\",\n otpNotFound: \"सत्यापन कोड मोनाखै। अननानै गोदान कोड बिथां।\",\n otpVerifyFailed: \"ओटीपी (OTP) रोखा खालामनो हायाखै। अननानै फिन नाजा।\",\n otpSendFailed: \"ओटीपी (OTP) दैथायनो हायाखै। अननानै फिन नाजा।\",\n consentConfirmed: \"रायजुमनाय रोखा जाबाय\",\n recordedUnder: \"ओटीपी (OTP) रोखा जाबाय · {regulation} नि सिङाव लिरनाय जादों\",\n recordedUnderAt:\n \"ओटीपी (OTP) रोखा जाबाय · {regulation} नि सिङाव {time} आव लिरनाय जादों\",\n consentReferenceId: \"रायजुमनाय रेफरेन्स आइडि\",\n proceed: \"सिगांआव थां\",\n loadingNotice: \"नोटिस लोड जागासिनो दं\",\n loadFailedTitle: \"रायजुमनाय नोटिस लोड खालामनो हायाखै\",\n tryAgain: \"अननानै फिन नाजा।\",\n close: \"बन्द खालामो\",\n};\n\nconst doi: StaticStrings = {\n useEmailInstead: \"ईमेल बरतो\",\n useMobileInstead: \"मोबाइल बरतो\",\n emailAddress: \"ईमेल पता\",\n otpHelperEmail: \"अस इस ईमेल पर इक बारी बरतोने आह्ला पासवर्ड भेजगे।\",\n changeEmail: \"ईमेल बदलो\",\n expandDetails: \"{name} दा विवरण फैलाओ\",\n collapseDetails: \"{name} दा विवरण समेटो\",\n selectAllFor: \"{name} आस्तै सब्भै डेटा तत्व चुनो\",\n selectElement: \"{name} चुनो\",\n selectElementRequired: \"{name} चुनो (लोड़चदा)\",\n required: \"लोड़चदा\",\n logoAlt: \"लोगो\",\n selectLanguage: \"भाशा चुनो\",\n selectLanguageCurrent: \"भाशा चुनो। मजूदा भाशा: {lang}\",\n opensInNewTab: \"नमें टैब च खुल्लदा ऐ\",\n audioStart: \"ऑडियो प्लेबैक शुरू करो\",\n audioPause: \"ऑडियो प्लेबैक रोको\",\n talkbackStart: \"टॉकबैक शुरू करो\",\n talkbackPause: \"टॉकबैक रोको\",\n mobileNumber: \"मोबाइल नंबर\",\n otpHelper: \"अस इस नंबर पर इक बारी बरतोने आह्ला पासवर्ड भेजगे।\",\n otpSentTo: \"ओटीपी (OTP) भेजेआ गेआ\",\n changeMobile: \"मोबाइल नंबर बदलो\",\n enterNDigitOtp: \"{count}-अंकें दा ओटीपी (OTP) पाओ\",\n otpDigit: \"ओटीपी (OTP) अंक {index}\",\n resendIn: \"{seconds} सकिंटें च ओटीपी (OTP) फ्ही भेजो\",\n sending: \"भेजेआ जा करदा ऐ…\",\n resendOtp: \"ओटीपी (OTP) फ्ही भेजो\",\n getOtp: \"ओटीपी (OTP) हासल करो\",\n verifying: \"तसदीक कीती जा करदी ऐ…\",\n verifyOtp: \"ओटीपी (OTP) दी तसदीक करो\",\n sendOtp: \"ओटीपी (OTP) भेजो\",\n confirmOtp: \"ओटीपी (OTP) दी पुष्टी करो\",\n verifyWithOtp: \"ओटीपी (OTP) कन्नै तसदीक करो\",\n editSelections: \"चोनें गी बदलो\",\n otpIncorrect:\n \"तुसें दर्ज कीता तसदीक कोड गलत ऐ। किरपा करियै जाँच करो ते फ्ही कोशिश करो।\",\n otpExpired:\n \"तुंदे तसदीक कोड दी मीयाद खत्म होई गेई ऐ। किरपा करियै नमां कोड मंगो।\",\n otpNotFound: \"तसदीक कोड नेईं मिलेआ। किरपा करियै नमां कोड मंगो।\",\n otpVerifyFailed:\n \"ओटीपी (OTP) दी तसदीक नेईं होई सकी। किरपा करियै फ्ही कोशिश करो।\",\n otpSendFailed: \"ओटीपी (OTP) नेईं भेजेआ जाई सकेआ। किरपा करियै फ्ही कोशिश करो।\",\n consentConfirmed: \"सहमति दी पुष्टी होई\",\n recordedUnder: \"ओटीपी (OTP) तसदीकशुदा · {regulation} दे तहत दर्ज कीता गेआ\",\n recordedUnderAt:\n \"ओटीपी (OTP) तसदीकशुदा · {regulation} दे तहत {time} पर दर्ज कीता गेआ\",\n consentReferenceId: \"सहमति रैफरैंस आईडी\",\n proceed: \"अग्गें बधो\",\n loadingNotice: \"नोटिस लोड होआ करदा ऐ\",\n loadFailedTitle: \"सहमति नोटिस लोड नेईं होई सकेआ\",\n tryAgain: \"किरपा करियै फ्ही कोशिश करो।\",\n close: \"बंद करो\",\n};\n\nexport const STATIC_STRINGS: Record<string, StaticStrings> = {\n en,\n hi,\n bn,\n gu,\n kn,\n ks,\n gom,\n mai,\n ml,\n \"mni-Mtei\": mniMtei,\n mr,\n ne,\n or,\n pa,\n sa,\n sat,\n sd,\n ta,\n te,\n ur,\n as,\n brx,\n doi,\n};\n\nconst interpolate = (template: string, vars?: StaticVars): string =>\n vars\n ? template.replace(/\\{(\\w+)\\}/g, (match, token) =>\n token in vars ? String(vars[token]) : match,\n )\n : template;\n\nexport const makeStaticT =\n (langCode: string) =>\n (key: StaticKey, vars?: StaticVars): string => {\n const table = STATIC_STRINGS[langCode] ?? en;\n const template = table[key] ?? en[key];\n return interpolate(template, vars);\n };\n","import { svg } from \"../core/dom\";\n\nconst icon = (size: number, color: string, strokeWidth: number, ...children: SVGElement[]): SVGElement =>\n svg(\n \"svg\",\n {\n width: String(size),\n height: String(size),\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: color,\n \"stroke-width\": String(strokeWidth),\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n \"aria-hidden\": \"true\",\n style: { flexShrink: 0 },\n },\n ...children\n );\n\nexport const lockIcon = (color: string): SVGElement =>\n icon(\n 15,\n color,\n 2,\n svg(\"rect\", { x: \"3\", y: \"11\", width: \"18\", height: \"11\", rx: \"2\" }),\n svg(\"path\", { d: \"M7 11V7a5 5 0 0 1 10 0v4\" })\n );\n\nexport const checkIcon = (color: string): SVGElement =>\n icon(15, color, 2.5, svg(\"path\", { d: \"M20 6 9 17l-5-5\" }));\n\nexport const clockIcon = (color: string): SVGElement =>\n icon(13, color, 2, svg(\"circle\", { cx: \"12\", cy: \"12\", r: \"9\" }), svg(\"path\", { d: \"M12 7v5l3 2\" }));\n\nexport const phoneIcon = (color: string): SVGElement =>\n icon(\n 14,\n color,\n 2,\n svg(\"path\", {\n d: \"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92z\",\n })\n );\n\nexport const mailIcon = (color: string): SVGElement =>\n icon(\n 14,\n color,\n 2,\n svg(\"rect\", { x: \"2\", y: \"4\", width: \"20\", height: \"16\", rx: \"2\" }),\n svg(\"path\", { d: \"m22 7-10 5L2 7\" })\n );\n\nexport const chevronIcon = (expanded: boolean): SVGElement =>\n svg(\n \"svg\",\n {\n width: \"7\",\n height: \"12\",\n viewBox: \"0 0 7 12\",\n fill: \"none\",\n stroke: \"#323B4B\",\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n \"aria-hidden\": \"true\",\n style: {\n transform: expanded ? \"rotate(90deg)\" : \"rotate(0deg)\",\n transition: \"transform 0.3s ease\",\n },\n },\n svg(\"path\", { d: \"M1 1L6 6L1 11\" })\n );\n\nexport const speakerIcon = (playing: boolean): SVGElement =>\n playing\n ? icon(\n 16,\n \"currentColor\",\n 2,\n svg(\"rect\", { x: \"6\", y: \"4\", width: \"4\", height: \"16\" }),\n svg(\"rect\", { x: \"14\", y: \"4\", width: \"4\", height: \"16\" })\n )\n : icon(\n 16,\n \"currentColor\",\n 2,\n svg(\"polygon\", { points: \"11 5 6 9 2 9 2 15 6 15 11 19 11 5\" }),\n svg(\"path\", { d: \"M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07\" })\n );\n","import { buildSelectionForMode, dataElementKey } from \"../modal/consentSelection\";\nimport { ASSISTED_CONFIG, DEFAULT_PURPOSE_PRESELECTION, EMAIL_REGEX } from \"./constants\";\nimport type { Purpose, PurposeItemData } from \"../api/types\";\nimport type { AcceptMode, SelectablePurpose } from \"../types\";\nimport { ApiError } from \"../shared/api-errors\";\nimport type { AssistedSelection, PurposePreselection, StaticKey, VerifyMethod } from \"./types\";\n\nexport const isBlockingRequiredElement = (element: {\n enabled: boolean;\n required: boolean;\n}): boolean => element.required && element.enabled;\n\nexport const hasBlockingRequiredElement = (purpose: SelectablePurpose): boolean =>\n purpose.data_elements.some(isBlockingRequiredElement);\n\nexport const resolvePurposePreselection = (\n raw: string | undefined | null\n): PurposePreselection =>\n raw === \"MANDATORY\" || raw === \"ALL\" ? raw : DEFAULT_PURPOSE_PRESELECTION;\n\nexport const buildPreselection = (\n purposes: ReadonlyArray<SelectablePurpose>,\n mode: PurposePreselection\n): AssistedSelection => {\n const empty: AssistedSelection = { selectedPurposes: {}, selectedDataElements: {} };\n if (mode === \"ALL\") {\n return buildSelectionForMode(purposes.map((purpose) => ({ purpose })), \"all\", empty);\n }\n\n purposes.forEach((purpose) => {\n let hasPreselectedElement = false;\n purpose.data_elements.forEach((element) => {\n const isPreselected = mode === \"MANDATORY\" && isBlockingRequiredElement(element);\n empty.selectedDataElements[dataElementKey(purpose.uuid, element.uuid)] = isPreselected;\n hasPreselectedElement = hasPreselectedElement || isPreselected;\n });\n empty.selectedPurposes[purpose.uuid] = hasPreselectedElement;\n });\n\n return empty;\n};\n\nexport const togglePurposeSelection = (\n purpose: SelectablePurpose,\n current: AssistedSelection\n): AssistedSelection => {\n const next = !current.selectedPurposes[purpose.uuid];\n const selectedDataElements = { ...current.selectedDataElements };\n purpose.data_elements.forEach((element) => {\n selectedDataElements[dataElementKey(purpose.uuid, element.uuid)] = next && element.enabled;\n });\n return {\n selectedPurposes: { ...current.selectedPurposes, [purpose.uuid]: next },\n selectedDataElements,\n };\n};\n\nexport const toggleDataElementSelection = (\n purpose: SelectablePurpose,\n elementUuid: string,\n current: AssistedSelection\n): AssistedSelection => {\n const key = dataElementKey(purpose.uuid, elementUuid);\n const selectedDataElements = {\n ...current.selectedDataElements,\n [key]: !current.selectedDataElements[key],\n };\n const isTicked = (element: { uuid: string }) =>\n Boolean(selectedDataElements[dataElementKey(purpose.uuid, element.uuid)]);\n const blocking = purpose.data_elements.filter(isBlockingRequiredElement);\n const purposeSelected =\n blocking.length > 0\n ? blocking.every(isTicked)\n : purpose.data_elements.some((element) => element.enabled && isTicked(element));\n return {\n selectedPurposes: { ...current.selectedPurposes, [purpose.uuid]: purposeSelected },\n selectedDataElements,\n };\n};\n\nexport const areAllRequiredElementsChecked = (\n purposes: ReadonlyArray<SelectablePurpose>,\n selectedDataElements: Record<string, boolean>\n): boolean =>\n purposes.every((purpose) =>\n purpose.data_elements\n .filter(isBlockingRequiredElement)\n .every((element) => Boolean(selectedDataElements[dataElementKey(purpose.uuid, element.uuid)]))\n );\n\nexport const selectionForMode = (\n purposes: ReadonlyArray<SelectablePurpose>,\n mode: AcceptMode,\n current: AssistedSelection\n): AssistedSelection =>\n buildSelectionForMode(purposes.map((purpose) => ({ purpose })), mode, current);\n\nexport const buildAssistedSubmitPurposes = (\n purposes: ReadonlyArray<PurposeItemData>,\n selection: AssistedSelection\n): Purpose[] =>\n purposes.map((purpose) => ({\n uuid: purpose.uuid,\n name: purpose.name,\n description: purpose.description,\n selected: Boolean(selection.selectedPurposes[purpose.uuid]),\n data_elements: purpose.data_elements.map((element) => ({\n uuid: element.uuid,\n name: element.name,\n enabled: element.enabled !== false,\n required: element.required,\n selected: isBlockingRequiredElement(element)\n ? true\n : Boolean(selection.selectedDataElements[dataElementKey(purpose.uuid, element.uuid)]),\n })),\n }));\n\nexport const sanitiseMobile = (raw: string): string =>\n raw.replace(/\\D/g, \"\").slice(0, ASSISTED_CONFIG.mobileDigits);\n\nexport const isContactValid = (method: VerifyMethod, mobile: string, email: string): boolean =>\n method === \"email\"\n ? EMAIL_REGEX.test(email.trim())\n : mobile.replace(/\\D/g, \"\").length >= ASSISTED_CONFIG.mobileDigits;\n\nexport const otpRecipient = (method: VerifyMethod, mobile: string, email: string): string =>\n method === \"email\" ? email.trim() : `${ASSISTED_CONFIG.dialCode}${mobile}`;\n\nexport const otpChannel = (method: VerifyMethod): string =>\n method === \"email\" ? ASSISTED_CONFIG.emailChannel : ASSISTED_CONFIG.channel;\n\nexport const emptyOtpDigits = (): string[] =>\n Array.from({ length: ASSISTED_CONFIG.otpLength }, () => \"\");\n\nexport const isOtpComplete = (digits: ReadonlyArray<string>): boolean =>\n digits.join(\"\").length === ASSISTED_CONFIG.otpLength;\n\nexport const applyOtpDigit = (\n digits: ReadonlyArray<string>,\n index: number,\n raw: string\n): { digits: string[]; focusIndex: number | null } => {\n const digit = raw.replace(/\\D/g, \"\").slice(-1);\n const next = [...digits];\n next[index] = digit;\n const focusIndex = digit && index < ASSISTED_CONFIG.otpLength - 1 ? index + 1 : null;\n return { digits: next, focusIndex };\n};\n\nexport const applyOtpPaste = (text: string): { digits: string[]; focusIndex: number } | null => {\n const pasted = text.replace(/\\D/g, \"\").slice(0, ASSISTED_CONFIG.otpLength);\n if (!pasted) return null;\n return {\n digits: Array.from({ length: ASSISTED_CONFIG.otpLength }, (_, i) => pasted[i] ?? \"\"),\n focusIndex: Math.min(pasted.length, ASSISTED_CONFIG.otpLength - 1),\n };\n};\n\nexport const backspaceFocusIndex = (digits: ReadonlyArray<string>, index: number): number | null =>\n !digits[index] && index > 0 ? index - 1 : null;\n\nexport const verifyFailureKey = (error: unknown): StaticKey => {\n if (error instanceof ApiError && error.status === 404) return \"otpNotFound\";\n if (error instanceof ApiError && error.status === 400) {\n return error.shouldRequestNew ? \"otpExpired\" : \"otpIncorrect\";\n }\n return \"otpVerifyFailed\";\n};\n\nexport const isAlreadyConsentedError = (error: unknown): boolean =>\n error instanceof ApiError && (error.status === 409 || error.code === \"CONSENT_ALREADY_PROVIDED\");\n\nexport const purposeHidingElement = (\n purposes: ReadonlyArray<PurposeItemData>,\n collapsedPurposes: Record<string, boolean>,\n elementId: string | null\n): string | null => {\n if (!elementId) return null;\n const owner = purposes.find((purpose) =>\n purpose.data_elements.some(\n (element) =>\n element.enabled !== false && elementId === `data-element-${purpose.uuid}-${element.uuid}`\n )\n );\n return owner && collapsedPurposes[owner.uuid] ? owner.uuid : null;\n};\n","import { ASSISTED_STYLE_ID } from \"./constants\";\n\nconst ASSISTED_CSS = `\n .redacto-assisted-phone-field:focus-within {\n border-color: var(--ra-accent, #4f87ff) !important;\n box-shadow: 0 0 0 3px var(--ra-accent-soft, rgba(79, 135, 255, 0.18)) !important;\n }\n .redacto-assisted-phone-input {\n border: none !important;\n outline: none !important;\n background: transparent !important;\n flex: 1 1 auto !important;\n min-width: 0 !important;\n font: inherit !important;\n font-size: 15px !important;\n color: #101828 !important;\n padding: 0 !important;\n }\n .redacto-assisted-otp-input {\n width: 42px !important;\n height: 46px !important;\n text-align: center !important;\n font: inherit !important;\n font-size: 18px !important;\n font-weight: 600 !important;\n border: 1px solid #d0d5dd !important;\n border-radius: 8px !important;\n box-sizing: border-box !important;\n outline: none !important;\n }\n .redacto-assisted-otp-input:focus {\n border-color: var(--ra-accent, #4f87ff) !important;\n box-shadow: 0 0 0 3px var(--ra-accent-soft, rgba(79, 135, 255, 0.18)) !important;\n }\n .redacto-assisted-otp-error {\n border-color: #D92D20 !important;\n }\n .redacto-assisted-link {\n background: none !important;\n border: none !important;\n padding: 0 !important;\n cursor: pointer !important;\n font: inherit !important;\n font-size: 13px !important;\n font-weight: 500 !important;\n display: inline-flex !important;\n align-items: center !important;\n gap: 4px !important;\n }\n .redacto-assisted-link:disabled {\n opacity: 0.5 !important;\n cursor: not-allowed !important;\n }\n button:disabled.redacto-assisted-primary-btn {\n opacity: 0.5 !important;\n cursor: not-allowed !important;\n }\n @keyframes redactoAssistedReveal {\n from { opacity: 0; transform: translateY(6px); }\n to { opacity: 1; transform: translateY(0); }\n }\n .redacto-assisted-reveal {\n animation: redactoAssistedReveal 0.2s ease-out;\n }\n @media (prefers-reduced-motion: reduce) {\n .redacto-assisted-reveal { animation: none; }\n }\n`;\n\nexport const injectAssistedStyles = (root: ShadowRoot): void => {\n if (root.querySelector(`#${ASSISTED_STYLE_ID}`)) return;\n const style = document.createElement(\"style\");\n style.id = ASSISTED_STYLE_ID;\n style.textContent = ASSISTED_CSS;\n root.appendChild(style);\n};\n\nexport const assistedStyles = {\n lockedOptions: {\n opacity: \"0.6\",\n pointerEvents: \"none\",\n },\n verifyPanel: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"14px\",\n border: \"1px solid #EAECF0\",\n borderRadius: \"12px\",\n padding: \"16px\",\n backgroundColor: \"#FCFCFD\",\n boxSizing: \"border-box\",\n },\n verifyPanelHeader: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n gap: \"8px\",\n },\n verifyPanelTitle: {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"6px\",\n fontSize: \"15px\",\n fontWeight: 600,\n color: \"#101828\",\n },\n fieldLabelRow: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n gap: \"8px\",\n },\n fieldLabel: {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"6px\",\n fontSize: \"13px\",\n fontWeight: 500,\n color: \"#475467\",\n },\n phoneField: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n border: \"1px solid #d0d5dd\",\n borderRadius: \"8px\",\n padding: \"10px 12px\",\n backgroundColor: \"#ffffff\",\n boxSizing: \"border-box\",\n },\n phonePrefix: {\n fontSize: \"15px\",\n color: \"#475467\",\n fontWeight: 500,\n },\n helperText: {\n margin: 0,\n fontSize: \"12px\",\n color: \"#667085\",\n },\n otpStatusRow: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n gap: \"8px\",\n flexWrap: \"wrap\",\n },\n otpSentText: {\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"6px\",\n fontSize: \"13px\",\n color: \"#344054\",\n },\n fieldError: {\n margin: 0,\n fontSize: \"13px\",\n color: \"#D92D20\",\n },\n centerLabel: {\n margin: 0,\n fontSize: \"13px\",\n color: \"#475467\",\n textAlign: \"center\",\n },\n otpRow: {\n display: \"flex\",\n justifyContent: \"center\",\n gap: \"8px\",\n },\n resendText: {\n margin: 0,\n display: \"flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n gap: \"4px\",\n fontSize: \"13px\",\n color: \"#667085\",\n },\n errorTitle: {\n margin: 0,\n fontSize: \"16px\",\n fontWeight: 600,\n color: \"#101828\",\n },\n errorText: {\n margin: 0,\n fontSize: \"14px\",\n color: \"#475467\",\n },\n declineSpacer: {\n marginRight: \"auto\",\n },\n rowButton: {\n width: \"auto\",\n },\n stackButton: {\n width: \"100%\",\n },\n} as const;\n","import { el } from \"../core/dom\";\nimport { createRequiredMarker } from \"../core/required-marker\";\nimport { dataElementKey } from \"../modal/consentSelection\";\nimport { styles } from \"../styles/modal\";\nimport { ASSISTED_IDS, FOCUS_KEY_ATTRIBUTE, FOCUS_KEYS } from \"./constants\";\nimport { chevronIcon } from \"./icons\";\nimport { hasBlockingRequiredElement, isBlockingRequiredElement } from \"./selection\";\nimport { assistedStyles } from \"./styles\";\nimport type { PurposeItemData } from \"../api/types\";\nimport type { AssistedViewContext } from \"./types\";\n\nconst linkAttrs = (ctx: AssistedViewContext, id: string, href: string) => ({\n id,\n href,\n target: \"_blank\",\n rel: \"noopener noreferrer\",\n style: { ...styles.link, color: ctx.linkColor },\n});\n\nconst textStyle = (ctx: AssistedViewContext) => ({\n ...styles.privacyText,\n fontSize: ctx.isMobile ? \"14px\" : \"16px\",\n});\n\nexport const renderNoticeText = (ctx: AssistedViewContext): HTMLElement => {\n const { content, t, ts } = ctx;\n const anchorText = t(\n \"privacy_policy_anchor_text\",\n content.privacy_policy_anchor_text || \"Privacy Policy\"\n );\n const link = el(\n \"a\",\n {\n ...linkAttrs(ctx, \"privacy-policy-link\", content.privacy_policy_url || \"#\"),\n \"aria-label\": `${anchorText} (${ts(\"opensInNewTab\")})`,\n },\n anchorText\n );\n return el(\n \"p\",\n { style: textStyle(ctx) },\n el(\"span\", { id: \"privacy-notice-text\" }, t(\"notice_text\", content.notice_text)),\n el(\"br\"),\n el(\n \"span\",\n null,\n el(\n \"span\",\n { id: \"privacy-policy-text\" },\n t(\"privacy_policy_prefix_text\", content.privacy_policy_prefix_text || \"\")\n ),\n \" \",\n link\n )\n );\n};\n\nexport const renderPurposeHeading = (ctx: AssistedViewContext): HTMLElement =>\n el(\n \"h2\",\n {\n id: \"purpose-section-heading\",\n style: { ...styles.subTitle, fontSize: ctx.isMobile ? \"14px\" : \"16px\" },\n },\n ctx.t(\"purpose_section_heading\", ctx.content.purpose_section_heading || \"Manage What You Share\")\n );\n\nconst renderPurpose = (\n ctx: AssistedViewContext,\n purpose: PurposeItemData,\n locked: boolean\n): HTMLElement => {\n const { state, t, ts, handlers, isMobile } = ctx;\n const isExpanded = !state.collapsedPurposes[purpose.uuid];\n const name = t(\"purposes.name\", purpose.name, purpose.uuid);\n const description = t(\"purposes.description\", purpose.description, purpose.uuid);\n const dataElements = purpose.data_elements.filter((element) => element.enabled !== false);\n const containerId = `${ASSISTED_IDS.purposeContainerPrefix}${purpose.uuid}`;\n\n const title = el(\"h2\", {\n id: `purpose-name-${purpose.uuid}`,\n style: { ...styles.optionTitle, fontSize: isMobile ? \"14px\" : \"16px\" },\n });\n title.textContent = name;\n if (hasBlockingRequiredElement(purpose)) {\n title.appendChild(createRequiredMarker(ts(\"required\")));\n }\n\n const textContainer = el(\"div\", { style: styles.optionTextContainer }, title);\n if (description) {\n textContainer.appendChild(\n el(\n \"h3\",\n {\n id: `purpose-description-${purpose.uuid}`,\n style: { ...styles.optionDescription, fontSize: isMobile ? \"12px\" : \"14px\" },\n },\n description\n )\n );\n }\n\n const collapse = el(\n \"div\",\n {\n style: styles.optionLeft,\n role: \"button\",\n tabIndex: \"0\",\n \"aria-expanded\": String(isExpanded),\n \"aria-controls\": containerId,\n \"aria-label\": isExpanded ? ts(\"collapseDetails\", { name }) : ts(\"expandDetails\", { name }),\n [FOCUS_KEY_ATTRIBUTE]: FOCUS_KEYS.collapse(purpose.uuid),\n onClick: () => handlers.onPurposeCollapse(purpose.uuid),\n onKeydown: (event: KeyboardEvent) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n handlers.onPurposeCollapse(purpose.uuid);\n }\n },\n },\n el(\n \"div\",\n { style: { display: \"flex\", alignItems: \"center\", justifyContent: \"center\", marginLeft: \"5px\" } },\n chevronIcon(isExpanded)\n ),\n textContainer\n );\n\n const checkbox = el(\"input\", {\n className: \"redacto-checkbox-large\",\n type: \"checkbox\",\n checked: Boolean(state.selectedPurposes[purpose.uuid]),\n disabled: locked,\n \"aria-label\": ts(\"selectAllFor\", { name }),\n [FOCUS_KEY_ATTRIBUTE]: FOCUS_KEYS.purpose(purpose.uuid),\n onChange: () => handlers.onPurposeToggle(purpose.uuid),\n });\n\n const elementsContainer = el(\"div\", {\n id: containerId,\n style: {\n ...styles.dataElementsContainer,\n display: isExpanded && dataElements.length > 0 ? \"flex\" : \"none\",\n },\n });\n for (const element of dataElements) {\n const elementName = t(\"data_elements.name\", element.name, element.uuid);\n const label = el(\"span\", {\n id: `data-element-${purpose.uuid}-${element.uuid}`,\n style: { ...styles.dataElementText, fontSize: isMobile ? \"12px\" : \"14px\" },\n });\n label.textContent = elementName;\n if (isBlockingRequiredElement(element)) {\n label.appendChild(createRequiredMarker(ts(\"required\")));\n }\n const elementCheckbox = el(\"input\", {\n className: \"redacto-checkbox-small\",\n type: \"checkbox\",\n checked: Boolean(state.selectedDataElements[dataElementKey(purpose.uuid, element.uuid)]),\n disabled: locked,\n \"aria-label\": element.required\n ? ts(\"selectElementRequired\", { name: elementName })\n : ts(\"selectElement\", { name: elementName }),\n [FOCUS_KEY_ATTRIBUTE]: FOCUS_KEYS.element(purpose.uuid, element.uuid),\n onChange: () => handlers.onDataElementToggle(purpose.uuid, element.uuid),\n });\n elementsContainer.appendChild(\n el(\"div\", { style: styles.dataElementItem }, label, elementCheckbox)\n );\n }\n\n return el(\n \"div\",\n null,\n el(\"div\", { style: styles.optionItem }, collapse, checkbox),\n elementsContainer\n );\n};\n\nexport const renderPurposes = (ctx: AssistedViewContext, locked: boolean): HTMLElement => {\n const container = el(\"div\", {\n style: { ...styles.optionsContainer, ...(locked ? assistedStyles.lockedOptions : {}) },\n \"aria-disabled\": locked ? \"true\" : null,\n });\n for (const purpose of ctx.content.purposes) {\n container.appendChild(renderPurpose(ctx, purpose, locked));\n }\n return container;\n};\n\nexport const renderDpoFooter = (ctx: AssistedViewContext): HTMLElement | null => {\n const { content, t, tDpo, isMobile } = ctx;\n const dpo = content.dpo_info;\n if (!content.privacy_center_url && !dpo) return null;\n\n const paragraph = el(\"p\", { style: { margin: 0, opacity: \"0.6\" } });\n\n if (content.privacy_center_url) {\n paragraph.appendChild(\n el(\n \"span\",\n { id: \"additional-text\" },\n t(\"additional_text\", content.additional_text || \"Manage or withdraw consent anytime at\")\n )\n );\n paragraph.appendChild(document.createTextNode(\" \"));\n paragraph.appendChild(\n el(\n \"a\",\n linkAttrs(ctx, \"privacy-center-link\", content.privacy_center_url),\n t(\"privacy_center_anchor_text\", content.privacy_center_anchor_text || \"Privacy Center\")\n )\n );\n paragraph.appendChild(document.createTextNode(\".\"));\n }\n\n if (dpo) {\n if (content.privacy_center_url) paragraph.appendChild(el(\"br\"));\n paragraph.appendChild(\n el(\"span\", { id: \"dpo-grievance-text\" }, tDpo(\"grievance_text\", dpo.grievance_text))\n );\n paragraph.appendChild(document.createTextNode(\" \"));\n if (dpo.grievance_url) {\n paragraph.appendChild(\n el(\n \"a\",\n linkAttrs(ctx, \"dpo-grievance-link\", dpo.grievance_url),\n tDpo(\"grievance_anchor_text\", dpo.grievance_anchor_text || \"click here\")\n )\n );\n }\n paragraph.appendChild(document.createTextNode(\" \"));\n if (dpo.grievance_email) {\n paragraph.appendChild(\n el(\n \"span\",\n { id: \"dpo-grievance-email-connector\" },\n tDpo(\"grievance_email_connector_text\", dpo.grievance_email_connector_text || \"or email to\")\n )\n );\n paragraph.appendChild(document.createTextNode(\" \"));\n paragraph.appendChild(\n el(\n \"a\",\n {\n id: \"dpo-grievance-email\",\n href: `mailto:${dpo.grievance_email}`,\n style: { ...styles.link, color: ctx.linkColor },\n },\n dpo.grievance_email\n )\n );\n }\n paragraph.appendChild(el(\"br\"));\n paragraph.appendChild(\n el(\"span\", { id: \"dpo-dp-board-text\" }, tDpo(\"dp_board_text\", dpo.dp_board_text))\n );\n paragraph.appendChild(document.createTextNode(\" \"));\n if (dpo.dp_board_url) {\n paragraph.appendChild(\n el(\n \"a\",\n linkAttrs(ctx, \"dpo-dp-board-link\", dpo.dp_board_url),\n tDpo(\"dp_board_anchor_text\", dpo.dp_board_anchor_text || \"click here\")\n )\n );\n }\n paragraph.appendChild(el(\"br\"));\n paragraph.appendChild(el(\"span\", { id: \"dpo-dpo-text\" }, tDpo(\"dpo_text\", dpo.dpo_text)));\n paragraph.appendChild(document.createTextNode(\" \"));\n const dpoAnchor = tDpo(\"dpo_anchor_text\", dpo.dpo_anchor_text || \"Click here\");\n if (dpo.dpo_email) {\n paragraph.appendChild(\n el(\n \"a\",\n {\n id: \"dpo-dpo-link\",\n href: `mailto:${dpo.dpo_email}`,\n style: { ...styles.link, color: ctx.linkColor },\n },\n dpoAnchor\n )\n );\n } else if (dpo.dpo_url) {\n paragraph.appendChild(el(\"a\", linkAttrs(ctx, \"dpo-dpo-link\", dpo.dpo_url), dpoAnchor));\n }\n }\n\n return el(\n \"div\",\n {\n style: {\n ...styles.privacyText,\n fontSize: isMobile ? \"13px\" : \"14px\",\n lineHeight: \"1.4\",\n borderTop: \"1px solid rgba(152, 162, 179, 0.3)\",\n paddingTop: \"12px\",\n marginTop: \"12px\",\n },\n },\n paragraph\n );\n};\n","export const hexToRgba = (hex: string, alpha: number): string | null => {\n if (typeof hex !== \"string\" || hex[0] !== \"#\") return null;\n let h = hex.slice(1);\n if (h.length === 3) {\n h = h\n .split(\"\")\n .map((c) => c + c)\n .join(\"\");\n }\n if (h.length !== 6 || /[^0-9a-fA-F]/.test(h)) return null;\n const n = parseInt(h, 16);\n return `rgba(${(n >> 16) & 255}, ${(n >> 8) & 255}, ${n & 255}, ${alpha})`;\n};\n\nexport const isDefaultLanguage = (lang: string): boolean =>\n lang === \"English\" || lang === \"en\" || lang === \"EN\";\n\nexport const normaliseLanguage = (lang: string | undefined | null): string =>\n !lang || isDefaultLanguage(lang) ? \"English\" : lang;\n\nexport const availableLanguages = (\n defaultLanguage: string | undefined,\n translations: Record<string, unknown> | undefined\n): string[] => {\n const pinned = [\"English\"];\n const normalised = normaliseLanguage(defaultLanguage);\n if (normalised !== \"English\") pinned.push(normalised);\n const rest = Object.keys(translations || {})\n .filter((lang) => !pinned.includes(lang))\n .sort((a, b) => a.localeCompare(b, \"en\"));\n return [...pinned, ...rest];\n};\n","import { el } from \"../core/dom\";\nimport { styles } from \"../styles/modal\";\nimport {\n ACCEPT_ALL_BUTTON_ID,\n ACCEPT_SELECTED_BUTTON_ID,\n DECLINE_BUTTON_ID,\n DEFAULT_ACCEPT_ALL_BUTTON_TEXT,\n DEFAULT_ACCEPT_SELECTED_BUTTON_TEXT,\n DEFAULT_DECLINE_BUTTON_TEXT,\n} from \"../constants\";\nimport { ASSISTED_CONFIG, ASSISTED_IDS, FOCUS_KEY_ATTRIBUTE, FOCUS_KEYS } from \"./constants\";\nimport { checkIcon, clockIcon, lockIcon, mailIcon, phoneIcon } from \"./icons\";\nimport { areAllRequiredElementsChecked, isContactValid, isOtpComplete } from \"./selection\";\nimport { assistedStyles } from \"./styles\";\nimport type { AssistedPrimaryAction, AssistedViewContext } from \"./types\";\n\nconst renderContactField = (ctx: AssistedViewContext): HTMLElement => {\n const { state, handlers } = ctx;\n const locked = state.otpSent || state.isSendingOtp;\n if (state.verifyMethod === \"mobile\") {\n return el(\n \"div\",\n { className: \"redacto-assisted-phone-field\", style: assistedStyles.phoneField },\n el(\"span\", { style: assistedStyles.phonePrefix }, ASSISTED_CONFIG.dialCode),\n el(\"input\", {\n id: ASSISTED_IDS.mobileInput,\n type: \"tel\",\n inputmode: \"numeric\",\n autocomplete: \"tel-national\",\n className: \"redacto-assisted-phone-input\",\n placeholder: \"98765 43210\",\n value: state.mobile,\n disabled: locked,\n onInput: (event: Event) => handlers.onMobileInput((event.target as HTMLInputElement).value),\n })\n );\n }\n return el(\n \"div\",\n { className: \"redacto-assisted-phone-field\", style: assistedStyles.phoneField },\n el(\"input\", {\n id: ASSISTED_IDS.emailInput,\n type: \"email\",\n inputmode: \"email\",\n autocomplete: \"email\",\n className: \"redacto-assisted-phone-input\",\n placeholder: \"you@example.com\",\n value: state.email,\n disabled: locked,\n onInput: (event: Event) => handlers.onEmailInput((event.target as HTMLInputElement).value),\n })\n );\n};\n\nexport const otpBoxStyle = (ctx: AssistedViewContext, digit: string, index: number) => ({\n borderColor: digit ? ctx.primaryColor : \"\",\n backgroundColor: digit ? ctx.accentTint : \"\",\n marginLeft: index === 3 ? \"8px\" : \"\",\n});\n\nexport const renderResend = (ctx: AssistedViewContext): HTMLElement => {\n const { state, ts, handlers, primaryColor } = ctx;\n if (state.resendCountdown > 0) {\n return el(\n \"p\",\n { id: ASSISTED_IDS.resend, style: assistedStyles.resendText },\n clockIcon(\"#667085\"),\n ts(\"resendIn\", { seconds: state.resendCountdown })\n );\n }\n return el(\n \"p\",\n { id: ASSISTED_IDS.resend, style: assistedStyles.resendText },\n el(\n \"button\",\n {\n type: \"button\",\n className: \"redacto-assisted-link\",\n style: { color: primaryColor },\n disabled: state.isSendingOtp,\n [FOCUS_KEY_ATTRIBUTE]: FOCUS_KEYS.resend,\n onClick: () => handlers.onResend(),\n },\n state.isSendingOtp ? ts(\"sending\") : ts(\"resendOtp\")\n )\n );\n};\n\nconst renderOtpEntry = (ctx: AssistedViewContext): HTMLElement => {\n const { state, ts, handlers } = ctx;\n const boxes = state.otpDigits.map((digit, index) =>\n el(\"input\", {\n id: `${ASSISTED_IDS.otpInputPrefix}${index}`,\n type: \"text\",\n inputmode: \"numeric\",\n autocomplete: \"one-time-code\",\n maxlength: \"1\",\n className: `redacto-assisted-otp-input${state.otpError ? \" redacto-assisted-otp-error\" : \"\"}`,\n style: otpBoxStyle(ctx, digit, index),\n value: digit,\n disabled: state.isVerifying,\n \"aria-label\": ts(\"otpDigit\", { index: index + 1 }),\n onInput: (event: Event) => handlers.onOtpInput(index, (event.target as HTMLInputElement).value),\n onKeydown: (event: KeyboardEvent) => handlers.onOtpKeydown(index, event),\n onPaste: (event: ClipboardEvent) => handlers.onOtpPaste(event),\n })\n );\n\n return el(\n \"div\",\n { style: { display: \"flex\", flexDirection: \"column\", gap: \"12px\" } },\n el(\n \"p\",\n { style: assistedStyles.centerLabel },\n ts(\"enterNDigitOtp\", { count: ASSISTED_CONFIG.otpLength })\n ),\n el(\"div\", { style: assistedStyles.otpRow }, ...boxes),\n state.otpError ? el(\"p\", { role: \"alert\", style: assistedStyles.fieldError }, state.otpError) : null,\n renderResend(ctx)\n );\n};\n\nexport const renderVerifyPanel = (ctx: AssistedViewContext): HTMLElement => {\n const { state, ts, handlers, primaryColor } = ctx;\n const isEmail = state.verifyMethod === \"email\";\n const linksLocked = state.isVerifying || state.isSendingOtp;\n\n const labelRow = el(\n \"div\",\n { style: assistedStyles.fieldLabelRow },\n el(\n \"label\",\n { for: isEmail ? ASSISTED_IDS.emailInput : ASSISTED_IDS.mobileInput, style: assistedStyles.fieldLabel },\n isEmail ? mailIcon(\"#475467\") : phoneIcon(\"#475467\"),\n isEmail ? ts(\"emailAddress\") : ts(\"mobileNumber\")\n ),\n state.otpSent\n ? null\n : el(\n \"button\",\n {\n type: \"button\",\n className: \"redacto-assisted-link\",\n style: { color: primaryColor },\n disabled: state.isSendingOtp,\n [FOCUS_KEY_ATTRIBUTE]: FOCUS_KEYS.switchMethod,\n onClick: () => handlers.onSwitchMethod(),\n },\n isEmail ? phoneIcon(primaryColor) : mailIcon(primaryColor),\n isEmail ? ts(\"useMobileInstead\") : ts(\"useEmailInstead\")\n )\n );\n\n const status = state.otpSent\n ? el(\n \"div\",\n { style: assistedStyles.otpStatusRow },\n el(\n \"span\",\n { style: assistedStyles.otpSentText },\n checkIcon(\"#10B981\"),\n `${ts(\"otpSentTo\")} ${isEmail ? state.email : `${ASSISTED_CONFIG.dialCode} ${state.mobile}`}`\n ),\n el(\n \"button\",\n {\n type: \"button\",\n className: \"redacto-assisted-link\",\n style: { color: primaryColor },\n disabled: linksLocked,\n [FOCUS_KEY_ATTRIBUTE]: FOCUS_KEYS.changeContact,\n onClick: () => handlers.onChangeContact(),\n },\n isEmail ? ts(\"changeEmail\") : ts(\"changeMobile\")\n )\n )\n : el(\"p\", { style: assistedStyles.helperText }, isEmail ? ts(\"otpHelperEmail\") : ts(\"otpHelper\"));\n\n return el(\n \"div\",\n {\n id: ASSISTED_IDS.verifyPanel,\n className: \"redacto-assisted-reveal\",\n style: assistedStyles.verifyPanel,\n },\n el(\n \"div\",\n { style: assistedStyles.verifyPanelHeader },\n el(\"span\", { style: assistedStyles.verifyPanelTitle }, lockIcon(primaryColor), ts(\"verifyWithOtp\")),\n el(\n \"button\",\n {\n type: \"button\",\n className: \"redacto-assisted-link\",\n style: { color: primaryColor },\n disabled: linksLocked,\n [FOCUS_KEY_ATTRIBUTE]: FOCUS_KEYS.editSelections,\n onClick: () => handlers.onEditSelections(),\n },\n ts(\"editSelections\")\n )\n ),\n el(\n \"div\",\n { style: { display: \"flex\", flexDirection: \"column\", gap: \"10px\" } },\n labelRow,\n renderContactField(ctx),\n status,\n state.createError\n ? el(\"p\", { role: \"alert\", style: assistedStyles.fieldError }, state.createError)\n : null,\n state.otpSent ? renderOtpEntry(ctx) : null\n )\n );\n};\n\nexport const primaryAction = (ctx: AssistedViewContext): AssistedPrimaryAction => {\n const { state, content, t, ts, handlers } = ctx;\n if (state.step === \"verify\" && !state.otpSent) {\n return {\n label: state.isSendingOtp ? ts(\"sending\") : ts(\"sendOtp\"),\n disabled: !isContactValid(state.verifyMethod, state.mobile, state.email) || state.isSendingOtp,\n action: handlers.onGetOtp,\n };\n }\n if (state.step === \"verify\") {\n return {\n label: state.isVerifying ? ts(\"verifying\") : ts(\"confirmOtp\"),\n disabled: !isOtpComplete(state.otpDigits) || state.isVerifying,\n action: handlers.onConfirmOtp,\n };\n }\n return {\n label: t(\"confirm_button_text\", content.confirm_button_text || DEFAULT_ACCEPT_SELECTED_BUTTON_TEXT),\n disabled: !areAllRequiredElementsChecked(content.purposes, state.selectedDataElements),\n action: handlers.onAcceptSelected,\n };\n};\n\nexport const renderFooter = (ctx: AssistedViewContext): HTMLElement => {\n const { state, content, t, handlers, isMobile, primaryColor } = ctx;\n const isVerify = state.step === \"verify\";\n const buttonBase = { ...styles.button, fontSize: isMobile ? \"14px\" : \"16px\", padding: isMobile ? \"10px 20px\" : \"9px 45px\" };\n const width = isMobile ? assistedStyles.stackButton : assistedStyles.rowButton;\n const primaryState = primaryAction(ctx);\n\n const primary = el(\n \"button\",\n {\n type: \"button\",\n id: ACCEPT_SELECTED_BUTTON_ID,\n className: \"redacto-assisted-primary-btn\",\n style: isVerify\n ? { ...buttonBase, ...styles.acceptButton, backgroundColor: primaryColor }\n : { ...buttonBase, ...styles.cancelButton, ...width, color: primaryColor, borderColor: primaryColor },\n disabled: primaryState.disabled,\n [FOCUS_KEY_ATTRIBUTE]: FOCUS_KEYS.primary,\n onClick: () => primaryState.action(),\n },\n primaryState.label\n );\n\n const decline = el(\n \"button\",\n {\n type: \"button\",\n id: DECLINE_BUTTON_ID,\n style: {\n ...buttonBase,\n ...styles.cancelButton,\n ...(isVerify ? {} : width),\n ...(isVerify || isMobile ? {} : assistedStyles.declineSpacer),\n },\n [FOCUS_KEY_ATTRIBUTE]: FOCUS_KEYS.decline,\n onClick: () => handlers.onDecline(),\n },\n t(\"decline_button_text\", content.decline_button_text || DEFAULT_DECLINE_BUTTON_TEXT)\n );\n\n if (isVerify) {\n return el(\"div\", { style: { ...styles.bottomSection, flexDirection: isMobile ? \"column\" : \"row\" } }, primary, decline);\n }\n\n const acceptAll = el(\n \"button\",\n {\n type: \"button\",\n id: ACCEPT_ALL_BUTTON_ID,\n style: { ...buttonBase, ...styles.acceptButton, ...width, backgroundColor: primaryColor },\n [FOCUS_KEY_ATTRIBUTE]: FOCUS_KEYS.acceptAll,\n onClick: () => handlers.onAcceptAll(),\n },\n t(\"accept_all_button_text\", content.accept_all_button_text || DEFAULT_ACCEPT_ALL_BUTTON_TEXT)\n );\n\n return isMobile\n ? el(\"div\", { style: styles.actionButtonStack }, acceptAll, primary, decline)\n : el(\"div\", { style: styles.actionButtonRow }, decline, primary, acceptAll);\n};\n","import { Store } from \"../core/state\";\nimport { applyStyles, clearElement, el } from \"../core/dom\";\nimport { createMediaQuery, type MediaQuerySubscription } from \"../core/media-query\";\nimport { injectCheckboxStyles } from \"../styles/inject\";\nimport { styles } from \"../styles/modal\";\nimport { renderLanguageSelector, type LanguageSelectorRefs } from \"../modal/language-selector\";\nimport { setupKeyboardTrap, type KeyboardTrapCleanup } from \"../modal/keyboard\";\nimport { injectNoticeFontStyles, resolveNoticeFontFamily } from \"../modal/notice-font\";\nimport { TTSManager } from \"../modal/tts\";\nimport {\n fetchNoticeConsentStatusForScope,\n isNoticeFullyConsented,\n} from \"../api/notice-consent-status\";\nimport { toLanguageCode } from \"../api/language\";\nimport { NOTICE_FONT_ROOT_ATTRIBUTE } from \"../constants\";\nimport type { TranslationObject } from \"../api/types\";\nimport type { AcceptMode } from \"../types\";\nimport {\n createOtp,\n fetchAssistedNotice,\n fetchAssistedTTSAudioUrls,\n submitAssistedConsent,\n verifyOtp,\n} from \"./api\";\nimport {\n ASSISTED_CONFIG,\n ASSISTED_DEFAULT_PRIMARY_COLOR,\n ASSISTED_HOST_ATTRIBUTE,\n ASSISTED_IDS,\n FOCUS_KEY_ATTRIBUTE,\n FOCUS_KEYS,\n MOBILE_QUERY,\n} from \"./constants\";\nimport { makeStaticT } from \"./i18n\";\nimport { speakerIcon } from \"./icons\";\nimport { renderDpoFooter, renderNoticeText, renderPurposeHeading, renderPurposes } from \"./notice-view\";\nimport {\n applyOtpDigit,\n applyOtpPaste,\n areAllRequiredElementsChecked,\n backspaceFocusIndex,\n buildAssistedSubmitPurposes,\n buildPreselection,\n emptyOtpDigits,\n isAlreadyConsentedError,\n isContactValid,\n isOtpComplete,\n otpChannel,\n otpRecipient,\n purposeHidingElement,\n resolvePurposePreselection,\n sanitiseMobile,\n selectionForMode,\n toggleDataElementSelection,\n togglePurposeSelection,\n verifyFailureKey,\n} from \"./selection\";\nimport { assistedStyles, injectAssistedStyles } from \"./styles\";\nimport { availableLanguages, hexToRgba, isDefaultLanguage, normaliseLanguage } from \"./theme\";\nimport { otpBoxStyle, primaryAction, renderFooter, renderResend, renderVerifyPanel } from \"./verify-view\";\nimport type {\n AssistedActiveConfig,\n AssistedHandlers,\n AssistedOptions,\n AssistedState,\n AssistedViewContext,\n StaticTranslate,\n VerifiedOtp,\n} from \"./types\";\n\nconst PATCHABLE_KEYS: ReadonlySet<keyof AssistedState> = new Set<keyof AssistedState>([\n \"mobile\",\n \"email\",\n \"otpDigits\",\n \"resendCountdown\",\n \"ttsRevision\",\n]);\n\nconst initialState = (): AssistedState => ({\n isLoading: true,\n fetchError: null,\n content: null,\n step: \"notice\",\n acceptMode: \"selected\",\n selectedPurposes: {},\n selectedDataElements: {},\n collapsedPurposes: {},\n selectedLanguage: \"English\",\n verifyMethod: \"mobile\",\n mobile: \"\",\n email: \"\",\n otpSent: false,\n otpDigits: emptyOtpDigits(),\n otpUuid: \"\",\n resendCountdown: 0,\n isSendingOtp: false,\n isVerifying: false,\n createError: null,\n otpError: null,\n ttsRevision: 0,\n});\n\nconst otpInputId = (index: number): string => `${ASSISTED_IDS.otpInputPrefix}${index}`;\n\nconst scrollIntoViewSoft = (target: Element | null): void => {\n if (!target || typeof (target as HTMLElement).scrollIntoView !== \"function\") return;\n const reduce =\n typeof window.matchMedia === \"function\" &&\n Boolean(window.matchMedia(\"(prefers-reduced-motion: reduce)\")?.matches);\n (target as HTMLElement).scrollIntoView({ behavior: reduce ? \"auto\" : \"smooth\", block: \"nearest\" });\n};\n\nexport class AssistedController {\n private options: AssistedOptions;\n private store: Store<AssistedState>;\n private mediaQuery: MediaQuerySubscription;\n private hostEl: HTMLElement | null = null;\n private shadowRoot: ShadowRoot | null = null;\n private modalEl: HTMLElement | null = null;\n private middleEl: HTMLElement | null = null;\n private langSelectorRefs: LanguageSelectorRefs | null = null;\n private ttsManager: TTSManager | null = null;\n private keyboardCleanup: KeyboardTrapCleanup | null = null;\n private unsubscribe: (() => void) | null = null;\n private abortController = new AbortController();\n private resendTimer: ReturnType<typeof setInterval> | null = null;\n private pendingFocusId: string | null = null;\n private pendingReveal: string | null = null;\n private previousBodyOverflow: string | null = null;\n private previousHtmlOverflow: string | null = null;\n private otpRequest = 0;\n private verified: VerifiedOtp | null = null;\n private destroyed = false;\n private handlers: AssistedHandlers;\n\n constructor(options: AssistedOptions) {\n this.options = options;\n this.store = new Store<AssistedState>(initialState());\n this.mediaQuery = createMediaQuery(MOBILE_QUERY);\n this.handlers = {\n onPurposeToggle: (uuid) => this.handlePurposeToggle(uuid),\n onPurposeCollapse: (uuid) => this.handlePurposeCollapse(uuid),\n onDataElementToggle: (purposeUuid, elementUuid) =>\n this.handleDataElementToggle(purposeUuid, elementUuid),\n onAcceptAll: () => this.handleConfirmStep(\"all\"),\n onAcceptSelected: () => this.handleConfirmStep(\"selected\"),\n onDecline: () => this.handleDecline(),\n onGetOtp: () => this.handleGetOtp(),\n onConfirmOtp: () => {\n void this.handleConfirmOtp();\n },\n onEditSelections: () => this.handleEditSelections(),\n onSwitchMethod: () => this.handleSwitchMethod(),\n onMobileInput: (value) => this.store.setState({ mobile: sanitiseMobile(value) }),\n onEmailInput: (value) => this.store.setState({ email: value }),\n onChangeContact: () => this.handleChangeContact(),\n onResend: () => this.handleResend(),\n onOtpInput: (index, value) => this.handleOtpInput(index, value),\n onOtpKeydown: (index, event) => this.handleOtpKeydown(index, event),\n onOtpPaste: (event) => this.handleOtpPaste(event),\n };\n }\n\n async init(): Promise<void> {\n this.mount();\n this.unsubscribe = this.store.subscribe((state, prev) => this.handleStateChange(state, prev));\n this.mediaQuery.subscribe(() => this.render());\n this.render();\n await this.fetchNotice();\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.abortController.abort();\n this.stopCountdown();\n this.keyboardCleanup?.();\n this.langSelectorRefs?.close();\n this.ttsManager?.destroy();\n this.unsubscribe?.();\n this.store.destroy();\n this.mediaQuery.destroy();\n if (this.hostEl?.parentNode) {\n this.hostEl.parentNode.removeChild(this.hostEl);\n }\n if (this.previousBodyOverflow !== null) {\n document.body.style.overflow = this.previousBodyOverflow;\n }\n if (this.previousHtmlOverflow !== null) {\n document.documentElement.style.overflow = this.previousHtmlOverflow;\n }\n this.hostEl = null;\n this.shadowRoot = null;\n this.modalEl = null;\n this.middleEl = null;\n this.langSelectorRefs = null;\n }\n\n private mount(): void {\n this.hostEl = document.createElement(\"div\");\n this.hostEl.setAttribute(ASSISTED_HOST_ATTRIBUTE, \"\");\n this.hostEl.style.position = \"fixed\";\n this.hostEl.style.top = \"0\";\n this.hostEl.style.left = \"0\";\n this.hostEl.style.width = \"0\";\n this.hostEl.style.height = \"0\";\n this.hostEl.style.zIndex = \"2147483646\";\n document.body.appendChild(this.hostEl);\n this.shadowRoot = this.hostEl.attachShadow({ mode: \"open\" });\n\n this.previousBodyOverflow = document.body.style.overflow;\n this.previousHtmlOverflow = document.documentElement.style.overflow;\n document.body.style.overflow = \"hidden\";\n document.documentElement.style.overflow = \"hidden\";\n\n injectCheckboxStyles(this.shadowRoot);\n injectNoticeFontStyles(this.shadowRoot);\n injectAssistedStyles(this.shadowRoot);\n\n this.ttsManager = new TTSManager(\n () => this.handleTtsChange(),\n this.shadowRoot,\n (params) =>\n fetchAssistedTTSAudioUrls({\n organisationUuid: this.options.organisationUuid,\n workspaceUuid: this.options.workspaceUuid,\n noticeUuid: params.noticeUuid,\n language: params.language,\n baseUrl: this.options.baseUrl,\n signal: params.signal,\n })\n );\n\n this.shadowRoot.appendChild(el(\"div\", { style: styles.overlay, role: \"presentation\" }));\n this.modalEl = el(\"div\", {\n style: styles.modal,\n role: \"dialog\",\n \"aria-modal\": \"true\",\n [NOTICE_FONT_ROOT_ATTRIBUTE]: \"\",\n });\n this.shadowRoot.appendChild(this.modalEl);\n }\n\n private handleTtsChange(): void {\n if (this.destroyed) return;\n const state = this.store.getState();\n const hidingPurpose = state.content\n ? purposeHidingElement(\n state.content.purposes,\n state.collapsedPurposes,\n this.ttsManager?.currentElementId ?? null\n )\n : null;\n this.store.setState(\n hidingPurpose\n ? {\n collapsedPurposes: { ...state.collapsedPurposes, [hidingPurpose]: false },\n ttsRevision: state.ttsRevision + 1,\n }\n : { ttsRevision: state.ttsRevision + 1 }\n );\n }\n\n private ts(): StaticTranslate {\n return makeStaticT(toLanguageCode(this.store.getState().selectedLanguage) || \"en\");\n }\n\n private translate(key: string, fallback: string, itemId?: string): string {\n const { content, selectedLanguage } = this.store.getState();\n if (!content) return fallback;\n if (isDefaultLanguage(selectedLanguage)) {\n if (itemId) return fallback;\n const value = (content as unknown as Record<string, unknown>)[key];\n return typeof value === \"string\" && value ? value : fallback;\n }\n const map = content.supported_languages_and_translations?.[selectedLanguage] as\n | TranslationObject\n | undefined;\n if (!map) return fallback;\n if (itemId) {\n if (key === \"purposes.name\" || key === \"purposes.description\") {\n const purpose = map.purposes?.[itemId];\n if (!purpose) return fallback;\n if (typeof purpose === \"string\") {\n return key === \"purposes.name\" ? purpose : fallback;\n }\n return key === \"purposes.name\" ? purpose.name || fallback : purpose.description || fallback;\n }\n if (key.startsWith(\"data_elements.\")) {\n return map.data_elements?.[itemId] || fallback;\n }\n return fallback;\n }\n const value = (map as unknown as Record<string, unknown>)[key];\n return typeof value === \"string\" && value ? value : fallback;\n }\n\n private translateDpo(key: string, fallback: string): string {\n const { content, selectedLanguage } = this.store.getState();\n if (!content?.dpo_info) return fallback;\n const base = (content.dpo_info as unknown as Record<string, string | undefined>)[key] || fallback;\n if (isDefaultLanguage(selectedLanguage)) return base;\n const map = content.supported_languages_and_translations?.[selectedLanguage];\n const translated = (map?.dpo_info as Record<string, string | undefined> | undefined)?.[key];\n return translated || base;\n }\n\n private async fetchNotice(): Promise<void> {\n try {\n const data = await fetchAssistedNotice({\n organisationUuid: this.options.organisationUuid,\n workspaceUuid: this.options.workspaceUuid,\n noticeUuid: this.options.noticeUuid,\n baseUrl: this.options.baseUrl,\n signal: this.abortController.signal,\n });\n if (this.destroyed) return;\n const activeConfig = data.detail.active_config;\n const preselection = buildPreselection(\n activeConfig.purposes,\n resolvePurposePreselection(activeConfig.purpose_preselection)\n );\n const collapsedPurposes: Record<string, boolean> = {};\n activeConfig.purposes.forEach((purpose) => {\n collapsedPurposes[purpose.uuid] = true;\n });\n this.store.setState({\n content: activeConfig,\n isLoading: false,\n selectedLanguage: normaliseLanguage(activeConfig.default_language),\n collapsedPurposes,\n ...preselection,\n });\n if (this.modalEl) {\n this.keyboardCleanup = setupKeyboardTrap(this.modalEl, () => undefined);\n }\n this.fetchAudio();\n } catch (err) {\n if (this.destroyed || (err instanceof Error && err.name === \"AbortError\")) return;\n const error = err instanceof Error ? err : new Error(String(err));\n this.store.setState({ fetchError: error, isLoading: false });\n this.options.onError?.(error);\n }\n }\n\n private fetchAudio(): void {\n const { content, selectedLanguage } = this.store.getState();\n if (!content?.notice_uuid || !this.ttsManager) return;\n void this.ttsManager.fetchAudioUrls({\n noticeUuid: content.notice_uuid,\n language: selectedLanguage,\n content,\n });\n }\n\n private viewContext(state: AssistedState, content: AssistedActiveConfig): AssistedViewContext {\n const primaryColor = content.primary_color || ASSISTED_DEFAULT_PRIMARY_COLOR;\n return {\n state,\n content,\n isMobile: this.mediaQuery.matches,\n primaryColor,\n linkColor: content.secondary_color || ASSISTED_DEFAULT_PRIMARY_COLOR,\n accentTint: hexToRgba(primaryColor, 0.08) || \"#F5F8FF\",\n t: (key, fallback, itemId) => this.translate(key, fallback, itemId),\n tDpo: (key, fallback) => this.translateDpo(key, fallback),\n ts: this.ts(),\n handlers: this.handlers,\n };\n }\n\n private handleStateChange(state: AssistedState, prev: AssistedState): void {\n const changed = (Object.keys(state) as Array<keyof AssistedState>).filter(\n (key) => state[key] !== prev[key]\n );\n if (changed.length === 0) return;\n if (state.content && changed.every((key) => PATCHABLE_KEYS.has(key)) && this.patch(state, changed)) {\n return;\n }\n this.render();\n }\n\n private patch(state: AssistedState, changed: Array<keyof AssistedState>): boolean {\n const root = this.shadowRoot;\n if (!root || !state.content) return false;\n const ctx = this.viewContext(state, state.content);\n\n if (changed.includes(\"mobile\")) {\n const input = root.getElementById(ASSISTED_IDS.mobileInput) as HTMLInputElement | null;\n if (input && input.value !== state.mobile) input.value = state.mobile;\n }\n\n if (changed.includes(\"otpDigits\")) {\n state.otpDigits.forEach((digit, index) => {\n const box = root.getElementById(otpInputId(index)) as HTMLInputElement | null;\n if (!box) return;\n if (box.value !== digit) box.value = digit;\n applyStyles(box, otpBoxStyle(ctx, digit, index));\n });\n if (this.pendingFocusId) {\n (root.getElementById(this.pendingFocusId) as HTMLElement | null)?.focus();\n this.pendingFocusId = null;\n }\n }\n\n if (changed.includes(\"resendCountdown\")) {\n const resend = root.getElementById(ASSISTED_IDS.resend);\n if (resend) resend.replaceWith(renderResend(ctx));\n }\n\n if (changed.includes(\"ttsRevision\")) {\n const slot = root.getElementById(ASSISTED_IDS.speakerSlot);\n if (slot) {\n clearElement(slot);\n const speaker = this.renderSpeaker(ctx);\n if (speaker) slot.appendChild(speaker);\n }\n }\n\n const primary = root.querySelector<HTMLButtonElement>(`[${FOCUS_KEY_ATTRIBUTE}=\"${FOCUS_KEYS.primary}\"]`);\n if (primary) {\n const next = primaryAction(ctx);\n primary.disabled = next.disabled;\n if (primary.textContent !== next.label) primary.textContent = next.label;\n }\n return true;\n }\n\n private focusTarget(): { key: string | null; id: string | null; caret: number | null } {\n const active = this.shadowRoot?.activeElement as HTMLInputElement | null;\n if (this.pendingFocusId) {\n const id = this.pendingFocusId;\n this.pendingFocusId = null;\n return { key: null, id, caret: null };\n }\n if (!active) return { key: null, id: null, caret: null };\n return {\n key: active.getAttribute(FOCUS_KEY_ATTRIBUTE),\n id: active.id || null,\n caret: active.type === \"tel\" || active.type === \"text\" ? active.selectionStart : null,\n };\n }\n\n private restoreFocus(target: { key: string | null; id: string | null; caret: number | null }): void {\n const root = this.shadowRoot;\n if (!root) return;\n const element = (\n target.key\n ? root.querySelector(`[${FOCUS_KEY_ATTRIBUTE}=\"${target.key}\"]`)\n : target.id\n ? root.getElementById(target.id)\n : null\n ) as HTMLInputElement | null;\n if (!element) return;\n element.focus();\n if (target.caret !== null && (element.type === \"tel\" || element.type === \"text\")) {\n element.setSelectionRange(target.caret, target.caret);\n }\n }\n\n private render(): void {\n if (this.destroyed || !this.modalEl || !this.shadowRoot) return;\n const state = this.store.getState();\n const focus = this.focusTarget();\n const scrollTop = this.middleEl?.scrollTop ?? 0;\n\n this.removeLanguageDropdown();\n clearElement(this.modalEl);\n const ts = this.ts();\n const body = el(\"div\", { style: styles.content });\n this.modalEl.appendChild(body);\n this.middleEl = null;\n\n if (state.isLoading) {\n body.appendChild(\n el(\n \"div\",\n { style: styles.loadingContainer },\n el(\"div\", { style: styles.loadingSpinner, role: \"status\", \"aria-label\": ts(\"loadingNotice\") })\n )\n );\n return;\n }\n\n if (state.fetchError || !state.content) {\n body.appendChild(\n el(\n \"div\",\n { style: { ...styles.loadingContainer, gap: \"8px\" } },\n el(\"p\", { style: assistedStyles.errorTitle }, ts(\"loadFailedTitle\")),\n el(\"p\", { style: assistedStyles.errorText }, state.fetchError?.message || ts(\"tryAgain\")),\n el(\n \"button\",\n {\n type: \"button\",\n style: { ...styles.button, ...styles.cancelButton, width: \"auto\" },\n [FOCUS_KEY_ATTRIBUTE]: FOCUS_KEYS.close,\n onClick: () => this.handleDecline(),\n },\n ts(\"close\")\n )\n )\n );\n return;\n }\n\n const content = state.content;\n const ctx = this.viewContext(state, content);\n const noticeTitle = ctx.t(\"notice_banner_heading\", content.notice_banner_heading || \"Privacy Notice\");\n this.modalEl.setAttribute(\"aria-label\", noticeTitle);\n this.modalEl.style.width = ctx.isMobile ? \"90%\" : \"700px\";\n this.modalEl.style.fontFamily = resolveNoticeFontFamily({ noticeFont: content.font_preference });\n this.modalEl.style.setProperty(\"--ra-accent\", ctx.primaryColor);\n this.modalEl.style.setProperty(\n \"--ra-accent-soft\",\n hexToRgba(ctx.primaryColor, 0.18) || \"rgba(79, 135, 255, 0.18)\"\n );\n\n body.appendChild(this.renderHeader(ctx, noticeTitle));\n const isVerify = state.step === \"verify\";\n this.middleEl = el(\n \"div\",\n { style: { ...styles.middleSection, paddingRight: ctx.isMobile ? \"10px\" : \"15px\" } },\n renderNoticeText(ctx),\n renderPurposeHeading(ctx),\n renderPurposes(ctx, isVerify),\n renderDpoFooter(ctx),\n isVerify ? renderVerifyPanel(ctx) : null\n );\n body.appendChild(this.middleEl);\n body.appendChild(renderFooter(ctx));\n this.middleEl.scrollTop = scrollTop;\n this.restoreFocus(focus);\n\n if (this.pendingReveal) {\n const reveal = this.pendingReveal;\n this.pendingReveal = null;\n setTimeout(() => scrollIntoViewSoft(this.shadowRoot?.getElementById(reveal) ?? null), 60);\n }\n }\n\n private renderSpeaker(ctx: AssistedViewContext): HTMLElement | null {\n const tts = this.ttsManager;\n if (!tts?.isAvailable || ctx.state.step !== \"notice\") return null;\n const playing = tts.isPlaying && !tts.isPaused;\n return el(\n \"button\",\n {\n type: \"button\",\n style: {\n ...styles.topRight,\n padding: \"3px 9px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n \"aria-label\": playing ? ctx.ts(\"audioPause\") : ctx.ts(\"audioStart\"),\n title: playing ? ctx.ts(\"talkbackPause\") : ctx.ts(\"talkbackStart\"),\n [FOCUS_KEY_ATTRIBUTE]: FOCUS_KEYS.speaker,\n onClick: () => this.ttsManager?.toggle(),\n },\n speakerIcon(playing)\n );\n }\n\n private renderHeader(ctx: AssistedViewContext, noticeTitle: string): HTMLElement {\n const { content, ts, isMobile, state } = ctx;\n const title = el(\n \"h2\",\n { id: \"privacy-notice-title\", style: { ...styles.title, fontSize: isMobile ? \"16px\" : \"18px\" } },\n noticeTitle\n );\n const logo = content.logo_url\n ? el(\"img\", {\n src: content.logo_url,\n alt: ts(\"logoAlt\"),\n style: {\n ...styles.logo,\n maxWidth: isMobile ? \"96px\" : \"140px\",\n maxHeight: isMobile ? \"28px\" : \"32px\",\n },\n })\n : null;\n\n const speakerSlot = el(\"span\", { id: ASSISTED_IDS.speakerSlot, style: { display: \"flex\" } });\n const speaker = this.renderSpeaker(ctx);\n if (speaker) speakerSlot.appendChild(speaker);\n\n this.langSelectorRefs = renderLanguageSelector({\n languages: availableLanguages(content.default_language, content.supported_languages_and_translations),\n selectedLanguage: state.selectedLanguage,\n onSelect: (lang) => this.handleLanguageSelect(lang),\n dropdownContainer: this.shadowRoot as ShadowRoot,\n });\n this.langSelectorRefs.button.setAttribute(FOCUS_KEY_ATTRIBUTE, FOCUS_KEYS.language);\n\n const controls = el(\n \"div\",\n { style: { display: \"flex\", alignItems: \"center\", gap: \"8px\", flexShrink: 0 } },\n speakerSlot,\n this.langSelectorRefs.container\n );\n\n const sectionStyle = {\n ...styles.topSection,\n flexDirection: isMobile ? \"column\" : \"row\",\n alignItems: isMobile ? \"stretch\" : \"flex-start\",\n gap: isMobile ? \"12px\" : \"10px\",\n };\n\n if (isMobile) {\n return el(\n \"div\",\n { style: sectionStyle },\n el(\n \"div\",\n { style: { display: \"flex\", alignItems: \"center\", gap: \"10px\", width: \"100%\" } },\n logo,\n el(\"div\", { style: { marginLeft: \"auto\", display: \"flex\", alignItems: \"center\", flexShrink: 0 } }, controls)\n ),\n title\n );\n }\n return el(\"div\", { style: sectionStyle }, el(\"div\", { style: styles.topLeft }, logo, title), controls);\n }\n\n private removeLanguageDropdown(): void {\n const refs = this.langSelectorRefs;\n if (!refs) return;\n refs.close();\n if (this.shadowRoot && refs.dropdown.parentNode === this.shadowRoot) {\n this.shadowRoot.removeChild(refs.dropdown);\n }\n this.langSelectorRefs = null;\n }\n\n private handleLanguageSelect(lang: string): void {\n this.store.setState({ selectedLanguage: lang });\n this.fetchAudio();\n }\n\n private handlePurposeToggle(purposeUuid: string): void {\n const state = this.store.getState();\n const purpose = state.content?.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose || state.step !== \"notice\") return;\n this.store.setState(togglePurposeSelection(purpose, state));\n }\n\n private handleDataElementToggle(purposeUuid: string, elementUuid: string): void {\n const state = this.store.getState();\n const purpose = state.content?.purposes.find((p) => p.uuid === purposeUuid);\n if (!purpose || state.step !== \"notice\") return;\n this.store.setState(toggleDataElementSelection(purpose, elementUuid, state));\n }\n\n private handlePurposeCollapse(purposeUuid: string): void {\n const { collapsedPurposes } = this.store.getState();\n this.store.setState({\n collapsedPurposes: { ...collapsedPurposes, [purposeUuid]: !collapsedPurposes[purposeUuid] },\n });\n }\n\n private handleConfirmStep(mode: AcceptMode): void {\n const state = this.store.getState();\n const content = state.content;\n if (!content || state.step !== \"notice\") return;\n if (mode === \"selected\" && !areAllRequiredElementsChecked(content.purposes, state.selectedDataElements)) {\n return;\n }\n const selection = selectionForMode(content.purposes, mode, state);\n this.ttsManager?.stop();\n this.pendingFocusId =\n state.verifyMethod === \"email\" ? ASSISTED_IDS.emailInput : ASSISTED_IDS.mobileInput;\n this.pendingReveal = ASSISTED_IDS.verifyPanel;\n this.store.setState({\n selectedPurposes: selection.selectedPurposes,\n selectedDataElements: selection.selectedDataElements,\n acceptMode: mode,\n step: \"verify\",\n otpSent: false,\n });\n }\n\n private discardOtpSession(): void {\n this.otpRequest += 1;\n this.verified = null;\n this.stopCountdown();\n }\n\n private handleEditSelections(): void {\n this.discardOtpSession();\n this.store.setState({\n acceptMode: \"selected\",\n step: \"notice\",\n otpSent: false,\n otpUuid: \"\",\n mobile: \"\",\n email: \"\",\n otpDigits: emptyOtpDigits(),\n resendCountdown: 0,\n isSendingOtp: false,\n createError: null,\n otpError: null,\n });\n }\n\n private handleSwitchMethod(): void {\n const state = this.store.getState();\n if (state.otpSent || state.isSendingOtp) return;\n const verifyMethod = state.verifyMethod === \"email\" ? \"mobile\" : \"email\";\n this.pendingFocusId = verifyMethod === \"email\" ? ASSISTED_IDS.emailInput : ASSISTED_IDS.mobileInput;\n this.store.setState({ verifyMethod, createError: null });\n }\n\n private handleGetOtp(): void {\n const state = this.store.getState();\n if (state.isSendingOtp || !isContactValid(state.verifyMethod, state.mobile, state.email)) return;\n void this.sendOtp();\n }\n\n private handleResend(): void {\n if (this.store.getState().isSendingOtp) return;\n void this.sendOtp();\n }\n\n private async sendOtp(): Promise<void> {\n const state = this.store.getState();\n const request = ++this.otpRequest;\n this.verified = null;\n this.store.setState({ createError: null, isSendingOtp: true });\n try {\n const detail = await createOtp({\n organisationUuid: this.options.organisationUuid,\n workspaceUuid: this.options.workspaceUuid,\n to: otpRecipient(state.verifyMethod, state.mobile, state.email),\n channel: otpChannel(state.verifyMethod),\n baseUrl: this.options.baseUrl,\n signal: this.abortController.signal,\n });\n if (this.destroyed || request !== this.otpRequest) return;\n this.pendingFocusId = otpInputId(0);\n this.pendingReveal = otpInputId(0);\n this.store.setState({\n otpUuid: detail.uuid,\n otpDigits: emptyOtpDigits(),\n otpError: null,\n resendCountdown: ASSISTED_CONFIG.resendSeconds,\n otpSent: true,\n isSendingOtp: false,\n });\n this.startCountdown();\n } catch {\n if (this.destroyed || request !== this.otpRequest) return;\n this.store.setState({ createError: this.ts()(\"otpSendFailed\"), isSendingOtp: false });\n }\n }\n\n private startCountdown(): void {\n this.stopCountdown();\n this.resendTimer = setInterval(() => {\n const remaining = this.store.getState().resendCountdown;\n if (remaining <= 1) {\n this.stopCountdown();\n this.store.setState({ resendCountdown: 0 });\n return;\n }\n this.store.setState({ resendCountdown: remaining - 1 });\n }, 1000);\n }\n\n private stopCountdown(): void {\n if (this.resendTimer) {\n clearInterval(this.resendTimer);\n this.resendTimer = null;\n }\n }\n\n private handleChangeContact(): void {\n const state = this.store.getState();\n this.discardOtpSession();\n this.pendingFocusId =\n state.verifyMethod === \"email\" ? ASSISTED_IDS.emailInput : ASSISTED_IDS.mobileInput;\n this.store.setState({\n otpSent: false,\n otpUuid: \"\",\n otpDigits: emptyOtpDigits(),\n resendCountdown: 0,\n isSendingOtp: false,\n createError: null,\n otpError: null,\n });\n }\n\n private handleOtpInput(index: number, value: string): void {\n const next = applyOtpDigit(this.store.getState().otpDigits, index, value);\n this.pendingFocusId = next.focusIndex !== null ? otpInputId(next.focusIndex) : null;\n this.store.setState({ otpDigits: next.digits });\n this.pendingFocusId = null;\n }\n\n private handleOtpKeydown(index: number, event: KeyboardEvent): void {\n if (event.key !== \"Backspace\") return;\n const target = backspaceFocusIndex(this.store.getState().otpDigits, index);\n if (target === null) return;\n (this.shadowRoot?.getElementById(otpInputId(target)) as HTMLInputElement | null)?.focus();\n }\n\n private handleOtpPaste(event: ClipboardEvent): void {\n const pasted = applyOtpPaste(event.clipboardData?.getData(\"text\") ?? \"\");\n if (!pasted) return;\n event.preventDefault();\n this.pendingFocusId = otpInputId(pasted.focusIndex);\n this.store.setState({ otpDigits: pasted.digits });\n this.pendingFocusId = null;\n }\n\n private async verifiedToken(otpUuid: string, code: string): Promise<string> {\n if (this.verified?.otpUuid === otpUuid) return this.verified.accessToken;\n const detail = await verifyOtp({\n organisationUuid: this.options.organisationUuid,\n workspaceUuid: this.options.workspaceUuid,\n uuid: otpUuid,\n otp: code,\n purpose: ASSISTED_CONFIG.otpPurpose,\n baseUrl: this.options.baseUrl,\n signal: this.abortController.signal,\n });\n this.verified = { otpUuid, accessToken: detail.access_token };\n return detail.access_token;\n }\n\n private async handleConfirmOtp(): Promise<void> {\n const state = this.store.getState();\n const content = state.content;\n if (!content || state.isVerifying || !isOtpComplete(state.otpDigits)) return;\n const ts = this.ts();\n this.store.setState({ otpError: null, isVerifying: true });\n\n let accessToken: string;\n try {\n accessToken = await this.verifiedToken(state.otpUuid, state.otpDigits.join(\"\"));\n } catch (err) {\n if (this.destroyed) return;\n this.store.setState({ otpError: ts(verifyFailureKey(err)), isVerifying: false });\n return;\n }\n if (this.destroyed) return;\n\n const noticeUuid = content.notice_uuid || this.options.noticeUuid;\n try {\n if (this.options.ledgerBaseUrl) {\n const status = await fetchNoticeConsentStatusForScope({\n accessToken,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n organisationUuid: this.options.organisationUuid,\n workspaceUuid: this.options.workspaceUuid,\n noticeUuid,\n signal: this.abortController.signal,\n });\n if (this.destroyed) return;\n if (status && isNoticeFullyConsented(status)) {\n this.complete();\n return;\n }\n }\n\n const latest = this.store.getState();\n const selection = selectionForMode(content.purposes, latest.acceptMode, latest);\n await submitAssistedConsent({\n accessToken,\n organisationUuid: this.options.organisationUuid,\n workspaceUuid: this.options.workspaceUuid,\n baseUrl: this.options.baseUrl,\n ledgerBaseUrl: this.options.ledgerBaseUrl,\n noticeUuid,\n purposes: buildAssistedSubmitPurposes(content.purposes, selection),\n language: latest.selectedLanguage,\n signal: this.abortController.signal,\n });\n if (this.destroyed) return;\n this.complete();\n } catch (err) {\n if (this.destroyed) return;\n if (isAlreadyConsentedError(err)) {\n this.complete();\n return;\n }\n this.store.setState({ otpError: ts(\"tryAgain\"), isVerifying: false });\n this.options.onError?.(err instanceof Error ? err : new Error(String(err)));\n }\n }\n\n private complete(): void {\n this.options.onComplete?.();\n this.destroy();\n }\n\n private handleDecline(): void {\n this.options.onDecline?.();\n this.destroy();\n }\n}\n","import { el } from \"../core/dom\";\nimport { injectCheckboxStyles } from \"../styles/inject\";\nimport { verifyGuardianStatus } from \"../api\";\nimport {\n getConsentState,\n updateConsentState,\n} from \"../services/storage\";\nimport type { DigiLockerCallbackOptions } from \"../types\";\nimport type { GuardianVerificationErrorCode } from \"../api/types\";\n\nfunction getErrorMessage(errorCode?: GuardianVerificationErrorCode | string | null): string {\n switch (errorCode) {\n case \"GUARDIAN_UNDER_18\":\n return \"Guardian verification failed: The guardian must be 18 years or older.\";\n case \"SESSION_EXPIRED\":\n return \"Verification session has expired. Please restart the verification process.\";\n case \"TOKEN_FAILED\":\n return \"DigiLocker authentication failed. Please try again.\";\n case \"DIGILOCKER_AUTH_FAILED\":\n return \"DigiLocker authorization was cancelled or failed. Please try again.\";\n case \"NO_AUTH_CODE\":\n return \"Missing authorization code from DigiLocker. Please try again.\";\n default:\n return \"Verification failed. Please try again.\";\n }\n}\n\nexport function handleDigilockerCallback(options: DigiLockerCallbackOptions): void {\n // The DigiLocker callback page is a standalone screen, not embedded in a\n // host site, so styles can safely live in document.head here.\n injectCheckboxStyles(document);\n\n const params = new URLSearchParams(window.location.search);\n const sessionToken = params.get(\"session_token\");\n const urlStatus = params.get(\"status\") as \"verified\" | \"failed\" | \"expired\" | null;\n const verificationReference = params.get(\"verification_reference\");\n const errorCode = params.get(\"error_code\") as GuardianVerificationErrorCode | null;\n\n const persistedState = getConsentState();\n const originalUrl = persistedState?.originalUrl || \"/\";\n const storedBaseUrl = persistedState?.baseUrl;\n const storedSessionToken = persistedState?.sessionToken;\n const activeSessionToken = sessionToken || storedSessionToken;\n const apiBaseUrl = options.baseUrl || storedBaseUrl;\n\n // Check if in iframe\n let isInIframe = false;\n try {\n isInIframe = window.self !== window.top;\n } catch {\n isInIframe = true;\n }\n\n // Render status UI\n const container = el(\"div\", {\n style: {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"200px\",\n padding: \"32px\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n },\n });\n\n const statusEl = el(\"p\", {\n style: { fontSize: \"16px\", fontWeight: 600, color: \"#101828\", textAlign: \"center\" },\n });\n statusEl.textContent = \"Processing verification...\";\n\n const spinnerEl = el(\"div\", {\n style: {\n width: \"40px\",\n height: \"40px\",\n border: \"4px solid #f3f3f3\",\n borderTop: \"4px solid #3498db\",\n borderRadius: \"50%\",\n animation: \"spin 1s linear infinite\",\n marginBottom: \"16px\",\n },\n });\n\n container.appendChild(spinnerEl);\n container.appendChild(statusEl);\n document.body.appendChild(container);\n\n const redirectToOriginal = (\n result: \"verified\" | \"failed\" | \"expired\",\n ref?: string\n ) => {\n updateConsentState({\n verificationResult: result,\n verificationReference: ref,\n flowState: result === \"verified\" ? \"consent-form\" : \"error\",\n });\n\n statusEl.textContent = result === \"verified\"\n ? \"Verification successful! Redirecting...\"\n : \"Verification failed. Redirecting...\";\n\n spinnerEl.style.display = \"none\";\n\n setTimeout(() => {\n window.location.href = originalUrl;\n }, 1500);\n };\n\n // Handle direct status from URL\n if (urlStatus === \"verified\" && verificationReference) {\n if (isInIframe && window.parent) {\n window.parent.postMessage({\n type: \"DIGILOCKER_VERIFICATION_STATUS\",\n status: \"verified\",\n verificationReference,\n }, window.location.origin);\n statusEl.textContent = \"Verification successful!\";\n spinnerEl.style.display = \"none\";\n return;\n }\n options.onSuccess?.(verificationReference);\n redirectToOriginal(\"verified\", verificationReference);\n return;\n }\n\n if (urlStatus === \"failed\" || urlStatus === \"expired\") {\n const errorMsg = getErrorMessage(errorCode);\n if (isInIframe && window.parent) {\n window.parent.postMessage({\n type: \"DIGILOCKER_VERIFICATION_STATUS\",\n status: urlStatus,\n errorCode,\n error: errorMsg,\n }, window.location.origin);\n statusEl.textContent = errorMsg;\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n return;\n }\n options.onError?.(new Error(errorMsg), errorCode || undefined);\n redirectToOriginal(urlStatus);\n return;\n }\n\n // No status in URL — poll the backend\n if (!activeSessionToken) {\n statusEl.textContent = \"No verification session found.\";\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n options.onError?.(new Error(\"No session token available\"));\n return;\n }\n\n let retryCount = 0;\n const MAX_RETRIES = 3;\n\n const pollStatus = async () => {\n try {\n const response = await verifyGuardianStatus({\n accessToken: options.accessToken,\n baseUrl: apiBaseUrl,\n sessionToken: activeSessionToken,\n });\n\n if (response.status === \"verified\") {\n const ref = response.verification_reference ||\n response.guardian_details?.verification_reference;\n\n if (isInIframe && window.parent) {\n window.parent.postMessage({\n type: \"DIGILOCKER_VERIFICATION_STATUS\",\n status: \"verified\",\n verificationReference: ref,\n }, window.location.origin);\n statusEl.textContent = \"Verification successful!\";\n spinnerEl.style.display = \"none\";\n return;\n }\n\n if (ref) options.onSuccess?.(ref);\n redirectToOriginal(\"verified\", ref || undefined);\n return;\n }\n\n if (response.status === \"failed\" || response.status === \"expired\") {\n const errorMsg = getVerificationError(response.error_code, response.error);\n\n if (isInIframe && window.parent) {\n window.parent.postMessage({\n type: \"DIGILOCKER_VERIFICATION_STATUS\",\n status: response.status,\n errorCode: response.error_code,\n error: errorMsg,\n }, window.location.origin);\n statusEl.textContent = errorMsg;\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n return;\n }\n\n options.onError?.(new Error(errorMsg), response.error_code || undefined);\n redirectToOriginal(response.status);\n return;\n }\n\n // Still in progress — retry with backoff\n retryCount++;\n if (retryCount > MAX_RETRIES) {\n const timeoutMsg = \"Verification is taking too long. Please return to the original page.\";\n statusEl.textContent = timeoutMsg;\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n options.onError?.(new Error(timeoutMsg));\n redirectToOriginal(\"failed\");\n return;\n }\n\n const delay = 3000 * Math.pow(2, retryCount - 1);\n statusEl.textContent = \"Still processing... Please wait.\";\n setTimeout(pollStatus, delay);\n } catch (error) {\n retryCount++;\n if (retryCount > MAX_RETRIES) {\n const errMsg = (error as Error).message || \"Failed to check verification status.\";\n statusEl.textContent = errMsg;\n statusEl.style.color = \"#DC2626\";\n spinnerEl.style.display = \"none\";\n options.onError?.(error as Error);\n redirectToOriginal(\"failed\");\n return;\n }\n\n const delay = 3000 * Math.pow(2, retryCount - 1);\n setTimeout(pollStatus, delay);\n }\n };\n\n // Start first poll after 3s\n setTimeout(pollStatus, 3000);\n}\n\nfunction getVerificationError(errorCode: string | null, fallbackError: string | null): string {\n return getErrorMessage(errorCode) || fallbackError || \"Verification failed. Please try again.\";\n}\n","import type { PrivacyCenterHandle, PrivacyCenterOptions } from \"./types\";\n\n/** Where the hosted Privacy Center lives in production. */\nexport const DEFAULT_PRIVACY_CENTER_ORIGIN = \"https://console.redacto.io\";\n\n/** The message the hosted page posts with its content height, on load and on resize. */\nexport const PRIVACY_CENTER_HEIGHT_MESSAGE = \"redacto:privacy-center:height\";\n\nconst DEFAULT_HEIGHT = \"720px\";\nconst DEFAULT_TITLE = \"Privacy Center\";\n\nconst toCssLength = (value: number | string): string =>\n typeof value === \"number\" ? `${value}px` : value;\n\nconst resolveTarget = (target: string | HTMLElement): HTMLElement => {\n if (typeof target !== \"string\") {\n return target;\n }\n const element = document.querySelector<HTMLElement>(target);\n if (!element) {\n throw new Error(`Target element not found: ${target}`);\n }\n return element;\n};\n\n/**\n * The page to frame: `url` as given, else the hosted sign-in for `slug` on\n * `origin`. `language` becomes `?lang=` either way.\n */\nexport const privacyCenterUrl = (options: PrivacyCenterOptions): string => {\n const base = options.url\n ? options.url\n : `${(options.origin ?? DEFAULT_PRIVACY_CENTER_ORIGIN).replace(/\\/+$/, \"\")}/consent/privacy-center/${encodeURIComponent(\n options.slug ?? \"\",\n )}/sign-in`;\n const url = new URL(base, window.location.href);\n if (options.language) {\n url.searchParams.set(\"lang\", options.language);\n }\n return url.toString();\n};\n\nconst readHeight = (data: unknown): number | null => {\n if (typeof data !== \"object\" || data === null) {\n return null;\n }\n const message = data as { type?: unknown; height?: unknown };\n if (message.type !== PRIVACY_CENTER_HEIGHT_MESSAGE) {\n return null;\n }\n const height = message.height;\n return typeof height === \"number\" && Number.isFinite(height) && height > 0\n ? Math.ceil(height)\n : null;\n};\n\n/**\n * Mounts the hosted Privacy Center in an iframe inside `target`. The frame\n * grows to fit its content when the hosted page reports its height; with\n * `height` set it keeps that height instead. Returns a handle whose\n * `destroy()` removes the frame and its listener.\n */\nexport const mountPrivacyCenter = (options: PrivacyCenterOptions): PrivacyCenterHandle => {\n if (!options.url && !options.slug) {\n throw new Error(\"privacyCenter() needs a slug or a url\");\n }\n const container = resolveTarget(options.target);\n const src = privacyCenterUrl(options);\n const fixedHeight = options.height !== undefined && options.height !== \"auto\";\n\n const iframe = document.createElement(\"iframe\");\n iframe.src = src;\n iframe.title = options.title ?? DEFAULT_TITLE;\n iframe.setAttribute(\"data-redacto-privacy-center\", \"\");\n iframe.setAttribute(\"allow\", \"clipboard-write\");\n iframe.style.display = \"block\";\n iframe.style.width = \"100%\";\n iframe.style.border = \"0\";\n iframe.style.height = fixedHeight ? toCssLength(options.height as number | string) : DEFAULT_HEIGHT;\n\n // Only the frame this call created may resize it; its payload is a number.\n const onMessage = (event: MessageEvent) => {\n if (fixedHeight || event.source !== iframe.contentWindow) {\n return;\n }\n const height = readHeight(event.data);\n if (height !== null) {\n iframe.style.height = `${height}px`;\n }\n };\n\n window.addEventListener(\"message\", onMessage);\n container.appendChild(iframe);\n\n let destroyed = false;\n return {\n iframe,\n destroy: () => {\n if (destroyed) {\n return;\n }\n destroyed = true;\n window.removeEventListener(\"message\", onMessage);\n iframe.remove();\n },\n };\n};\n"],"mappings":"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","names":["src_exports","__export","ApiError","assisted","src_default","destroy","digilockerCallback","init","inline","privacyCenter","updateToken","Store","initialState","partial","prevState","listener","el","tag","attrs","children","element","applyAttrs","appendChildren","svg","key","value","applyStyles","event","UNITLESS_PROPS","styles","stringValue","parent","child","clearElement","createMediaQuery","query","mql","currentMatches","listeners","handler","e","cb","apiCache","CACHE_TTL","getCachedData","key","cached","setCachedData","data","ttl","clearApiCache","InvalidTokenError","b64DecodeUnicode","str","m","p","code","base64UrlDecode","output","jwtDecode","token","options","pos","part","decoded","e","decodeTokenSafely","token","jwtDecode","error","SANDBOX_TOKEN_HEADER","resolveSandboxAuth","options","_a","_b","_c","_d","_e","_f","token","organisationUuid","workspaceUuid","ucic","email","mobile","resolveRequestAuth","accessToken","sandbox","decodedToken","decodeTokenSafely","organisation_uuid","workspace_uuid","buildAuthHeaders","sandboxBodyIdentity","payload","sandboxQueryIdentity","CODE_BY_NAME","CODE_BY_LOWER","c","toLanguageCode","lang","_a","_b","trimmed","lower","CODE_BY_LOWER","CODE_BY_NAME","resolveDisplayLanguage","requested","defaultLanguage","translations","fallback","requestedCode","key","toSubmitPurposes","purposes","purpose","dataElements","element","ApiError","_ApiError","opts","statusFallback","status","extractFromDetail","detail","_a","obj","parseApiError","response","fallbackMessage","_b","_c","_d","body","parsedBody","fromDetail","serverMessage","message","code","HEADER","pending","toHex","bytes","byte","mintIdempotencyKey","source","statusOf","outcome","status","settledOnResolve","result","settledOnReject","error","withIdempotencyKey","url","body","send","signature","entry","oldest","held","settle","settled","HEADER","DEFAULT_CONSENT_API_BASE_URL","DEFAULT_LOGO_POSITION","DEFAULT_ACCEPT_ALL_BUTTON_TEXT","DEFAULT_ACCEPT_SELECTED_BUTTON_TEXT","DEFAULT_DECLINE_BUTTON_TEXT","ACCEPT_ALL_BUTTON_ID","ACCEPT_SELECTED_BUTTON_ID","DECLINE_BUTTON_ID","SUBMITTING_BUTTON_TEXT","LOGO_POSITION_JUSTIFY","REQUIRED_MARKER_GLYPH","REQUIRED_MARKER_ARIA_LABEL","REQUIRED_MARKER_COLOR","REQUIRED_MARKER_GAP","REQUIRED_MARKER_STYLE","DPO_AUDIO_ELEMENT_MAP","PURPOSE_STATUS_ACTIVE","PRODUCT_SECTION_COPY","productName","purposeCount","CONFIRM_HINT_ID","CONFIRM_HINT_COPY","productNames","DEFAULT_PURPOSE_PRESELECTION","PURPOSE_STATUS_INACTIVE","OTP_GATE_LENGTH","OTP_GATE_TITLE_ID","OTP_GATE_COPY","PRODUCT_POLICIES_LABEL","DEFAULT_SELECTION_CONTROL","SELECTION_CONTROL_ACCENT","SELECTION_CONTROL_COPY","answer","CONFIRM_DIALOG_ID","CONFIRM_DIALOG_DETAIL_ID","CONFIRM_DIALOG_COPY","INHERIT_FONT_FAMILY","DEFAULT_NOTICE_FONT_ID","NOTICE_FONT_GENERIC_FALLBACK","NOTICE_FONT_CATALOGUE","CSS_FONT_KEYWORDS","UNSAFE_FONT_CHARACTERS","NOTICE_FONT_ROOT_ATTRIBUTE","NOTICE_FONT_STYLE_ID","NOTICE_FONT_CSS","BASE_URL","DEFAULT_CONSENT_API_BASE_URL","fetchConsentContent","noticeId","accessToken","baseUrl","language","specific_uuid","validate_against","include_fully_consented_data","signal","sandboxParams","ORG","WS","sandbox","resolveRequestAuth","apiBaseUrl","cacheKey","cached","getCachedData","url","key","value","sandboxQueryIdentity","response","buildAuthHeaders","parseApiError","data","setCachedData","fetchConsentContentPublic","org_uuid","workspace_uuid","notice_uuid","noticesUrl","submitConsentEvent","ledgerBaseUrl","noticeUuid","purposes","declined","meta_data","guardianVerificationReference","selfDeclaredAdult","payload","toSubmitPurposes","toLanguageCode","requestBody","sandboxBodyIdentity","serialisedBody","withIdempotencyKey","idempotencyHeaders","clearApiCache","submitConsentEventPublic","fetchTTSAudioUrls","initiateGuardianVerification","guardianName","guardianContact","guardianRelationship","frontendCallbackUrl","metadata","_a","decodedToken","decodeTokenSafely","responseData","detail","verifyGuardianStatus","sessionToken","_b","_c","_d","_e","_f","_g","fetchNoticeConsentStatusForScope","accessToken","ledgerBaseUrl","organisationUuid","workspaceUuid","noticeUuid","signal","response","data","body","fetchNoticeConsentStatus","decodedToken","decodeTokenSafely","ORG","WS","isNoticeFullyConsented","status","buildLedgerConsentOverlay","configPurposes","_a","_b","byUuid","p","purpose_selections","cp","lp","purposeStatus","selectedByUuid","de","data_elements","STYLE_ID","STYLE_CONTENT","injectCheckboxStyles","root","style","styles","createRequiredMarker","label","REQUIRED_MARKER_ARIA_LABEL","el","REQUIRED_MARKER_STYLE","REQUIRED_MARKER_GLYPH","productPurposeKey","productUuid","purposeUuid","purposeCoversProduct","purpose","scope","isMultiProduct","products","purposeNamesProduct","_a","noticeScopesPurposes","purposes","_b","serverMarksMandatoryProducts","product","gatedProductUuids","rowProductUuid","row","mandatoryProductsFirst","products","mandatory","product","groupPurposesByProduct","purposes","order","covered","purpose","purposeCoversProduct","saved","byUuid","p","ordered","uuid","found","rest","group","expandPurposesByProduct","isMultiProduct","rows","noticePurposeRows","row","dataElementKey","purposeUuid","elementUuid","productUuid","productPurposeKey","buildSelectionForMode","rows","mode","current","selectedPurposes","selectedDataElements","purpose","element","isBlockingRequiredElement","hasRequiredDataElement","SIZES","groupStyle","optionStyle","dropdownWrapStyle","settledAnswerStyle","selectStyle","lockedBadgeStyle","box","lockedTick","label","glyph","el","svg","checkboxClass","size","className","renderSelectionControl","props","_a","control","onSelect","groupName","locked","lockedLabel","recordedAnswer","scale","checked","indeterminate","select","next","held","value","optionLabel","text","SELECTION_CONTROL_COPY","paintRadios","radios","radio","option","SELECTION_CONTROL_ACCENT","nextIndeterminate","mixedOption","selectEl","paint","checkbox","renderModalPurposes","purposes","options","_a","_b","_c","selectedPurposes","collapsedPurposes","selectedDataElements","initialDataElementSelections","recordedAnswers","settings","isMobile","isAlreadyConsented","productUuid","isRowLocked","getTranslatedText","onPurposeToggle","onPurposeCollapse","onDataElementToggle","checkboxes","purposeControls","collapseButtons","dataElementContainers","chevrons","titleElements","descriptionElements","dataElementLabels","headingColor","textColor","font","container","el","styles","purpose","purposeWrapper","stateKey","productPurposeKey","locked","chevron","svg","chevronContainer","titleEl","hasRequiredDataElement","createRequiredMarker","descEl","textContainer","collapseBtn","e","purposeName","purposeControl","renderSelectionControl","DEFAULT_SELECTION_CONTROL","rightElement","optionRow","deContainer","dataElement","combinedId","labelSpan","isBlockingRequiredElement","deRightElement","createGreenCheckmark","deCheckbox","deRow","size","ariaLabel","svgSize","strokeWidth","pathD","checkSvg","LANGUAGE_NATIVE_LABELS","toNativeLabel","name","_a","renderLanguageSelector","options","_b","_c","_d","languages","selectedLanguage","settings","onSelect","dropdownContainer","isOpen","buttonText","el","chevronSvg","svg","buttonStyle","styles","button","toggleDropdown","e","closeDropdown","dropdown","lang","isSelected","itemStyle","item","container","positionDropdown","rect","clickOutsideHandler","path","target","repositionHandler","openDropdown","setupKeyboardTrap","modalEl","onEscape","handler","e","_a","focusableElements","focusable","el","first","last","active","firstFocusable","STORAGE_KEY","isBrowser","saveConsentState","state","stateWithTimestamp","STORAGE_KEY","error","getConsentState","savedState","parsed","clearConsentState","updateConsentState","updates","currentState","TTSManager","onStateChange","root","fetchAudio","fetchTTSAudioUrls","params","_a","response","error","content","_b","urls","audioSeq","elementSeq","push","url","elementId","purpose","purposeAudio","de","deAudio","mapping","DPO_AUDIO_ELEMENT_MAP","audioUrl","ACCEPT_ALL_BUTTON_ID","ACCEPT_SELECTED_BUTTON_ID","DECLINE_BUTTON_ID","startIndex","index","audio","element","rect","el","renderAgeVerification","options","settings","colors","isMobile","logoUrl","onYes","onNo","onClose","headingColor","textColor","font","logo","el","styles","title","topLeft","closeBtn","closeSvg","svg","topSection","description","question","middleSection","btnBase","yesBtn","noBtn","bottomSection","RELATIONSHIP_OPTIONS","renderGuardianForm","options","_a","formData","settings","colors","isMobile","logoUrl","isSubmitting","onSubmit","onCancel","onFieldChange","headingColor","textColor","borderColor","bgColor","radius","font","accentColor","inputStyle","errorStyle","labelStyle","hintStyle","logo","el","styles","title","topLeft","topSection","subtitle","infoIcon","svg","infoText","infoBanner","nameLabel","nameInput","e","nameHint","nameError","nameGroup","contactLabel","contactInput","contactHint","contactError","contactGroup","relLabel","selectedLabel","o","chevronSvg","selectedSpan","relationshipDisplay","dropdownList","i","option","isSelected","optionEl","doClose","label","checkSvg","dropdownOpen","relContainer","handleClickOutside","doOpen","rect","spaceBelow","dropdownHeight","relationshipError","generalError","fieldsContainer","middleSection","btnBase","submitBtn","cancelBtn","bottomSection","validateGuardianForm","data","errors","getVerificationErrorMessage","errorCode","fallbackError","renderVerificationScreen","options","settings","colors","isMobile","logoUrl","isInitiating","isPolling","isComplete","isAutoTransitioning","error","canRetry","onContinue","onBack","headingColor","textColor","font","accentColor","logo","el","styles","title","topLeft","topSection","middleSection","successCircle","checkSvg","svg","successText","wrapper","spinner","statusMsg","errorCircle","xSvg","failedText","errorBox","btnBase","bottomSection","acceptBtnStyle","declineBtnStyle","continueBtn","retryBtn","goBackBtn","cancelBtn","resolveColors","settings","activeConfig","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","primaryColor","secondaryColor","rowKey","row","productPurposeKey","recordedSelectionLookup","purposeSelections","productPurposeSelections","purposeUuid","productUuid","_a","perProduct","seedSelection","rows","recordedFor","selectedPurposes","selectedDataElements","recorded","element","_b","_c","dataElementKey","collapseEveryRow","acc","initialCollapsedProducts","groups","defaultOpenProducts","openByDefault","soleSection","group","recordedBaseline","PURPOSE_STATUS_ACTIVE","settleProducts","products","productList","isSettled","consentedPurposes","rowsByProduct","resolved","rowProductUuid","consentedProducts","mandatory","hasRequiredDataElement","deciding","isFullyConsented","productBoxPurposes","purposes","required","purposeToggle","purpose","key","nextState","sectionToggle","sectionPurposes","keyProductUuid","next","purposeOverrides","elementOverrides","purposeCheckedFromElements","requiredElements","isBlockingRequiredElement","confirmVerdict","recordedPurposeSelections","isSelected","wasRecorded","isMandatory","satisfies","touched","unresolved","serverMarksMandatoryProducts","baseline","blocking","ok","gated","gatedProductUuids","scoped","noticeScopesPurposes","engagingRows","purposeNamesProduct","engaged","confirmHint","verdict","productName","CONFIRM_HINT_COPY","byUuid","product","names","uuid","submissionPurposes","selection","rowsOf","config","noticePurposeRows","groupsOf","groupPurposesByProduct","seedProductState","purposeSelections","productPurposeSelections","defaultOpenProducts","includeFullyConsentedData","rows","recordedFor","recordedSelectionLookup","hasRecord","settled","settleProducts","seed","initialCollapsedProducts","recordedBaseline","isMultiProduct","seeded","seedSelection","collapseEveryRow","isFullyConsented","productIsRequired","products","productUuid","list","serverMarksMandatoryProducts","gatedProductUuids","noticeConfirmVerdict","selectedPurposes","recordedPurposeSelections","confirmVerdict","CHEVRON_OPEN","CHEVRON_CLOSED","sectionTally","boxPurposes","keyProductUuid","selectedPurposes","selectedCount","purpose","productPurposeKey","renderProductSection","options","_a","product","purposes","collapsed","locked","isRequired","settings","isMobile","getTranslatedText","onToggleCollapse","onToggleSelect","name","headingColor","productBoxPurposes","chevron","svg","collapseButton","el","styles","title","createRequiredMarker","tally","selection","renderSelectionControl","DEFAULT_SELECTION_CONTROL","next","PRODUCT_SECTION_COPY","control","header","body","renderProductGroups","container","sections","parts","group","productUuid","section","productIsRequired","rows","renderModalPurposes","purposeUuid","mergePurposeRefs","updateProductSection","refs","merge","pick","renderConfirmHint","CONFIRM_HINT_ID","updateConfirmHint","hintEl","anchor","describedButton","text","resolveLogoPosition","raw","DEFAULT_LOGO_POSITION","logoRowJustify","position","LOGO_POSITION_JUSTIFY","shouldHoldForOtp","gate","verified","emptyOtpDigits","length","OTP_GATE_LENGTH","otpCodeOf","digits","isOtpComplete","digit","onlyDigits","value","withDigit","index","current","fillFromStart","code","_","i","_a","typedOver","text","previous","withoutPrevious","applyOtpText","typed","applyOtpBackspace","settleVerify","result","OtpGateSession","mode","token","onBusy","_b","OTP_GATE_COPY","panelStyle","titleStyle","descriptionStyle","digitsStyle","digitStyle","errorStyle","buttonStyle","renderOtpGatePanel","options","view","inputs","errorEl","el","confirmButton","isOtpComplete","paint","_a","input","index","blocked","OTP_GATE_COPY","focusDigit","applyEntry","entry","digitRow","_","applyOtpText","event","applyOtpBackspace","_b","text","container","OTP_GATE_TITLE_ID","next","lockSelections","control","button","overlayStyle","panelStyle","titleStyle","detailStyle","actionsStyle","buttonStyle","activeIn","root","_a","openConfirmDialog","options","action","onConfirm","onCancel","confirmStyle","fontFamily","opener","disposed","dispose","onKeyDown","overlay","cancel","confirm","cancelButton","el","CONFIRM_DIALOG_COPY","confirmButton","panel","CONFIRM_DIALOG_ID","CONFIRM_DIALOG_DETAIL_ID","NOTICE_FONT_ROOT_ATTRIBUTE","event","active","getProductPolicyLinks","products","policies","product","url","shouldShowNoticePolicyLink","links","_a","productCount","renderProductPolicyLine","label","links","linkStyle","line","el","link","index","resolvePurposePreselection","raw","DEFAULT_PURPOSE_PRESELECTION","hasRecordedPurposeState","selection","_a","PURPOSE_STATUS_INACTIVE","buildPreselection","purposes","mode","buildSelectionForMode","purpose","selectedPurposes","selectedDataElements","hasPreselectedElement","element","isPreselected","dataElementKey","openingSelection","preselection","recordedFor","hint","isRecorded","purposeUuid","productUuid","elementUuid","applyPreselection","rows","seeded","opening","row","productPurposeKey","recordedAnswersFor","answers","entryById","id","NOTICE_FONT_CATALOGUE","entry","toFontFamilyValue","value","_a","_b","family","UNSAFE_FONT_CHARACTERS","INHERIT_FONT_FAMILY","lowered","CSS_FONT_KEYWORDS","NOTICE_FONT_GENERIC_FALLBACK","toNoticeFontEntry","fontPreference","stored","DEFAULT_NOTICE_FONT_ID","resolveNoticeFontFamily","hostFont","noticeFont","host","injectNoticeFontStyles","root","NOTICE_FONT_STYLE_ID","style","NOTICE_FONT_CSS","ModalController","options","OtpGateSession","Store","createMediaQuery","state","prevState","_a","_b","_c","_d","_e","accessToken","mode","wasLocked","content","lockSelections","gate","colors","resolveColors","renderOtpGatePanel","OTP_GATE_COPY","digits","verified","kind","action","openConfirmDialog","legacySubject","legacyEmail","legacyMobile","noticeBaseUrl","data","fetchConsentContent","activeConfig","purposeSelections","reconsentRequired","ledgerOverlayApplied","ledgerStatus","fetchNoticeConsentStatus","overlay","buildLedgerConsentOverlay","initialCollapsed","initialDataElementSelections","needsConsentPurposes","alreadyConsentedPurposes","isFullyConsentedReviewMode","recordedFor","recordedSelectionLookup","seedRows","rowsOf","reviewsFullRecord","isFullyConsented","purpose","selection","de","combinedId","deSelection","productSeed","seedProductState","productPreselection","applyPreselection","seedSelection","selectedLanguage","resolveDisplayLanguage","isMinorFlow","showAgeVerification","restoreState","pollingTokenToResume","persistedState","getConsentState","clearConsentState","recordedAnswersFor","err","error","injectCheckboxStyles","injectNoticeFontStyles","TTSManager","el","styles","settingsObj","modalStyle","NOTICE_FONT_ROOT_ATTRIBUTE","loadingEl","contentEl","_f","_g","_h","isMobile","resolveNoticeFontFamily","clearElement","ageRefs","renderAgeVerification","setupKeyboardTrap","renderGuardianForm","field","value","s","verRefs","renderVerificationScreen","clearName","headingColor","textColor","linkColor","font","logoImg","supportedLangs","allLanguages","l","renderLanguageSelector","lang","ttsStrokeColor","speakerSvg","svg","topRight","logoPosition","resolveLogoPosition","headerRows","logoRowJustify","topSection","baseTextStyle","noticeTextSpan","policyPrefixText","policyAnchorText","policySpan","productPolicyLinks","getProductPolicyLinks","showNoticePolicyLink","shouldShowNoticePolicyLink","noticeAndPolicyP","soleSection","purposesHost","isMultiProduct","grouped","renderProductGroups","groupsOf","key","defaultText","itemId","uuid","productUuid","euuid","puuid","choice","renderModalPurposes","footerDiv","footerP","addlSpan","pcAnchorText","renderProductPolicyLine","PRODUCT_POLICIES_LABEL","dpo","gText","gLink","connectorSpan","emailLink","dpText","dpLink","dpoTextSpan","dpoLink","acceptBtnText","DEFAULT_ACCEPT_SELECTED_BUTTON_TEXT","gridButtonBox","acceptStyle","ACCEPT_SELECTED_BUTTON_ID","shortcutStyle","ACCEPT_ALL_BUTTON_ID","DEFAULT_ACCEPT_ALL_BUTTON_TEXT","declineBtnText","DEFAULT_DECLINE_BUTTON_TEXT","declineStyle","DECLINE_BUTTON_ID","bottomSection","contentWrapper","renderConfirmHint","displayLanguage","translations","translationMap","message","errorContent","purposeData","productData","purposeUuid","productPurposeKey","p","next","purposeToggle","elementUuid","newDataElements","purposeCheckedFromElements","section","refs","editable","sectionToggle","products","product","renderProductSection","productIsRequired","updateProductSection","rows","buildSelectionForMode","purposes","submissionPurposes","submitConsentEvent","control","checkbox","noticeConfirmVerdict","verdict","text","confirmHint","updateConfirmHint","submitting","setDisabled","btn","disabled","updateRefs","container","isCollapsed","chevron","collapseBtn","errors","validateGuardianForm","digilockerMode","callbackUrl","response","initiateGuardianVerification","saveConsentState","popup","openedWindow","token","attempts","consecutiveErrors","paused","MAX_ATTEMPTS","MAX_CONSECUTIVE_ERRORS","POLL_INTERVAL","poll","verifyGuardianStatus","ref","getVerificationErrorMessage","strokeColor","pauseSvg","applySubmittingState","idleLabel","SUBMITTING_BUTTON_TEXT","inlineStyles","hasBlockingRequiredElement","purpose","isBlockingRequiredElement","inlineElementKey","productUuid","purposeUuid","elementUuid","productPurposeKey","inlinePurposeRows","config","noticePurposeRows","initialCollapsedPurposes","rows","acc","row","initialSelection","selectedPurposes","selectedDataElements","element","allRequiredElementsChecked","withPurposeElements","selected","updated","toggleDataElement","combinedId","next","isTicked","requiredElements","purposeSelected","buildInlineSubmitPurposes","key","hasSelectedRequiredElement","hasSelectedDataElement","inlineSubmissionKey","accessToken","configUuid","isRetryableFailure","error","status","renderInlinePurposes","purposes","options","selectedPurposes","collapsedPurposes","selectedDataElements","products","productPurposeOrder","settings","isMobile","getTranslatedText","onPurposeToggle","onPurposeCollapse","onDataElementToggle","checkboxes","collapseButtons","dataElementContainers","chevrons","titleElements","descriptionElements","dataElementLabels","headingColor","textColor","container","el","renderPurpose","purpose","productUuid","_a","stateKey","productPurposeKey","purposeWrapper","chevron","svg","chevronContainer","titleEl","inlineStyles","hasBlockingRequiredElement","createRequiredMarker","descEl","textContainer","collapseBtn","e","purposeCheckbox","optionRow","deContainer","dataElement","combinedId","labelSpan","isBlockingRequiredElement","deCheckbox","deRow","isMultiProduct","group","groupPurposesByProduct","heading","section","InlineController","options","Store","createMediaQuery","injectCheckboxStyles","state","prevState","_a","_b","accessToken","_c","_d","generation","data","fetchConsentContentPublic","activeConfig","rows","inlinePurposeRows","selection","initialSelection","resolveDisplayLanguage","initialCollapsedPurposes","err","error","status","fetchNoticeConsentStatusForScope","isNoticeFullyConsented","textColor","el","inlineStyles","renderInlinePurposes","key","defaultText","itemId","uuid","productUuid","elementUuid","purposeUuid","content","lang","translations","translationMap","purposeData","productData","value","productPurposeKey","purpose","p","newPurposeState","withPurposeElements","next","toggleDataElement","checkbox","rowsByKey","row","stateKey","container","isCollapsed","chevron","collapseBtn","allRequiredElementsChecked","isValid","skipKey","submissionKey","inlineSubmissionKey","isRetryableFailure","tokenToUse","submitConsentEventPublic","buildInlineSubmitPurposes","message","ASSISTED_BASE_URL","DEFAULT_CONSENT_API_BASE_URL","ASSISTED_CONFIG","EMAIL_REGEX","DEFAULT_PURPOSE_PRESELECTION","ASSISTED_FALLBACK_MESSAGES","ASSISTED_HOST_ATTRIBUTE","ASSISTED_IDS","FOCUS_KEY_ATTRIBUTE","FOCUS_KEYS","purposeUuid","elementUuid","ASSISTED_DEFAULT_PRIMARY_COLOR","ASSISTED_STYLE_ID","MOBILE_QUERY","publicScope","baseUrl","organisationUuid","workspaceUuid","ASSISTED_BASE_URL","fetchAssistedNotice","noticeUuid","signal","url","response","parseApiError","ASSISTED_FALLBACK_MESSAGES","createOtp","to","channel","verifyOtp","uuid","otp","purpose","submitAssistedConsent","accessToken","ledgerBaseUrl","purposes","language","payload","toSubmitPurposes","toLanguageCode","serialisedBody","withIdempotencyKey","idempotencyHeaders","text","fetchAssistedTTSAudioUrls","en","hi","bn","gu","kn","ks","gom","mai","ml","mniMtei","mr","ne","or","pa","sa","sat","sd","ta","te","ur","as","brx","doi","STATIC_STRINGS","interpolate","template","vars","match","token","makeStaticT","langCode","key","_a","_b","icon","size","color","strokeWidth","children","svg","lockIcon","checkIcon","clockIcon","phoneIcon","mailIcon","chevronIcon","expanded","speakerIcon","playing","isBlockingRequiredElement","element","hasBlockingRequiredElement","purpose","resolvePurposePreselection","raw","DEFAULT_PURPOSE_PRESELECTION","buildPreselection","purposes","mode","empty","buildSelectionForMode","hasPreselectedElement","isPreselected","dataElementKey","togglePurposeSelection","current","next","selectedDataElements","toggleDataElementSelection","elementUuid","key","isTicked","blocking","purposeSelected","areAllRequiredElementsChecked","selectionForMode","buildAssistedSubmitPurposes","selection","sanitiseMobile","ASSISTED_CONFIG","isContactValid","method","mobile","email","EMAIL_REGEX","otpRecipient","otpChannel","emptyOtpDigits","isOtpComplete","digits","applyOtpDigit","index","digit","focusIndex","applyOtpPaste","text","pasted","_","i","_a","backspaceFocusIndex","verifyFailureKey","error","ApiError","isAlreadyConsentedError","purposeHidingElement","collapsedPurposes","elementId","owner","ASSISTED_CSS","injectAssistedStyles","root","ASSISTED_STYLE_ID","style","assistedStyles","linkAttrs","ctx","id","href","styles","textStyle","renderNoticeText","content","ts","anchorText","link","el","renderPurposeHeading","renderPurpose","purpose","locked","state","t","handlers","isMobile","isExpanded","name","description","dataElements","element","containerId","ASSISTED_IDS","title","hasBlockingRequiredElement","createRequiredMarker","textContainer","collapse","FOCUS_KEY_ATTRIBUTE","FOCUS_KEYS","event","chevronIcon","checkbox","elementsContainer","elementName","label","isBlockingRequiredElement","elementCheckbox","dataElementKey","renderPurposes","container","assistedStyles","renderDpoFooter","tDpo","dpo","paragraph","dpoAnchor","hexToRgba","hex","alpha","h","c","isDefaultLanguage","lang","normaliseLanguage","availableLanguages","defaultLanguage","translations","pinned","normalised","rest","a","b","renderContactField","ctx","state","handlers","locked","el","assistedStyles","ASSISTED_CONFIG","ASSISTED_IDS","event","otpBoxStyle","digit","index","renderResend","ts","primaryColor","clockIcon","FOCUS_KEY_ATTRIBUTE","FOCUS_KEYS","renderOtpEntry","boxes","renderVerifyPanel","isEmail","linksLocked","labelRow","mailIcon","phoneIcon","status","checkIcon","lockIcon","primaryAction","content","t","isContactValid","isOtpComplete","DEFAULT_ACCEPT_SELECTED_BUTTON_TEXT","areAllRequiredElementsChecked","renderFooter","isMobile","isVerify","buttonBase","styles","width","primaryState","primary","ACCEPT_SELECTED_BUTTON_ID","decline","DECLINE_BUTTON_ID","DEFAULT_DECLINE_BUTTON_TEXT","acceptAll","ACCEPT_ALL_BUTTON_ID","DEFAULT_ACCEPT_ALL_BUTTON_TEXT","PATCHABLE_KEYS","initialState","emptyOtpDigits","otpInputId","index","ASSISTED_IDS","scrollIntoViewSoft","target","_a","reduce","AssistedController","options","Store","createMediaQuery","MOBILE_QUERY","uuid","purposeUuid","elementUuid","value","sanitiseMobile","event","state","prev","_b","_c","_d","_e","ASSISTED_HOST_ATTRIBUTE","injectCheckboxStyles","injectNoticeFontStyles","injectAssistedStyles","TTSManager","params","fetchAssistedTTSAudioUrls","el","styles","NOTICE_FONT_ROOT_ATTRIBUTE","hidingPurpose","purposeHidingElement","makeStaticT","toLanguageCode","key","fallback","itemId","content","selectedLanguage","isDefaultLanguage","map","purpose","base","data","fetchAssistedNotice","activeConfig","preselection","buildPreselection","resolvePurposePreselection","collapsedPurposes","normaliseLanguage","setupKeyboardTrap","err","error","primaryColor","ASSISTED_DEFAULT_PRIMARY_COLOR","hexToRgba","changed","root","ctx","input","digit","box","applyStyles","otpBoxStyle","resend","renderResend","slot","clearElement","speaker","primary","FOCUS_KEY_ATTRIBUTE","FOCUS_KEYS","next","primaryAction","active","id","element","focus","scrollTop","ts","body","assistedStyles","noticeTitle","resolveNoticeFontFamily","isVerify","renderNoticeText","renderPurposeHeading","renderPurposes","renderDpoFooter","renderVerifyPanel","renderFooter","reveal","tts","playing","speakerIcon","isMobile","title","logo","speakerSlot","renderLanguageSelector","availableLanguages","lang","controls","sectionStyle","refs","p","togglePurposeSelection","toggleDataElementSelection","mode","areAllRequiredElementsChecked","selection","selectionForMode","verifyMethod","isContactValid","request","detail","createOtp","otpRecipient","otpChannel","ASSISTED_CONFIG","remaining","applyOtpDigit","backspaceFocusIndex","pasted","applyOtpPaste","otpUuid","code","verifyOtp","isOtpComplete","accessToken","verifyFailureKey","noticeUuid","status","fetchNoticeConsentStatusForScope","isNoticeFullyConsented","latest","submitAssistedConsent","buildAssistedSubmitPurposes","isAlreadyConsentedError","getErrorMessage","errorCode","handleDigilockerCallback","options","_a","_b","_c","injectCheckboxStyles","params","sessionToken","urlStatus","verificationReference","persistedState","getConsentState","originalUrl","storedBaseUrl","storedSessionToken","activeSessionToken","apiBaseUrl","isInIframe","container","el","statusEl","spinnerEl","redirectToOriginal","result","ref","updateConsentState","errorMsg","retryCount","MAX_RETRIES","pollStatus","_d","_e","response","verifyGuardianStatus","getVerificationError","timeoutMsg","delay","error","errMsg","fallbackError","DEFAULT_PRIVACY_CENTER_ORIGIN","PRIVACY_CENTER_HEIGHT_MESSAGE","DEFAULT_HEIGHT","DEFAULT_TITLE","toCssLength","value","resolveTarget","target","element","privacyCenterUrl","options","_a","_b","base","url","readHeight","data","message","height","mountPrivacyCenter","container","src","fixedHeight","iframe","onMessage","event","destroyed","activeModal","activeInline","activeAssisted","activePrivacyCenters","init","options","destroy","ModalController","err","_a","inline","InlineController","updateToken","accessToken","assisted","AssistedController","privacyCenter","handle","mountPrivacyCenter","tracked","digilockerCallback","handleDigilockerCallback","RedactoConsent","src_default"]}