@arkyc/widget 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"arkyc-widget.iife.global.js","names":["themeCss"],"sources":["../src/client.ts","../src/realtime.ts","../src/theme.ts","../src/capture.ts","../../types/dist/realtime.mjs","../../types/dist/workflow.mjs","../src/flow.ts","../src/face.ts","../src/document.ts","../src/countries.ts","../src/ui.ts","../src/device.ts","../../../node_modules/.pnpm/qrcode-generator@1.5.2/node_modules/qrcode-generator/qrcode.js","../src/qr.ts","../src/controller.ts","../src/WidgetHandler.ts","../src/ArkycWidget.ts","../src/index.ts"],"sourcesContent":["import type {\n CaptureModel,\n DocumentType,\n LivenessChallenge,\n LivenessMode,\n ProjectBranding,\n VerificationStatus,\n WorkflowConfig,\n} from '@arkyc/types'\n\n/** The session view exposed by the Client/Widget API (`GET /v1/client/session`). */\nexport interface ClientSession {\n id: string\n status: VerificationStatus\n expires_at: string\n /** The capture flow this session runs (Phase 17). */\n capture_model?: CaptureModel\n /** The active-liveness challenge sequence to prompt the user through. */\n liveness_challenges?: LivenessChallenge[]\n /** Cross-device handoff config resolved from the project setting. */\n handoff?: ClientHandoff\n /** How to watch this session live (push transport params or `polling`). */\n realtime?: ClientRealtime\n /** Project branding (colours/logo/name) so the widget themes itself at runtime. */\n branding?: ProjectBranding | null\n /** The applied workflow (ordered, toggleable stages + skip_ocr), or null for the default flow. */\n workflow?: WorkflowConfig | null\n}\n\n/**\n * Realtime connection info for this session (Phase 16). `transport` selects how\n * the widget watches the session: `pusher`/`firebase` subscribe to `channel`;\n * `polling` (and `off`/`memory`) mean poll the session endpoint instead. The\n * remaining fields carry the active transport's public connection params; `token`\n * is a per-session Firebase custom token when applicable.\n */\nexport interface ClientRealtime {\n transport: 'pusher' | 'firebase' | 'polling' | 'off' | 'memory'\n /** The private channel this session's events publish to. */\n channel: string\n /** Per-session Firebase custom token (firebase transport only). */\n token?: string | null\n [param: string]: unknown\n}\n\n/** Whether (and where) the widget may offer cross-device handoff. */\nexport interface ClientHandoff {\n enabled: boolean\n /** Whether a desktop user may continue on the desktop device instead of handing off. */\n allow_desktop: boolean\n /** First-party hosted page the QR points to (the phone resumes the session there). */\n url: string\n}\n\n/**\n * Mock-driver signal hints. Real provider drivers ignore these; the `mock`\n * drivers use them to make the demo/playground flow deterministic.\n */\nexport interface ProviderSignalHints {\n quality_score?: number\n ocr_confidence?: number\n expired?: boolean\n liveness_score?: number\n liveness_passed?: boolean\n multiple_faces?: boolean\n face_similarity?: number\n face_match_passed?: boolean\n}\n\n/** Input for the document-front submission. */\nexport interface DocumentFrontInput {\n image?: Blob | null\n country?: string | null\n documentType?: DocumentType | null\n signals?: ProviderSignalHints\n}\n\n/** Input for the document-back submission. */\nexport interface DocumentBackInput {\n image?: Blob | null\n country?: string | null\n documentType?: DocumentType | null\n}\n\n/** Input for the liveness submission (passive selfie or active challenge video). */\nexport interface LivenessInput {\n selfie?: Blob | null\n /** Recorded challenge video (active mode). */\n video?: Blob | null\n /** Passive (selfie) or active (challenge video). Defaults to passive. */\n mode?: LivenessMode\n /** The challenge sequence the user performed, in order (active mode). */\n challenges?: LivenessChallenge[]\n signals?: ProviderSignalHints\n}\n\n/** Input for completing the session (runs face-match + decision). */\nexport interface CompleteInput {\n signals?: ProviderSignalHints\n}\n\n/**\n * Raised when the Client API returns a non-2xx response.\n */\nexport class WidgetApiError extends Error {\n readonly status: number\n readonly code?: string\n\n constructor(message: string, status: number, code?: string) {\n super(message)\n this.name = 'WidgetApiError'\n this.status = status\n this.code = code\n }\n}\n\n/** Options for {@link ArkycClient}. */\nexport interface ArkycClientOptions {\n /** Short-lived client token minted for this session. */\n token: string\n /** API origin (defaults to the same origin the widget is served from). */\n baseUrl?: string\n /** Injectable for testing; defaults to the global `fetch`. */\n fetch?: typeof fetch\n}\n\ntype EnvelopeNumber = number | boolean\n\nfunction appendSignals(form: FormData, signals?: ProviderSignalHints): void {\n if (!signals) return\n for (const [key, value] of Object.entries(signals)) {\n if (value == null) continue\n form.append(key, String(value as EnvelopeNumber))\n }\n}\n\n/**\n * A thin, framework-agnostic client for the Arkyc Client/Widget API. Drives a\n * single verification session with a short-lived client token. All responses\n * are unwrapped from the standard `{ status, message, data }` envelope.\n */\nexport class ArkycClient {\n private readonly token: string\n private readonly baseUrl: string\n private readonly fetchImpl: typeof fetch\n\n constructor(options: ArkycClientOptions) {\n if (!options.token) throw new Error('ArkycClient requires a client `token`.')\n this.token = options.token\n this.baseUrl = (options.baseUrl ?? '').replace(/\\/$/, '')\n const f = options.fetch ?? globalThis.fetch\n if (!f) throw new Error('No `fetch` implementation available.')\n this.fetchImpl = f.bind(globalThis)\n }\n\n /**\n * Load the current session (marks it `started` on first call).\n *\n * @returns\n */\n getSession(): Promise<ClientSession> {\n return this.request('GET', '/v1/client/session')\n }\n\n /**\n * Submit the document front image (triggers OCR + portrait extraction).\n *\n * @param input\n * @returns\n */\n submitDocumentFront(input: DocumentFrontInput): Promise<ClientSession> {\n const form = new FormData()\n if (input.image) form.append('image', input.image, 'document-front.jpg')\n if (input.country) form.append('country', input.country)\n if (input.documentType) form.append('document_type', input.documentType)\n appendSignals(form, input.signals)\n return this.request('POST', '/v1/client/document/front', form)\n }\n\n /**\n * Submit the document back image.\n *\n * @param input\n * @returns\n */\n submitDocumentBack(input: DocumentBackInput): Promise<ClientSession> {\n const form = new FormData()\n if (input.image) form.append('image', input.image, 'document-back.jpg')\n if (input.country) form.append('country', input.country)\n if (input.documentType) form.append('document_type', input.documentType)\n return this.request('POST', '/v1/client/document/back', form)\n }\n\n /**\n * Submit the selfie for the liveness check.\n *\n * @param input\n * @returns\n */\n submitLiveness(input: LivenessInput): Promise<ClientSession> {\n const form = new FormData()\n if (input.selfie) form.append('selfie', input.selfie, 'selfie.jpg')\n if (input.video) form.append('video', input.video, 'liveness.webm')\n if (input.mode) form.append('mode', input.mode)\n if (input.challenges) form.append('challenges', JSON.stringify(input.challenges))\n appendSignals(form, input.signals)\n return this.request('POST', '/v1/client/liveness', form)\n }\n\n /**\n * Finalise the session (runs face-match + the decision engine).\n *\n * @param input\n * @returns\n */\n complete(input: CompleteInput = {}): Promise<ClientSession> {\n return this.request('POST', '/v1/client/complete', input.signals ?? {})\n }\n\n private async request(method: string, path: string, body?: FormData | object): Promise<ClientSession> {\n const headers: Record<string, string> = { 'X-Client-Token': this.token }\n let payload: BodyInit | undefined\n\n if (body instanceof FormData) {\n payload = body\n } else if (body) {\n headers['Content-Type'] = 'application/json'\n payload = JSON.stringify(body)\n }\n\n const res = await this.fetchImpl(`${this.baseUrl}${path}`, { method, headers, body: payload })\n const text = await res.text()\n const json = text ? (JSON.parse(text) as { message?: string; data?: ClientSession }) : {}\n\n if (!res.ok) {\n throw new WidgetApiError(json.message ?? `Request failed (${res.status})`, res.status)\n }\n return json.data as ClientSession\n }\n}\n","import type { ClientRealtime } from './client'\n\n/** Fires for every event received on a subscribed channel. */\nexport type WidgetRealtimeHandler = (event: string, data: unknown) => void\n\n/** A connected push transport. `subscribe` returns an unsubscribe function. */\nexport interface WidgetRealtimeClient {\n subscribe(channel: string, handler: WidgetRealtimeHandler): () => void\n disconnect(): void\n}\n\n/** A factory that builds a push client from the session's realtime config. */\nexport type WidgetRealtimeFactory = (\n config: ClientRealtime,\n options: WidgetRealtimeOptions,\n) => Promise<WidgetRealtimeClient | null>\n\nexport interface WidgetRealtimeOptions {\n /** The client-token channel-auth endpoint (pusher). */\n authEndpoint: string\n /** The session's client token (sent as `X-Client-Token` to the authorizer). */\n token: string\n}\n\n/** CDN that serves any npm package as ESM (`…/pkg@ver/+esm`). */\nconst CDN = 'https://cdn.jsdelivr.net/npm/'\n\n/**\n * Import an optional transport SDK. Tries the bare package specifier first (a\n * bundler, import map, or Node resolves it), then falls back to the jsdelivr CDN\n * so a plain browser embed still loads it — a bare specifier like `pusher-js`\n * isn't resolvable at runtime in the browser, which would otherwise leave the\n * widget silently polling. Non-literal specifiers also keep the bundler from\n * trying to resolve these (they aren't hard dependencies) and avoid needing their\n * type declarations.\n */\nasync function loadOptional(pkg: string, cdnPath: string): Promise<unknown> {\n try {\n return await import(/* @vite-ignore */ /* webpackIgnore: true */ pkg)\n } catch {\n return await import(/* @vite-ignore */ /* webpackIgnore: true */ `${CDN}${cdnPath}`)\n }\n}\n\n/**\n * Connect to whichever push transport the API reported for this session. Returns\n * null for `polling`/`off`/`memory` (no push — the widget polls instead) and also\n * when the transport SDK can't be loaded (e.g. a plain `<script>` standalone embed\n * with no bundler), so realtime degrades gracefully to polling. The SDK is\n * dynamically imported so only the active transport is ever pulled in.\n */\nexport async function createWidgetRealtimeClient(\n config: ClientRealtime,\n options: WidgetRealtimeOptions,\n): Promise<WidgetRealtimeClient | null> {\n try {\n if (config.transport === 'pusher') return await createPusherClient(config, options)\n if (config.transport === 'firebase') return await createFirebaseClient(config)\n } catch {\n // Transport SDK unavailable / failed to connect — fall back to polling.\n return null\n }\n\n return null\n}\n\n// --- pusher-js (minimal surface we depend on) ---\n\ninterface PusherChannel {\n bind_global(cb: (event: string, data: unknown) => void): void\n unbind_global(cb: (event: string, data: unknown) => void): void\n}\ninterface PusherInstance {\n subscribe(channel: string): PusherChannel\n unsubscribe(channel: string): void\n disconnect(): void\n}\ntype PusherCtor = new (key: string, options: Record<string, unknown>) => PusherInstance\n\nasync function createPusherClient(\n config: ClientRealtime,\n options: WidgetRealtimeOptions,\n): Promise<WidgetRealtimeClient> {\n const mod = (await loadOptional('pusher-js', 'pusher-js@8/+esm')) as { default: PusherCtor }\n const Pusher = mod.default\n const pusher = new Pusher(String(config.key ?? ''), {\n cluster: String(config.cluster ?? 'mt1'),\n forceTLS: Boolean(config.forceTLS ?? false),\n ...(config.wsHost\n ? {\n wsHost: String(config.wsHost),\n wsPort: Number(config.wsPort),\n wssPort: Number(config.wssPort ?? config.wsPort),\n enabledTransports: (config.enabledTransports as string[]) ?? ['ws', 'wss'],\n }\n : {}),\n // The widget authorizes private channels with its short-lived client token,\n // which the API scopes to this session's own channel only.\n channelAuthorization: {\n transport: 'ajax',\n endpoint: options.authEndpoint,\n headers: { 'X-Client-Token': options.token },\n },\n })\n\n return {\n subscribe(channel, handler) {\n const ch = pusher.subscribe(channel)\n const cb = (event: string, data: unknown) => handler(event, data)\n ch.bind_global(cb)\n\n return () => {\n ch.unbind_global(cb)\n pusher.unsubscribe(channel)\n }\n },\n disconnect() {\n pusher.disconnect()\n },\n }\n}\n\n// --- firebase (minimal surface we depend on) ---\n\ninterface FirebaseApp {\n name: string\n}\ninterface FirebaseAppModule {\n initializeApp(options: Record<string, unknown>, name: string): FirebaseApp\n getApps(): FirebaseApp[]\n getApp(name: string): FirebaseApp\n}\ninterface FirebaseAuthModule {\n getAuth(app: FirebaseApp): unknown\n signInWithCustomToken(auth: unknown, token: string): Promise<unknown>\n}\ninterface FirebaseSnapshot {\n val(): { event: string; payload: unknown } | null\n}\ninterface FirebaseDatabaseModule {\n getDatabase(app: FirebaseApp): unknown\n ref(db: unknown, path: string): unknown\n query(ref: unknown, ...constraints: unknown[]): unknown\n orderByChild(path: string): unknown\n startAt(value: number): unknown\n onChildAdded(query: unknown, cb: (snap: FirebaseSnapshot) => void): () => void\n}\n\nasync function createFirebaseClient(config: ClientRealtime): Promise<WidgetRealtimeClient> {\n const [app, auth, database] = (await Promise.all([\n loadOptional('firebase/app', 'firebase@11/app/+esm'),\n loadOptional('firebase/auth', 'firebase@11/auth/+esm'),\n loadOptional('firebase/database', 'firebase@11/database/+esm'),\n ])) as [FirebaseAppModule, FirebaseAuthModule, FirebaseDatabaseModule]\n\n const name = 'arkyc-widget-realtime'\n const fbApp = app.getApps().some((a) => a.name === name)\n ? app.getApp(name)\n : app.initializeApp(\n {\n apiKey: String(config.apiKey ?? ''),\n authDomain: String(config.authDomain ?? ''),\n projectId: String(config.projectId ?? ''),\n databaseURL: String(config.databaseURL ?? ''),\n },\n name,\n )\n\n // The per-session custom token authorizes reads of this session's channel only.\n if (config.token) await auth.signInWithCustomToken(auth.getAuth(fbApp), config.token)\n\n const db = database.getDatabase(fbApp)\n const since = Date.now()\n\n return {\n subscribe(channel, handler) {\n const q = database.query(\n database.ref(db, `realtime/${channel}`),\n database.orderByChild('at'),\n database.startAt(since),\n )\n const unsubscribe = database.onChildAdded(q, (snap) => {\n const value = snap.val()\n if (value) handler(value.event, value.payload)\n })\n\n return () => unsubscribe()\n },\n disconnect() {\n // Firebase listeners are torn down per-subscription via the returned unsub.\n },\n }\n}\n","import type { ProjectBranding } from '@arkyc/types'\nimport themeCss from 'virtual:arkyc-theme-css'\n\nconst LIGHT = {\n background: '#ffffff',\n foreground: '#0f172a',\n muted: '#64748b',\n border: '#e2e8f0',\n}\n\nconst DARK = {\n background: '#0f172a',\n foreground: '#f8fafc',\n muted: '#94a3b8',\n border: '#1e293b',\n}\n\n/**\n * Resolves project branding into a concrete theme and renders its CSS. One class\n * owns the whole \"theme\" concern: defaulted colour/logo/radius values plus the\n * CSS-variable block and stylesheet derived from them.\n */\nexport class Theme {\n readonly primaryColor: string\n readonly borderRadius: number\n readonly mode: 'light' | 'dark'\n readonly logoUrl: string | null\n /** Project/company display name shown in the header (when branding is shown). */\n readonly name: string | null\n /** Whether to show the project name/logo in the header (white-label off → false). */\n readonly showBranding: boolean\n /** Surface (card) background. */\n readonly background: string\n /** Primary text colour. */\n readonly foreground: string\n /** Muted text colour. */\n readonly muted: string\n /** Subtle border colour. */\n readonly border: string\n\n constructor(branding?: ProjectBranding | null) {\n this.mode = branding?.theme === 'dark' ? 'dark' : 'light'\n const palette = this.mode === 'dark' ? DARK : LIGHT\n this.primaryColor = branding?.primary_color ?? '#b8860b'\n this.borderRadius = branding?.border_radius ?? 12\n this.logoUrl = branding?.logo_url ?? null\n this.name = branding?.name ?? null\n this.showBranding = branding?.show_branding !== false\n this.background = palette.background\n this.foreground = palette.foreground\n this.muted = palette.muted\n this.border = palette.border\n }\n\n /**\n * The CSS-variable declaration block for this theme.\n *\n * @returns\n */\n variables(): string {\n return [\n `--arkyc-primary:${this.primaryColor}`,\n `--arkyc-radius:${this.borderRadius}px`,\n `--arkyc-bg:${this.background}`,\n `--arkyc-fg:${this.foreground}`,\n `--arkyc-muted:${this.muted}`,\n `--arkyc-border:${this.border}`,\n ].join(';')\n }\n\n /**\n * The widget stylesheet, parameterised by this theme's variables.\n *\n * @returns\n */\n stylesheet(): string {\n return themeCss.replace('/* {variables} */', `${this.variables()};`).trim()\n }\n}\n","/**\n * Camera capture, scoped to one class. DOM-injectable so the widget core stays\n * testable without a real browser. A live `getUserMedia` preview is used when\n * available; the view always offers a file input as a fallback. An instance\n * owns the active stream so callers don't track it themselves.\n */\n\n/** Which camera to request: `environment` for documents, `user` for selfies. */\nexport type Facing = 'environment' | 'user'\n\nexport class Camera {\n private stream: MediaStream | null = null\n\n constructor(\n private readonly doc: Document = globalThis.document,\n private readonly nav: Navigator = globalThis.navigator,\n ) {}\n\n /** Whether live camera capture is available in this environment. */\n get supported(): boolean {\n return !!this.nav?.mediaDevices?.getUserMedia\n }\n\n /**\n * Start a camera stream and bind it to a `<video>` element for preview.\n *\n * @param video\n * @param facing\n * @returns\n */\n async start(video: HTMLVideoElement, facing: Facing): Promise<MediaStream> {\n const stream = await this.nav.mediaDevices.getUserMedia({\n video: { facingMode: facing },\n audio: false,\n })\n this.stream = stream\n video.srcObject = stream\n video.setAttribute('playsinline', 'true')\n video.muted = true\n await video.play().catch(() => undefined)\n return stream\n }\n\n /**\n * Stop the active stream and release the camera.\n */\n stop(): void {\n this.stream?.getTracks().forEach((track) => track.stop())\n this.stream = null\n }\n\n /** Whether this environment can record video (active liveness). */\n get canRecord(): boolean {\n return typeof (globalThis as { MediaRecorder?: unknown }).MediaRecorder !== 'undefined'\n }\n\n /**\n * Start recording the active stream. Returns a handle whose `stop()` resolves\n * to the recorded `video/webm` blob — used by the active-liveness flow to record\n * the user performing the challenge sequence.\n *\n * @param stream\n * @returns\n */\n recordStart(stream: MediaStream): { stop(): Promise<Blob> } {\n const chunks: BlobPart[] = []\n const recorder = new MediaRecorder(stream, { mimeType: 'video/webm' })\n recorder.ondataavailable = (event) => {\n if (event.data && event.data.size > 0) chunks.push(event.data)\n }\n recorder.start()\n\n return {\n stop: () =>\n new Promise<Blob>((resolve) => {\n recorder.onstop = () => resolve(new Blob(chunks, { type: 'video/webm' }))\n recorder.stop()\n }),\n }\n }\n\n /**\n * Sample the current frame's average luminance for basic quality hints (too\n * dark / glare). A cheap proxy with no model — enough to guide the user and\n * gate auto-capture.\n *\n * @param video\n * @returns A 0–1 brightness plus `tooDark`/`glare` flags, or `null` if unreadable.\n */\n sampleQuality(video: HTMLVideoElement): { brightness: number; tooDark: boolean; glare: boolean } | null {\n const canvas = this.doc.createElement('canvas')\n // Downscale heavily — we only need an average, not detail.\n canvas.width = 32\n canvas.height = 32\n const ctx = canvas.getContext('2d')\n if (!ctx || !video.videoWidth) return null\n ctx.drawImage(video, 0, 0, canvas.width, canvas.height)\n\n const { data } = ctx.getImageData(0, 0, canvas.width, canvas.height)\n let sum = 0\n let bright = 0\n const pixels = data.length / 4\n for (let i = 0; i < data.length; i += 4) {\n const lum = (0.299 * data[i]! + 0.587 * data[i + 1]! + 0.114 * data[i + 2]!) / 255\n sum += lum\n if (lum > 0.92) bright += 1\n }\n const brightness = sum / pixels\n return { brightness, tooDark: brightness < 0.25, glare: bright / pixels > 0.15 }\n }\n\n /**\n * Grab the current video frame as a JPEG `Blob` via an offscreen canvas.\n *\n * @param video\n * @param quality\n * @returns\n */\n grabFrame(video: HTMLVideoElement, quality = 0.92): Promise<Blob> {\n const canvas = this.doc.createElement('canvas')\n canvas.width = video.videoWidth || 1280\n canvas.height = video.videoHeight || 720\n const ctx = canvas.getContext('2d')\n if (!ctx) return Promise.reject(new Error('Canvas 2D context unavailable.'))\n ctx.drawImage(video, 0, 0, canvas.width, canvas.height)\n\n return new Promise<Blob>((resolve, reject) => {\n canvas.toBlob(\n (blob) => (blob ? resolve(blob) : reject(new Error('Failed to capture frame.'))),\n 'image/jpeg',\n quality,\n )\n })\n }\n\n /**\n * Read a selected file from an `<input type=\"file\">` as a `Blob`.\n *\n * @param input\n * @returns\n */\n static fileFromInput(input: HTMLInputElement): Blob | null {\n return input.files?.[0] ?? null\n }\n}\n","//#region src/realtime.ts\n/**\n* Realtime transport contracts (Phase 16). Pure, dependency-free helpers shared\n* by the API (server publish) and the dashboard/widget (client subscribe), so\n* channel and event names never drift between them.\n*/\n/** Events the API broadcasts. Clients react by invalidating their caches. */\nconst REALTIME_EVENT = {\n\t/** A verification session changed status (the `transitionTo` choke point). */\n\tsessionTransition: \"session.transition\",\n\t/** A reviewer acted on a session (assign/note/suspicious/decision/retry). */\n\treviewAction: \"review.action\"\n};\n/**\n* Private channel name builders. All channels are `private-` (Pusher protocol),\n* so a subscription must be authorized server-side against the caller's scope.\n*/\nconst realtimeChannels = {\n\t/** Everything in an organization. */\n\torganization: (organizationId) => `private-organization-${organizationId}`,\n\t/** Everything in a project. */\n\tproject: (organizationId, projectId) => `private-organization-${organizationId}-project-${projectId}`,\n\t/** A single verification session (used by the widget via client token). */\n\tsession: (sessionId) => `private-session-${sessionId}`\n};\n/** Parse a private channel name back into its scope, or null if unrecognized. */\nfunction parseRealtimeChannel(channel) {\n\tconst project = /^private-organization-(.+)-project-(.+)$/.exec(channel);\n\tif (project) return {\n\t\tkind: \"project\",\n\t\torganizationId: project[1],\n\t\tprojectId: project[2]\n\t};\n\tconst organization = /^private-organization-(.+)$/.exec(channel);\n\tif (organization) return {\n\t\tkind: \"organization\",\n\t\torganizationId: organization[1]\n\t};\n\tconst session = /^private-session-(.+)$/.exec(channel);\n\tif (session) return {\n\t\tkind: \"session\",\n\t\tsessionId: session[1]\n\t};\n\treturn null;\n}\n//#endregion\nexport { REALTIME_EVENT, parseRealtimeChannel, realtimeChannels };\n\n//# sourceMappingURL=realtime.mjs.map","//#region src/workflow.ts\n/** The canonical stage order used as the default and to normalise stored steps. */\nconst WORKFLOW_STEP_KEYS = [\n\t\"document\",\n\t\"liveness\",\n\t\"face_match\"\n];\n/** The default pipeline applied when a session has no workflow. */\nconst DEFAULT_WORKFLOW_CONFIG = {\n\tsteps: [\n\t\t{\n\t\t\tkey: \"document\",\n\t\t\tenabled: true\n\t\t},\n\t\t{\n\t\t\tkey: \"liveness\",\n\t\t\tenabled: true\n\t\t},\n\t\t{\n\t\t\tkey: \"face_match\",\n\t\t\tenabled: true\n\t\t}\n\t],\n\toptions: { skip_ocr: false }\n};\n/**\n* Whether a stage runs under a config. A `null` config means \"no workflow\" — the\n* default pipeline, where every stage runs. Within a real config, a stage that is\n* absent or `enabled: false` does not run.\n*/\nfunction workflowEnables(config, key) {\n\tif (!config) return true;\n\treturn config.steps.some((step) => step.key === key && step.enabled);\n}\n/** Whether OCR parsing should run: the document stage is on and `skip_ocr` is off. */\nfunction workflowRunsOcr(config) {\n\tif (!config) return true;\n\treturn workflowEnables(config, \"document\") && !config.options.skip_ocr;\n}\n/** The enabled stages in pipeline order (used by the widget to sequence its steps). */\nfunction workflowEnabledSteps(config) {\n\tif (!config) return [...WORKFLOW_STEP_KEYS];\n\treturn config.steps.filter((step) => step.enabled).map((step) => step.key);\n}\n//#endregion\nexport { DEFAULT_WORKFLOW_CONFIG, WORKFLOW_STEP_KEYS, workflowEnabledSteps, workflowEnables, workflowRunsOcr };\n\n//# sourceMappingURL=workflow.mjs.map","import {\n type DocumentType,\n type LivenessMode,\n type VerificationDecision,\n type VerificationStatus,\n type WidgetStep,\n type WorkflowConfig,\n type WorkflowStepKey,\n workflowEnabledSteps,\n workflowRunsOcr,\n} from '@arkyc/types'\n\n/** Context that influences flow branching. */\nexport interface FlowContext {\n documentType?: DocumentType | null\n /** Which liveness flow this session runs (resolved from the capture model). */\n livenessMode?: LivenessMode\n /** The applied workflow (orders/toggles the coarse stages), or null for the default flow. */\n workflow?: WorkflowConfig | null\n}\n\n/** The widget screens that make up each coarse verification stage, in stage-local order. */\nconst STAGE_STEPS: Record<WorkflowStepKey, WidgetStep[]> = {\n document: ['document_selection', 'front_capture', 'back_capture', 'ocr_processing'],\n liveness: ['active_liveness', 'selfie_capture', 'passive_liveness'],\n face_match: ['face_match'],\n}\n\n/**\n * The verification flow's step machine. Stateless — exposed as static members so\n * the single \"flow\" concern lives in one class rather than as floating helpers.\n */\nexport class Flow {\n /**\n * The flow screens, in the order the widget walks them. The `back_capture`\n * screen is skipped for single-sided documents (passports).\n */\n static readonly STEP_ORDER: WidgetStep[] = [\n 'welcome',\n 'document_selection',\n 'front_capture',\n 'back_capture',\n 'ocr_processing',\n 'active_liveness',\n 'selfie_capture',\n 'passive_liveness',\n 'face_match',\n 'processing',\n 'result',\n ]\n\n /**\n * Statuses from which a session can no longer progress.\n */\n static readonly TERMINAL_STATUSES: VerificationStatus[] = [\n 'approved',\n 'rejected',\n 'requires_review',\n 'expired',\n 'cancelled',\n ]\n\n /**\n * Whether a document type has a second (back) side to capture.\n *\n * @param type\n * @returns\n */\n static documentHasBack(type: DocumentType | null | undefined): boolean {\n return type != null && type !== 'passport'\n }\n\n /**\n * The screens to walk for this session, in order. With no workflow this is the\n * default {@link STEP_ORDER}; a workflow reorders the coarse stages and drops\n * disabled ones (their screens are excluded entirely), always bracketed by\n * `welcome` and `processing`/`result`.\n */\n static stepOrder(ctx: FlowContext = {}): WidgetStep[] {\n const stages = workflowEnabledSteps(ctx.workflow) as WorkflowStepKey[]\n const middle = stages.flatMap((stage) => STAGE_STEPS[stage])\n\n return ['welcome', ...middle, 'processing', 'result']\n }\n\n /**\n * Whether a step runs for the given context. `back_capture` is skipped for\n * single-sided documents; `ocr_processing` is skipped when the workflow skips\n * OCR; the liveness steps branch on the resolved mode — `active_liveness` only\n * in active mode, `selfie_capture`/`passive_liveness` only in passive mode.\n * Stage-level disabling is handled by {@link stepOrder} (disabled stages are\n * absent from the order), so this only covers within-stage branching.\n */\n static isStepEnabled(step: WidgetStep, ctx: FlowContext = {}): boolean {\n if (step === 'back_capture') return Flow.documentHasBack(ctx.documentType)\n if (step === 'ocr_processing') return workflowRunsOcr(ctx.workflow)\n if (step === 'active_liveness') return ctx.livenessMode === 'active'\n if (step === 'selfie_capture' || step === 'passive_liveness') {\n return ctx.livenessMode !== 'active'\n }\n return true\n }\n\n /**\n * The next enabled screen after `current`, honouring the workflow order and the\n * branch rules. Returns `current` when already at the end.\n *\n * @param current\n * @param ctx\n * @returns\n */\n static nextStep(current: WidgetStep, ctx: FlowContext = {}): WidgetStep {\n const order = Flow.stepOrder(ctx)\n const idx = order.indexOf(current)\n if (idx < 0) return current\n for (let i = idx + 1; i < order.length; i += 1) {\n const step = order[i]!\n if (Flow.isStepEnabled(step, ctx)) return step\n }\n return current\n }\n\n /**\n * Whether a session status is terminal (the flow is done).\n *\n * @param status\n * @returns\n */\n static isTerminal(status: VerificationStatus): boolean {\n return Flow.TERMINAL_STATUSES.includes(status)\n }\n\n /**\n * Map a terminal session status to the decision the integrator cares about.\n * Non-decision terminals (`expired`/`cancelled`) and in-flight statuses map to\n * `null`.\n */\n static statusToDecision(status: VerificationStatus): VerificationDecision | null {\n switch (status) {\n case 'approved':\n return 'approved'\n case 'rejected':\n return 'rejected'\n case 'requires_review':\n return 'requires_review'\n default:\n return null\n }\n }\n}\n","/**\n * In-browser face analysis for selfie auto-capture and active-liveness detection.\n *\n * The real implementation loads MediaPipe's FaceLandmarker (landmarks +\n * blendshapes) lazily from a CDN at runtime — it is NOT bundled, and never\n * touched unless a live camera screen actually asks for it. Everything is\n * feature-detected and wrapped so that on any failure (no WebGL/WASM, offline,\n * a non-browser/test host) `ready()` resolves `false` and callers fall back to\n * the manual flow. The widget's pure, fake-DOM tests therefore never load it.\n */\nimport type { LivenessChallenge } from '@arkyc/types'\n\n/** A normalized read of the current frame's face. */\nexport interface FaceSample {\n present: boolean\n /** Face bounding-box centre, normalized 0–1. */\n centerX: number\n centerY: number\n /** Face bounding-box height, normalized 0–1 (proxy for distance). */\n scale: number\n /** Head turn: <0 toward one side, >0 the other (approx, from landmark asymmetry). */\n turn: number\n /** Head pitch proxy: nose-to-eye offset over face height (relative changes matter). */\n pitch: number\n /** Eyes-closed score 0–1 (blendshape). */\n blink: number\n /** Smile score 0–1 (blendshape). */\n smile: number\n}\n\nexport interface FaceAnalyzer {\n /** Load models. Resolves `false` if unavailable — callers then go manual. */\n ready(): Promise<boolean>\n /** Analyze the current video frame, or `null` if it can't be read. */\n analyze(video: HTMLVideoElement): FaceSample | null\n /** Release resources. */\n close(): void\n}\n\n// CDN asset locations. Built at runtime (not string literals) so bundlers leave\n// the dynamic import live instead of trying to resolve/inline it.\nconst TASKS_VERSION = '0.10.20'\nconst npm = (path: string) => 'https://cdn.jsdelivr.net/npm/' + path\nconst MODEL_URL =\n 'https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task'\n\n// MediaPipe FaceMesh canonical landmark indices.\nconst NOSE = 1\nconst LEFT_EYE = 33\nconst RIGHT_EYE = 263\nconst LEFT_EDGE = 234\nconst RIGHT_EDGE = 454\nconst CHIN = 152\n\ninterface Pt {\n x: number\n y: number\n}\ninterface LmResult {\n faceLandmarks: Pt[][]\n faceBlendshapes?: { categories: { categoryName: string; score: number }[] }[]\n}\n\nfunction blend(cats: { categoryName: string; score: number }[] | undefined, name: string): number {\n return cats?.find((c) => c.categoryName === name)?.score ?? 0\n}\n\nfunction now(): number {\n const p = (globalThis as { performance?: { now?: () => number } }).performance\n return p?.now ? p.now() : 0\n}\n\nclass MediapipeFaceAnalyzer implements FaceAnalyzer {\n private landmarker: { detectForVideo(v: HTMLVideoElement, t: number): LmResult; close(): void } | null = null\n private state: 'idle' | 'loading' | 'ready' | 'failed' = 'idle'\n private loading: Promise<boolean> | null = null\n\n async ready(): Promise<boolean> {\n if (this.state === 'ready') return true\n if (this.state === 'failed') return false\n if (this.loading) return this.loading\n this.loading = this.load()\n return this.loading\n }\n\n private async load(): Promise<boolean> {\n this.state = 'loading'\n try {\n if (typeof document === 'undefined') throw new Error('no document')\n // Bail early if WebGL2 isn't available — MediaPipe needs it.\n const probe = document.createElement('canvas')\n if (!probe.getContext('webgl2')) throw new Error('no webgl2')\n\n const visionUrl = npm(`@mediapipe/tasks-vision@${TASKS_VERSION}/vision_bundle.mjs`)\n const vision = (await import(/* @vite-ignore */ visionUrl)) as {\n FilesetResolver: { forVisionTasks(url: string): Promise<unknown> }\n FaceLandmarker: { createFromOptions(fileset: unknown, opts: unknown): Promise<unknown> }\n }\n const fileset = await vision.FilesetResolver.forVisionTasks(npm(`@mediapipe/tasks-vision@${TASKS_VERSION}/wasm`))\n this.landmarker = (await vision.FaceLandmarker.createFromOptions(fileset, {\n baseOptions: { modelAssetPath: MODEL_URL, delegate: 'GPU' },\n outputFaceBlendshapes: true,\n runningMode: 'VIDEO',\n numFaces: 1,\n })) as MediapipeFaceAnalyzer['landmarker']\n this.state = 'ready'\n return true\n } catch {\n this.state = 'failed'\n return false\n }\n }\n\n analyze(video: HTMLVideoElement): FaceSample | null {\n if (this.state !== 'ready' || !this.landmarker || !video.videoWidth) return null\n let res: LmResult\n try {\n res = this.landmarker.detectForVideo(video, now())\n } catch {\n return null\n }\n const lm = res.faceLandmarks?.[0]\n if (!lm || lm.length === 0) {\n return { present: false, centerX: 0.5, centerY: 0.5, scale: 0, turn: 0, pitch: 0, blink: 0, smile: 0 }\n }\n\n let minX = 1\n let maxX = 0\n let minY = 1\n let maxY = 0\n for (const p of lm) {\n if (p.x < minX) minX = p.x\n if (p.x > maxX) maxX = p.x\n if (p.y < minY) minY = p.y\n if (p.y > maxY) maxY = p.y\n }\n const height = Math.max(1e-3, maxY - minY)\n\n const nose = lm[NOSE]!\n const leftEye = lm[LEFT_EYE]!\n const rightEye = lm[RIGHT_EYE]!\n const leftEdge = lm[LEFT_EDGE]!\n const rightEdge = lm[RIGHT_EDGE]!\n const chin = lm[CHIN]!\n\n // Turn: horizontal asymmetry of the nose between the two face edges. Signed\n // (empirically, against a real front camera) so that turning the head right\n // yields turn>0 and left yields turn<0 — matching the turn_left/turn_right\n // prompts. Computed on the raw frame; the preview's CSS mirror is cosmetic.\n const dLeft = nose.x - leftEdge.x\n const dRight = rightEdge.x - nose.x\n const turn = (dRight - dLeft) / Math.max(1e-3, dLeft + dRight)\n\n // Pitch proxy: nose vertical position between the eye line and the chin.\n const eyeY = (leftEye.y + rightEye.y) / 2\n const pitch = (nose.y - eyeY) / Math.max(1e-3, chin.y - eyeY)\n\n const cats = res.faceBlendshapes?.[0]?.categories\n const blink = Math.max(blend(cats, 'eyeBlinkLeft'), blend(cats, 'eyeBlinkRight'))\n const smile = (blend(cats, 'mouthSmileLeft') + blend(cats, 'mouthSmileRight')) / 2\n\n return {\n present: true,\n centerX: (minX + maxX) / 2,\n centerY: (minY + maxY) / 2,\n scale: height,\n turn,\n pitch,\n blink,\n smile,\n }\n }\n\n close(): void {\n try {\n this.landmarker?.close()\n } catch {\n /* ignore */\n }\n this.landmarker = null\n this.state = 'failed'\n }\n}\n\n/** The default (real, MediaPipe-backed) analyzer. */\nexport function createDefaultFaceAnalyzer(): FaceAnalyzer {\n return new MediapipeFaceAnalyzer()\n}\n\n/** A challenge detector: fed frame samples, returns `true` once satisfied. */\nexport interface ChallengeDetector {\n feed(sample: FaceSample): boolean\n /**\n * 0–1 progress toward satisfying the challenge, updated on each `feed` — drives\n * the UI's hold-progress ring. Multi-stage gestures (blink/nod) step through\n * intermediate values; sustained gestures ramp with the hold streak.\n */\n readonly progress: number\n}\n\n/**\n * Detection thresholds. These are the knobs to tune against a real camera —\n * use the calibration harness (`playground/calibration.html`) to read live\n * signal values and adjust. All are overridable per-widget via `faceTuning`.\n */\nexport interface FaceTuning {\n /** |turn| asymmetry needed to count as a head turn. */\n turn: number\n /** Mouth-smile blendshape score needed to count as a smile. */\n smile: number\n /** Eye-blink score above which the eyes count as closed. */\n blinkClosed: number\n /** Eye-blink score below which they count as re-opened. */\n blinkOpen: number\n /** Consecutive frames a condition must hold before it fires. */\n hold: number\n /** Pitch increase (looking down) needed to arm a nod. */\n nodDown: number\n /** Pitch return delta (back up) that completes a nod. */\n nodReturn: number\n /** Face must grow past `baseline * closerFactor` for move-closer. */\n closerFactor: number\n /** Selfie framing tolerances (distance from frame centre / size window). */\n selfieCenterTol: number\n selfieCenterYTol: number\n selfieMinScale: number\n selfieMaxScale: number\n}\n\nexport const DEFAULT_TUNING: FaceTuning = {\n turn: 0.18,\n smile: 0.5,\n blinkClosed: 0.55,\n blinkOpen: 0.25,\n hold: 3,\n nodDown: 0.06,\n nodReturn: 0.02,\n closerFactor: 1.22,\n selfieCenterTol: 0.2,\n selfieCenterYTol: 0.25,\n selfieMinScale: 0.28,\n selfieMaxScale: 0.85,\n}\n\n/**\n * Build a stateful detector for a single active-liveness challenge.\n *\n * @param challenge\n * @param t\n * @returns\n */\nexport function makeChallengeDetector(challenge: LivenessChallenge, t: FaceTuning = DEFAULT_TUNING): ChallengeDetector {\n // A sustained gesture: a condition that must hold for `t.hold` frames. Progress\n // ramps with the streak.\n const sustained = (ok: (s: FaceSample) => boolean): ChallengeDetector => {\n let n = 0\n return {\n feed(s) {\n n = s.present && ok(s) ? n + 1 : 0\n return n >= t.hold\n },\n get progress() {\n return Math.min(1, n / Math.max(1, t.hold))\n },\n }\n }\n\n // A two-stage gesture: reach an extreme, then return. Progress is 0 → ~0.6 (mid)\n // → 1 (done).\n const twoStage = (\n pick: (s: FaceSample) => number,\n extreme: (v: number, base: number) => boolean,\n settled: (v: number, base: number) => boolean,\n ): ChallengeDetector => {\n let base: number | null = null\n let reached = false\n let done = false\n return {\n feed(s) {\n if (!s.present) return false\n const v = pick(s)\n if (base === null) {\n base = v\n return false\n }\n if (extreme(v, base)) reached = true\n else if (reached && settled(v, base)) {\n done = true\n return true\n }\n return false\n },\n get progress() {\n return done ? 1 : reached ? 0.6 : 0\n },\n }\n }\n\n switch (challenge) {\n case 'blink': {\n // No baseline: eyes must close (absolute) then re-open. Processed from the\n // first frame, unlike the baseline-relative two-stage gestures.\n let closed = false\n let done = false\n return {\n feed(s) {\n if (!s.present) return false\n if (s.blink > t.blinkClosed) closed = true\n else if (closed && s.blink < t.blinkOpen) {\n done = true\n return true\n }\n return false\n },\n get progress() {\n return done ? 1 : closed ? 0.6 : 0\n },\n }\n }\n case 'smile':\n return sustained((s) => s.smile > t.smile)\n case 'turn_left':\n return sustained((s) => s.turn < -t.turn)\n case 'turn_right':\n return sustained((s) => s.turn > t.turn)\n case 'nod':\n return twoStage(\n (s) => s.pitch,\n (v, base) => v > base + t.nodDown,\n (v, base) => v < base + t.nodReturn,\n )\n case 'move_closer': {\n let base: number | null = null\n let n = 0\n return {\n feed(s) {\n if (!s.present) return false\n if (base === null) {\n base = s.scale\n return false\n }\n n = s.scale > base * t.closerFactor ? n + 1 : 0\n return n >= t.hold\n },\n get progress() {\n return Math.min(1, n / Math.max(1, t.hold))\n },\n }\n }\n }\n}\n\n/** Whether a face is well-framed for a selfie (present, centred, right distance). */\nexport function isSelfieReady(s: FaceSample, t: FaceTuning = DEFAULT_TUNING): boolean {\n return (\n s.present &&\n Math.abs(s.centerX - 0.5) < t.selfieCenterTol &&\n Math.abs(s.centerY - 0.5) < t.selfieCenterYTol &&\n s.scale > t.selfieMinScale &&\n s.scale < t.selfieMaxScale\n )\n}\n","/**\n * In-browser document detection for the capture screens. Pure JavaScript, no\n * dependency: it draws the current frame to a small canvas and runs Sobel edge\n * projection to locate the document's four borders, then judges whether a real,\n * well-framed, in-focus document is present before auto-capturing.\n *\n * Like the face analyzer it is feature-detected and wrapped so that on any\n * failure (no 2D canvas, a non-browser/test host) `ready()` resolves `false` and\n * the caller falls back to the simpler brightness heuristic. The detection core\n * (`analyzeDocumentGray` / `documentGuidance`) is a set of pure functions over a\n * grayscale buffer, so it is unit-testable without a real canvas or camera.\n */\n\n/** Detected document rectangle, normalized 0–1 within the frame. */\nexport interface DocRect {\n x: number\n y: number\n w: number\n h: number\n}\n\n/**\n * A normalized read of the current frame's document candidate.\n */\nexport interface DocumentSample {\n /** A plausible rectangular document border was found. */\n present: boolean\n /** The detected border rectangle (normalized 0–1). */\n rect: DocRect\n /** Rectangle area as a fraction of the frame (proxy for distance). */\n fill: number\n centerX: number\n centerY: number\n /** Weakest of the four border edges, 0–1 (how convincingly bordered it is). */\n edgeStrength: number\n /** Variance of the Laplacian over the frame — a focus/blur proxy (higher = sharper). */\n sharpness: number\n /** Mean luminance, 0–1. */\n brightness: number\n}\n\nexport interface DocumentAnalyzer {\n /** Prepare the canvas. Resolves `false` if unavailable — callers go manual. */\n ready(): Promise<boolean>\n /** Analyze the current video frame, or `null` if it can't be read. */\n analyze(video: HTMLVideoElement): DocumentSample | null\n /** Release resources. */\n close(): void\n}\n\n/**\n * Detection thresholds. Tunable per-widget via `documentTuning`. Like the face\n * tuning, the geometric/strength knobs benefit from calibration against real\n * devices and lighting.\n */\nexport interface DocumentTuning {\n /** Width (px) the frame is downscaled to before analysis. */\n sampleWidth: number\n /** Min / max rectangle area (fraction of frame) — too small = far, too big = cropped. */\n minFill: number\n maxFill: number\n /** Max distance of the document centre from the frame centre (0–1). */\n centerTol: number\n /** Min weakest-border strength to count as a real document edge (0–1). */\n minEdgeStrength: number\n /** Min Laplacian variance to count as in-focus. */\n minSharpness: number\n /** Each border must sit at least this far (0–1) inside the frame (not cropped). */\n borderMargin: number\n /** Below this mean luminance the frame is treated as too dark. */\n minBrightness: number\n /** Consecutive \"ready\" frames before auto-capture fires. */\n hold: number\n}\n\nexport const DEFAULT_DOCUMENT_TUNING: DocumentTuning = {\n sampleWidth: 320,\n // Edge-projection underestimates the document rectangle when the strongest\n // borders sit inside the card, so a demanding minFill reads as a constant\n // \"move closer\". Keep it modest; framing is still gated by maxFill + margins.\n minFill: 0.18,\n maxFill: 0.97,\n centerTol: 0.22,\n minEdgeStrength: 0.1,\n minSharpness: 8,\n borderMargin: 0.012,\n minBrightness: 0.18,\n hold: 5,\n}\n\n/**\n * The four border insets of a rect from the frame edges (top, right, bottom, left).\n *\n * @param rect\n * @returns\n */\nfunction margins(rect: DocRect): [number, number, number, number] {\n return [rect.y, 1 - (rect.x + rect.w), 1 - (rect.y + rect.h), rect.x]\n}\n\nfunction peak(arr: Float64Array, lo: number, hi: number): { i: number; v: number } {\n let bi = lo\n let bv = -1\n for (let i = lo; i < hi; i += 1) {\n const v = arr[i]!\n if (v > bv) {\n bv = v\n bi = i\n }\n }\n return { i: bi, v: bv }\n}\n\n/**\n * Locate the dominant rectangle in a grayscale frame via Sobel edge projection,\n * and measure focus and brightness. Pure — operates on a grayscale buffer.\n *\n * @param tuning\n * @returns\n */\nexport function analyzeDocumentGray(gray: ArrayLike<number>, w: number, h: number): DocumentSample {\n const empty: DocumentSample = {\n present: false,\n rect: { x: 0, y: 0, w: 0, h: 0 },\n fill: 0,\n centerX: 0.5,\n centerY: 0.5,\n edgeStrength: 0,\n sharpness: 0,\n brightness: 0,\n }\n if (w < 8 || h < 8 || gray.length < w * h) return empty\n\n // Per-row horizontal-edge energy (|gy|) and per-column vertical-edge energy (|gx|).\n const rowH = new Float64Array(h)\n const colV = new Float64Array(w)\n let lapSum = 0\n let lapSumSq = 0\n let lapN = 0\n let lumSum = 0\n for (let i = 0; i < w * h; i += 1) lumSum += gray[i]!\n const brightness = lumSum / (w * h * 255)\n\n for (let y = 1; y < h - 1; y += 1) {\n for (let x = 1; x < w - 1; x += 1) {\n const i = y * w + x\n const tl = gray[i - w - 1]!\n const tc = gray[i - w]!\n const tr = gray[i - w + 1]!\n const ml = gray[i - 1]!\n const c = gray[i]!\n const mr = gray[i + 1]!\n const bl = gray[i + w - 1]!\n const bc = gray[i + w]!\n const br = gray[i + w + 1]!\n const gx = tr + 2 * mr + br - (tl + 2 * ml + bl)\n const gy = bl + 2 * bc + br - (tl + 2 * tc + tr)\n rowH[y]! += Math.abs(gy)\n colV[x]! += Math.abs(gx)\n const lap = 4 * c - ml - mr - tc - bc\n lapSum += lap\n lapSumSq += lap * lap\n lapN += 1\n }\n }\n const sharpness = lapN ? lapSumSq / lapN - (lapSum / lapN) ** 2 : 0\n\n const bandH = Math.max(1, Math.floor(h * 0.05))\n const bandW = Math.max(1, Math.floor(w * 0.05))\n const midY = Math.floor(h / 2)\n const midX = Math.floor(w / 2)\n\n // Top/bottom borders are the strongest horizontal edges in the upper/lower half;\n // left/right borders the strongest vertical edges in the left/right half.\n const top = peak(rowH, bandH, midY)\n const bottom = peak(rowH, midY, h - bandH)\n const left = peak(colV, bandW, midX)\n const right = peak(colV, midX, w - bandW)\n\n const x0 = left.i / w\n const x1 = right.i / w\n const y0 = top.i / h\n const y1 = bottom.i / h\n const rect: DocRect = { x: x0, y: y0, w: Math.max(0, x1 - x0), h: Math.max(0, y1 - y0) }\n\n // Normalize each border by its own length (max |sobel| ≈ 4·255), so strength\n // measures how cleanly bordered the edge is, independent of document size —\n // size is judged separately by `fill`.\n const topLenPx = Math.max(1, rect.w * w)\n const sideLenPx = Math.max(1, rect.h * h)\n const edgeStrength = Math.min(\n top.v / (topLenPx * 1020),\n bottom.v / (topLenPx * 1020),\n left.v / (sideLenPx * 1020),\n right.v / (sideLenPx * 1020),\n )\n const present = rect.w > 0.12 && rect.h > 0.12 && edgeStrength > 0.04\n\n return {\n present,\n rect,\n fill: rect.w * rect.h,\n centerX: (x0 + x1) / 2,\n centerY: (y0 + y1) / 2,\n edgeStrength,\n sharpness,\n brightness,\n }\n}\n\n/**\n * Whether a document is present, well-framed and in focus, with a guidance hint.\n *\n * @param tuning\n * @returns\n */\nexport function documentGuidance(\n s: DocumentSample,\n t: DocumentTuning = DEFAULT_DOCUMENT_TUNING,\n): { ready: boolean; hint: string } {\n if (s.brightness < t.minBrightness) return { ready: false, hint: 'Too dark — find better lighting' }\n if (!s.present || s.edgeStrength < t.minEdgeStrength) {\n return { ready: false, hint: 'Fit your document inside the frame' }\n }\n if (s.fill > t.maxFill || Math.min(...margins(s.rect)) < t.borderMargin) {\n return { ready: false, hint: 'Move back a little — fit the whole document' }\n }\n if (s.fill < t.minFill) return { ready: false, hint: 'Move closer' }\n if (Math.abs(s.centerX - 0.5) > t.centerTol || Math.abs(s.centerY - 0.5) > t.centerTol) {\n return { ready: false, hint: 'Center the document' }\n }\n if (s.sharpness < t.minSharpness) return { ready: false, hint: 'Hold steady to focus' }\n return { ready: true, hint: 'Looks good — hold steady' }\n}\n\n/**\n * Whether the sample is a well-framed, in-focus document ready to capture.\n *\n * @param s\n * @param t\n * @returns\n */\nexport function isDocumentReady(s: DocumentSample, t: DocumentTuning = DEFAULT_DOCUMENT_TUNING): boolean {\n return documentGuidance(s, t).ready\n}\n\nclass CanvasDocumentAnalyzer implements DocumentAnalyzer {\n private canvas: HTMLCanvasElement | null = null\n private ctx: CanvasRenderingContext2D | null = null\n\n constructor(private readonly tuning: DocumentTuning) {}\n\n ready(): Promise<boolean> {\n try {\n if (typeof document === 'undefined') return Promise.resolve(false)\n const canvas = document.createElement('canvas')\n const ctx = canvas.getContext('2d', { willReadFrequently: true })\n if (!ctx) return Promise.resolve(false)\n this.canvas = canvas\n this.ctx = ctx\n return Promise.resolve(true)\n } catch {\n return Promise.resolve(false)\n }\n }\n\n analyze(video: HTMLVideoElement): DocumentSample | null {\n if (!this.ctx || !this.canvas || !video.videoWidth) return null\n const tw = this.tuning.sampleWidth\n const th = Math.max(1, Math.round((tw * video.videoHeight) / video.videoWidth))\n this.canvas.width = tw\n this.canvas.height = th\n let data: Uint8ClampedArray\n try {\n this.ctx.drawImage(video, 0, 0, tw, th)\n data = this.ctx.getImageData(0, 0, tw, th).data\n } catch {\n return null\n }\n const gray = new Float32Array(tw * th)\n for (let i = 0, p = 0; i < gray.length; i += 1, p += 4) {\n gray[i] = 0.299 * data[p]! + 0.587 * data[p + 1]! + 0.114 * data[p + 2]!\n }\n return analyzeDocumentGray(gray, tw, th)\n }\n\n close(): void {\n this.canvas = null\n this.ctx = null\n }\n}\n\n/**\n * The default (canvas edge-projection) document analyzer.\n *\n * @param tuning\n * @returns\n */\nexport function createDefaultDocumentAnalyzer(tuning: DocumentTuning = DEFAULT_DOCUMENT_TUNING): DocumentAnalyzer {\n return new CanvasDocumentAnalyzer(tuning)\n}\n","export const countries = [\n {\n name: 'United States',\n iso2: 'US',\n flag: '🇺🇸',\n },\n {\n name: 'Canada',\n iso2: 'CA',\n flag: '🇨🇦',\n },\n {\n name: 'Brazil',\n iso2: 'BR',\n flag: '🇧🇷',\n },\n {\n name: 'United Kingdom',\n iso2: 'GB',\n flag: '🇬🇧',\n },\n {\n name: 'Germany',\n iso2: 'DE',\n flag: '🇩🇪',\n },\n {\n name: 'France',\n iso2: 'FR',\n flag: '🇫🇷',\n },\n {\n name: 'China',\n iso2: 'CN',\n flag: '🇨🇳',\n },\n {\n name: 'Japan',\n iso2: 'JP',\n flag: '🇯🇵',\n },\n {\n name: 'India',\n iso2: 'IN',\n flag: '🇮🇳',\n },\n {\n name: 'Australia',\n iso2: 'AU',\n flag: '🇦🇺',\n },\n {\n name: 'South Africa',\n iso2: 'ZA',\n flag: '🇿🇦',\n },\n {\n name: 'Russia',\n iso2: 'RU',\n flag: '🇷🇺',\n },\n {\n name: 'Saudi Arabia',\n iso2: 'SA',\n flag: '🇸🇦',\n },\n {\n name: 'Afghanistan',\n iso2: 'AF',\n flag: '🇦🇫',\n },\n {\n name: 'Albania',\n iso2: 'AL',\n flag: '🇦🇱',\n },\n {\n name: 'Algeria',\n iso2: 'DZ',\n flag: '🇩🇿',\n },\n {\n name: 'Andorra',\n iso2: 'AD',\n flag: '🇦🇩',\n },\n {\n name: 'Angola',\n iso2: 'AO',\n flag: '🇦🇴',\n },\n {\n name: 'Antigua and Barbuda',\n iso2: 'AG',\n flag: '🇦🇬',\n },\n {\n name: 'Argentina',\n iso2: 'AR',\n flag: '🇦🇷',\n },\n {\n name: 'Armenia',\n iso2: 'AM',\n flag: '🇦🇲',\n },\n {\n name: 'Austria',\n iso2: 'AT',\n flag: '🇦🇹',\n },\n {\n name: 'Azerbaijan',\n iso2: 'AZ',\n flag: '🇦🇿',\n },\n {\n name: 'Bahamas',\n iso2: 'BS',\n flag: '🇧🇸',\n },\n {\n name: 'Bahrain',\n iso2: 'BH',\n flag: '🇧🇭',\n },\n {\n name: 'Bangladesh',\n iso2: 'BD',\n flag: '🇧🇩',\n },\n {\n name: 'Barbados',\n iso2: 'BB',\n flag: '🇧🇧',\n },\n {\n name: 'Belarus',\n iso2: 'BY',\n flag: '🇧🇾',\n },\n {\n name: 'Belgium',\n iso2: 'BE',\n flag: '🇧🇪',\n },\n {\n name: 'Belize',\n iso2: 'BZ',\n flag: '🇧🇿',\n },\n {\n name: 'Benin',\n iso2: 'BJ',\n flag: '🇧🇯',\n },\n {\n name: 'Bhutan',\n iso2: 'BT',\n flag: '🇧🇹',\n },\n {\n name: 'Bolivia',\n iso2: 'BO',\n flag: '🇧🇴',\n },\n {\n name: 'Bosnia and Herzegovina',\n iso2: 'BA',\n flag: '🇧🇦',\n },\n {\n name: 'Botswana',\n iso2: 'BW',\n flag: '🇧🇼',\n },\n {\n name: 'Brunei',\n iso2: 'BN',\n flag: '🇧🇳',\n },\n {\n name: 'Bulgaria',\n iso2: 'BG',\n flag: '🇧🇬',\n },\n {\n name: 'Burkina Faso',\n iso2: 'BF',\n flag: '🇧🇫',\n },\n {\n name: 'Burundi',\n iso2: 'BI',\n flag: '🇧🇮',\n },\n {\n name: 'Cabo Verde',\n iso2: 'CV',\n flag: '🇨🇻',\n },\n {\n name: 'Cambodia',\n iso2: 'KH',\n flag: '🇰🇭',\n },\n {\n name: 'Cameroon',\n iso2: 'CM',\n flag: '🇨🇲',\n },\n {\n name: 'Central African Republic',\n iso2: 'CF',\n flag: '🇨🇫',\n },\n {\n name: 'Chad',\n iso2: 'TD',\n flag: '🇹🇩',\n },\n {\n name: 'Chile',\n iso2: 'CL',\n flag: '🇨🇱',\n },\n {\n name: 'Colombia',\n iso2: 'CO',\n flag: '🇨🇴',\n },\n {\n name: 'Comoros',\n iso2: 'KM',\n flag: '🇰🇲',\n },\n {\n name: 'Congo (Congo-Brazzaville)',\n iso2: 'CG',\n flag: '🇨🇬',\n },\n {\n name: 'Congo (Congo-Kinshasa)',\n iso2: 'CD',\n flag: '🇨🇩',\n },\n {\n name: 'Costa Rica',\n iso2: 'CR',\n flag: '🇨🇷',\n },\n {\n name: 'Croatia',\n iso2: 'HR',\n flag: '🇭🇷',\n },\n {\n name: 'Cuba',\n iso2: 'CU',\n flag: '🇨🇺',\n },\n {\n name: 'Cyprus',\n iso2: 'CY',\n flag: '🇨🇾',\n },\n {\n name: 'Czech Republic',\n iso2: 'CZ',\n flag: '🇨🇿',\n },\n {\n name: 'Denmark',\n iso2: 'DK',\n flag: '🇩🇰',\n },\n {\n name: 'Djibouti',\n iso2: 'DJ',\n flag: '🇩🇯',\n },\n {\n name: 'Dominica',\n iso2: 'DM',\n flag: '🇩🇲',\n },\n {\n name: 'Dominican Republic',\n iso2: 'DO',\n flag: '🇩🇴',\n },\n {\n name: 'Ecuador',\n iso2: 'EC',\n flag: '🇪🇨',\n },\n {\n name: 'Egypt',\n iso2: 'EG',\n flag: '🇪🇬',\n },\n {\n name: 'El Salvador',\n iso2: 'SV',\n flag: '🇸🇻',\n },\n {\n name: 'Equatorial Guinea',\n iso2: 'GQ',\n flag: '🇬🇶',\n },\n {\n name: 'Eritrea',\n iso2: 'ER',\n flag: '🇪🇷',\n },\n {\n name: 'Estonia',\n iso2: 'EE',\n flag: '🇪🇪',\n },\n {\n name: 'Eswatini',\n iso2: 'SZ',\n flag: '🇸🇿',\n },\n {\n name: 'Ethiopia',\n iso2: 'ET',\n flag: '🇪🇹',\n },\n {\n name: 'Fiji',\n iso2: 'FJ',\n flag: '🇫🇯',\n },\n {\n name: 'Finland',\n iso2: 'FI',\n flag: '🇫🇮',\n },\n {\n name: 'Gabon',\n iso2: 'GA',\n flag: '🇬🇦',\n },\n {\n name: 'Gambia',\n iso2: 'GM',\n flag: '🇬🇲',\n },\n {\n name: 'Georgia',\n iso2: 'GE',\n flag: '🇬🇪',\n },\n {\n name: 'Ghana',\n iso2: 'GH',\n flag: '🇬🇭',\n },\n {\n name: 'Greece',\n iso2: 'GR',\n flag: '🇬🇷',\n },\n {\n name: 'Grenada',\n iso2: 'GD',\n flag: '🇬🇩',\n },\n {\n name: 'Guatemala',\n iso2: 'GT',\n flag: '🇬🇹',\n },\n {\n name: 'Guinea',\n iso2: 'GN',\n flag: '🇬🇳',\n },\n {\n name: 'Guinea-Bissau',\n iso2: 'GW',\n flag: '🇬🇼',\n },\n {\n name: 'Guyana',\n iso2: 'GY',\n flag: '🇬🇾',\n },\n {\n name: 'Haiti',\n iso2: 'HT',\n flag: '🇭🇹',\n },\n {\n name: 'Honduras',\n iso2: 'HN',\n flag: '🇭🇳',\n },\n {\n name: 'Hungary',\n iso2: 'HU',\n flag: '🇭🇺',\n },\n {\n name: 'Iceland',\n iso2: 'IS',\n flag: '🇮🇸',\n },\n {\n name: 'Indonesia',\n iso2: 'ID',\n flag: '🇮🇩',\n },\n {\n name: 'Iran',\n iso2: 'IR',\n flag: '🇮🇷',\n },\n {\n name: 'Iraq',\n iso2: 'IQ',\n flag: '🇮🇶',\n },\n {\n name: 'Ireland',\n iso2: 'IE',\n flag: '🇮🇪',\n },\n {\n name: 'Israel',\n iso2: 'IL',\n flag: '🇮🇱',\n },\n {\n name: 'Italy',\n iso2: 'IT',\n flag: '🇮🇹',\n },\n {\n name: 'Jamaica',\n iso2: 'JM',\n flag: '🇯🇲',\n },\n {\n name: 'Jordan',\n iso2: 'JO',\n flag: '🇯🇴',\n },\n {\n name: 'Kazakhstan',\n iso2: 'KZ',\n flag: '🇰🇿',\n },\n {\n name: 'Kenya',\n iso2: 'KE',\n flag: '🇰🇪',\n },\n {\n name: 'Kiribati',\n iso2: 'KI',\n flag: '🇰🇮',\n },\n {\n name: 'Kuwait',\n iso2: 'KW',\n flag: '🇰🇼',\n },\n {\n name: 'Kyrgyzstan',\n iso2: 'KG',\n flag: '🇰🇬',\n },\n {\n name: 'Laos',\n iso2: 'LA',\n flag: '🇱🇦',\n },\n {\n name: 'Latvia',\n iso2: 'LV',\n flag: '🇱🇻',\n },\n {\n name: 'Lebanon',\n iso2: 'LB',\n flag: '🇱🇧',\n },\n {\n name: 'Lesotho',\n iso2: 'LS',\n flag: '🇱🇸',\n },\n {\n name: 'Liberia',\n iso2: 'LR',\n flag: '🇱🇷',\n },\n {\n name: 'Libya',\n iso2: 'LY',\n flag: '🇱🇾',\n },\n {\n name: 'Liechtenstein',\n iso2: 'LI',\n flag: '🇱🇮',\n },\n {\n name: 'Lithuania',\n iso2: 'LT',\n flag: '🇱🇹',\n },\n {\n name: 'Luxembourg',\n iso2: 'LU',\n flag: '🇱🇺',\n },\n {\n name: 'Madagascar',\n iso2: 'MG',\n flag: '🇲🇬',\n },\n {\n name: 'Malawi',\n iso2: 'MW',\n flag: '🇲🇼',\n },\n {\n name: 'Malaysia',\n iso2: 'MY',\n flag: '🇲🇾',\n },\n {\n name: 'Maldives',\n iso2: 'MV',\n flag: '🇲🇻',\n },\n {\n name: 'Mali',\n iso2: 'ML',\n flag: '🇲🇱',\n },\n {\n name: 'Malta',\n iso2: 'MT',\n flag: '🇲🇹',\n },\n {\n name: 'Marshall Islands',\n iso2: 'MH',\n flag: '🇲🇭',\n },\n {\n name: 'Mauritania',\n iso2: 'MR',\n flag: '🇲🇷',\n },\n {\n name: 'Mauritius',\n iso2: 'MU',\n flag: '🇲🇺',\n },\n {\n name: 'Mexico',\n iso2: 'MX',\n flag: '🇲🇽',\n },\n {\n name: 'Micronesia',\n iso2: 'FM',\n flag: '🇫🇲',\n },\n {\n name: 'Moldova',\n iso2: 'MD',\n flag: '🇲🇩',\n },\n {\n name: 'Monaco',\n iso2: 'MC',\n flag: '🇲🇨',\n },\n {\n name: 'Mongolia',\n iso2: 'MN',\n flag: '🇲🇳',\n },\n {\n name: 'Montenegro',\n iso2: 'ME',\n flag: '🇲🇪',\n },\n {\n name: 'Morocco',\n iso2: 'MA',\n flag: '🇲🇦',\n },\n {\n name: 'Mozambique',\n iso2: 'MZ',\n flag: '🇲🇿',\n },\n {\n name: 'Myanmar',\n iso2: 'MM',\n flag: '🇲🇲',\n },\n {\n name: 'Namibia',\n iso2: 'NA',\n flag: '🇳🇦',\n },\n {\n name: 'Nauru',\n iso2: 'NR',\n flag: '🇳🇷',\n },\n {\n name: 'Nepal',\n iso2: 'NP',\n flag: '🇳🇵',\n },\n {\n name: 'Netherlands',\n iso2: 'NL',\n flag: '🇳🇱',\n },\n {\n name: 'New Zealand',\n iso2: 'NZ',\n flag: '🇳🇿',\n },\n {\n name: 'Nicaragua',\n iso2: 'NI',\n flag: '🇳🇮',\n },\n {\n name: 'Niger',\n iso2: 'NE',\n flag: '🇳🇪',\n },\n {\n name: 'Nigeria',\n iso2: 'NG',\n flag: '🇳🇬',\n },\n {\n name: 'North Korea',\n iso2: 'KP',\n flag: '🇰🇵',\n },\n {\n name: 'North Macedonia',\n iso2: 'MK',\n flag: '🇲🇰',\n },\n {\n name: 'Norway',\n iso2: 'NO',\n flag: '🇳🇴',\n },\n {\n name: 'Oman',\n iso2: 'OM',\n flag: '🇴🇲',\n },\n {\n name: 'Pakistan',\n iso2: 'PK',\n flag: '🇵🇰',\n },\n {\n name: 'Palau',\n iso2: 'PW',\n flag: '🇵🇼',\n },\n {\n name: 'Panama',\n iso2: 'PA',\n flag: '🇵🇦',\n },\n {\n name: 'Papua New Guinea',\n iso2: 'PG',\n flag: '🇵🇬',\n },\n {\n name: 'Paraguay',\n iso2: 'PY',\n flag: '🇵🇾',\n },\n {\n name: 'Peru',\n iso2: 'PE',\n flag: '🇵🇪',\n },\n {\n name: 'Philippines',\n iso2: 'PH',\n flag: '🇵🇭',\n },\n {\n name: 'Poland',\n iso2: 'PL',\n flag: '🇵🇱',\n },\n {\n name: 'Portugal',\n iso2: 'PT',\n flag: '🇵🇹',\n },\n {\n name: 'Qatar',\n iso2: 'QA',\n flag: '🇶🇦',\n },\n {\n name: 'Romania',\n iso2: 'RO',\n flag: '🇷🇴',\n },\n {\n name: 'Rwanda',\n iso2: 'RW',\n flag: '🇷🇼',\n },\n {\n name: 'Saint Kitts and Nevis',\n iso2: 'KN',\n flag: '🇰🇳',\n },\n {\n name: 'Saint Lucia',\n iso2: 'LC',\n flag: '🇱🇨',\n },\n {\n name: 'Saint Vincent and the Grenadines',\n iso2: 'VC',\n flag: '🇻🇨',\n },\n {\n name: 'Samoa',\n iso2: 'WS',\n flag: '🇼🇸',\n },\n {\n name: 'San Marino',\n iso2: 'SM',\n flag: '🇸🇲',\n },\n {\n name: 'Sao Tome and Principe',\n iso2: 'ST',\n flag: '🇸🇹',\n },\n {\n name: 'Senegal',\n iso2: 'SN',\n flag: '🇸🇳',\n },\n {\n name: 'Serbia',\n iso2: 'RS',\n flag: '🇷🇸',\n },\n {\n name: 'Seychelles',\n iso2: 'SC',\n flag: '🇸🇨',\n },\n {\n name: 'Sierra Leone',\n iso2: 'SL',\n flag: '🇸🇱',\n },\n {\n name: 'Singapore',\n iso2: 'SG',\n flag: '🇸🇬',\n },\n {\n name: 'Slovakia',\n iso2: 'SK',\n flag: '🇸🇰',\n },\n {\n name: 'Slovenia',\n iso2: 'SI',\n flag: '🇸🇮',\n },\n {\n name: 'Solomon Islands',\n iso2: 'SB',\n flag: '🇸🇧',\n },\n {\n name: 'Somalia',\n iso2: 'SO',\n flag: '🇸🇴',\n },\n {\n name: 'South Korea',\n iso2: 'KR',\n flag: '🇰🇷',\n },\n {\n name: 'South Sudan',\n iso2: 'SS',\n flag: '🇸🇸',\n },\n {\n name: 'Spain',\n iso2: 'ES',\n flag: '🇪🇸',\n },\n {\n name: 'Sri Lanka',\n iso2: 'LK',\n flag: '🇱🇰',\n },\n {\n name: 'Sudan',\n iso2: 'SD',\n flag: '🇸🇩',\n },\n {\n name: 'Suriname',\n iso2: 'SR',\n flag: '🇸🇷',\n },\n {\n name: 'Sweden',\n iso2: 'SE',\n flag: '🇸🇪',\n },\n {\n name: 'Switzerland',\n iso2: 'CH',\n flag: '🇨🇭',\n },\n {\n name: 'Syria',\n iso2: 'SY',\n flag: '🇸🇾',\n },\n {\n name: 'Tajikistan',\n iso2: 'TJ',\n flag: '🇹🇯',\n },\n {\n name: 'Tanzania',\n iso2: 'TZ',\n flag: '🇹🇿',\n },\n {\n name: 'Thailand',\n iso2: 'TH',\n flag: '🇹🇭',\n },\n {\n name: 'Togo',\n iso2: 'TG',\n flag: '🇹🇬',\n },\n {\n name: 'Tonga',\n iso2: 'TO',\n flag: '🇹🇴',\n },\n {\n name: 'Trinidad and Tobago',\n iso2: 'TT',\n flag: '🇹🇹',\n },\n {\n name: 'Tunisia',\n iso2: 'TN',\n flag: '🇹🇳',\n },\n {\n name: 'Turkey',\n iso2: 'TR',\n flag: '🇹🇷',\n },\n {\n name: 'Turkmenistan',\n iso2: 'TM',\n flag: '🇹🇲',\n },\n {\n name: 'Tuvalu',\n iso2: 'TV',\n flag: '🇹🇻',\n },\n {\n name: 'Uganda',\n iso2: 'UG',\n flag: '🇺🇬',\n },\n {\n name: 'Ukraine',\n iso2: 'UA',\n flag: '🇺🇦',\n },\n {\n name: 'United Arab Emirates',\n iso2: 'AE',\n flag: '🇦🇪',\n },\n {\n name: 'Uruguay',\n iso2: 'UY',\n flag: '🇺🇾',\n },\n {\n name: 'Uzbekistan',\n iso2: 'UZ',\n flag: '🇺🇿',\n },\n {\n name: 'Vanuatu',\n iso2: 'VU',\n flag: '🇻🇺',\n },\n {\n name: 'Venezuela',\n iso2: 'VE',\n flag: '🇻🇪',\n },\n {\n name: 'Vietnam',\n iso2: 'VN',\n flag: '🇻🇳',\n },\n {\n name: 'Yemen',\n iso2: 'YE',\n flag: '🇾🇪',\n },\n {\n name: 'Zambia',\n iso2: 'ZM',\n flag: '🇿🇲',\n },\n {\n name: 'Zimbabwe',\n iso2: 'ZW',\n flag: '🇿🇼',\n },\n {\n name: 'Timor-Leste',\n iso2: 'TL',\n flag: '🇹🇱',\n },\n] as const\n","import type {\n DocumentType,\n LivenessChallenge,\n ProjectBranding,\n VerificationDecision,\n VerificationStatus,\n WidgetStep,\n} from '@arkyc/types'\n\nimport { Camera } from './capture'\nimport type { Facing } from './capture'\nimport {\n createDefaultDocumentAnalyzer,\n DEFAULT_DOCUMENT_TUNING,\n documentGuidance,\n type DocRect,\n type DocumentAnalyzer,\n type DocumentTuning,\n} from './document'\nimport {\n createDefaultFaceAnalyzer,\n DEFAULT_TUNING,\n isSelfieReady,\n makeChallengeDetector,\n type FaceAnalyzer,\n type FaceTuning,\n} from './face'\nimport { Theme } from './theme'\nimport { countries } from './countries'\n\n/** High-level events the view raises back to the controller. */\nexport interface ViewHandlers {\n onClose(): void\n onStart(): void\n onDocumentSelected(type: DocumentType, country: string): void\n /** A capture screen produced an image (or `null` when skipped in demo mode). */\n onImage(blob: Blob | null): void\n /**\n * Active liveness finished: the recorded video (or `null`), the performed\n * sequence, and a still selfie frame grabbed from the live video (or `null`).\n */\n onActiveLiveness(video: Blob | null, performed: LivenessChallenge[], selfie?: Blob | null): void\n /** The result screen was acknowledged (\"Done\"). */\n onAcknowledge(): void\n /** The user chose to continue the verification on another device (handoff). */\n onUsePhone(): void\n /** The user chose to keep verifying on this (desktop) device instead of handing off. */\n onContinueHere(): void\n}\n\n/** Per-render data the view needs for the current step. */\nexport interface ViewState {\n step: WidgetStep\n documentType: DocumentType | null\n decision?: VerificationDecision | null\n /** The session status (drives the close-only terminal notice). */\n status?: VerificationStatus\n /** Render the result as a close-only notice (session was already terminal on load). */\n terminalNotice?: boolean\n statusLabel?: string\n errorMessage?: string\n /** Show a \"Skip\" affordance on capture screens (demo / mock-driver flows). */\n allowSkip?: boolean\n /** The challenge sequence to prompt for the active-liveness screen. */\n livenessChallenges?: LivenessChallenge[]\n /**\n * Capture model demands a live camera (`capture_model === 'active'`). When set,\n * the active-liveness screen must NOT offer a manual/file fallback on\n * unsupported devices — it shows an \"unsupported device\" message instead.\n */\n requireLiveCamera?: boolean\n /**\n * The session runs the active flow (resolved liveness is `active`). Document\n * capture is then strict: detection-gated auto-capture only — no manual capture\n * button, no permissive brightness/upload fallback that could bypass detection.\n */\n strictCapture?: boolean\n /** Offer a \"Continue on your phone\" affordance on the welcome screen (handoff). */\n handoffAvailable?: boolean\n}\n\nconst DOCUMENT_LABELS: Record<DocumentType, string> = {\n passport: 'Passport',\n id_card: 'ID Card',\n drivers_license: \"Driver's License\",\n residence_permit: 'Residence Permit',\n}\n\nconst CHALLENGE_LABELS: Record<LivenessChallenge, string> = {\n turn_left: 'Slowly turn your head to the left, and hold',\n turn_right: 'Slowly turn your head to the right, and hold',\n blink: 'Blink slowly',\n smile: 'Smile, and hold it',\n nod: 'Slowly nod your head',\n move_closer: 'Slowly move closer to the camera',\n}\n\ninterface Notice {\n cls: string\n icon: string\n title: string\n copy: string\n}\n\n/** Fallback notice for an expired/unknown terminal session. */\nconst EXPIRED_NOTICE: Notice = {\n cls: 'warn',\n icon: '⏳',\n title: 'Link expired',\n copy: 'This verification link has expired.',\n}\n\n/** Close-only notice copy for a session that was already terminal on load. */\nconst TERMINAL_NOTICE: Partial<Record<VerificationStatus, Notice>> = {\n approved: { cls: 'ok', icon: '✓', title: 'Already complete', copy: 'This verification has already been completed.' },\n rejected: { cls: 'ok', icon: '✓', title: 'Already complete', copy: 'This verification has already been completed.' },\n requires_review: {\n cls: 'ok',\n icon: '✓',\n title: 'Already complete',\n copy: 'This verification has already been submitted and is being reviewed.',\n },\n expired: EXPIRED_NOTICE,\n cancelled: { cls: 'warn', icon: '⏳', title: 'Cancelled', copy: 'This verification was cancelled.' },\n}\n\nconst SVG = (body: string) =>\n `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${body}</svg>`\n\n/** Per-challenge directional cue icons, animated via CSS over the preview. */\nconst CUE_ICONS: Record<LivenessChallenge, string> = {\n turn_right: SVG('<path d=\"M5 12h14M13 6l6 6-6 6\"/>'),\n turn_left: SVG('<path d=\"M19 12H5M11 6l-6 6 6 6\"/>'),\n nod: SVG('<path d=\"M12 5v14M6 13l6 6 6-6\"/>'),\n move_closer: SVG('<circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M12 2v3M12 19v3M2 12h3M19 12h3\"/>'),\n blink: SVG('<path d=\"M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/>'),\n smile: SVG('<path d=\"M8 14s1.5 2 4 2 4-2 4-2\"/><path d=\"M9 9h.01M15 9h.01\"/>'),\n}\n\nconst CHECK_ICON = SVG('<path d=\"M20 6 9 17l-5-5\"/>')\n\n/** Larger line-art illustration used to dress the informative / lead-in screens. */\nconst ART = (body: string) =>\n `<svg viewBox=\"0 0 64 64\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${body}</svg>`\n\n/** Per-screen decorative illustrations, keyed by step (plus a welcome hero). */\nconst STEP_ART: Partial<Record<WidgetStep | 'welcome', string>> = {\n // Shield with a check — trust / \"verify your identity\".\n welcome: ART(\n '<path d=\"M32 7 52 14v14c0 12.5-8.2 21.6-20 25.6C20.2 49.6 12 40.5 12 28V14z\"/><path d=\"M23 30.5l6.2 6.2L41 24.5\"/>',\n ),\n // ID card with a portrait + text lines.\n front_capture: ART(\n '<rect x=\"7\" y=\"15\" width=\"50\" height=\"34\" rx=\"5\"/><circle cx=\"22\" cy=\"28\" r=\"5\"/><path d=\"M14 42c1-5 5-7 8-7s7 2 8 7\"/><path d=\"M38 27h12M38 34h12M38 41h8\"/>',\n ),\n // ID card flipped: magnetic stripe + MRZ lines.\n back_capture: ART(\n '<rect x=\"7\" y=\"15\" width=\"50\" height=\"34\" rx=\"5\"/><rect x=\"7\" y=\"20\" width=\"50\" height=\"6\" fill=\"currentColor\" stroke=\"none\" opacity=\".18\"/><path d=\"M14 34h36M14 41h24\"/>',\n ),\n // A person centred in a camera viewfinder (corner brackets).\n selfie_capture: ART(\n '<path d=\"M10 20v-6a4 4 0 0 1 4-4h6\"/><path d=\"M44 10h6a4 4 0 0 1 4 4v6\"/><path d=\"M54 44v6a4 4 0 0 1-4 4h-6\"/><path d=\"M20 54h-6a4 4 0 0 1-4-4v-6\"/><circle cx=\"32\" cy=\"27\" r=\"8\"/><path d=\"M19 50c0-7 6-11 13-11s13 4 13 11\"/>',\n ),\n // A smiling face with turn-your-head arrows on each side.\n active_liveness: ART(\n '<circle cx=\"32\" cy=\"30\" r=\"13\"/><circle cx=\"27\" cy=\"27\" r=\"1.2\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"37\" cy=\"27\" r=\"1.2\" fill=\"currentColor\" stroke=\"none\"/><path d=\"M26 34c2 2.5 10 2.5 12 0\"/><path d=\"M13 30H6M10 26l-4 4 4 4\"/><path d=\"M51 30h7M54 26l4 4-4 4\"/>',\n ),\n}\n\n/** Handles for driving the circular preview overlay (ring + cue + success check). */\ninterface FaceStage {\n stage: HTMLElement\n /** 0–1 fill of the progress ring. */\n setProgress(p: number): void\n /** Visual state: searching, holding (green), or completed (check). */\n setState(state: 'wait' | 'good' | 'done'): void\n /** Show a challenge cue icon (or clear it with `null`). */\n setCue(challenge: LivenessChallenge | null): void\n}\n\n/** Handles for driving the document preview overlay (bracket frame + scan line). */\ninterface DocStage {\n stage: HTMLElement\n /** Tint the frame for the current capture quality. */\n setQuality(quality: 'wait' | 'good' | 'bad'): void\n /** Flag whether a document is currently detected (brightens the fixed guide). */\n setFrame(rect: DocRect | null): void\n}\n\n/** Handles for driving the liveness step-progress dots. */\ninterface StepDots {\n el: HTMLElement\n /** Mark the given step index as the active one. */\n setActive(index: number): void\n /** Mark the given step index as completed. */\n markDone(index: number): void\n}\n\ninterface ElProps {\n class?: string\n text?: string\n html?: string\n type?: string\n src?: string\n accept?: string\n placeholder?: string\n value?: string\n [attr: string]: string | undefined\n}\n\n/**\n * Renders the widget's screens into a host element. DOM- and camera-injectable\n * so it can run under a fake DOM in tests. The view owns capture-screen camera\n * mechanics and raises only high-level events to the controller.\n */\nexport class WidgetView {\n private readonly root: HTMLElement\n private readonly body: HTMLElement\n private readonly footer: HTMLElement\n /** The `<style>` carrying the theme's CSS vars; swapped on runtime re-brand. */\n private readonly styleEl: HTMLElement\n /** The header brand group (logo/name/title); rebuilt on runtime re-brand. */\n private readonly brandEl: HTMLElement\n private readonly camera: Camera\n private readonly analyzer: FaceAnalyzer | null\n private readonly tuning: FaceTuning\n private readonly docAnalyzer: DocumentAnalyzer | null\n private readonly docTuning: DocumentTuning\n /** Interval ids for live quality/recording timers, cleared on re-render. */\n private timers: ReturnType<typeof setInterval>[] = []\n /** Extra teardown run on each re-render (cancels in-flight detection loops). */\n private cleanups: (() => void)[] = []\n\n constructor(\n private readonly doc: Document,\n private theme: Theme,\n private readonly handlers: ViewHandlers,\n nav: Navigator = globalThis.navigator,\n analyzer: FaceAnalyzer | null = createDefaultFaceAnalyzer(),\n tuning: FaceTuning = DEFAULT_TUNING,\n docAnalyzer: DocumentAnalyzer | null = createDefaultDocumentAnalyzer(),\n docTuning: DocumentTuning = DEFAULT_DOCUMENT_TUNING,\n ) {\n this.camera = new Camera(doc, nav)\n this.analyzer = analyzer\n this.tuning = tuning\n this.docAnalyzer = docAnalyzer\n this.docTuning = docTuning\n this.root = this.el('div', { class: 'arkyc-root' })\n\n this.styleEl = this.el('style', { text: theme.stylesheet() })\n this.root.appendChild(this.styleEl)\n\n const card = this.el('div', { class: 'arkyc-card' })\n const header = this.el('div', { class: 'arkyc-header' })\n this.brandEl = this.el('div', { class: 'arkyc-brand' })\n this.fillBrand()\n header.appendChild(this.brandEl)\n const close = this.el('button', {\n class: 'arkyc-close',\n html: '&times;',\n 'aria-label': 'Close',\n })\n close.addEventListener('click', () => this.handlers.onClose())\n header.appendChild(close)\n\n this.body = this.el('div', { class: 'arkyc-body' })\n this.footer = this.el('div', { class: 'arkyc-footer' })\n\n card.appendChild(header)\n card.appendChild(this.body)\n card.appendChild(this.footer)\n this.root.appendChild(card)\n }\n\n /**\n * Populate the header brand group from the current theme: the project logo\n * and/or name when branding is shown, otherwise a neutral title.\n */\n private fillBrand(): void {\n this.clear(this.brandEl)\n const lastTenMins = Date.now() - Math.floor(Math.random() * (10 * 60 * 1000))\n\n if (this.theme.showBranding && (this.theme.logoUrl || this.theme.name)) {\n if (this.theme.logoUrl)\n this.brandEl.appendChild(\n this.el('img', {\n class: 'arkyc-logo',\n src: this.theme.logoUrl + '?stamp=' + lastTenMins,\n }),\n )\n if (this.theme.name)\n this.brandEl.appendChild(this.el('span', { class: 'arkyc-brand-name', text: this.theme.name }))\n } else {\n this.brandEl.appendChild(this.el('p', { class: 'arkyc-title', text: 'Verify your identity' }))\n }\n }\n\n /**\n * Re-theme the widget at runtime from project branding (resolved server-side):\n * swap the CSS-variable stylesheet (colours/radius) and rebuild the header\n * brand (logo/name). Cascades to every already-rendered element via the vars.\n */\n applyBranding(branding: ProjectBranding | null): void {\n this.theme = new Theme(branding)\n this.styleEl.textContent = this.theme.stylesheet()\n this.fillBrand()\n }\n\n /**\n * The widget's root element — append this to the overlay / container.\n */\n get element(): HTMLElement {\n return this.root\n }\n\n /**\n * Whether live camera capture is available (drives the active-liveness branch).\n */\n get cameraSupported(): boolean {\n return this.camera.supported\n }\n\n /**\n * Release any active camera stream and clear live timers.\n */\n destroy(): void {\n this.timers.forEach((id) => clearInterval(id))\n this.timers = []\n this.cleanups.forEach((fn) => fn())\n this.cleanups = []\n this.camera.stop()\n }\n\n /**\n * Render the screen for the given state.\n *\n * @param state\n * @returns\n */\n render(state: ViewState): void {\n this.destroy()\n this.clear(this.body)\n this.clear(this.footer)\n this.root.classList.remove('arkyc-handoff')\n\n switch (state.step) {\n case 'welcome':\n return this.renderWelcome(state.handoffAvailable)\n case 'document_selection':\n return this.renderDocumentSelection()\n case 'front_capture':\n return this.renderCapture('Front of document', 'environment', state.allowSkip, false, state.strictCapture)\n case 'back_capture':\n return this.renderCapture('Back of document', 'environment', state.allowSkip, false, state.strictCapture)\n case 'selfie_capture':\n return this.renderCapture('Take a selfie', 'user', state.allowSkip, true, state.strictCapture)\n case 'active_liveness':\n return this.renderActiveLiveness(state.livenessChallenges ?? [], state.allowSkip, state.requireLiveCamera)\n case 'ocr_processing':\n return this.renderProcessing('Reading your document…')\n case 'passive_liveness':\n return this.renderProcessing('Checking liveness…')\n case 'face_match':\n return this.renderProcessing('Matching your face…')\n case 'processing':\n return this.renderProcessing(state.statusLabel ?? 'Finalising verification…')\n case 'result':\n return this.renderResult(state.decision ?? null, state.errorMessage, {\n terminal: state.terminalNotice,\n status: state.status,\n })\n }\n }\n\n /** Prepend a decorative illustration for the given screen, when one exists. */\n private appendArt(key: WidgetStep | 'welcome'): void {\n const art = STEP_ART[key]\n if (art) this.body.appendChild(this.el('div', { class: 'arkyc-illus', html: art }))\n }\n\n private renderWelcome(handoffAvailable?: boolean): void {\n this.appendArt('welcome')\n this.body.appendChild(this.el('h2', { class: 'arkyc-h', text: 'Verify your identity' }))\n this.body.appendChild(\n this.el('p', {\n class: 'arkyc-p',\n text: 'You will need a government-issued ID and a moment to take a selfie. Your data is processed securely.',\n }),\n )\n this.footer.appendChild(this.button('Get started', () => this.handlers.onStart()))\n if (handoffAvailable) {\n this.footer.appendChild(\n this.button('Continue on your phone', () => this.handlers.onUsePhone(), 'arkyc-btn-ghost'),\n )\n }\n }\n\n /** A neutral connecting screen shown while the widget bootstraps the session. */\n renderLoading(label = 'Loading…'): void {\n this.destroy()\n this.clear(this.body)\n this.clear(this.footer)\n this.root.classList.remove('arkyc-handoff')\n this.renderProcessing(label)\n }\n\n /**\n * An interstitial that tells the user what the next step is, with a single\n * Continue button — so each step starts deliberately rather than the camera\n * springing to life unannounced.\n */\n renderInstruction(step: WidgetStep, title: string, body: string, cta: string, onContinue: () => void): void {\n this.destroy()\n this.clear(this.body)\n this.clear(this.footer)\n this.root.classList.remove('arkyc-handoff')\n this.appendArt(step)\n this.body.appendChild(this.el('h2', { class: 'arkyc-h', text: title }))\n this.body.appendChild(this.el('p', { class: 'arkyc-p', text: body }))\n this.footer.appendChild(this.button(cta, onContinue))\n }\n\n /**\n * Show the cross-device handoff QR: the user scans it to resume this same\n * session on their phone. The widget then waits for the other device to finish.\n * `allowContinueHere` offers an escape hatch to keep verifying on this device.\n */\n renderHandoff(qrSvg: string, allowContinueHere: boolean): void {\n this.destroy()\n this.clear(this.body)\n this.clear(this.footer)\n // Keep the QR prominent (edge-to-edge in fullscreen) rather than a small dialog.\n this.root.classList.add('arkyc-handoff')\n this.body.appendChild(this.el('h2', { class: 'arkyc-h', text: 'Continue on your phone' }))\n this.body.appendChild(\n this.el('p', { class: 'arkyc-p', text: 'Scan this code with your phone camera to finish verifying there.' }),\n )\n this.body.appendChild(this.el('div', { class: 'arkyc-qr', html: qrSvg }))\n const waiting = this.el('div', { class: 'arkyc-handoff-wait' })\n waiting.appendChild(this.el('div', { class: 'arkyc-spinner sm' }))\n waiting.appendChild(this.el('span', { text: 'Waiting for your phone…' }))\n this.body.appendChild(waiting)\n if (allowContinueHere) {\n this.footer.appendChild(\n this.button('Continue on this device', () => this.handlers.onContinueHere(), 'arkyc-btn-ghost'),\n )\n }\n }\n\n private renderDocumentSelection(): void {\n this.body.appendChild(this.el('h2', { class: 'arkyc-h', text: 'Select your document' }))\n const country = this.el('select', {\n class: 'arkyc-btn arkyc-btn-ghost arkyc-text-center',\n name: 'country',\n autocomplete: 'country',\n 'aria-label': 'Country',\n }) as HTMLSelectElement\n\n const placeholder = this.el('option', {\n value: '',\n selected: 'selected',\n })\n\n placeholder.textContent = 'Country'\n\n country.appendChild(placeholder)\n\n countries.forEach(({ name, iso2, flag }) => {\n const option = this.el('option', { value: iso2 }) as HTMLOptionElement\n option.textContent = `${flag} ${name}`\n country.appendChild(option)\n })\n\n const choices = this.el('div', { class: 'arkyc-choices' })\n\n choices.appendChild(country)\n ;(Object.keys(DOCUMENT_LABELS) as DocumentType[]).forEach((type) => {\n const btn = this.button(DOCUMENT_LABELS[type], () =>\n this.handlers.onDocumentSelected(type, (country.value || '').trim().toUpperCase()),\n )\n btn.classList.add('arkyc-btn-ghost')\n choices.appendChild(btn)\n })\n this.body.appendChild(choices)\n }\n\n private renderCapture(title: string, facing: Facing, allowSkip?: boolean, selfie = false, strict = false): void {\n // Documents in the active flow are strict: detection-gated only (no manual\n // bypass). Selfies are always pure auto, so strictness only changes documents.\n const strictDoc = strict && !selfie\n this.body.appendChild(this.el('h2', { class: 'arkyc-h', text: title }))\n this.body.appendChild(this.el('p', { class: 'arkyc-p', text: 'Position it clearly in frame, then capture.' }))\n\n const fileInput = this.el('input', {\n type: 'file',\n accept: 'image/*',\n class: 'arkyc-hidden',\n }) as HTMLInputElement\n fileInput.addEventListener('change', () => this.handlers.onImage(Camera.fileFromInput(fileInput)))\n this.body.appendChild(fileInput)\n\n if (this.camera.supported) {\n const video = this.el('video', {\n class: `arkyc-preview${selfie ? ' selfie' : ''}`,\n }) as HTMLVideoElement\n\n // Wrap the preview in its animated overlay (circular ring for selfies,\n // bracket frame for documents).\n const face = selfie ? this.buildFaceStage(video) : null\n const doc = selfie ? null : this.buildDocStage(video)\n const mount = face?.stage ?? doc!.stage\n this.body.appendChild(mount)\n\n // Live guidance hint (quality for documents, framing for selfies).\n const hint = this.el('p', { class: 'arkyc-p arkyc-hint' }) as HTMLParagraphElement\n this.body.appendChild(hint)\n\n // After a capture, wait for an explicit \"Continue\" so the user can review\n // and get ready for the next step — never auto-advance. Swap the live\n // preview for a still of the captured frame: this shows exactly what was\n // captured and removes the overlay (brackets / scan line / ring) entirely,\n // rather than leaving a stopped (black) video with animations still running.\n const confirmCapture = (blob: Blob | null) => {\n this.destroy() // stop the camera + detection timers\n if (blob) {\n const url = URL.createObjectURL(blob)\n const still = this.el('img', {\n class: `arkyc-preview${selfie ? ' selfie' : ''}`,\n src: url,\n }) as HTMLImageElement\n mount.replaceWith(still)\n this.cleanups.push(() => URL.revokeObjectURL(url))\n } else {\n mount.classList.add('arkyc-hidden')\n }\n this.clear(this.footer)\n hint.textContent = '✓ Captured'\n this.footer.appendChild(this.button('Continue', () => this.handlers.onImage(blob)))\n const retake = this.button('Retake', () => {\n this.destroy()\n this.clear(this.body)\n this.clear(this.footer)\n this.renderCapture(title, facing, allowSkip, selfie, strict)\n })\n retake.classList.add('arkyc-btn-ghost')\n this.footer.appendChild(retake)\n }\n\n const onCapture = () => void this.camera.grabFrame(video).then(confirmCapture)\n\n void this.camera.start(video, facing).catch(() => {\n mount.classList.add('arkyc-hidden')\n if (strictDoc) {\n // Strict document capture: no file fallback — a live camera is required.\n hint.textContent = 'Camera access is required to scan your document. Please allow access and try again.'\n return\n }\n // Camera denied/unavailable — fall back to the file input.\n fileInput.click()\n })\n\n if (selfie) {\n // Pure auto-capture: face detection grabs the frame when the user is\n // framed. The manual button only appears if the detector can't load.\n this.runSelfieAutoCapture(video, hint, onCapture, face!)\n } else {\n this.runDocumentAutoCapture(video, hint, doc!, strictDoc, onCapture)\n // Passive model only: a manual capture button as a reliable override.\n // The active flow is detection-gated — no manual bypass.\n if (!strictDoc) this.footer.appendChild(this.button('Capture', onCapture))\n }\n } else if (strictDoc) {\n // Strict document capture with no camera — surface as unsupported.\n this.body.appendChild(this.el('div', { class: 'arkyc-badge err', html: '!' }))\n this.body.appendChild(\n this.el('p', {\n class: 'arkyc-p',\n text: 'This step needs a working camera to scan your document. Please retry on a device with a camera.',\n }),\n )\n } else {\n const upload = this.button('Upload photo', () => fileInput.click())\n this.footer.appendChild(upload)\n }\n\n if (allowSkip) {\n const skip = this.button('Skip (demo)', () => this.handlers.onImage(null))\n skip.classList.add('arkyc-btn-ghost')\n this.footer.appendChild(skip)\n }\n }\n\n /**\n * Run `cb` once the live camera feed appears (the video has frames). The\n * detection model may still be downloading at that point, so callers use this\n * to replace the \"starting camera\" hint with a neutral one.\n *\n * @param video\n * @param cb\n */\n private onCameraLive(video: HTMLVideoElement, cb: () => void): void {\n if ((video.readyState ?? 0) >= 2) {\n cb()\n return\n }\n video.addEventListener('playing', cb, { once: true })\n }\n\n /**\n * Document capture: detect a real, well-framed, in-focus document (edge\n * projection) and auto-grab only once it's been held steady. Falls back to the\n * brightness/glare heuristic when the detector can't run.\n *\n * @param video\n * @returns\n */\n private runDocumentAutoCapture(\n video: HTMLVideoElement,\n hint: HTMLElement,\n doc: DocStage,\n strict: boolean,\n capture: () => void,\n ): void {\n // In strict mode the permissive brightness heuristic is disabled — it can't\n // tell a document from a well-lit blank frame, which would defeat detection.\n const onNoDetector = () => {\n if (strict) {\n hint.textContent = 'Document scanning isn’t available on this device.'\n return\n }\n this.runDocumentBrightnessCapture(video, hint, doc, capture)\n }\n\n const analyzer = this.docAnalyzer\n if (!analyzer) return onNoDetector()\n\n hint.textContent = 'Starting camera…'\n let cancelled = false\n let modelReady = false\n this.cleanups.push(() => {\n cancelled = true\n })\n // The camera feed appears before the document scanner model finishes loading;\n // once the video is live, stop implying the camera is still starting.\n this.onCameraLive(video, () => {\n if (!cancelled && !modelReady) hint.textContent = 'Getting ready…'\n })\n void analyzer.ready().then((ok) => {\n modelReady = true\n if (cancelled) return\n if (!ok) {\n onNoDetector()\n return\n }\n let goodStreak = 0\n // Smooth the noisiest geometry signals (fill/edge strength) across frames so a\n // single jittery edge-projection read doesn't flip the hint to \"move closer\"\n // and reset the streak. Exponential moving average; null until the first frame.\n let fillEma: number | null = null\n let edgeEma: number | null = null\n const ema = (prev: number | null, next: number) => (prev == null ? next : prev * 0.6 + next * 0.4)\n const timer = setInterval(() => {\n const sample = analyzer.analyze(video)\n if (!sample) return\n fillEma = ema(fillEma, sample.fill)\n edgeEma = ema(edgeEma, sample.edgeStrength)\n const smoothed = { ...sample, fill: fillEma, edgeStrength: edgeEma }\n const { ready, hint: message } = documentGuidance(smoothed, this.docTuning)\n hint.textContent = message\n doc.setFrame(sample.present ? sample.rect : null)\n doc.setQuality(ready ? 'good' : sample.present ? 'wait' : 'bad')\n // Soft reset: a single off frame nudges the streak down rather than zeroing\n // it, so transient detector noise doesn't perpetually restart the hold.\n goodStreak = ready ? goodStreak + 1 : Math.max(0, goodStreak - 1)\n // Auto-capture once a framed, focused document has held for ~1.25s.\n if (goodStreak >= this.docTuning.hold) {\n clearInterval(timer)\n doc.setQuality('good')\n capture()\n }\n }, 250)\n this.timers.push(timer)\n })\n }\n\n /**\n * Coarse fallback: brightness/glare heuristic, used when detection can't run.\n *\n * @param video\n * @param hint\n * @param doc\n */\n private runDocumentBrightnessCapture(\n video: HTMLVideoElement,\n hint: HTMLElement,\n doc: DocStage,\n capture: () => void,\n ): void {\n let goodStreak = 0\n const timer = setInterval(() => {\n const quality = this.camera.sampleQuality(video)\n if (!quality) return\n if (quality.tooDark) {\n hint.textContent = 'Too dark — find better lighting'\n goodStreak = 0\n doc.setQuality('bad')\n } else if (quality.glare) {\n hint.textContent = 'Reduce glare on the document'\n goodStreak = 0\n doc.setQuality('bad')\n } else {\n hint.textContent = 'Looks good — hold steady'\n goodStreak += 1\n doc.setQuality('good')\n }\n // Auto-capture a steady document after ~1.5s of good quality.\n if (goodStreak >= 5) {\n clearInterval(timer)\n capture()\n }\n }, 300)\n this.timers.push(timer)\n }\n\n /**\n * Selfie capture: when face detection is available, auto-grab once a centred\n * face is held steady. Falls back to a brightness hint (manual capture) when\n * the detector can't load (unsupported browser / offline / test host).\n *\n * @param video\n * @param hint\n * @param capture\n * @returns\n */\n private runSelfieAutoCapture(video: HTMLVideoElement, hint: HTMLElement, capture: () => void, face: FaceStage): void {\n const analyzer = this.analyzer\n const addManualCapture = () => this.footer.appendChild(this.button('Capture', capture))\n if (!analyzer) {\n // No detector available — fall back to a manual capture button.\n hint.textContent = 'Center your face, then capture'\n addManualCapture()\n return\n }\n hint.textContent = 'Starting camera…'\n let cancelled = false\n let modelReady = false\n this.cleanups.push(() => {\n cancelled = true\n })\n // The camera feed appears before the detection model (MediaPipe WASM, lazily\n // fetched from a CDN) finishes loading. Once the video is live, stop implying\n // the camera is still starting.\n this.onCameraLive(video, () => {\n if (!cancelled && !modelReady) hint.textContent = 'Getting ready…'\n })\n void analyzer.ready().then((ok) => {\n modelReady = true\n if (cancelled) return\n if (!ok) {\n // Detector failed to load — guide with brightness and offer manual capture.\n hint.textContent = 'Center your face, then capture'\n addManualCapture()\n return\n }\n const need = 4\n let streak = 0\n const timer = setInterval(() => {\n const sample = analyzer.analyze(video)\n if (!sample || !sample.present) {\n hint.textContent = 'Position your face in the circle'\n streak = 0\n face.setState('wait')\n face.setProgress(0)\n return\n }\n if (isSelfieReady(sample, this.tuning)) {\n hint.textContent = 'Hold still…'\n streak += 1\n face.setState('good')\n face.setProgress(streak / need)\n } else {\n hint.textContent = sample.scale <= this.tuning.selfieMinScale ? 'Move a little closer' : 'Center your face'\n streak = 0\n face.setState('wait')\n face.setProgress(0)\n }\n if (streak >= need) {\n clearInterval(timer)\n face.setState('done')\n face.setProgress(1)\n capture()\n }\n }, 180)\n this.timers.push(timer)\n })\n }\n\n /**\n * Guided active-liveness screen: live front-camera preview, a recorded video,\n * and a sequence of challenge prompts the user advances through. The performed\n * sequence (the prompts shown, in order) is submitted for the driver to verify.\n *\n * @param video\n * @returns\n */\n private renderActiveLiveness(\n challenges: LivenessChallenge[],\n allowSkip?: boolean,\n requireLiveCamera?: boolean,\n ): void {\n this.body.appendChild(this.el('h2', { class: 'arkyc-h', text: 'Liveness check' }))\n const prompt = this.el('p', {\n class: 'arkyc-p',\n text: 'Follow the on-screen prompts. Keep your face centred in the circle.',\n })\n this.body.appendChild(prompt)\n\n const fileFallback = !this.camera.supported || !this.camera.canRecord\n\n if (fileFallback) {\n if (requireLiveCamera) {\n // capture_model = active: a live camera is mandatory. Do NOT offer a\n // manual \"I did it\" path — surface the device as unsupported instead.\n this.body.appendChild(this.el('div', { class: 'arkyc-badge err', html: '!' }))\n prompt.textContent =\n 'This check needs camera access on a supported device. Please retry on a device with a working camera.'\n if (allowSkip) {\n const skip = this.button('Skip (demo)', () => this.handlers.onActiveLiveness(null, challenges))\n skip.classList.add('arkyc-btn-ghost')\n this.footer.appendChild(skip)\n }\n return\n }\n // No camera/recorder — let the user finish (or skip) without a video.\n const finish = this.button('I performed the steps', () => this.handlers.onActiveLiveness(null, challenges))\n this.footer.appendChild(finish)\n if (allowSkip) {\n const skip = this.button('Skip (demo)', () => this.handlers.onActiveLiveness(null, challenges))\n skip.classList.add('arkyc-btn-ghost')\n this.footer.appendChild(skip)\n }\n return\n }\n\n const video = this.el('video', { class: 'arkyc-preview selfie' }) as HTMLVideoElement\n const face = this.buildFaceStage(video)\n const dots = this.buildDots(challenges.length)\n if (challenges.length > 1) this.body.appendChild(dots.el)\n this.body.appendChild(face.stage)\n\n let recording: { stop(): Promise<Blob> } | null = null\n let index = 0\n // The challenges the user actually completed, in order (detected or advanced).\n const performed: LivenessChallenge[] = []\n let detector = makeChallengeDetector(challenges[0] ?? 'blink', this.tuning)\n\n const showPrompt = (done = false) => {\n const challenge = challenges[index]\n if (!challenge) {\n prompt.textContent = 'Hold still…'\n return\n }\n prompt.textContent = done\n ? `✓ ${CHALLENGE_LABELS[challenge]}`\n : `Step ${index + 1} of ${challenges.length}: ${CHALLENGE_LABELS[challenge]}`\n }\n\n // Arm the overlay for the current challenge: show its cue, reset the ring,\n // and highlight the active step dot.\n const armChallenge = () => {\n face.setCue(challenges[index] ?? null)\n face.setState('wait')\n face.setProgress(0)\n dots.setActive(index)\n }\n\n const finish = () => {\n advance.setAttribute('disabled', 'true')\n // Grab a still selfie from the live video before stopping the recorder, so\n // active liveness yields a face image for review + face matching.\n void this.camera\n .grabFrame(video)\n .then((selfie) =>\n Promise.resolve(recording?.stop() ?? Promise.resolve(null)).then((blob) =>\n this.handlers.onActiveLiveness(blob, performed, selfie),\n ),\n )\n }\n\n const advanceStep = () => {\n if (index >= challenges.length) return\n const current = challenges[index]\n if (current) performed.push(current)\n dots.markDone(index)\n index += 1\n if (index >= challenges.length) {\n finish()\n return\n }\n detector = makeChallengeDetector(challenges[index]!, this.tuning)\n showPrompt()\n armChallenge()\n if (index === challenges.length - 1) advance.textContent = 'Finish'\n }\n\n // Manual advance is only revealed as a fallback when detection can't run.\n const advance = this.button('Next', () => advanceStep())\n if (challenges.length <= 1) advance.textContent = 'Finish'\n let manualShown = false\n const showManualAdvance = () => {\n if (manualShown) return\n manualShown = true\n this.footer.appendChild(advance)\n }\n\n void this.camera\n .start(video, 'user')\n .then((stream) => {\n recording = this.camera.recordStart(stream)\n showPrompt()\n armChallenge()\n\n // Real detection when available: auto-advance only when the prompted\n // challenge is actually performed. Reveals the manual button if the\n // detector is absent or fails to load.\n const analyzer = this.analyzer\n if (!analyzer) {\n showManualAdvance()\n return\n }\n let cancelled = false\n this.cleanups.push(() => {\n cancelled = true\n })\n void analyzer.ready().then((ok) => {\n if (cancelled) return\n if (!ok) {\n showManualAdvance()\n return\n }\n // While the success check is held, pause detection so the next cue\n // doesn't flash in before the user sees the confirmation.\n let flashing = false\n const timer = setInterval(() => {\n if (index >= challenges.length) {\n clearInterval(timer)\n return\n }\n if (flashing) return\n const sample = analyzer.analyze(video)\n if (!sample) return\n const hit = detector.feed(sample)\n face.setProgress(detector.progress)\n if (hit) {\n face.setState('done')\n showPrompt(true)\n flashing = true\n const to = setTimeout(() => {\n flashing = false\n advanceStep()\n }, 650)\n this.cleanups.push(() => clearTimeout(to))\n } else {\n face.setState(detector.progress > 0 ? 'good' : 'wait')\n }\n }, 160)\n this.timers.push(timer)\n })\n })\n .catch(() => {\n face.stage.classList.add('arkyc-hidden')\n if (requireLiveCamera) {\n // Mandatory live camera was denied — require a retry, don't fall back.\n prompt.textContent = 'Camera access is required to continue. Please allow access and try again.'\n return\n }\n this.handlers.onActiveLiveness(null, challenges)\n })\n\n if (allowSkip) {\n const skip = this.button('Skip (demo)', () => this.handlers.onActiveLiveness(null, challenges))\n skip.classList.add('arkyc-btn-ghost')\n this.footer.appendChild(skip)\n }\n }\n\n /**\n * Build the circular selfie/liveness preview overlay: an SVG progress ring, a\n * gesture-cue layer, and a success checkmark — driven via the returned handles.\n *\n * @param video\n * @returns\n */\n private buildFaceStage(video: HTMLVideoElement): FaceStage {\n const stage = this.el('div', { class: 'arkyc-stage' })\n stage.setAttribute('data-state', 'wait')\n stage.appendChild(video)\n\n const ring = this.el('div', {\n class: 'arkyc-ring',\n html: '<svg viewBox=\"0 0 100 100\"><circle class=\"arkyc-ring-track\" cx=\"50\" cy=\"50\" r=\"46\"/><circle class=\"arkyc-ring-arc\" cx=\"50\" cy=\"50\" r=\"46\"/></svg>',\n })\n stage.appendChild(ring)\n const cue = this.el('div', { class: 'arkyc-cue' })\n stage.appendChild(cue)\n stage.appendChild(this.el('div', { class: 'arkyc-check', html: CHECK_ICON }))\n\n const arc = ring.querySelector('.arkyc-ring-arc') as SVGCircleElement | null\n const circumference = 2 * Math.PI * 46\n if (arc) {\n arc.style.strokeDasharray = String(circumference)\n arc.style.strokeDashoffset = String(circumference)\n }\n\n return {\n stage,\n setProgress: (p) => {\n if (arc) arc.style.strokeDashoffset = String(circumference * (1 - Math.max(0, Math.min(1, p))))\n },\n setState: (state) => stage.setAttribute('data-state', state),\n setCue: (challenge) => {\n cue.className = 'arkyc-cue' + (challenge ? ` show arkyc-cue-${challenge}` : '')\n cue.innerHTML = challenge ? CUE_ICONS[challenge] : ''\n },\n }\n }\n\n /**\n * Build the liveness step-progress dots (one per challenge).\n *\n * @param video\n * @param hint\n * @param doc\n */\n private buildDots(count: number): StepDots {\n const el = this.el('div', { class: 'arkyc-dots' })\n const dots: HTMLElement[] = []\n for (let i = 0; i < count; i += 1) {\n const dot = this.el('div', { class: 'arkyc-dot' })\n dots.push(dot)\n el.appendChild(dot)\n }\n return {\n el,\n setActive: (index) =>\n dots.forEach((d, i) => d.classList.toggle('active', i === index && !d.classList.contains('done'))),\n markDone: (index) => {\n const d = dots[index]\n if (d) {\n d.classList.remove('active')\n d.classList.add('done')\n }\n },\n }\n }\n\n /**\n * Build the document preview overlay: a fixed card-shaped alignment guide\n * (corner brackets + border) with an animated scan line. The guide is a target,\n * not a tracker — it stays put so the user aligns the card to it; detection only\n * tints it for quality and brightens it once a document is in view.\n *\n * @param video\n * @returns\n */\n private buildDocStage(video: HTMLVideoElement): DocStage {\n const stage = this.el('div', { class: 'arkyc-doc' })\n stage.setAttribute('data-q', 'wait')\n stage.appendChild(video)\n const frame = this.el('div', { class: 'arkyc-doc-frame' })\n for (const corner of ['tl', 'tr', 'bl', 'br']) {\n frame.appendChild(this.el('span', { class: `arkyc-corner ${corner}` }))\n }\n frame.appendChild(this.el('div', { class: 'arkyc-scan' }))\n stage.appendChild(frame)\n return {\n stage,\n setQuality: (quality) => stage.setAttribute('data-q', quality),\n // The guide never moves; a detected document only brightens it as feedback.\n setFrame: (rect) => stage.setAttribute('data-detected', rect ? 'true' : 'false'),\n }\n }\n\n private renderProcessing(label: string): void {\n this.body.appendChild(this.el('div', { class: 'arkyc-spinner' }))\n this.body.appendChild(this.el('p', { class: 'arkyc-p', text: label }))\n }\n\n private renderResult(\n decision: VerificationDecision | null,\n errorMessage?: string,\n opts: { terminal?: boolean; status?: VerificationStatus } = {},\n ): void {\n if (errorMessage) {\n this.body.appendChild(this.el('div', { class: 'arkyc-badge err', html: '!' }))\n this.body.appendChild(this.el('h2', { class: 'arkyc-h', text: 'Something went wrong' }))\n this.body.appendChild(this.el('p', { class: 'arkyc-p', text: errorMessage }))\n } else if (opts.terminal) {\n // The session was already finished/expired when this device opened it (e.g.\n // a stale handoff link). Show a notice, not the live result — and only Close.\n const n = TERMINAL_NOTICE[opts.status ?? 'expired'] ?? EXPIRED_NOTICE\n this.body.appendChild(this.el('div', { class: `arkyc-badge ${n.cls}`, text: n.icon }))\n this.body.appendChild(this.el('h2', { class: 'arkyc-h', text: n.title }))\n this.body.appendChild(this.el('p', { class: 'arkyc-p', text: n.copy }))\n this.footer.appendChild(this.button('Close', () => this.handlers.onClose()))\n return\n } else {\n const map = {\n approved: {\n cls: 'ok',\n icon: '✓',\n title: 'Verified',\n copy: 'Your identity has been verified.',\n },\n requires_review: {\n cls: 'warn',\n icon: '⏳',\n title: 'Under review',\n copy: 'Your verification is being reviewed. We will be in touch shortly.',\n },\n rejected: {\n cls: 'err',\n icon: '✕',\n title: 'Not verified',\n copy: 'We could not verify your identity. Please try again.',\n },\n } as const\n const r = map[decision ?? 'requires_review'] ?? map.requires_review\n this.body.appendChild(this.el('div', { class: `arkyc-badge ${r.cls}`, text: r.icon }))\n this.body.appendChild(this.el('h2', { class: 'arkyc-h', text: r.title }))\n this.body.appendChild(this.el('p', { class: 'arkyc-p', text: r.copy }))\n }\n this.footer.appendChild(this.button('Done', () => this.handlers.onAcknowledge()))\n }\n\n private button(label: string, onClick: () => void, extraClass?: string): HTMLButtonElement {\n const cls = extraClass ? `arkyc-btn ${extraClass}` : 'arkyc-btn'\n const btn = this.el('button', { class: cls, text: label }) as HTMLButtonElement\n // Guard against accidental double-clicks: a button fires once, then disables\n // and shows an inline loader while its (usually async) handler runs. The next\n // screen re-renders a fresh button, so this only spans the in-flight gap.\n let fired = false\n btn.addEventListener('click', () => {\n if (fired) return\n fired = true\n btn.setAttribute('disabled', 'true')\n btn.classList.add('arkyc-busy')\n onClick()\n })\n return btn\n }\n\n private clear(node: HTMLElement): void {\n while (node.firstChild) node.removeChild(node.firstChild)\n }\n\n private el<T extends HTMLElement = HTMLElement>(tag: string, props: ElProps = {}): T {\n const node = this.doc.createElement(tag) as T\n for (const [key, value] of Object.entries(props)) {\n if (value == null) continue\n if (key === 'class') node.className = value\n else if (key === 'text') node.textContent = value\n else if (key === 'html') node.innerHTML = value\n else if (key === 'value' || key === 'src' || key === 'type' || key === 'accept' || key === 'placeholder') {\n ;(node as unknown as Record<string, string>)[key] = value\n } else node.setAttribute(key, value)\n }\n return node\n }\n}\n","/**\n * Coarse desktop/mobile detection used to decide whether to offer cross-device\n * handoff. Handoff is most useful when the user starts on a desktop (no good\n * camera) and continues on a phone, so projects can restrict it to desktops.\n */\nexport function isDesktopDevice(nav: Navigator): boolean {\n const ua = nav.userAgent || ''\n // Require a positive desktop signal: an unknown/empty UA is treated as\n // non-desktop so the QR-first handoff flow never triggers on uncertainty.\n if (!ua) return false\n const mobile = /Android|iPhone|iPad|iPod|Opera Mini|IEMobile|Mobile|BlackBerry|Windows Phone/i.test(ua)\n // iPadOS 13+ masquerades as desktop Safari but reports touch points.\n const iPadOS = nav.platform === 'MacIntel' && (nav.maxTouchPoints ?? 0) > 1\n return !mobile && !iPadOS\n}\n","//---------------------------------------------------------------------\n//\n// QR Code Generator for JavaScript\n//\n// Copyright (c) 2009 Kazuhiko Arase\n//\n// URL: http://www.d-project.com/\n//\n// Licensed under the MIT license:\n// http://www.opensource.org/licenses/mit-license.php\n//\n// The word 'QR Code' is registered trademark of\n// DENSO WAVE INCORPORATED\n// http://www.denso-wave.com/qrcode/faqpatent-e.html\n//\n//---------------------------------------------------------------------\n\nvar qrcode = function() {\n\n //---------------------------------------------------------------------\n // qrcode\n //---------------------------------------------------------------------\n\n /**\n * qrcode\n * @param typeNumber 1 to 40\n * @param errorCorrectionLevel 'L','M','Q','H'\n */\n var qrcode = function(typeNumber, errorCorrectionLevel) {\n\n var PAD0 = 0xEC;\n var PAD1 = 0x11;\n\n var _typeNumber = typeNumber;\n var _errorCorrectionLevel = QRErrorCorrectionLevel[errorCorrectionLevel];\n var _modules = null;\n var _moduleCount = 0;\n var _dataCache = null;\n var _dataList = [];\n\n var _this = {};\n\n var makeImpl = function(test, maskPattern) {\n\n _moduleCount = _typeNumber * 4 + 17;\n _modules = function(moduleCount) {\n var modules = new Array(moduleCount);\n for (var row = 0; row < moduleCount; row += 1) {\n modules[row] = new Array(moduleCount);\n for (var col = 0; col < moduleCount; col += 1) {\n modules[row][col] = null;\n }\n }\n return modules;\n }(_moduleCount);\n\n setupPositionProbePattern(0, 0);\n setupPositionProbePattern(_moduleCount - 7, 0);\n setupPositionProbePattern(0, _moduleCount - 7);\n setupPositionAdjustPattern();\n setupTimingPattern();\n setupTypeInfo(test, maskPattern);\n\n if (_typeNumber >= 7) {\n setupTypeNumber(test);\n }\n\n if (_dataCache == null) {\n _dataCache = createData(_typeNumber, _errorCorrectionLevel, _dataList);\n }\n\n mapData(_dataCache, maskPattern);\n };\n\n var setupPositionProbePattern = function(row, col) {\n\n for (var r = -1; r <= 7; r += 1) {\n\n if (row + r <= -1 || _moduleCount <= row + r) continue;\n\n for (var c = -1; c <= 7; c += 1) {\n\n if (col + c <= -1 || _moduleCount <= col + c) continue;\n\n if ( (0 <= r && r <= 6 && (c == 0 || c == 6) )\n || (0 <= c && c <= 6 && (r == 0 || r == 6) )\n || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {\n _modules[row + r][col + c] = true;\n } else {\n _modules[row + r][col + c] = false;\n }\n }\n }\n };\n\n var getBestMaskPattern = function() {\n\n var minLostPoint = 0;\n var pattern = 0;\n\n for (var i = 0; i < 8; i += 1) {\n\n makeImpl(true, i);\n\n var lostPoint = QRUtil.getLostPoint(_this);\n\n if (i == 0 || minLostPoint > lostPoint) {\n minLostPoint = lostPoint;\n pattern = i;\n }\n }\n\n return pattern;\n };\n\n var setupTimingPattern = function() {\n\n for (var r = 8; r < _moduleCount - 8; r += 1) {\n if (_modules[r][6] != null) {\n continue;\n }\n _modules[r][6] = (r % 2 == 0);\n }\n\n for (var c = 8; c < _moduleCount - 8; c += 1) {\n if (_modules[6][c] != null) {\n continue;\n }\n _modules[6][c] = (c % 2 == 0);\n }\n };\n\n var setupPositionAdjustPattern = function() {\n\n var pos = QRUtil.getPatternPosition(_typeNumber);\n\n for (var i = 0; i < pos.length; i += 1) {\n\n for (var j = 0; j < pos.length; j += 1) {\n\n var row = pos[i];\n var col = pos[j];\n\n if (_modules[row][col] != null) {\n continue;\n }\n\n for (var r = -2; r <= 2; r += 1) {\n\n for (var c = -2; c <= 2; c += 1) {\n\n if (r == -2 || r == 2 || c == -2 || c == 2\n || (r == 0 && c == 0) ) {\n _modules[row + r][col + c] = true;\n } else {\n _modules[row + r][col + c] = false;\n }\n }\n }\n }\n }\n };\n\n var setupTypeNumber = function(test) {\n\n var bits = QRUtil.getBCHTypeNumber(_typeNumber);\n\n for (var i = 0; i < 18; i += 1) {\n var mod = (!test && ( (bits >> i) & 1) == 1);\n _modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod;\n }\n\n for (var i = 0; i < 18; i += 1) {\n var mod = (!test && ( (bits >> i) & 1) == 1);\n _modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod;\n }\n };\n\n var setupTypeInfo = function(test, maskPattern) {\n\n var data = (_errorCorrectionLevel << 3) | maskPattern;\n var bits = QRUtil.getBCHTypeInfo(data);\n\n // vertical\n for (var i = 0; i < 15; i += 1) {\n\n var mod = (!test && ( (bits >> i) & 1) == 1);\n\n if (i < 6) {\n _modules[i][8] = mod;\n } else if (i < 8) {\n _modules[i + 1][8] = mod;\n } else {\n _modules[_moduleCount - 15 + i][8] = mod;\n }\n }\n\n // horizontal\n for (var i = 0; i < 15; i += 1) {\n\n var mod = (!test && ( (bits >> i) & 1) == 1);\n\n if (i < 8) {\n _modules[8][_moduleCount - i - 1] = mod;\n } else if (i < 9) {\n _modules[8][15 - i - 1 + 1] = mod;\n } else {\n _modules[8][15 - i - 1] = mod;\n }\n }\n\n // fixed module\n _modules[_moduleCount - 8][8] = (!test);\n };\n\n var mapData = function(data, maskPattern) {\n\n var inc = -1;\n var row = _moduleCount - 1;\n var bitIndex = 7;\n var byteIndex = 0;\n var maskFunc = QRUtil.getMaskFunction(maskPattern);\n\n for (var col = _moduleCount - 1; col > 0; col -= 2) {\n\n if (col == 6) col -= 1;\n\n while (true) {\n\n for (var c = 0; c < 2; c += 1) {\n\n if (_modules[row][col - c] == null) {\n\n var dark = false;\n\n if (byteIndex < data.length) {\n dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);\n }\n\n var mask = maskFunc(row, col - c);\n\n if (mask) {\n dark = !dark;\n }\n\n _modules[row][col - c] = dark;\n bitIndex -= 1;\n\n if (bitIndex == -1) {\n byteIndex += 1;\n bitIndex = 7;\n }\n }\n }\n\n row += inc;\n\n if (row < 0 || _moduleCount <= row) {\n row -= inc;\n inc = -inc;\n break;\n }\n }\n }\n };\n\n var createBytes = function(buffer, rsBlocks) {\n\n var offset = 0;\n\n var maxDcCount = 0;\n var maxEcCount = 0;\n\n var dcdata = new Array(rsBlocks.length);\n var ecdata = new Array(rsBlocks.length);\n\n for (var r = 0; r < rsBlocks.length; r += 1) {\n\n var dcCount = rsBlocks[r].dataCount;\n var ecCount = rsBlocks[r].totalCount - dcCount;\n\n maxDcCount = Math.max(maxDcCount, dcCount);\n maxEcCount = Math.max(maxEcCount, ecCount);\n\n dcdata[r] = new Array(dcCount);\n\n for (var i = 0; i < dcdata[r].length; i += 1) {\n dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset];\n }\n offset += dcCount;\n\n var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);\n var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1);\n\n var modPoly = rawPoly.mod(rsPoly);\n ecdata[r] = new Array(rsPoly.getLength() - 1);\n for (var i = 0; i < ecdata[r].length; i += 1) {\n var modIndex = i + modPoly.getLength() - ecdata[r].length;\n ecdata[r][i] = (modIndex >= 0)? modPoly.getAt(modIndex) : 0;\n }\n }\n\n var totalCodeCount = 0;\n for (var i = 0; i < rsBlocks.length; i += 1) {\n totalCodeCount += rsBlocks[i].totalCount;\n }\n\n var data = new Array(totalCodeCount);\n var index = 0;\n\n for (var i = 0; i < maxDcCount; i += 1) {\n for (var r = 0; r < rsBlocks.length; r += 1) {\n if (i < dcdata[r].length) {\n data[index] = dcdata[r][i];\n index += 1;\n }\n }\n }\n\n for (var i = 0; i < maxEcCount; i += 1) {\n for (var r = 0; r < rsBlocks.length; r += 1) {\n if (i < ecdata[r].length) {\n data[index] = ecdata[r][i];\n index += 1;\n }\n }\n }\n\n return data;\n };\n\n var createData = function(typeNumber, errorCorrectionLevel, dataList) {\n\n var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectionLevel);\n\n var buffer = qrBitBuffer();\n\n for (var i = 0; i < dataList.length; i += 1) {\n var data = dataList[i];\n buffer.put(data.getMode(), 4);\n buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );\n data.write(buffer);\n }\n\n // calc num max data.\n var totalDataCount = 0;\n for (var i = 0; i < rsBlocks.length; i += 1) {\n totalDataCount += rsBlocks[i].dataCount;\n }\n\n if (buffer.getLengthInBits() > totalDataCount * 8) {\n throw 'code length overflow. ('\n + buffer.getLengthInBits()\n + '>'\n + totalDataCount * 8\n + ')';\n }\n\n // end code\n if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {\n buffer.put(0, 4);\n }\n\n // padding\n while (buffer.getLengthInBits() % 8 != 0) {\n buffer.putBit(false);\n }\n\n // padding\n while (true) {\n\n if (buffer.getLengthInBits() >= totalDataCount * 8) {\n break;\n }\n buffer.put(PAD0, 8);\n\n if (buffer.getLengthInBits() >= totalDataCount * 8) {\n break;\n }\n buffer.put(PAD1, 8);\n }\n\n return createBytes(buffer, rsBlocks);\n };\n\n _this.addData = function(data, mode) {\n\n mode = mode || 'Byte';\n\n var newData = null;\n\n switch(mode) {\n case 'Numeric' :\n newData = qrNumber(data);\n break;\n case 'Alphanumeric' :\n newData = qrAlphaNum(data);\n break;\n case 'Byte' :\n newData = qr8BitByte(data);\n break;\n case 'Kanji' :\n newData = qrKanji(data);\n break;\n default :\n throw 'mode:' + mode;\n }\n\n _dataList.push(newData);\n _dataCache = null;\n };\n\n _this.isDark = function(row, col) {\n if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) {\n throw row + ',' + col;\n }\n return _modules[row][col];\n };\n\n _this.getModuleCount = function() {\n return _moduleCount;\n };\n\n _this.make = function() {\n if (_typeNumber < 1) {\n var typeNumber = 1;\n\n for (; typeNumber < 40; typeNumber++) {\n var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, _errorCorrectionLevel);\n var buffer = qrBitBuffer();\n\n for (var i = 0; i < _dataList.length; i++) {\n var data = _dataList[i];\n buffer.put(data.getMode(), 4);\n buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );\n data.write(buffer);\n }\n\n var totalDataCount = 0;\n for (var i = 0; i < rsBlocks.length; i++) {\n totalDataCount += rsBlocks[i].dataCount;\n }\n\n if (buffer.getLengthInBits() <= totalDataCount * 8) {\n break;\n }\n }\n\n _typeNumber = typeNumber;\n }\n\n makeImpl(false, getBestMaskPattern() );\n };\n\n _this.createTableTag = function(cellSize, margin) {\n\n cellSize = cellSize || 2;\n margin = (typeof margin == 'undefined')? cellSize * 4 : margin;\n\n var qrHtml = '';\n\n qrHtml += '<table style=\"';\n qrHtml += ' border-width: 0px; border-style: none;';\n qrHtml += ' border-collapse: collapse;';\n qrHtml += ' padding: 0px; margin: ' + margin + 'px;';\n qrHtml += '\">';\n qrHtml += '<tbody>';\n\n for (var r = 0; r < _this.getModuleCount(); r += 1) {\n\n qrHtml += '<tr>';\n\n for (var c = 0; c < _this.getModuleCount(); c += 1) {\n qrHtml += '<td style=\"';\n qrHtml += ' border-width: 0px; border-style: none;';\n qrHtml += ' border-collapse: collapse;';\n qrHtml += ' padding: 0px; margin: 0px;';\n qrHtml += ' width: ' + cellSize + 'px;';\n qrHtml += ' height: ' + cellSize + 'px;';\n qrHtml += ' background-color: ';\n qrHtml += _this.isDark(r, c)? '#000000' : '#ffffff';\n qrHtml += ';';\n qrHtml += '\"/>';\n }\n\n qrHtml += '</tr>';\n }\n\n qrHtml += '</tbody>';\n qrHtml += '</table>';\n\n return qrHtml;\n };\n\n _this.createSvgTag = function(cellSize, margin, alt, title) {\n\n var opts = {};\n if (typeof arguments[0] == 'object') {\n // Called by options.\n opts = arguments[0];\n // overwrite cellSize and margin.\n cellSize = opts.cellSize;\n margin = opts.margin;\n alt = opts.alt;\n title = opts.title;\n }\n\n cellSize = cellSize || 2;\n margin = (typeof margin == 'undefined')? cellSize * 4 : margin;\n\n // Compose alt property surrogate\n alt = (typeof alt === 'string') ? {text: alt} : alt || {};\n alt.text = alt.text || null;\n alt.id = (alt.text) ? alt.id || 'qrcode-description' : null;\n\n // Compose title property surrogate\n title = (typeof title === 'string') ? {text: title} : title || {};\n title.text = title.text || null;\n title.id = (title.text) ? title.id || 'qrcode-title' : null;\n\n var size = _this.getModuleCount() * cellSize + margin * 2;\n var c, mc, r, mr, qrSvg='', rect;\n\n rect = 'l' + cellSize + ',0 0,' + cellSize +\n ' -' + cellSize + ',0 0,-' + cellSize + 'z ';\n\n qrSvg += '<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"';\n qrSvg += !opts.scalable ? ' width=\"' + size + 'px\" height=\"' + size + 'px\"' : '';\n qrSvg += ' viewBox=\"0 0 ' + size + ' ' + size + '\" ';\n qrSvg += ' preserveAspectRatio=\"xMinYMin meet\"';\n qrSvg += (title.text || alt.text) ? ' role=\"img\" aria-labelledby=\"' +\n escapeXml([title.id, alt.id].join(' ').trim() ) + '\"' : '';\n qrSvg += '>';\n qrSvg += (title.text) ? '<title id=\"' + escapeXml(title.id) + '\">' +\n escapeXml(title.text) + '</title>' : '';\n qrSvg += (alt.text) ? '<description id=\"' + escapeXml(alt.id) + '\">' +\n escapeXml(alt.text) + '</description>' : '';\n qrSvg += '<rect width=\"100%\" height=\"100%\" fill=\"white\" cx=\"0\" cy=\"0\"/>';\n qrSvg += '<path d=\"';\n\n for (r = 0; r < _this.getModuleCount(); r += 1) {\n mr = r * cellSize + margin;\n for (c = 0; c < _this.getModuleCount(); c += 1) {\n if (_this.isDark(r, c) ) {\n mc = c*cellSize+margin;\n qrSvg += 'M' + mc + ',' + mr + rect;\n }\n }\n }\n\n qrSvg += '\" stroke=\"transparent\" fill=\"black\"/>';\n qrSvg += '</svg>';\n\n return qrSvg;\n };\n\n _this.createDataURL = function(cellSize, margin) {\n\n cellSize = cellSize || 2;\n margin = (typeof margin == 'undefined')? cellSize * 4 : margin;\n\n var size = _this.getModuleCount() * cellSize + margin * 2;\n var min = margin;\n var max = size - margin;\n\n return createDataURL(size, size, function(x, y) {\n if (min <= x && x < max && min <= y && y < max) {\n var c = Math.floor( (x - min) / cellSize);\n var r = Math.floor( (y - min) / cellSize);\n return _this.isDark(r, c)? 0 : 1;\n } else {\n return 1;\n }\n } );\n };\n\n _this.createImgTag = function(cellSize, margin, alt) {\n\n cellSize = cellSize || 2;\n margin = (typeof margin == 'undefined')? cellSize * 4 : margin;\n\n var size = _this.getModuleCount() * cellSize + margin * 2;\n\n var img = '';\n img += '<img';\n img += '\\u0020src=\"';\n img += _this.createDataURL(cellSize, margin);\n img += '\"';\n img += '\\u0020width=\"';\n img += size;\n img += '\"';\n img += '\\u0020height=\"';\n img += size;\n img += '\"';\n if (alt) {\n img += '\\u0020alt=\"';\n img += escapeXml(alt);\n img += '\"';\n }\n img += '/>';\n\n return img;\n };\n\n var escapeXml = function(s) {\n var escaped = '';\n for (var i = 0; i < s.length; i += 1) {\n var c = s.charAt(i);\n switch(c) {\n case '<': escaped += '&lt;'; break;\n case '>': escaped += '&gt;'; break;\n case '&': escaped += '&amp;'; break;\n case '\"': escaped += '&quot;'; break;\n default : escaped += c; break;\n }\n }\n return escaped;\n };\n\n var _createHalfASCII = function(margin) {\n var cellSize = 1;\n margin = (typeof margin == 'undefined')? cellSize * 2 : margin;\n\n var size = _this.getModuleCount() * cellSize + margin * 2;\n var min = margin;\n var max = size - margin;\n\n var y, x, r1, r2, p;\n\n var blocks = {\n '██': '█',\n '█ ': '▀',\n ' █': '▄',\n ' ': ' '\n };\n\n var blocksLastLineNoMargin = {\n '██': '▀',\n '█ ': '▀',\n ' █': ' ',\n ' ': ' '\n };\n\n var ascii = '';\n for (y = 0; y < size; y += 2) {\n r1 = Math.floor((y - min) / cellSize);\n r2 = Math.floor((y + 1 - min) / cellSize);\n for (x = 0; x < size; x += 1) {\n p = '█';\n\n if (min <= x && x < max && min <= y && y < max && _this.isDark(r1, Math.floor((x - min) / cellSize))) {\n p = ' ';\n }\n\n if (min <= x && x < max && min <= y+1 && y+1 < max && _this.isDark(r2, Math.floor((x - min) / cellSize))) {\n p += ' ';\n }\n else {\n p += '█';\n }\n\n // Output 2 characters per pixel, to create full square. 1 character per pixels gives only half width of square.\n ascii += (margin < 1 && y+1 >= max) ? blocksLastLineNoMargin[p] : blocks[p];\n }\n\n ascii += '\\n';\n }\n\n if (size % 2 && margin > 0) {\n return ascii.substring(0, ascii.length - size - 1) + Array(size+1).join('▀');\n }\n\n return ascii.substring(0, ascii.length-1);\n };\n\n _this.createASCII = function(cellSize, margin) {\n cellSize = cellSize || 1;\n\n if (cellSize < 2) {\n return _createHalfASCII(margin);\n }\n\n cellSize -= 1;\n margin = (typeof margin == 'undefined')? cellSize * 2 : margin;\n\n var size = _this.getModuleCount() * cellSize + margin * 2;\n var min = margin;\n var max = size - margin;\n\n var y, x, r, p;\n\n var white = Array(cellSize+1).join('██');\n var black = Array(cellSize+1).join(' ');\n\n var ascii = '';\n var line = '';\n for (y = 0; y < size; y += 1) {\n r = Math.floor( (y - min) / cellSize);\n line = '';\n for (x = 0; x < size; x += 1) {\n p = 1;\n\n if (min <= x && x < max && min <= y && y < max && _this.isDark(r, Math.floor((x - min) / cellSize))) {\n p = 0;\n }\n\n // Output 2 characters per pixel, to create full square. 1 character per pixels gives only half width of square.\n line += p ? white : black;\n }\n\n for (r = 0; r < cellSize; r += 1) {\n ascii += line + '\\n';\n }\n }\n\n return ascii.substring(0, ascii.length-1);\n };\n\n _this.renderTo2dContext = function(context, cellSize) {\n cellSize = cellSize || 2;\n var length = _this.getModuleCount();\n for (var row = 0; row < length; row++) {\n for (var col = 0; col < length; col++) {\n context.fillStyle = _this.isDark(row, col) ? 'black' : 'white';\n context.fillRect(row * cellSize, col * cellSize, cellSize, cellSize);\n }\n }\n }\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // qrcode.stringToBytes\n //---------------------------------------------------------------------\n\n qrcode.stringToBytesFuncs = {\n 'default' : function(s) {\n var bytes = [];\n for (var i = 0; i < s.length; i += 1) {\n var c = s.charCodeAt(i);\n bytes.push(c & 0xff);\n }\n return bytes;\n }\n };\n\n qrcode.stringToBytes = qrcode.stringToBytesFuncs['default'];\n\n //---------------------------------------------------------------------\n // qrcode.createStringToBytes\n //---------------------------------------------------------------------\n\n /**\n * @param unicodeData base64 string of byte array.\n * [16bit Unicode],[16bit Bytes], ...\n * @param numChars\n */\n qrcode.createStringToBytes = function(unicodeData, numChars) {\n\n // create conversion map.\n\n var unicodeMap = function() {\n\n var bin = base64DecodeInputStream(unicodeData);\n var read = function() {\n var b = bin.read();\n if (b == -1) throw 'eof';\n return b;\n };\n\n var count = 0;\n var unicodeMap = {};\n while (true) {\n var b0 = bin.read();\n if (b0 == -1) break;\n var b1 = read();\n var b2 = read();\n var b3 = read();\n var k = String.fromCharCode( (b0 << 8) | b1);\n var v = (b2 << 8) | b3;\n unicodeMap[k] = v;\n count += 1;\n }\n if (count != numChars) {\n throw count + ' != ' + numChars;\n }\n\n return unicodeMap;\n }();\n\n var unknownChar = '?'.charCodeAt(0);\n\n return function(s) {\n var bytes = [];\n for (var i = 0; i < s.length; i += 1) {\n var c = s.charCodeAt(i);\n if (c < 128) {\n bytes.push(c);\n } else {\n var b = unicodeMap[s.charAt(i)];\n if (typeof b == 'number') {\n if ( (b & 0xff) == b) {\n // 1byte\n bytes.push(b);\n } else {\n // 2bytes\n bytes.push(b >>> 8);\n bytes.push(b & 0xff);\n }\n } else {\n bytes.push(unknownChar);\n }\n }\n }\n return bytes;\n };\n };\n\n //---------------------------------------------------------------------\n // QRMode\n //---------------------------------------------------------------------\n\n var QRMode = {\n MODE_NUMBER : 1 << 0,\n MODE_ALPHA_NUM : 1 << 1,\n MODE_8BIT_BYTE : 1 << 2,\n MODE_KANJI : 1 << 3\n };\n\n //---------------------------------------------------------------------\n // QRErrorCorrectionLevel\n //---------------------------------------------------------------------\n\n var QRErrorCorrectionLevel = {\n L : 1,\n M : 0,\n Q : 3,\n H : 2\n };\n\n //---------------------------------------------------------------------\n // QRMaskPattern\n //---------------------------------------------------------------------\n\n var QRMaskPattern = {\n PATTERN000 : 0,\n PATTERN001 : 1,\n PATTERN010 : 2,\n PATTERN011 : 3,\n PATTERN100 : 4,\n PATTERN101 : 5,\n PATTERN110 : 6,\n PATTERN111 : 7\n };\n\n //---------------------------------------------------------------------\n // QRUtil\n //---------------------------------------------------------------------\n\n var QRUtil = function() {\n\n var PATTERN_POSITION_TABLE = [\n [],\n [6, 18],\n [6, 22],\n [6, 26],\n [6, 30],\n [6, 34],\n [6, 22, 38],\n [6, 24, 42],\n [6, 26, 46],\n [6, 28, 50],\n [6, 30, 54],\n [6, 32, 58],\n [6, 34, 62],\n [6, 26, 46, 66],\n [6, 26, 48, 70],\n [6, 26, 50, 74],\n [6, 30, 54, 78],\n [6, 30, 56, 82],\n [6, 30, 58, 86],\n [6, 34, 62, 90],\n [6, 28, 50, 72, 94],\n [6, 26, 50, 74, 98],\n [6, 30, 54, 78, 102],\n [6, 28, 54, 80, 106],\n [6, 32, 58, 84, 110],\n [6, 30, 58, 86, 114],\n [6, 34, 62, 90, 118],\n [6, 26, 50, 74, 98, 122],\n [6, 30, 54, 78, 102, 126],\n [6, 26, 52, 78, 104, 130],\n [6, 30, 56, 82, 108, 134],\n [6, 34, 60, 86, 112, 138],\n [6, 30, 58, 86, 114, 142],\n [6, 34, 62, 90, 118, 146],\n [6, 30, 54, 78, 102, 126, 150],\n [6, 24, 50, 76, 102, 128, 154],\n [6, 28, 54, 80, 106, 132, 158],\n [6, 32, 58, 84, 110, 136, 162],\n [6, 26, 54, 82, 110, 138, 166],\n [6, 30, 58, 86, 114, 142, 170]\n ];\n var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0);\n var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0);\n var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1);\n\n var _this = {};\n\n var getBCHDigit = function(data) {\n var digit = 0;\n while (data != 0) {\n digit += 1;\n data >>>= 1;\n }\n return digit;\n };\n\n _this.getBCHTypeInfo = function(data) {\n var d = data << 10;\n while (getBCHDigit(d) - getBCHDigit(G15) >= 0) {\n d ^= (G15 << (getBCHDigit(d) - getBCHDigit(G15) ) );\n }\n return ( (data << 10) | d) ^ G15_MASK;\n };\n\n _this.getBCHTypeNumber = function(data) {\n var d = data << 12;\n while (getBCHDigit(d) - getBCHDigit(G18) >= 0) {\n d ^= (G18 << (getBCHDigit(d) - getBCHDigit(G18) ) );\n }\n return (data << 12) | d;\n };\n\n _this.getPatternPosition = function(typeNumber) {\n return PATTERN_POSITION_TABLE[typeNumber - 1];\n };\n\n _this.getMaskFunction = function(maskPattern) {\n\n switch (maskPattern) {\n\n case QRMaskPattern.PATTERN000 :\n return function(i, j) { return (i + j) % 2 == 0; };\n case QRMaskPattern.PATTERN001 :\n return function(i, j) { return i % 2 == 0; };\n case QRMaskPattern.PATTERN010 :\n return function(i, j) { return j % 3 == 0; };\n case QRMaskPattern.PATTERN011 :\n return function(i, j) { return (i + j) % 3 == 0; };\n case QRMaskPattern.PATTERN100 :\n return function(i, j) { return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; };\n case QRMaskPattern.PATTERN101 :\n return function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; };\n case QRMaskPattern.PATTERN110 :\n return function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; };\n case QRMaskPattern.PATTERN111 :\n return function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; };\n\n default :\n throw 'bad maskPattern:' + maskPattern;\n }\n };\n\n _this.getErrorCorrectPolynomial = function(errorCorrectLength) {\n var a = qrPolynomial([1], 0);\n for (var i = 0; i < errorCorrectLength; i += 1) {\n a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0) );\n }\n return a;\n };\n\n _this.getLengthInBits = function(mode, type) {\n\n if (1 <= type && type < 10) {\n\n // 1 - 9\n\n switch(mode) {\n case QRMode.MODE_NUMBER : return 10;\n case QRMode.MODE_ALPHA_NUM : return 9;\n case QRMode.MODE_8BIT_BYTE : return 8;\n case QRMode.MODE_KANJI : return 8;\n default :\n throw 'mode:' + mode;\n }\n\n } else if (type < 27) {\n\n // 10 - 26\n\n switch(mode) {\n case QRMode.MODE_NUMBER : return 12;\n case QRMode.MODE_ALPHA_NUM : return 11;\n case QRMode.MODE_8BIT_BYTE : return 16;\n case QRMode.MODE_KANJI : return 10;\n default :\n throw 'mode:' + mode;\n }\n\n } else if (type < 41) {\n\n // 27 - 40\n\n switch(mode) {\n case QRMode.MODE_NUMBER : return 14;\n case QRMode.MODE_ALPHA_NUM : return 13;\n case QRMode.MODE_8BIT_BYTE : return 16;\n case QRMode.MODE_KANJI : return 12;\n default :\n throw 'mode:' + mode;\n }\n\n } else {\n throw 'type:' + type;\n }\n };\n\n _this.getLostPoint = function(qrcode) {\n\n var moduleCount = qrcode.getModuleCount();\n\n var lostPoint = 0;\n\n // LEVEL1\n\n for (var row = 0; row < moduleCount; row += 1) {\n for (var col = 0; col < moduleCount; col += 1) {\n\n var sameCount = 0;\n var dark = qrcode.isDark(row, col);\n\n for (var r = -1; r <= 1; r += 1) {\n\n if (row + r < 0 || moduleCount <= row + r) {\n continue;\n }\n\n for (var c = -1; c <= 1; c += 1) {\n\n if (col + c < 0 || moduleCount <= col + c) {\n continue;\n }\n\n if (r == 0 && c == 0) {\n continue;\n }\n\n if (dark == qrcode.isDark(row + r, col + c) ) {\n sameCount += 1;\n }\n }\n }\n\n if (sameCount > 5) {\n lostPoint += (3 + sameCount - 5);\n }\n }\n };\n\n // LEVEL2\n\n for (var row = 0; row < moduleCount - 1; row += 1) {\n for (var col = 0; col < moduleCount - 1; col += 1) {\n var count = 0;\n if (qrcode.isDark(row, col) ) count += 1;\n if (qrcode.isDark(row + 1, col) ) count += 1;\n if (qrcode.isDark(row, col + 1) ) count += 1;\n if (qrcode.isDark(row + 1, col + 1) ) count += 1;\n if (count == 0 || count == 4) {\n lostPoint += 3;\n }\n }\n }\n\n // LEVEL3\n\n for (var row = 0; row < moduleCount; row += 1) {\n for (var col = 0; col < moduleCount - 6; col += 1) {\n if (qrcode.isDark(row, col)\n && !qrcode.isDark(row, col + 1)\n && qrcode.isDark(row, col + 2)\n && qrcode.isDark(row, col + 3)\n && qrcode.isDark(row, col + 4)\n && !qrcode.isDark(row, col + 5)\n && qrcode.isDark(row, col + 6) ) {\n lostPoint += 40;\n }\n }\n }\n\n for (var col = 0; col < moduleCount; col += 1) {\n for (var row = 0; row < moduleCount - 6; row += 1) {\n if (qrcode.isDark(row, col)\n && !qrcode.isDark(row + 1, col)\n && qrcode.isDark(row + 2, col)\n && qrcode.isDark(row + 3, col)\n && qrcode.isDark(row + 4, col)\n && !qrcode.isDark(row + 5, col)\n && qrcode.isDark(row + 6, col) ) {\n lostPoint += 40;\n }\n }\n }\n\n // LEVEL4\n\n var darkCount = 0;\n\n for (var col = 0; col < moduleCount; col += 1) {\n for (var row = 0; row < moduleCount; row += 1) {\n if (qrcode.isDark(row, col) ) {\n darkCount += 1;\n }\n }\n }\n\n var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;\n lostPoint += ratio * 10;\n\n return lostPoint;\n };\n\n return _this;\n }();\n\n //---------------------------------------------------------------------\n // QRMath\n //---------------------------------------------------------------------\n\n var QRMath = function() {\n\n var EXP_TABLE = new Array(256);\n var LOG_TABLE = new Array(256);\n\n // initialize tables\n for (var i = 0; i < 8; i += 1) {\n EXP_TABLE[i] = 1 << i;\n }\n for (var i = 8; i < 256; i += 1) {\n EXP_TABLE[i] = EXP_TABLE[i - 4]\n ^ EXP_TABLE[i - 5]\n ^ EXP_TABLE[i - 6]\n ^ EXP_TABLE[i - 8];\n }\n for (var i = 0; i < 255; i += 1) {\n LOG_TABLE[EXP_TABLE[i] ] = i;\n }\n\n var _this = {};\n\n _this.glog = function(n) {\n\n if (n < 1) {\n throw 'glog(' + n + ')';\n }\n\n return LOG_TABLE[n];\n };\n\n _this.gexp = function(n) {\n\n while (n < 0) {\n n += 255;\n }\n\n while (n >= 256) {\n n -= 255;\n }\n\n return EXP_TABLE[n];\n };\n\n return _this;\n }();\n\n //---------------------------------------------------------------------\n // qrPolynomial\n //---------------------------------------------------------------------\n\n function qrPolynomial(num, shift) {\n\n if (typeof num.length == 'undefined') {\n throw num.length + '/' + shift;\n }\n\n var _num = function() {\n var offset = 0;\n while (offset < num.length && num[offset] == 0) {\n offset += 1;\n }\n var _num = new Array(num.length - offset + shift);\n for (var i = 0; i < num.length - offset; i += 1) {\n _num[i] = num[i + offset];\n }\n return _num;\n }();\n\n var _this = {};\n\n _this.getAt = function(index) {\n return _num[index];\n };\n\n _this.getLength = function() {\n return _num.length;\n };\n\n _this.multiply = function(e) {\n\n var num = new Array(_this.getLength() + e.getLength() - 1);\n\n for (var i = 0; i < _this.getLength(); i += 1) {\n for (var j = 0; j < e.getLength(); j += 1) {\n num[i + j] ^= QRMath.gexp(QRMath.glog(_this.getAt(i) ) + QRMath.glog(e.getAt(j) ) );\n }\n }\n\n return qrPolynomial(num, 0);\n };\n\n _this.mod = function(e) {\n\n if (_this.getLength() - e.getLength() < 0) {\n return _this;\n }\n\n var ratio = QRMath.glog(_this.getAt(0) ) - QRMath.glog(e.getAt(0) );\n\n var num = new Array(_this.getLength() );\n for (var i = 0; i < _this.getLength(); i += 1) {\n num[i] = _this.getAt(i);\n }\n\n for (var i = 0; i < e.getLength(); i += 1) {\n num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i) ) + ratio);\n }\n\n // recursive call\n return qrPolynomial(num, 0).mod(e);\n };\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // QRRSBlock\n //---------------------------------------------------------------------\n\n var QRRSBlock = function() {\n\n var RS_BLOCK_TABLE = [\n\n // L\n // M\n // Q\n // H\n\n // 1\n [1, 26, 19],\n [1, 26, 16],\n [1, 26, 13],\n [1, 26, 9],\n\n // 2\n [1, 44, 34],\n [1, 44, 28],\n [1, 44, 22],\n [1, 44, 16],\n\n // 3\n [1, 70, 55],\n [1, 70, 44],\n [2, 35, 17],\n [2, 35, 13],\n\n // 4\n [1, 100, 80],\n [2, 50, 32],\n [2, 50, 24],\n [4, 25, 9],\n\n // 5\n [1, 134, 108],\n [2, 67, 43],\n [2, 33, 15, 2, 34, 16],\n [2, 33, 11, 2, 34, 12],\n\n // 6\n [2, 86, 68],\n [4, 43, 27],\n [4, 43, 19],\n [4, 43, 15],\n\n // 7\n [2, 98, 78],\n [4, 49, 31],\n [2, 32, 14, 4, 33, 15],\n [4, 39, 13, 1, 40, 14],\n\n // 8\n [2, 121, 97],\n [2, 60, 38, 2, 61, 39],\n [4, 40, 18, 2, 41, 19],\n [4, 40, 14, 2, 41, 15],\n\n // 9\n [2, 146, 116],\n [3, 58, 36, 2, 59, 37],\n [4, 36, 16, 4, 37, 17],\n [4, 36, 12, 4, 37, 13],\n\n // 10\n [2, 86, 68, 2, 87, 69],\n [4, 69, 43, 1, 70, 44],\n [6, 43, 19, 2, 44, 20],\n [6, 43, 15, 2, 44, 16],\n\n // 11\n [4, 101, 81],\n [1, 80, 50, 4, 81, 51],\n [4, 50, 22, 4, 51, 23],\n [3, 36, 12, 8, 37, 13],\n\n // 12\n [2, 116, 92, 2, 117, 93],\n [6, 58, 36, 2, 59, 37],\n [4, 46, 20, 6, 47, 21],\n [7, 42, 14, 4, 43, 15],\n\n // 13\n [4, 133, 107],\n [8, 59, 37, 1, 60, 38],\n [8, 44, 20, 4, 45, 21],\n [12, 33, 11, 4, 34, 12],\n\n // 14\n [3, 145, 115, 1, 146, 116],\n [4, 64, 40, 5, 65, 41],\n [11, 36, 16, 5, 37, 17],\n [11, 36, 12, 5, 37, 13],\n\n // 15\n [5, 109, 87, 1, 110, 88],\n [5, 65, 41, 5, 66, 42],\n [5, 54, 24, 7, 55, 25],\n [11, 36, 12, 7, 37, 13],\n\n // 16\n [5, 122, 98, 1, 123, 99],\n [7, 73, 45, 3, 74, 46],\n [15, 43, 19, 2, 44, 20],\n [3, 45, 15, 13, 46, 16],\n\n // 17\n [1, 135, 107, 5, 136, 108],\n [10, 74, 46, 1, 75, 47],\n [1, 50, 22, 15, 51, 23],\n [2, 42, 14, 17, 43, 15],\n\n // 18\n [5, 150, 120, 1, 151, 121],\n [9, 69, 43, 4, 70, 44],\n [17, 50, 22, 1, 51, 23],\n [2, 42, 14, 19, 43, 15],\n\n // 19\n [3, 141, 113, 4, 142, 114],\n [3, 70, 44, 11, 71, 45],\n [17, 47, 21, 4, 48, 22],\n [9, 39, 13, 16, 40, 14],\n\n // 20\n [3, 135, 107, 5, 136, 108],\n [3, 67, 41, 13, 68, 42],\n [15, 54, 24, 5, 55, 25],\n [15, 43, 15, 10, 44, 16],\n\n // 21\n [4, 144, 116, 4, 145, 117],\n [17, 68, 42],\n [17, 50, 22, 6, 51, 23],\n [19, 46, 16, 6, 47, 17],\n\n // 22\n [2, 139, 111, 7, 140, 112],\n [17, 74, 46],\n [7, 54, 24, 16, 55, 25],\n [34, 37, 13],\n\n // 23\n [4, 151, 121, 5, 152, 122],\n [4, 75, 47, 14, 76, 48],\n [11, 54, 24, 14, 55, 25],\n [16, 45, 15, 14, 46, 16],\n\n // 24\n [6, 147, 117, 4, 148, 118],\n [6, 73, 45, 14, 74, 46],\n [11, 54, 24, 16, 55, 25],\n [30, 46, 16, 2, 47, 17],\n\n // 25\n [8, 132, 106, 4, 133, 107],\n [8, 75, 47, 13, 76, 48],\n [7, 54, 24, 22, 55, 25],\n [22, 45, 15, 13, 46, 16],\n\n // 26\n [10, 142, 114, 2, 143, 115],\n [19, 74, 46, 4, 75, 47],\n [28, 50, 22, 6, 51, 23],\n [33, 46, 16, 4, 47, 17],\n\n // 27\n [8, 152, 122, 4, 153, 123],\n [22, 73, 45, 3, 74, 46],\n [8, 53, 23, 26, 54, 24],\n [12, 45, 15, 28, 46, 16],\n\n // 28\n [3, 147, 117, 10, 148, 118],\n [3, 73, 45, 23, 74, 46],\n [4, 54, 24, 31, 55, 25],\n [11, 45, 15, 31, 46, 16],\n\n // 29\n [7, 146, 116, 7, 147, 117],\n [21, 73, 45, 7, 74, 46],\n [1, 53, 23, 37, 54, 24],\n [19, 45, 15, 26, 46, 16],\n\n // 30\n [5, 145, 115, 10, 146, 116],\n [19, 75, 47, 10, 76, 48],\n [15, 54, 24, 25, 55, 25],\n [23, 45, 15, 25, 46, 16],\n\n // 31\n [13, 145, 115, 3, 146, 116],\n [2, 74, 46, 29, 75, 47],\n [42, 54, 24, 1, 55, 25],\n [23, 45, 15, 28, 46, 16],\n\n // 32\n [17, 145, 115],\n [10, 74, 46, 23, 75, 47],\n [10, 54, 24, 35, 55, 25],\n [19, 45, 15, 35, 46, 16],\n\n // 33\n [17, 145, 115, 1, 146, 116],\n [14, 74, 46, 21, 75, 47],\n [29, 54, 24, 19, 55, 25],\n [11, 45, 15, 46, 46, 16],\n\n // 34\n [13, 145, 115, 6, 146, 116],\n [14, 74, 46, 23, 75, 47],\n [44, 54, 24, 7, 55, 25],\n [59, 46, 16, 1, 47, 17],\n\n // 35\n [12, 151, 121, 7, 152, 122],\n [12, 75, 47, 26, 76, 48],\n [39, 54, 24, 14, 55, 25],\n [22, 45, 15, 41, 46, 16],\n\n // 36\n [6, 151, 121, 14, 152, 122],\n [6, 75, 47, 34, 76, 48],\n [46, 54, 24, 10, 55, 25],\n [2, 45, 15, 64, 46, 16],\n\n // 37\n [17, 152, 122, 4, 153, 123],\n [29, 74, 46, 14, 75, 47],\n [49, 54, 24, 10, 55, 25],\n [24, 45, 15, 46, 46, 16],\n\n // 38\n [4, 152, 122, 18, 153, 123],\n [13, 74, 46, 32, 75, 47],\n [48, 54, 24, 14, 55, 25],\n [42, 45, 15, 32, 46, 16],\n\n // 39\n [20, 147, 117, 4, 148, 118],\n [40, 75, 47, 7, 76, 48],\n [43, 54, 24, 22, 55, 25],\n [10, 45, 15, 67, 46, 16],\n\n // 40\n [19, 148, 118, 6, 149, 119],\n [18, 75, 47, 31, 76, 48],\n [34, 54, 24, 34, 55, 25],\n [20, 45, 15, 61, 46, 16]\n ];\n\n var qrRSBlock = function(totalCount, dataCount) {\n var _this = {};\n _this.totalCount = totalCount;\n _this.dataCount = dataCount;\n return _this;\n };\n\n var _this = {};\n\n var getRsBlockTable = function(typeNumber, errorCorrectionLevel) {\n\n switch(errorCorrectionLevel) {\n case QRErrorCorrectionLevel.L :\n return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];\n case QRErrorCorrectionLevel.M :\n return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];\n case QRErrorCorrectionLevel.Q :\n return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];\n case QRErrorCorrectionLevel.H :\n return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];\n default :\n return undefined;\n }\n };\n\n _this.getRSBlocks = function(typeNumber, errorCorrectionLevel) {\n\n var rsBlock = getRsBlockTable(typeNumber, errorCorrectionLevel);\n\n if (typeof rsBlock == 'undefined') {\n throw 'bad rs block @ typeNumber:' + typeNumber +\n '/errorCorrectionLevel:' + errorCorrectionLevel;\n }\n\n var length = rsBlock.length / 3;\n\n var list = [];\n\n for (var i = 0; i < length; i += 1) {\n\n var count = rsBlock[i * 3 + 0];\n var totalCount = rsBlock[i * 3 + 1];\n var dataCount = rsBlock[i * 3 + 2];\n\n for (var j = 0; j < count; j += 1) {\n list.push(qrRSBlock(totalCount, dataCount) );\n }\n }\n\n return list;\n };\n\n return _this;\n }();\n\n //---------------------------------------------------------------------\n // qrBitBuffer\n //---------------------------------------------------------------------\n\n var qrBitBuffer = function() {\n\n var _buffer = [];\n var _length = 0;\n\n var _this = {};\n\n _this.getBuffer = function() {\n return _buffer;\n };\n\n _this.getAt = function(index) {\n var bufIndex = Math.floor(index / 8);\n return ( (_buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;\n };\n\n _this.put = function(num, length) {\n for (var i = 0; i < length; i += 1) {\n _this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);\n }\n };\n\n _this.getLengthInBits = function() {\n return _length;\n };\n\n _this.putBit = function(bit) {\n\n var bufIndex = Math.floor(_length / 8);\n if (_buffer.length <= bufIndex) {\n _buffer.push(0);\n }\n\n if (bit) {\n _buffer[bufIndex] |= (0x80 >>> (_length % 8) );\n }\n\n _length += 1;\n };\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // qrNumber\n //---------------------------------------------------------------------\n\n var qrNumber = function(data) {\n\n var _mode = QRMode.MODE_NUMBER;\n var _data = data;\n\n var _this = {};\n\n _this.getMode = function() {\n return _mode;\n };\n\n _this.getLength = function(buffer) {\n return _data.length;\n };\n\n _this.write = function(buffer) {\n\n var data = _data;\n\n var i = 0;\n\n while (i + 2 < data.length) {\n buffer.put(strToNum(data.substring(i, i + 3) ), 10);\n i += 3;\n }\n\n if (i < data.length) {\n if (data.length - i == 1) {\n buffer.put(strToNum(data.substring(i, i + 1) ), 4);\n } else if (data.length - i == 2) {\n buffer.put(strToNum(data.substring(i, i + 2) ), 7);\n }\n }\n };\n\n var strToNum = function(s) {\n var num = 0;\n for (var i = 0; i < s.length; i += 1) {\n num = num * 10 + chatToNum(s.charAt(i) );\n }\n return num;\n };\n\n var chatToNum = function(c) {\n if ('0' <= c && c <= '9') {\n return c.charCodeAt(0) - '0'.charCodeAt(0);\n }\n throw 'illegal char :' + c;\n };\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // qrAlphaNum\n //---------------------------------------------------------------------\n\n var qrAlphaNum = function(data) {\n\n var _mode = QRMode.MODE_ALPHA_NUM;\n var _data = data;\n\n var _this = {};\n\n _this.getMode = function() {\n return _mode;\n };\n\n _this.getLength = function(buffer) {\n return _data.length;\n };\n\n _this.write = function(buffer) {\n\n var s = _data;\n\n var i = 0;\n\n while (i + 1 < s.length) {\n buffer.put(\n getCode(s.charAt(i) ) * 45 +\n getCode(s.charAt(i + 1) ), 11);\n i += 2;\n }\n\n if (i < s.length) {\n buffer.put(getCode(s.charAt(i) ), 6);\n }\n };\n\n var getCode = function(c) {\n\n if ('0' <= c && c <= '9') {\n return c.charCodeAt(0) - '0'.charCodeAt(0);\n } else if ('A' <= c && c <= 'Z') {\n return c.charCodeAt(0) - 'A'.charCodeAt(0) + 10;\n } else {\n switch (c) {\n case ' ' : return 36;\n case '$' : return 37;\n case '%' : return 38;\n case '*' : return 39;\n case '+' : return 40;\n case '-' : return 41;\n case '.' : return 42;\n case '/' : return 43;\n case ':' : return 44;\n default :\n throw 'illegal char :' + c;\n }\n }\n };\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // qr8BitByte\n //---------------------------------------------------------------------\n\n var qr8BitByte = function(data) {\n\n var _mode = QRMode.MODE_8BIT_BYTE;\n var _data = data;\n var _bytes = qrcode.stringToBytes(data);\n\n var _this = {};\n\n _this.getMode = function() {\n return _mode;\n };\n\n _this.getLength = function(buffer) {\n return _bytes.length;\n };\n\n _this.write = function(buffer) {\n for (var i = 0; i < _bytes.length; i += 1) {\n buffer.put(_bytes[i], 8);\n }\n };\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // qrKanji\n //---------------------------------------------------------------------\n\n var qrKanji = function(data) {\n\n var _mode = QRMode.MODE_KANJI;\n var _data = data;\n\n var stringToBytes = qrcode.stringToBytesFuncs['SJIS'];\n if (!stringToBytes) {\n throw 'sjis not supported.';\n }\n !function(c, code) {\n // self test for sjis support.\n var test = stringToBytes(c);\n if (test.length != 2 || ( (test[0] << 8) | test[1]) != code) {\n throw 'sjis not supported.';\n }\n }('\\u53cb', 0x9746);\n\n var _bytes = stringToBytes(data);\n\n var _this = {};\n\n _this.getMode = function() {\n return _mode;\n };\n\n _this.getLength = function(buffer) {\n return ~~(_bytes.length / 2);\n };\n\n _this.write = function(buffer) {\n\n var data = _bytes;\n\n var i = 0;\n\n while (i + 1 < data.length) {\n\n var c = ( (0xff & data[i]) << 8) | (0xff & data[i + 1]);\n\n if (0x8140 <= c && c <= 0x9FFC) {\n c -= 0x8140;\n } else if (0xE040 <= c && c <= 0xEBBF) {\n c -= 0xC140;\n } else {\n throw 'illegal char at ' + (i + 1) + '/' + c;\n }\n\n c = ( (c >>> 8) & 0xff) * 0xC0 + (c & 0xff);\n\n buffer.put(c, 13);\n\n i += 2;\n }\n\n if (i < data.length) {\n throw 'illegal char at ' + (i + 1);\n }\n };\n\n return _this;\n };\n\n //=====================================================================\n // GIF Support etc.\n //\n\n //---------------------------------------------------------------------\n // byteArrayOutputStream\n //---------------------------------------------------------------------\n\n var byteArrayOutputStream = function() {\n\n var _bytes = [];\n\n var _this = {};\n\n _this.writeByte = function(b) {\n _bytes.push(b & 0xff);\n };\n\n _this.writeShort = function(i) {\n _this.writeByte(i);\n _this.writeByte(i >>> 8);\n };\n\n _this.writeBytes = function(b, off, len) {\n off = off || 0;\n len = len || b.length;\n for (var i = 0; i < len; i += 1) {\n _this.writeByte(b[i + off]);\n }\n };\n\n _this.writeString = function(s) {\n for (var i = 0; i < s.length; i += 1) {\n _this.writeByte(s.charCodeAt(i) );\n }\n };\n\n _this.toByteArray = function() {\n return _bytes;\n };\n\n _this.toString = function() {\n var s = '';\n s += '[';\n for (var i = 0; i < _bytes.length; i += 1) {\n if (i > 0) {\n s += ',';\n }\n s += _bytes[i];\n }\n s += ']';\n return s;\n };\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // base64EncodeOutputStream\n //---------------------------------------------------------------------\n\n var base64EncodeOutputStream = function() {\n\n var _buffer = 0;\n var _buflen = 0;\n var _length = 0;\n var _base64 = '';\n\n var _this = {};\n\n var writeEncoded = function(b) {\n _base64 += String.fromCharCode(encode(b & 0x3f) );\n };\n\n var encode = function(n) {\n if (n < 0) {\n // error.\n } else if (n < 26) {\n return 0x41 + n;\n } else if (n < 52) {\n return 0x61 + (n - 26);\n } else if (n < 62) {\n return 0x30 + (n - 52);\n } else if (n == 62) {\n return 0x2b;\n } else if (n == 63) {\n return 0x2f;\n }\n throw 'n:' + n;\n };\n\n _this.writeByte = function(n) {\n\n _buffer = (_buffer << 8) | (n & 0xff);\n _buflen += 8;\n _length += 1;\n\n while (_buflen >= 6) {\n writeEncoded(_buffer >>> (_buflen - 6) );\n _buflen -= 6;\n }\n };\n\n _this.flush = function() {\n\n if (_buflen > 0) {\n writeEncoded(_buffer << (6 - _buflen) );\n _buffer = 0;\n _buflen = 0;\n }\n\n if (_length % 3 != 0) {\n // padding\n var padlen = 3 - _length % 3;\n for (var i = 0; i < padlen; i += 1) {\n _base64 += '=';\n }\n }\n };\n\n _this.toString = function() {\n return _base64;\n };\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // base64DecodeInputStream\n //---------------------------------------------------------------------\n\n var base64DecodeInputStream = function(str) {\n\n var _str = str;\n var _pos = 0;\n var _buffer = 0;\n var _buflen = 0;\n\n var _this = {};\n\n _this.read = function() {\n\n while (_buflen < 8) {\n\n if (_pos >= _str.length) {\n if (_buflen == 0) {\n return -1;\n }\n throw 'unexpected end of file./' + _buflen;\n }\n\n var c = _str.charAt(_pos);\n _pos += 1;\n\n if (c == '=') {\n _buflen = 0;\n return -1;\n } else if (c.match(/^\\s$/) ) {\n // ignore if whitespace.\n continue;\n }\n\n _buffer = (_buffer << 6) | decode(c.charCodeAt(0) );\n _buflen += 6;\n }\n\n var n = (_buffer >>> (_buflen - 8) ) & 0xff;\n _buflen -= 8;\n return n;\n };\n\n var decode = function(c) {\n if (0x41 <= c && c <= 0x5a) {\n return c - 0x41;\n } else if (0x61 <= c && c <= 0x7a) {\n return c - 0x61 + 26;\n } else if (0x30 <= c && c <= 0x39) {\n return c - 0x30 + 52;\n } else if (c == 0x2b) {\n return 62;\n } else if (c == 0x2f) {\n return 63;\n } else {\n throw 'c:' + c;\n }\n };\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // gifImage (B/W)\n //---------------------------------------------------------------------\n\n var gifImage = function(width, height) {\n\n var _width = width;\n var _height = height;\n var _data = new Array(width * height);\n\n var _this = {};\n\n _this.setPixel = function(x, y, pixel) {\n _data[y * _width + x] = pixel;\n };\n\n _this.write = function(out) {\n\n //---------------------------------\n // GIF Signature\n\n out.writeString('GIF87a');\n\n //---------------------------------\n // Screen Descriptor\n\n out.writeShort(_width);\n out.writeShort(_height);\n\n out.writeByte(0x80); // 2bit\n out.writeByte(0);\n out.writeByte(0);\n\n //---------------------------------\n // Global Color Map\n\n // black\n out.writeByte(0x00);\n out.writeByte(0x00);\n out.writeByte(0x00);\n\n // white\n out.writeByte(0xff);\n out.writeByte(0xff);\n out.writeByte(0xff);\n\n //---------------------------------\n // Image Descriptor\n\n out.writeString(',');\n out.writeShort(0);\n out.writeShort(0);\n out.writeShort(_width);\n out.writeShort(_height);\n out.writeByte(0);\n\n //---------------------------------\n // Local Color Map\n\n //---------------------------------\n // Raster Data\n\n var lzwMinCodeSize = 2;\n var raster = getLZWRaster(lzwMinCodeSize);\n\n out.writeByte(lzwMinCodeSize);\n\n var offset = 0;\n\n while (raster.length - offset > 255) {\n out.writeByte(255);\n out.writeBytes(raster, offset, 255);\n offset += 255;\n }\n\n out.writeByte(raster.length - offset);\n out.writeBytes(raster, offset, raster.length - offset);\n out.writeByte(0x00);\n\n //---------------------------------\n // GIF Terminator\n out.writeString(';');\n };\n\n var bitOutputStream = function(out) {\n\n var _out = out;\n var _bitLength = 0;\n var _bitBuffer = 0;\n\n var _this = {};\n\n _this.write = function(data, length) {\n\n if ( (data >>> length) != 0) {\n throw 'length over';\n }\n\n while (_bitLength + length >= 8) {\n _out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) );\n length -= (8 - _bitLength);\n data >>>= (8 - _bitLength);\n _bitBuffer = 0;\n _bitLength = 0;\n }\n\n _bitBuffer = (data << _bitLength) | _bitBuffer;\n _bitLength = _bitLength + length;\n };\n\n _this.flush = function() {\n if (_bitLength > 0) {\n _out.writeByte(_bitBuffer);\n }\n };\n\n return _this;\n };\n\n var getLZWRaster = function(lzwMinCodeSize) {\n\n var clearCode = 1 << lzwMinCodeSize;\n var endCode = (1 << lzwMinCodeSize) + 1;\n var bitLength = lzwMinCodeSize + 1;\n\n // Setup LZWTable\n var table = lzwTable();\n\n for (var i = 0; i < clearCode; i += 1) {\n table.add(String.fromCharCode(i) );\n }\n table.add(String.fromCharCode(clearCode) );\n table.add(String.fromCharCode(endCode) );\n\n var byteOut = byteArrayOutputStream();\n var bitOut = bitOutputStream(byteOut);\n\n // clear code\n bitOut.write(clearCode, bitLength);\n\n var dataIndex = 0;\n\n var s = String.fromCharCode(_data[dataIndex]);\n dataIndex += 1;\n\n while (dataIndex < _data.length) {\n\n var c = String.fromCharCode(_data[dataIndex]);\n dataIndex += 1;\n\n if (table.contains(s + c) ) {\n\n s = s + c;\n\n } else {\n\n bitOut.write(table.indexOf(s), bitLength);\n\n if (table.size() < 0xfff) {\n\n if (table.size() == (1 << bitLength) ) {\n bitLength += 1;\n }\n\n table.add(s + c);\n }\n\n s = c;\n }\n }\n\n bitOut.write(table.indexOf(s), bitLength);\n\n // end code\n bitOut.write(endCode, bitLength);\n\n bitOut.flush();\n\n return byteOut.toByteArray();\n };\n\n var lzwTable = function() {\n\n var _map = {};\n var _size = 0;\n\n var _this = {};\n\n _this.add = function(key) {\n if (_this.contains(key) ) {\n throw 'dup key:' + key;\n }\n _map[key] = _size;\n _size += 1;\n };\n\n _this.size = function() {\n return _size;\n };\n\n _this.indexOf = function(key) {\n return _map[key];\n };\n\n _this.contains = function(key) {\n return typeof _map[key] != 'undefined';\n };\n\n return _this;\n };\n\n return _this;\n };\n\n var createDataURL = function(width, height, getPixel) {\n var gif = gifImage(width, height);\n for (var y = 0; y < height; y += 1) {\n for (var x = 0; x < width; x += 1) {\n gif.setPixel(x, y, getPixel(x, y) );\n }\n }\n\n var b = byteArrayOutputStream();\n gif.write(b);\n\n var base64 = base64EncodeOutputStream();\n var bytes = b.toByteArray();\n for (var i = 0; i < bytes.length; i += 1) {\n base64.writeByte(bytes[i]);\n }\n base64.flush();\n\n return 'data:image/gif;base64,' + base64;\n };\n\n //---------------------------------------------------------------------\n // returns qrcode function.\n\n return qrcode;\n}();\n\n// multibyte support\n!function() {\n\n qrcode.stringToBytesFuncs['UTF-8'] = function(s) {\n // http://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array\n function toUTF8Array(str) {\n var utf8 = [];\n for (var i=0; i < str.length; i++) {\n var charcode = str.charCodeAt(i);\n if (charcode < 0x80) utf8.push(charcode);\n else if (charcode < 0x800) {\n utf8.push(0xc0 | (charcode >> 6),\n 0x80 | (charcode & 0x3f));\n }\n else if (charcode < 0xd800 || charcode >= 0xe000) {\n utf8.push(0xe0 | (charcode >> 12),\n 0x80 | ((charcode>>6) & 0x3f),\n 0x80 | (charcode & 0x3f));\n }\n // surrogate pair\n else {\n i++;\n // UTF-16 encodes 0x10000-0x10FFFF by\n // subtracting 0x10000 and splitting the\n // 20 bits of 0x0-0xFFFFF into two halves\n charcode = 0x10000 + (((charcode & 0x3ff)<<10)\n | (str.charCodeAt(i) & 0x3ff));\n utf8.push(0xf0 | (charcode >>18),\n 0x80 | ((charcode>>12) & 0x3f),\n 0x80 | ((charcode>>6) & 0x3f),\n 0x80 | (charcode & 0x3f));\n }\n }\n return utf8;\n }\n return toUTF8Array(s);\n };\n\n}();\n\n(function (factory) {\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n }\n}(function () {\n return qrcode;\n}));\n","import qrcode from 'qrcode-generator'\n\n/**\n * Encode `text` as a QR code and return a self-contained, scalable SVG string\n * (black modules on white) suitable for injecting via `innerHTML`. Type number 0\n * auto-sizes to the data; error-correction level \"M\" tolerates camera noise while\n * keeping the code dense enough to scan from a screen.\n */\nexport function renderQrSvg(text: string): string {\n const qr = qrcode(0, 'M')\n qr.addData(text)\n qr.make()\n return qr.createSvgTag({ cellSize: 6, margin: 4, scalable: true })\n}\n","import type {\n DocumentType,\n LivenessChallenge,\n LivenessMode,\n SessionTransitionEvent,\n VerificationStatus,\n WidgetResult,\n WidgetStep,\n WorkflowConfig,\n} from '@arkyc/types'\nimport { REALTIME_EVENT } from '@arkyc/types'\nimport { ArkycClient, type ClientHandoff, type ClientRealtime, type ClientSession, WidgetApiError } from './client'\nimport { Flow } from './flow'\nimport { Theme } from './theme'\nimport { WidgetView, type ViewHandlers } from './ui'\nimport { isDesktopDevice } from './device'\nimport { renderQrSvg } from './qr'\nimport { createWidgetRealtimeClient, type WidgetRealtimeClient } from './realtime'\nimport type { BaseWidgetOptions, WidgetControllerConfig, WidgetEventListener } from './types'\n\n/** Per-step lead-in copy shown before each capture/liveness step. */\nconst STEP_INSTRUCTIONS: Partial<Record<WidgetStep, { title: string; body: string; cta?: string }>> = {\n front_capture: {\n title: 'Front of your document',\n body: 'Place the front of your ID flat and fully inside the frame. We’ll capture it automatically.',\n },\n back_capture: {\n title: 'Back of your document',\n body: 'Now turn your ID over and show the back, fully inside the frame.',\n },\n selfie_capture: {\n title: 'Take a selfie',\n body: 'Look straight at the camera in good light and hold still — we’ll capture it automatically.',\n },\n active_liveness: {\n title: 'Quick liveness check',\n body: 'Follow the on-screen prompts (such as turn your head, blink or smile). This confirms you’re really here.',\n },\n}\n\n/**\n * Drives the full verification flow: renders each screen via {@link WidgetView},\n * advances through {@link flow}, and calls the Client API at each step. Cosmetic\n * processing screens auto-advance; capture screens wait for an image. On a\n * terminal result it surfaces the outcome and (in hosted mode) posts\n * `arkyc:complete` / `arkyc:error` / `arkyc:close` to the parent window.\n */\n/**\n * Re-base the server-resolved project logo onto the API origin the widget is\n * actually talking to. The stored `logo_url` carries the API's own host, which a\n * handed-off phone cannot reach — it reaches the API through the absolute\n * `baseUrl` passed in the handoff link. Rewriting the origin (keeping the path)\n * makes the logo load on whatever device runs the widget. Only applied when\n * `baseUrl` is absolute; the integrator's own branding is never re-based.\n */\nfunction rebaseBrandingLogo<T extends { logo_url?: string | null }>(branding: T, baseUrl: string | undefined): T {\n const logo = branding.logo_url\n if (!logo || !baseUrl || !/^https?:\\/\\//i.test(baseUrl)) return branding\n try {\n const base = new URL(baseUrl)\n const resolved = new URL(logo, base)\n if (resolved.origin === base.origin) return branding\n return { ...branding, logo_url: `${base.origin}${resolved.pathname}${resolved.search}${resolved.hash}` }\n } catch {\n return branding\n }\n}\n\nexport class WidgetController {\n private readonly client: ArkycClient\n private readonly view: WidgetView\n private readonly win: Window\n private readonly nav: Navigator\n private readonly postToParent: boolean\n private readonly scheduler: (fn: () => void, ms: number) => void\n private readonly transientMs: number\n private readonly pollMs: number\n private readonly maxPolls: number\n private readonly maxHandoffPolls: number\n\n /** Cross-device handoff: project config + whether the offer/QR is showing. */\n private handoffConfig: ClientHandoff = { enabled: false, allow_desktop: true, url: '' }\n private handoffReady = false\n private handoffActive = false\n\n /** This session's id + how to watch it live (push transport vs. polling). */\n private sessionId = ''\n private realtimeConfig: ClientRealtime | null = null\n private rtClient: WidgetRealtimeClient | null = null\n private rtResolved = false\n /** The last status observed, so a transition only emits once per change. */\n private lastStatus: VerificationStatus | null = null\n /** Per-name event listeners registered via {@link on}. */\n private listeners = new Map<string, Set<WidgetEventListener>>()\n /** Cancels the active session watch (e.g. continue-on-this-device). */\n private stopWatch: (() => void) | undefined\n\n private step: WidgetStep = 'welcome'\n private documentType: DocumentType | null = null\n private country: string | null = null\n private selfie: Blob | null = null\n private livenessMode: LivenessMode = 'passive'\n /** The session's capture model; `active` mandates a live camera (no fallback). */\n private captureModel: 'passive' | 'active' | 'both' = 'passive'\n private livenessChallenges: LivenessChallenge[] = []\n /** The applied workflow (orders/toggles stages, skip_ocr), or null for the default flow. */\n private workflow: WorkflowConfig | null = null\n private result: WidgetResult | null = null\n /** The session was already terminal when the widget loaded (show a close-only notice). */\n private terminalOnLoad = false\n /** Whether the current step's instruction interstitial has been acknowledged. */\n private instructionAcked = false\n private pendingError: Error | null = null\n private settled = false\n\n constructor(private readonly config: WidgetControllerConfig) {\n const doc = config.doc ?? globalThis.document\n const win = config.win ?? globalThis.window\n if (!doc || !win) throw new Error('The Arkyc widget must run in a browser environment.')\n this.win = win\n this.nav = config.nav ?? globalThis.navigator\n\n this.client = new ArkycClient({\n token: config.token,\n baseUrl: config.baseUrl,\n fetch: config.fetch,\n })\n const theme = new Theme(config.branding)\n this.view = new WidgetView(\n doc,\n theme,\n this.handlers(),\n config.nav ?? globalThis.navigator,\n config.faceAnalyzer,\n config.faceTuning,\n config.documentAnalyzer,\n config.documentTuning,\n )\n\n this.postToParent = config.postToParent ?? (!!win.parent && win.parent !== win)\n this.scheduler = config.scheduler ?? ((fn, ms) => setTimeout(fn, ms))\n this.transientMs = config.transientMs ?? 700\n this.pollMs = config.pollMs ?? 1500\n this.maxPolls = config.maxPolls ?? 40\n // A handed-off session is bounded by its TTL (~15 min); poll generously.\n this.maxHandoffPolls = config.maxHandoffPolls ?? 600\n }\n\n /** The widget's root element — append it to an overlay or inline container. */\n get element(): HTMLElement {\n return this.view.element\n }\n\n /** Connect to the session, then route to the result, the QR, or the welcome flow. */\n start(): void {\n this.view.renderLoading()\n void this.run(() => this.bootstrap())\n }\n\n /** Tear down the view and release the camera (does not fire callbacks). */\n destroy(): void {\n this.view.destroy()\n }\n\n /** Close the widget as if the user dismissed it (fires `onClose`/`onSettle`). */\n close(): void {\n this.finishClose()\n }\n\n /**\n * Subscribe to a named widget event; returns an unsubscribe function. Having a\n * listener (here or via `onEvent`) is what activates the event stream.\n */\n on(event: string, listener: WidgetEventListener): () => void {\n const set = this.listeners.get(event) ?? new Set<WidgetEventListener>()\n set.add(listener)\n this.listeners.set(event, set)\n\n return () => set.delete(listener)\n }\n\n /** Whether anyone is listening for `name` (the firehose or a named listener). */\n private hasListener(name: string): boolean {\n if (this.config.onEvent) return true\n const set = this.listeners.get(name)\n\n return !!set && set.size > 0\n }\n\n /**\n * Surface an event: to local listeners (firehose + `on`), and — in hosted\n * iframe mode — to the embedding parent as `arkyc:event` so the SDK's\n * `handle.on(...)` works across the frame.\n */\n private dispatch(name: string, data?: unknown): void {\n this.emit(name, data)\n // The parent window is the consumer in iframe mode, so forwarding there isn't\n // gated on a local listener (post() already no-ops when not embedding).\n this.post('arkyc:event', { name, data })\n }\n\n /** Emit an event to the firehose + named listeners — but only if one is active. */\n private emit(name: string, data?: unknown): void {\n if (!this.hasListener(name)) return\n try {\n this.config.onEvent?.({ name, data })\n } catch {\n // A consumer callback threw — never let it break the flow.\n }\n const set = this.listeners.get(name)\n if (set) {\n for (const listener of [...set]) {\n try {\n listener(data)\n } catch {\n // ditto\n }\n }\n }\n }\n\n /** Record an observed status, emitting `session.transition` on a real change. */\n private observe(status: VerificationStatus): void {\n if (status === this.lastStatus) return\n const previous = this.lastStatus\n this.lastStatus = status\n this.dispatch(REALTIME_EVENT.sessionTransition, {\n session_id: this.sessionId,\n status,\n previous_status: previous,\n } satisfies Partial<SessionTransitionEvent>)\n }\n\n /**\n * Lazily connect the push transport for this session (once). Returns null for\n * `polling`/`off`/`memory` or when the transport SDK can't load — the caller\n * then polls instead.\n */\n private async resolveRealtime(): Promise<WidgetRealtimeClient | null> {\n if (this.rtResolved) return this.rtClient\n this.rtResolved = true\n const cfg = this.realtimeConfig\n if (!cfg || cfg.transport === 'polling' || cfg.transport === 'off' || cfg.transport === 'memory') return null\n\n const factory = this.config.realtimeFactory ?? createWidgetRealtimeClient\n const apiBase = (this.config.baseUrl ?? '').replace(/\\/$/, '')\n try {\n this.rtClient = await factory(cfg, {\n authEndpoint: `${apiBase}/v1/client/realtime/auth`,\n token: this.config.token,\n })\n } catch {\n this.rtClient = null\n }\n\n return this.rtClient\n }\n\n private handlers(): ViewHandlers {\n return {\n onClose: () => this.finishClose(),\n // The session was already fetched + resolved during bootstrap; just advance.\n onStart: () => void this.run(() => this.enter(this.next())),\n onDocumentSelected: (type, country) => {\n this.documentType = type\n this.country = country || null\n void this.run(() => this.enter('front_capture'))\n },\n onImage: (blob) => void this.run(() => this.onImage(blob)),\n onActiveLiveness: (video, performed, selfie) =>\n void this.run(async () => {\n await this.client.submitLiveness({\n selfie,\n video,\n mode: 'active',\n challenges: performed,\n signals: this.config.signals,\n })\n await this.enter(this.next())\n }),\n onAcknowledge: () => this.finishResult(),\n onUsePhone: () => void this.run(() => this.startHandoff()),\n onContinueHere: () => {\n this.handoffActive = false\n this.stopWatch?.()\n this.step = 'welcome'\n this.render()\n },\n }\n }\n\n /**\n * Fetch the session and route: an already-terminal session (e.g. a stale handoff\n * link, or one finished on another device) shows a close-only notice; on a\n * desktop with handoff enabled we lead with the QR; otherwise the welcome flow.\n */\n private async bootstrap(): Promise<void> {\n if (this.settled) return\n const session = await this.client.getSession()\n if (this.settled) return\n this.sessionId = session.id\n this.realtimeConfig = session.realtime ?? null\n this.workflow = session.workflow ?? null\n // Theme from the project's branding (server-resolved) unless the integrator\n // passed branding explicitly — their value wins.\n if (this.config.branding == null && session.branding)\n this.view.applyBranding(rebaseBrandingLogo(session.branding, this.config.baseUrl))\n this.observe(session.status)\n if (Flow.isTerminal(session.status)) return this.showTerminal(session.status)\n this.resolveLiveness(session)\n if (session.handoff) this.handoffConfig = session.handoff\n const canHandoff =\n this.config.handoff !== false && isDesktopDevice(this.nav) && this.handoffConfig.enabled && !!this.handoffTarget()\n if (canHandoff) {\n this.handoffReady = true\n await this.startHandoff()\n } else {\n this.step = 'welcome'\n this.render()\n }\n }\n\n /** The hosted handoff page URL: a consumer override, else the server-provided one. */\n private handoffTarget(): string {\n return (this.config.handoffUrl ?? this.handoffConfig.url ?? '').trim()\n }\n\n /** Render the QR for this session and wait for the other device to finish. */\n private async startHandoff(): Promise<void> {\n const target = this.handoffTarget()\n if (!target) return\n this.handoffActive = true\n // Offer \"continue on this device\" only when the project permits it.\n this.view.renderHandoff(renderQrSvg(this.buildHandoffUrl(target)), this.handoffConfig.allow_desktop)\n await this.pollHandoff()\n }\n\n /** Build the hosted-page URL the QR encodes (carries the session token). */\n private buildHandoffUrl(target: string): string {\n const sep = target.includes('?') ? '&' : '?'\n let url = `${target}${sep}token=${encodeURIComponent(this.config.token)}`\n // The hosted page supplies its own API base; only pass one when ours is\n // absolute, so a custom cross-origin host can still reach the right API.\n const apiBase = (this.config.baseUrl ?? '').trim()\n if (/^https?:\\/\\//i.test(apiBase)) url += `&baseUrl=${encodeURIComponent(apiBase)}`\n return url\n }\n\n /** Watch the session while the user verifies on the other device; mirror the result. */\n private async pollHandoff(): Promise<void> {\n const rt = await this.resolveRealtime()\n if (rt) {\n const status = await this.pushWatch(rt, this.maxHandoffPolls, () => this.handoffActive && !this.settled)\n if (status) {\n this.handoffActive = false\n return this.showResult(status)\n }\n\n return // cancelled (continue here) or budget elapsed → the QR persists\n }\n\n let errors = 0\n for (let i = 0; i < this.maxHandoffPolls && this.handoffActive && !this.settled; i++) {\n await this.delay(this.pollMs)\n if (!this.handoffActive || this.settled) return\n try {\n const session = await this.client.getSession()\n errors = 0\n this.observe(session.status)\n if (Flow.isTerminal(session.status)) {\n this.handoffActive = false\n return this.showResult(session.status)\n }\n } catch (error) {\n // The session/token can expire mid-wait (401) — stop and reflect that.\n if (error instanceof WidgetApiError && error.status === 401) {\n this.handoffActive = false\n return this.showResult('expired')\n }\n if (++errors >= 5) return\n }\n }\n }\n\n /**\n * Await a terminal status over the push transport. Resolves to the terminal\n * status, or null if `active()` went false or the tick budget elapsed (push can\n * miss events / disconnect; the budget bounds the wait). An initial fetch\n * catches a session that finished before we subscribed.\n */\n private pushWatch(\n rt: WidgetRealtimeClient,\n budget: number,\n active: () => boolean,\n ): Promise<VerificationStatus | null> {\n return new Promise((resolve) => {\n let done = false\n const finish = (status: VerificationStatus | null) => {\n if (done) return\n done = true\n this.stopWatch = undefined\n unsubscribe()\n resolve(status)\n }\n const channel = this.realtimeConfig!.channel\n const unsubscribe = rt.subscribe(channel, (event, data) => {\n if (event !== REALTIME_EVENT.sessionTransition) return\n const status = (data as SessionTransitionEvent).status\n this.observe(status)\n if (Flow.isTerminal(status)) finish(status)\n })\n this.stopWatch = () => finish(null)\n // Catch a race where the session already finished before we subscribed.\n void this.client\n .getSession()\n .then((session) => {\n this.observe(session.status)\n if (Flow.isTerminal(session.status)) finish(session.status)\n })\n .catch((error) => {\n if (error instanceof WidgetApiError && error.status === 401) finish('expired')\n })\n // Bound the wait by the same tick budget the poller would use.\n const countdown = async (n: number): Promise<void> => {\n if (done) return\n if (!active() || n >= budget) return finish(null)\n await this.delay(this.pollMs)\n void countdown(n + 1)\n }\n void countdown(0)\n })\n }\n\n /** Resolve which liveness flow to run from the session's capture model. */\n private resolveLiveness(session: ClientSession): void {\n this.livenessChallenges = session.liveness_challenges ?? []\n const model = session.capture_model ?? 'passive'\n this.captureModel = model\n const wantsActive = model === 'active' || model === 'both'\n // `active` is honoured even without a live camera — the active-liveness\n // screen then shows the device as unsupported (no fallback). `both` falls\n // back to passive when the camera/recorder isn't available.\n this.livenessMode = wantsActive && (model === 'active' || this.view.cameraSupported) ? 'active' : 'passive'\n }\n\n private async onImage(blob: Blob | null): Promise<void> {\n const signals = this.config.signals\n switch (this.step) {\n case 'front_capture':\n await this.client.submitDocumentFront({\n image: blob,\n country: this.country,\n documentType: this.documentType,\n signals,\n })\n return this.enter(this.next())\n case 'back_capture':\n await this.client.submitDocumentBack({\n image: blob,\n country: this.country,\n documentType: this.documentType,\n })\n return this.enter('ocr_processing')\n case 'selfie_capture':\n this.selfie = blob\n return this.enter('passive_liveness')\n }\n }\n\n /** Enter a step: render it, and drive any automatic (processing) work. */\n private async enter(step: WidgetStep): Promise<void> {\n if (this.settled) return\n this.step = step\n\n // Lead each capture/liveness step with an instruction screen so the user\n // knows what's next and starts it deliberately. The Continue button re-enters\n // the same step with the instruction acknowledged.\n const instruction = STEP_INSTRUCTIONS[step]\n if (instruction && !this.instructionAcked) {\n this.view.renderInstruction(step, instruction.title, instruction.body, instruction.cta ?? 'Continue', () => {\n this.instructionAcked = true\n void this.run(() => this.enter(step))\n })\n return\n }\n this.instructionAcked = false\n this.render()\n\n switch (step) {\n case 'ocr_processing':\n await this.delay(this.transientMs)\n return this.enter(this.next())\n case 'passive_liveness':\n await this.client.submitLiveness({ selfie: this.selfie, signals: this.config.signals })\n return this.enter(this.next())\n case 'face_match':\n await this.client.complete({ signals: this.config.signals })\n return this.enter(this.next())\n case 'processing':\n return this.poll()\n }\n }\n\n /** Watch the session until it reaches a terminal status (then show the result). */\n private async poll(): Promise<void> {\n const rt = await this.resolveRealtime()\n if (rt) {\n const status = await this.pushWatch(rt, this.maxPolls, () => !this.settled)\n\n return this.showResult(status ?? 'requires_review')\n }\n\n for (let i = 0; i < this.maxPolls && !this.settled; i++) {\n const session = await this.client.getSession()\n this.observe(session.status)\n if (Flow.isTerminal(session.status)) return this.showResult(session.status)\n await this.delay(this.pollMs)\n }\n // Still processing after the poll budget — surface as pending review.\n this.showResult('requires_review')\n }\n\n private showResult(status: VerificationStatus): void {\n this.result = { status, decision: Flow.statusToDecision(status) }\n this.step = 'result'\n this.render()\n }\n\n /** A session that was already terminal on load: a notice with only a Close button. */\n private showTerminal(status: VerificationStatus): void {\n this.result = { status, decision: Flow.statusToDecision(status) }\n this.step = 'result'\n this.terminalOnLoad = true\n this.render()\n }\n\n private render(): void {\n this.view.render({\n step: this.step,\n documentType: this.documentType,\n decision: this.result?.decision,\n status: this.result?.status,\n terminalNotice: this.terminalOnLoad,\n allowSkip: !!this.config.signals,\n livenessChallenges: this.livenessChallenges,\n requireLiveCamera: this.captureModel === 'active',\n // The active flow is strict end-to-end: documents must be detected, not\n // manually waved through.\n strictCapture: this.livenessMode === 'active',\n handoffAvailable: this.handoffReady,\n })\n }\n\n private next(): WidgetStep {\n return Flow.nextStep(this.step, {\n documentType: this.documentType,\n livenessMode: this.livenessMode,\n workflow: this.workflow,\n })\n }\n\n private delay(ms: number): Promise<void> {\n return new Promise((resolve) => this.scheduler(resolve, ms))\n }\n\n /** Run an async step, routing any failure to the error screen. */\n private async run(fn: () => Promise<void> | void): Promise<void> {\n try {\n await fn()\n } catch (error) {\n this.fail(error)\n }\n }\n\n private fail(error: unknown): void {\n if (this.settled) return\n const err = error instanceof Error ? error : new Error(String(error))\n this.step = 'result'\n\n this.view.render({\n step: 'result',\n documentType: this.documentType,\n errorMessage: err.message,\n })\n\n this.pendingError = err\n }\n\n private finishResult(): void {\n if (this.settled) return\n this.settled = true\n this.teardownRealtime()\n\n if (this.pendingError) {\n this.post('arkyc:error', { error: serializeError(this.pendingError) })\n this.dispatch('error', { message: this.pendingError.message })\n this.config.onError?.(this.pendingError)\n } else if (this.result) {\n this.post('arkyc:complete', { payload: this.result })\n this.dispatch('complete', this.result)\n this.config.onComplete?.(this.result)\n }\n\n this.destroy()\n this.config.onSettle?.()\n }\n\n private finishClose(): void {\n if (this.settled) return\n\n this.settled = true\n this.teardownRealtime()\n this.post('arkyc:close', {})\n this.dispatch('close')\n this.config.onClose?.()\n this.destroy()\n this.config.onSettle?.()\n }\n\n /** Stop any active session watch + disconnect the push transport. */\n private teardownRealtime(): void {\n this.stopWatch?.()\n this.rtClient?.disconnect()\n this.rtClient = null\n }\n\n private post(type: string, extra: Record<string, unknown>): void {\n if (!this.postToParent) return\n try {\n this.win.parent?.postMessage({ type, ...extra }, '*')\n } catch {\n // Cross-origin parent without access — nothing more we can do.\n }\n }\n}\n\nfunction serializeError(error: Error): { message: string; name: string } {\n return { message: error.message, name: error.name }\n}\n\nexport const resolveContainer = (container: string | HTMLElement, doc: Document): HTMLElement => {\n const el = typeof container === 'string' ? doc.querySelector<HTMLElement>(container) : container\n if (!el) throw new Error(`ArkycWidget.mount: container \"${String(container)}\" not found.`)\n return el\n}\n\nexport const buildController = (options: BaseWidgetOptions, onSettle: () => void): WidgetController => {\n if (!options.token) throw new Error('ArkycWidget requires a client `token`.')\n return new WidgetController({\n token: options.token,\n baseUrl: options.baseUrl,\n handoff: options.handoff,\n handoffUrl: options.handoffUrl,\n branding: options.branding,\n signals: options.signals,\n onComplete: options.onComplete,\n onError: options.onError,\n onClose: options.onClose,\n onEvent: options.onEvent,\n onSettle,\n fetch: options.fetch,\n doc: options.doc,\n win: options.win,\n nav: options.nav,\n faceAnalyzer: options.faceAnalyzer,\n faceTuning: options.faceTuning,\n documentAnalyzer: options.documentAnalyzer,\n documentTuning: options.documentTuning,\n })\n}\n","import type { WidgetController } from './controller'\nimport type { WidgetEventListener, WidgetHandle } from './types'\n\nexport class WidgetHandler implements WidgetHandle {\n constructor(private controller: WidgetController) {}\n\n /**\n * Close the widget and release the camera (fires `onClose`).\n */\n close(): void {\n return this.controller.close()\n }\n /**\n * Subscribe to a named widget event (e.g. `session.transition`, `complete`).\n * Returns an unsubscribe function. Registering a listener activates the event\n * stream (events are only delivered while at least one listener is active).\n *\n * @param event\n * @param listener\n */\n on(event: string, listener: WidgetEventListener): () => void {\n return this.controller.on(event, listener)\n }\n}\n","import type { BaseWidgetOptions, MountWidgetOptions, WidgetHandle } from './types'\nimport { buildController, resolveContainer } from './controller'\n\nimport { WidgetHandler } from './WidgetHandler'\n\n/**\n * @arkyc/widget\n *\n * Framework-agnostic, embeddable identity-verification widget. Drives a single\n * session through the Arkyc Client/Widget API with a short-lived client token.\n *\n * ```ts\n * import { ArkycWidget } from '@arkyc/widget'\n *\n * // Overlay modal:\n * ArkycWidget.open({ token, onComplete: (r) => console.log(r.status) })\n *\n * // Inline (mounted into a container):\n * ArkycWidget.mount({ token, container: '#verify' })\n *\n * // Hosted page (reads ?token= and posts results to the parent window):\n * ArkycWidget.hosted()\n * ```\n */\nexport class ArkycWidget {\n /**\n * Open the widget as a full-screen overlay modal. Returns a close handle.\n *\n * @param options\n * @returns\n */\n static open(options: BaseWidgetOptions): WidgetHandle {\n const doc = options.doc ?? globalThis.document\n const overlay = doc.createElement('div')\n\n overlay.setAttribute('data-arkyc-widget', '')\n // Fullscreen: edge-to-edge with no backdrop gap. Otherwise a centred modal\n // over a dimmed backdrop.\n // Both modes use a dimmed, centred backdrop. Fullscreen fills the viewport on\n // mobile but renders as a large centred dialog on desktop (see the card CSS);\n // the dimmed backdrop is what's visible around that dialog.\n overlay.style.cssText = options.fullscreen\n ? 'position:fixed;inset:0;z-index:2147483647;background:rgba(0,0,0,0.55);display:flex;align-items:center;justify-content:center;padding:0;'\n : 'position:fixed;inset:0;z-index:2147483647;background:rgba(0,0,0,0.6);display:flex;align-items:center;justify-content:center;padding:16px;'\n\n const controller = buildController(options, () => overlay.remove())\n // Mark overlay mode so a handoff QR can take over the whole viewport here\n // (it escapes the dimmed backdrop) without doing the same when inline-mounted.\n controller.element.classList.add('arkyc-overlay')\n if (options.fullscreen) controller.element.classList.add('arkyc-fullscreen')\n overlay.appendChild(controller.element)\n ;(doc.body ?? doc.documentElement).appendChild(overlay)\n controller.start()\n\n return new WidgetHandler(controller)\n }\n\n /**\n * Mount the widget inline into a container element. Returns a close handle.\n *\n * @param options\n * @returns\n */\n static mount(options: MountWidgetOptions): WidgetHandle {\n const doc = options.doc ?? globalThis.document\n const container = resolveContainer(options.container, doc)\n const controller = buildController(options, () => controller.element.remove())\n\n container.appendChild(controller.element)\n controller.start()\n\n return new WidgetHandler(controller)\n }\n\n /**\n * Bootstrap the widget on its hosted page: read the client `token` (and\n * optional `baseUrl`) from the query string and run in overlay mode, posting\n * `arkyc:*` results to the parent (iframe) window.\n *\n * @param options\n * @returns\n */\n static hosted(options: Partial<BaseWidgetOptions> = {}): WidgetHandle {\n const win = options.win ?? globalThis.window\n const params = new URLSearchParams(win.location.search)\n const token = options.token ?? params.get('token') ?? ''\n const baseUrl = options.baseUrl ?? params.get('baseUrl') ?? undefined\n\n return ArkycWidget.open({ ...options, token, baseUrl })\n }\n}\n","export const PACKAGE_NAME = '@arkyc/widget'\nexport const VERSION = '0.1.0'\n\nexport type { WidgetController } from './controller'\nexport { ArkycClient, WidgetApiError } from './client'\nexport type { ClientSession, ClientRealtime, ProviderSignalHints, ArkycClientOptions } from './client'\nexport { createWidgetRealtimeClient } from './realtime'\nexport type { WidgetRealtimeClient, WidgetRealtimeFactory, WidgetRealtimeHandler } from './realtime'\nexport { Theme } from './theme'\nexport { Camera } from './capture'\nexport type { Facing } from './capture'\nexport { Flow } from './flow'\nexport type { FlowContext } from './flow'\nexport { createDefaultFaceAnalyzer, DEFAULT_TUNING, makeChallengeDetector, isSelfieReady } from './face'\nexport type { FaceAnalyzer, FaceSample, FaceTuning, ChallengeDetector } from './face'\nexport {\n createDefaultDocumentAnalyzer,\n DEFAULT_DOCUMENT_TUNING,\n analyzeDocumentGray,\n documentGuidance,\n isDocumentReady,\n} from './document'\nexport type { DocumentAnalyzer, DocumentSample, DocumentTuning, DocRect } from './document'\nexport type { WidgetResult } from '@arkyc/types'\nexport { ArkycWidget } from './ArkycWidget'\nexport { WidgetHandler } from './WidgetHandler'\nexport * from './types'\n"],"x_google_ignoreList":[12],"mappings":"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AAM,MACR,EACA,CACE,KAAM,eACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,sBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,yBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,eACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,2BACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,4BACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,yBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,iBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,qBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,oBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,gBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,gBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,mBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,kBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,mBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,wBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,mCACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,wBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,eACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,kBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,sBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,eACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,uBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KA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"}
1
+ {"version":3,"file":"arkyc-widget.iife.global.js","names":["themeCss"],"sources":["../src/client.ts","../src/realtime.ts","../src/theme.ts","../src/capture.ts","../../types/dist/realtime.mjs","../../types/dist/workflow.mjs","../src/flow.ts","../src/face.ts","../src/document.ts","../src/countries.ts","../src/h.ts","../src/ui.ts","../src/device.ts","../../../node_modules/.pnpm/qrcode-generator@1.5.2/node_modules/qrcode-generator/qrcode.js","../src/qr.ts","../src/controller.ts","../src/WidgetHandler.ts","../src/ArkycWidget.ts","../src/index.ts"],"sourcesContent":["import type {\n CaptureModel,\n DocumentType,\n LivenessChallenge,\n LivenessMode,\n ProjectBranding,\n VerificationStatus,\n WorkflowConfig,\n} from '@arkyc/types'\n\n/** The session view exposed by the Client/Widget API (`GET /v1/client/session`). */\nexport interface ClientSession {\n id: string\n status: VerificationStatus\n expires_at: string\n /** The capture flow this session runs (Phase 17). */\n capture_model?: CaptureModel\n /** The active-liveness challenge sequence to prompt the user through. */\n liveness_challenges?: LivenessChallenge[]\n /** Cross-device handoff config resolved from the project setting. */\n handoff?: ClientHandoff\n /** How to watch this session live (push transport params or `polling`). */\n realtime?: ClientRealtime\n /** Project branding (colours/logo/name) so the widget themes itself at runtime. */\n branding?: ProjectBranding | null\n /** The applied workflow (ordered, toggleable stages + skip_ocr), or null for the default flow. */\n workflow?: WorkflowConfig | null\n}\n\n/**\n * Realtime connection info for this session (Phase 16). `transport` selects how\n * the widget watches the session: `pusher`/`firebase` subscribe to `channel`;\n * `polling` (and `off`/`memory`) mean poll the session endpoint instead. The\n * remaining fields carry the active transport's public connection params; `token`\n * is a per-session Firebase custom token when applicable.\n */\nexport interface ClientRealtime {\n transport: 'pusher' | 'firebase' | 'polling' | 'off' | 'memory'\n /** The private channel this session's events publish to. */\n channel: string\n /** Per-session Firebase custom token (firebase transport only). */\n token?: string | null\n [param: string]: unknown\n}\n\n/** Whether (and where) the widget may offer cross-device handoff. */\nexport interface ClientHandoff {\n enabled: boolean\n /** Whether a desktop user may continue on the desktop device instead of handing off. */\n allow_desktop: boolean\n /** First-party hosted page the QR points to (the phone resumes the session there). */\n url: string\n}\n\n/**\n * Mock-driver signal hints. Real provider drivers ignore these; the `mock`\n * drivers use them to make the demo/playground flow deterministic.\n */\nexport interface ProviderSignalHints {\n quality_score?: number\n ocr_confidence?: number\n expired?: boolean\n liveness_score?: number\n liveness_passed?: boolean\n multiple_faces?: boolean\n face_similarity?: number\n face_match_passed?: boolean\n address_score?: number\n address_passed?: boolean\n}\n\n/** Input for the address-verification submission (opt-in stage). */\nexport interface AddressInput {\n /** The claimed address the user entered. */\n line1?: string | null\n line2?: string | null\n city?: string | null\n region?: string | null\n postalCode?: string | null\n /** ISO 3166-1 alpha-2 country code. */\n country?: string | null\n /** Proof-of-address document image. */\n poa?: Blob | null\n /** Captured device coordinates. */\n latitude?: number | null\n longitude?: number | null\n signals?: ProviderSignalHints\n}\n\n/** Input for the document-front submission. */\nexport interface DocumentFrontInput {\n image?: Blob | null\n country?: string | null\n documentType?: DocumentType | null\n signals?: ProviderSignalHints\n}\n\n/** Input for the document-back submission. */\nexport interface DocumentBackInput {\n image?: Blob | null\n country?: string | null\n documentType?: DocumentType | null\n}\n\n/** Input for the liveness submission (passive selfie or active challenge video). */\nexport interface LivenessInput {\n selfie?: Blob | null\n /** Recorded challenge video (active mode). */\n video?: Blob | null\n /** Passive (selfie) or active (challenge video). Defaults to passive. */\n mode?: LivenessMode\n /** The challenge sequence the user performed, in order (active mode). */\n challenges?: LivenessChallenge[]\n signals?: ProviderSignalHints\n}\n\n/** Input for completing the session (runs face-match + decision). */\nexport interface CompleteInput {\n signals?: ProviderSignalHints\n}\n\n/**\n * Raised when the Client API returns a non-2xx response.\n */\nexport class WidgetApiError extends Error {\n readonly status: number\n readonly code?: string\n\n constructor(message: string, status: number, code?: string) {\n super(message)\n this.name = 'WidgetApiError'\n this.status = status\n this.code = code\n }\n}\n\n/** Options for {@link ArkycClient}. */\nexport interface ArkycClientOptions {\n /** Short-lived client token minted for this session. */\n token: string\n /** API origin (defaults to the same origin the widget is served from). */\n baseUrl?: string\n /** Injectable for testing; defaults to the global `fetch`. */\n fetch?: typeof fetch\n}\n\ntype EnvelopeNumber = number | boolean\n\nfunction appendSignals(form: FormData, signals?: ProviderSignalHints): void {\n if (!signals) return\n for (const [key, value] of Object.entries(signals)) {\n if (value == null) continue\n form.append(key, String(value as EnvelopeNumber))\n }\n}\n\n/**\n * A thin, framework-agnostic client for the Arkyc Client/Widget API. Drives a\n * single verification session with a short-lived client token. All responses\n * are unwrapped from the standard `{ status, message, data }` envelope.\n */\nexport class ArkycClient {\n private readonly token: string\n private readonly baseUrl: string\n private readonly fetchImpl: typeof fetch\n\n constructor(options: ArkycClientOptions) {\n if (!options.token) throw new Error('ArkycClient requires a client `token`.')\n this.token = options.token\n this.baseUrl = (options.baseUrl ?? '').replace(/\\/$/, '')\n const f = options.fetch ?? globalThis.fetch\n if (!f) throw new Error('No `fetch` implementation available.')\n this.fetchImpl = f.bind(globalThis)\n }\n\n /**\n * Load the current session (marks it `started` on first call).\n *\n * @returns\n */\n getSession(): Promise<ClientSession> {\n return this.request('GET', '/v1/client/session')\n }\n\n /**\n * Submit the document front image (triggers OCR + portrait extraction).\n *\n * @param input\n * @returns\n */\n submitDocumentFront(input: DocumentFrontInput): Promise<ClientSession> {\n const form = new FormData()\n if (input.image) form.append('image', input.image, 'document-front.jpg')\n if (input.country) form.append('country', input.country)\n if (input.documentType) form.append('document_type', input.documentType)\n appendSignals(form, input.signals)\n return this.request('POST', '/v1/client/document/front', form)\n }\n\n /**\n * Submit the document back image.\n *\n * @param input\n * @returns\n */\n submitDocumentBack(input: DocumentBackInput): Promise<ClientSession> {\n const form = new FormData()\n if (input.image) form.append('image', input.image, 'document-back.jpg')\n if (input.country) form.append('country', input.country)\n if (input.documentType) form.append('document_type', input.documentType)\n return this.request('POST', '/v1/client/document/back', form)\n }\n\n /**\n * Submit the selfie for the liveness check.\n *\n * @param input\n * @returns\n */\n submitLiveness(input: LivenessInput): Promise<ClientSession> {\n const form = new FormData()\n if (input.selfie) form.append('selfie', input.selfie, 'selfie.jpg')\n if (input.video) form.append('video', input.video, 'liveness.webm')\n if (input.mode) form.append('mode', input.mode)\n if (input.challenges) form.append('challenges', JSON.stringify(input.challenges))\n appendSignals(form, input.signals)\n return this.request('POST', '/v1/client/liveness', form)\n }\n\n /**\n * Submit address verification (opt-in stage). Sends the claimed address plus\n * whichever evidence was gathered (proof-of-address image, device coordinates).\n *\n * @param input\n * @returns\n */\n submitAddress(input: AddressInput): Promise<ClientSession> {\n const form = new FormData()\n const fields: Record<string, string | null | undefined> = {\n line1: input.line1,\n line2: input.line2,\n city: input.city,\n region: input.region,\n postal_code: input.postalCode,\n country: input.country,\n }\n for (const [key, value] of Object.entries(fields)) {\n if (value) form.append(key, value)\n }\n if (input.poa) form.append('poa', input.poa, 'proof-of-address.jpg')\n if (input.latitude != null) form.append('latitude', String(input.latitude))\n if (input.longitude != null) form.append('longitude', String(input.longitude))\n appendSignals(form, input.signals)\n return this.request('POST', '/v1/client/address', form)\n }\n\n /**\n * Finalise the session (runs face-match + the decision engine).\n *\n * @param input\n * @returns\n */\n complete(input: CompleteInput = {}): Promise<ClientSession> {\n return this.request('POST', '/v1/client/complete', input.signals ?? {})\n }\n\n private async request(method: string, path: string, body?: FormData | object): Promise<ClientSession> {\n const headers: Record<string, string> = { 'X-Client-Token': this.token }\n let payload: BodyInit | undefined\n\n if (body instanceof FormData) {\n payload = body\n } else if (body) {\n headers['Content-Type'] = 'application/json'\n payload = JSON.stringify(body)\n }\n\n const res = await this.fetchImpl(`${this.baseUrl}${path}`, { method, headers, body: payload })\n const text = await res.text()\n const json = text ? (JSON.parse(text) as { message?: string; data?: ClientSession }) : {}\n\n if (!res.ok) {\n throw new WidgetApiError(json.message ?? `Request failed (${res.status})`, res.status)\n }\n return json.data as ClientSession\n }\n}\n","import type { ClientRealtime } from './client'\n\n/** Fires for every event received on a subscribed channel. */\nexport type WidgetRealtimeHandler = (event: string, data: unknown) => void\n\n/** A connected push transport. `subscribe` returns an unsubscribe function. */\nexport interface WidgetRealtimeClient {\n subscribe(channel: string, handler: WidgetRealtimeHandler): () => void\n disconnect(): void\n}\n\n/** A factory that builds a push client from the session's realtime config. */\nexport type WidgetRealtimeFactory = (\n config: ClientRealtime,\n options: WidgetRealtimeOptions,\n) => Promise<WidgetRealtimeClient | null>\n\nexport interface WidgetRealtimeOptions {\n /** The client-token channel-auth endpoint (pusher). */\n authEndpoint: string\n /** The session's client token (sent as `X-Client-Token` to the authorizer). */\n token: string\n}\n\n/** CDN that serves any npm package as ESM (`…/pkg@ver/+esm`). */\nconst CDN = 'https://cdn.jsdelivr.net/npm/'\n\n/**\n * Import an optional transport SDK. Tries the bare package specifier first (a\n * bundler, import map, or Node resolves it), then falls back to the jsdelivr CDN\n * so a plain browser embed still loads it — a bare specifier like `pusher-js`\n * isn't resolvable at runtime in the browser, which would otherwise leave the\n * widget silently polling. Non-literal specifiers also keep the bundler from\n * trying to resolve these (they aren't hard dependencies) and avoid needing their\n * type declarations.\n */\nasync function loadOptional(pkg: string, cdnPath: string): Promise<unknown> {\n try {\n return await import(/* @vite-ignore */ /* webpackIgnore: true */ pkg)\n } catch {\n return await import(/* @vite-ignore */ /* webpackIgnore: true */ `${CDN}${cdnPath}`)\n }\n}\n\n/**\n * Connect to whichever push transport the API reported for this session. Returns\n * null for `polling`/`off`/`memory` (no push — the widget polls instead) and also\n * when the transport SDK can't be loaded (e.g. a plain `<script>` standalone embed\n * with no bundler), so realtime degrades gracefully to polling. The SDK is\n * dynamically imported so only the active transport is ever pulled in.\n */\nexport async function createWidgetRealtimeClient(\n config: ClientRealtime,\n options: WidgetRealtimeOptions,\n): Promise<WidgetRealtimeClient | null> {\n try {\n if (config.transport === 'pusher') return await createPusherClient(config, options)\n if (config.transport === 'firebase') return await createFirebaseClient(config)\n } catch {\n // Transport SDK unavailable / failed to connect — fall back to polling.\n return null\n }\n\n return null\n}\n\n// --- pusher-js (minimal surface we depend on) ---\n\ninterface PusherChannel {\n bind_global(cb: (event: string, data: unknown) => void): void\n unbind_global(cb: (event: string, data: unknown) => void): void\n}\ninterface PusherInstance {\n subscribe(channel: string): PusherChannel\n unsubscribe(channel: string): void\n disconnect(): void\n}\ntype PusherCtor = new (key: string, options: Record<string, unknown>) => PusherInstance\n\nasync function createPusherClient(\n config: ClientRealtime,\n options: WidgetRealtimeOptions,\n): Promise<WidgetRealtimeClient> {\n const mod = (await loadOptional('pusher-js', 'pusher-js@8/+esm')) as { default: PusherCtor }\n const Pusher = mod.default\n const pusher = new Pusher(String(config.key ?? ''), {\n cluster: String(config.cluster ?? 'mt1'),\n forceTLS: Boolean(config.forceTLS ?? false),\n ...(config.wsHost\n ? {\n wsHost: String(config.wsHost),\n wsPort: Number(config.wsPort),\n wssPort: Number(config.wssPort ?? config.wsPort),\n enabledTransports: (config.enabledTransports as string[]) ?? ['ws', 'wss'],\n }\n : {}),\n // The widget authorizes private channels with its short-lived client token,\n // which the API scopes to this session's own channel only.\n channelAuthorization: {\n transport: 'ajax',\n endpoint: options.authEndpoint,\n headers: { 'X-Client-Token': options.token },\n },\n })\n\n return {\n subscribe(channel, handler) {\n const ch = pusher.subscribe(channel)\n const cb = (event: string, data: unknown) => handler(event, data)\n ch.bind_global(cb)\n\n return () => {\n ch.unbind_global(cb)\n pusher.unsubscribe(channel)\n }\n },\n disconnect() {\n pusher.disconnect()\n },\n }\n}\n\n// --- firebase (minimal surface we depend on) ---\n\ninterface FirebaseApp {\n name: string\n}\ninterface FirebaseAppModule {\n initializeApp(options: Record<string, unknown>, name: string): FirebaseApp\n getApps(): FirebaseApp[]\n getApp(name: string): FirebaseApp\n}\ninterface FirebaseAuthModule {\n getAuth(app: FirebaseApp): unknown\n signInWithCustomToken(auth: unknown, token: string): Promise<unknown>\n}\ninterface FirebaseSnapshot {\n val(): { event: string; payload: unknown } | null\n}\ninterface FirebaseDatabaseModule {\n getDatabase(app: FirebaseApp): unknown\n ref(db: unknown, path: string): unknown\n query(ref: unknown, ...constraints: unknown[]): unknown\n orderByChild(path: string): unknown\n startAt(value: number): unknown\n onChildAdded(query: unknown, cb: (snap: FirebaseSnapshot) => void): () => void\n}\n\nasync function createFirebaseClient(config: ClientRealtime): Promise<WidgetRealtimeClient> {\n const [app, auth, database] = (await Promise.all([\n loadOptional('firebase/app', 'firebase@11/app/+esm'),\n loadOptional('firebase/auth', 'firebase@11/auth/+esm'),\n loadOptional('firebase/database', 'firebase@11/database/+esm'),\n ])) as [FirebaseAppModule, FirebaseAuthModule, FirebaseDatabaseModule]\n\n const name = 'arkyc-widget-realtime'\n const fbApp = app.getApps().some((a) => a.name === name)\n ? app.getApp(name)\n : app.initializeApp(\n {\n apiKey: String(config.apiKey ?? ''),\n authDomain: String(config.authDomain ?? ''),\n projectId: String(config.projectId ?? ''),\n databaseURL: String(config.databaseURL ?? ''),\n },\n name,\n )\n\n // The per-session custom token authorizes reads of this session's channel only.\n if (config.token) await auth.signInWithCustomToken(auth.getAuth(fbApp), config.token)\n\n const db = database.getDatabase(fbApp)\n const since = Date.now()\n\n return {\n subscribe(channel, handler) {\n const q = database.query(\n database.ref(db, `realtime/${channel}`),\n database.orderByChild('at'),\n database.startAt(since),\n )\n const unsubscribe = database.onChildAdded(q, (snap) => {\n const value = snap.val()\n if (value) handler(value.event, value.payload)\n })\n\n return () => unsubscribe()\n },\n disconnect() {\n // Firebase listeners are torn down per-subscription via the returned unsub.\n },\n }\n}\n","import type { ProjectBranding } from '@arkyc/types'\nimport themeCss from 'virtual:arkyc-theme-css'\n\nconst LIGHT = {\n background: '#ffffff',\n foreground: '#0f172a',\n muted: '#64748b',\n border: '#e2e8f0',\n}\n\nconst DARK = {\n background: '#0f172a',\n foreground: '#f8fafc',\n muted: '#94a3b8',\n border: '#1e293b',\n}\n\n/**\n * Resolves project branding into a concrete theme and renders its CSS. One class\n * owns the whole \"theme\" concern: defaulted colour/logo/radius values plus the\n * CSS-variable block and stylesheet derived from them.\n */\nexport class Theme {\n readonly primaryColor: string\n readonly borderRadius: number\n readonly mode: 'light' | 'dark'\n readonly logoUrl: string | null\n /** Project/company display name shown in the header (when branding is shown). */\n readonly name: string | null\n /** Whether to show the project name/logo in the header (white-label off → false). */\n readonly showBranding: boolean\n /** Surface (card) background. */\n readonly background: string\n /** Primary text colour. */\n readonly foreground: string\n /** Muted text colour. */\n readonly muted: string\n /** Subtle border colour. */\n readonly border: string\n\n constructor(branding?: ProjectBranding | null) {\n this.mode = branding?.theme === 'dark' ? 'dark' : 'light'\n const palette = this.mode === 'dark' ? DARK : LIGHT\n this.primaryColor = branding?.primary_color ?? '#b8860b'\n this.borderRadius = branding?.border_radius ?? 12\n this.logoUrl = branding?.logo_url ?? null\n this.name = branding?.name ?? null\n this.showBranding = branding?.show_branding !== false\n this.background = palette.background\n this.foreground = palette.foreground\n this.muted = palette.muted\n this.border = palette.border\n }\n\n /**\n * The CSS-variable declaration block for this theme.\n *\n * @returns\n */\n variables(): string {\n return [\n `--arkyc-primary:${this.primaryColor}`,\n `--arkyc-radius:${this.borderRadius}px`,\n `--arkyc-bg:${this.background}`,\n `--arkyc-fg:${this.foreground}`,\n `--arkyc-muted:${this.muted}`,\n `--arkyc-border:${this.border}`,\n ].join(';')\n }\n\n /**\n * The widget stylesheet, parameterised by this theme's variables.\n *\n * @returns\n */\n stylesheet(): string {\n return themeCss.replace('/* {variables} */', `${this.variables()};`).trim()\n }\n}\n","/**\n * Camera capture, scoped to one class. DOM-injectable so the widget core stays\n * testable without a real browser. A live `getUserMedia` preview is used when\n * available; the view always offers a file input as a fallback. An instance\n * owns the active stream so callers don't track it themselves.\n */\n\n/** Which camera to request: `environment` for documents, `user` for selfies. */\nexport type Facing = 'environment' | 'user'\n\nexport class Camera {\n private stream: MediaStream | null = null\n\n constructor(\n private readonly doc: Document = globalThis.document,\n private readonly nav: Navigator = globalThis.navigator,\n ) {}\n\n /** Whether live camera capture is available in this environment. */\n get supported(): boolean {\n return !!this.nav?.mediaDevices?.getUserMedia\n }\n\n /**\n * Start a camera stream and bind it to a `<video>` element for preview.\n *\n * @param video\n * @param facing\n * @returns\n */\n async start(video: HTMLVideoElement, facing: Facing): Promise<MediaStream> {\n const stream = await this.nav.mediaDevices.getUserMedia({\n video: { facingMode: facing },\n audio: false,\n })\n this.stream = stream\n video.srcObject = stream\n video.setAttribute('playsinline', 'true')\n video.muted = true\n await video.play().catch(() => undefined)\n return stream\n }\n\n /**\n * Stop the active stream and release the camera.\n */\n stop(): void {\n this.stream?.getTracks().forEach((track) => track.stop())\n this.stream = null\n }\n\n /** Whether this environment can record video (active liveness). */\n get canRecord(): boolean {\n return typeof (globalThis as { MediaRecorder?: unknown }).MediaRecorder !== 'undefined'\n }\n\n /**\n * Start recording the active stream. Returns a handle whose `stop()` resolves\n * to the recorded `video/webm` blob — used by the active-liveness flow to record\n * the user performing the challenge sequence.\n *\n * @param stream\n * @returns\n */\n recordStart(stream: MediaStream): { stop(): Promise<Blob> } {\n const chunks: BlobPart[] = []\n const recorder = new MediaRecorder(stream, { mimeType: 'video/webm' })\n recorder.ondataavailable = (event) => {\n if (event.data && event.data.size > 0) chunks.push(event.data)\n }\n recorder.start()\n\n return {\n stop: () =>\n new Promise<Blob>((resolve) => {\n recorder.onstop = () => resolve(new Blob(chunks, { type: 'video/webm' }))\n recorder.stop()\n }),\n }\n }\n\n /**\n * Sample the current frame's average luminance for basic quality hints (too\n * dark / glare). A cheap proxy with no model — enough to guide the user and\n * gate auto-capture.\n *\n * @param video\n * @returns A 0–1 brightness plus `tooDark`/`glare` flags, or `null` if unreadable.\n */\n sampleQuality(video: HTMLVideoElement): { brightness: number; tooDark: boolean; glare: boolean } | null {\n const canvas = this.doc.createElement('canvas')\n // Downscale heavily — we only need an average, not detail.\n canvas.width = 32\n canvas.height = 32\n const ctx = canvas.getContext('2d')\n if (!ctx || !video.videoWidth) return null\n ctx.drawImage(video, 0, 0, canvas.width, canvas.height)\n\n const { data } = ctx.getImageData(0, 0, canvas.width, canvas.height)\n let sum = 0\n let bright = 0\n const pixels = data.length / 4\n for (let i = 0; i < data.length; i += 4) {\n const lum = (0.299 * data[i]! + 0.587 * data[i + 1]! + 0.114 * data[i + 2]!) / 255\n sum += lum\n if (lum > 0.92) bright += 1\n }\n const brightness = sum / pixels\n return { brightness, tooDark: brightness < 0.25, glare: bright / pixels > 0.15 }\n }\n\n /**\n * Grab the current video frame as a JPEG `Blob` via an offscreen canvas.\n *\n * @param video\n * @param quality\n * @returns\n */\n grabFrame(video: HTMLVideoElement, quality = 0.92): Promise<Blob> {\n const canvas = this.doc.createElement('canvas')\n canvas.width = video.videoWidth || 1280\n canvas.height = video.videoHeight || 720\n const ctx = canvas.getContext('2d')\n if (!ctx) return Promise.reject(new Error('Canvas 2D context unavailable.'))\n ctx.drawImage(video, 0, 0, canvas.width, canvas.height)\n\n return new Promise<Blob>((resolve, reject) => {\n canvas.toBlob(\n (blob) => (blob ? resolve(blob) : reject(new Error('Failed to capture frame.'))),\n 'image/jpeg',\n quality,\n )\n })\n }\n\n /**\n * Read a selected file from an `<input type=\"file\">` as a `Blob`.\n *\n * @param input\n * @returns\n */\n static fileFromInput(input: HTMLInputElement): Blob | null {\n return input.files?.[0] ?? null\n }\n}\n","//#region src/realtime.ts\n/**\n* Realtime transport contracts (Phase 16). Pure, dependency-free helpers shared\n* by the API (server publish) and the dashboard/widget (client subscribe), so\n* channel and event names never drift between them.\n*/\n/** Events the API broadcasts. Clients react by invalidating their caches. */\nconst REALTIME_EVENT = {\n\t/** A verification session changed status (the `transitionTo` choke point). */\n\tsessionTransition: \"session.transition\",\n\t/** A reviewer acted on a session (assign/note/suspicious/decision/retry). */\n\treviewAction: \"review.action\"\n};\n/**\n* Private channel name builders. All channels are `private-` (Pusher protocol),\n* so a subscription must be authorized server-side against the caller's scope.\n*/\nconst realtimeChannels = {\n\t/** Everything in an organization. */\n\torganization: (organizationId) => `private-organization-${organizationId}`,\n\t/** Everything in a project. */\n\tproject: (organizationId, projectId) => `private-organization-${organizationId}-project-${projectId}`,\n\t/** A single verification session (used by the widget via client token). */\n\tsession: (sessionId) => `private-session-${sessionId}`\n};\n/** Parse a private channel name back into its scope, or null if unrecognized. */\nfunction parseRealtimeChannel(channel) {\n\tconst project = /^private-organization-(.+)-project-(.+)$/.exec(channel);\n\tif (project) return {\n\t\tkind: \"project\",\n\t\torganizationId: project[1],\n\t\tprojectId: project[2]\n\t};\n\tconst organization = /^private-organization-(.+)$/.exec(channel);\n\tif (organization) return {\n\t\tkind: \"organization\",\n\t\torganizationId: organization[1]\n\t};\n\tconst session = /^private-session-(.+)$/.exec(channel);\n\tif (session) return {\n\t\tkind: \"session\",\n\t\tsessionId: session[1]\n\t};\n\treturn null;\n}\n//#endregion\nexport { REALTIME_EVENT, parseRealtimeChannel, realtimeChannels };\n\n//# sourceMappingURL=realtime.mjs.map","//#region src/workflow.ts\n/**\n* The default pipeline's stages, in canonical order — what runs when a session\n* has no workflow. `address` is deliberately NOT here: it's an opt-in stage,\n* available only on custom workflows.\n*/\nconst WORKFLOW_STEP_KEYS = [\n\t\"document\",\n\t\"liveness\",\n\t\"face_match\"\n];\n/**\n* Every stage a custom workflow may include, in canonical order. Used by the\n* workflow editor and to validate/normalise stored steps — a superset of\n* {@link WORKFLOW_STEP_KEYS} that adds the opt-in `address` stage.\n*/\nconst AVAILABLE_WORKFLOW_STEP_KEYS = [\n\t\"document\",\n\t\"address\",\n\t\"liveness\",\n\t\"face_match\"\n];\n/** Every selectable address-verification method, in display order. */\nconst ADDRESS_METHODS = [\n\t\"poa_document\",\n\t\"device_location\",\n\t\"geocode_lookup\"\n];\n/** The default address config applied when the stage is enabled without one. */\nconst DEFAULT_ADDRESS_CONFIG = {\n\tmethods: [\"geocode_lookup\"],\n\ton_fail: \"review\"\n};\n/** The default pipeline applied when a session has no workflow. */\nconst DEFAULT_WORKFLOW_CONFIG = {\n\tsteps: [\n\t\t{\n\t\t\tkey: \"document\",\n\t\t\tenabled: true\n\t\t},\n\t\t{\n\t\t\tkey: \"liveness\",\n\t\t\tenabled: true\n\t\t},\n\t\t{\n\t\t\tkey: \"face_match\",\n\t\t\tenabled: true\n\t\t}\n\t],\n\toptions: { skip_ocr: false }\n};\n/**\n* Whether a stage runs under a config. A `null` config means \"no workflow\" — the\n* default pipeline, where every stage runs. Within a real config, a stage that is\n* absent or `enabled: false` does not run.\n*/\nfunction workflowEnables(config, key) {\n\tif (!config) return WORKFLOW_STEP_KEYS.includes(key);\n\treturn config.steps.some((step) => step.key === key && step.enabled);\n}\n/**\n* The resolved address config for a session's workflow, or `null` when the\n* address stage isn't enabled. Missing fields fall back to {@link DEFAULT_ADDRESS_CONFIG}.\n*/\nfunction workflowAddressConfig(config) {\n\tif (!config) return null;\n\tconst step = config.steps.find((s) => s.key === \"address\" && s.enabled);\n\tif (!step) return null;\n\treturn {\n\t\t...DEFAULT_ADDRESS_CONFIG,\n\t\t...step.config ?? {}\n\t};\n}\n/** Whether OCR parsing should run: the document stage is on and `skip_ocr` is off. */\nfunction workflowRunsOcr(config) {\n\tif (!config) return true;\n\treturn workflowEnables(config, \"document\") && !config.options.skip_ocr;\n}\n/** The enabled stages in pipeline order (used by the widget to sequence its steps). */\nfunction workflowEnabledSteps(config) {\n\tif (!config) return [...WORKFLOW_STEP_KEYS];\n\treturn config.steps.filter((step) => step.enabled).map((step) => step.key);\n}\n//#endregion\nexport { ADDRESS_METHODS, AVAILABLE_WORKFLOW_STEP_KEYS, DEFAULT_ADDRESS_CONFIG, DEFAULT_WORKFLOW_CONFIG, WORKFLOW_STEP_KEYS, workflowAddressConfig, workflowEnabledSteps, workflowEnables, workflowRunsOcr };\n\n//# sourceMappingURL=workflow.mjs.map","import {\n type DocumentType,\n type LivenessMode,\n type VerificationDecision,\n type VerificationStatus,\n type WidgetStep,\n type WorkflowConfig,\n type WorkflowStepKey,\n workflowEnabledSteps,\n workflowRunsOcr,\n} from '@arkyc/types'\n\n/** Context that influences flow branching. */\nexport interface FlowContext {\n documentType?: DocumentType | null\n /** Which liveness flow this session runs (resolved from the capture model). */\n livenessMode?: LivenessMode\n /** The applied workflow (orders/toggles the coarse stages), or null for the default flow. */\n workflow?: WorkflowConfig | null\n}\n\n/** The widget screens that make up each coarse verification stage, in stage-local order. */\nconst STAGE_STEPS: Record<WorkflowStepKey, WidgetStep[]> = {\n document: ['document_selection', 'front_capture', 'back_capture', 'ocr_processing'],\n address: ['address_entry', 'address_processing'],\n liveness: ['active_liveness', 'selfie_capture', 'passive_liveness'],\n face_match: ['face_match'],\n}\n\n/**\n * The verification flow's step machine. Stateless — exposed as static members so\n * the single \"flow\" concern lives in one class rather than as floating helpers.\n */\nexport class Flow {\n /**\n * The flow screens, in the order the widget walks them. The `back_capture`\n * screen is skipped for single-sided documents (passports).\n */\n static readonly STEP_ORDER: WidgetStep[] = [\n 'welcome',\n 'document_selection',\n 'front_capture',\n 'back_capture',\n 'ocr_processing',\n 'active_liveness',\n 'selfie_capture',\n 'passive_liveness',\n 'face_match',\n 'processing',\n 'result',\n ]\n\n /**\n * Statuses from which a session can no longer progress.\n */\n static readonly TERMINAL_STATUSES: VerificationStatus[] = [\n 'approved',\n 'rejected',\n 'requires_review',\n 'expired',\n 'cancelled',\n ]\n\n /**\n * Whether a document type has a second (back) side to capture.\n *\n * @param type\n * @returns\n */\n static documentHasBack(type: DocumentType | null | undefined): boolean {\n return type != null && type !== 'passport'\n }\n\n /**\n * The screens to walk for this session, in order. With no workflow this is the\n * default {@link STEP_ORDER}; a workflow reorders the coarse stages and drops\n * disabled ones (their screens are excluded entirely), always bracketed by\n * `welcome` and `processing`/`result`.\n */\n static stepOrder(ctx: FlowContext = {}): WidgetStep[] {\n const stages = workflowEnabledSteps(ctx.workflow) as WorkflowStepKey[]\n const middle = stages.flatMap((stage) => STAGE_STEPS[stage])\n\n return ['welcome', ...middle, 'processing', 'result']\n }\n\n /**\n * Whether a step runs for the given context. `back_capture` is skipped for\n * single-sided documents; `ocr_processing` is skipped when the workflow skips\n * OCR; the liveness steps branch on the resolved mode — `active_liveness` only\n * in active mode, `selfie_capture`/`passive_liveness` only in passive mode.\n * Stage-level disabling is handled by {@link stepOrder} (disabled stages are\n * absent from the order), so this only covers within-stage branching.\n */\n static isStepEnabled(step: WidgetStep, ctx: FlowContext = {}): boolean {\n if (step === 'back_capture') return Flow.documentHasBack(ctx.documentType)\n if (step === 'ocr_processing') return workflowRunsOcr(ctx.workflow)\n if (step === 'active_liveness') return ctx.livenessMode === 'active'\n if (step === 'selfie_capture' || step === 'passive_liveness') {\n return ctx.livenessMode !== 'active'\n }\n return true\n }\n\n /**\n * The next enabled screen after `current`, honouring the workflow order and the\n * branch rules. Returns `current` when already at the end.\n *\n * @param current\n * @param ctx\n * @returns\n */\n static nextStep(current: WidgetStep, ctx: FlowContext = {}): WidgetStep {\n const order = Flow.stepOrder(ctx)\n const idx = order.indexOf(current)\n if (idx < 0) return current\n for (let i = idx + 1; i < order.length; i += 1) {\n const step = order[i]!\n if (Flow.isStepEnabled(step, ctx)) return step\n }\n return current\n }\n\n /**\n * Whether a session status is terminal (the flow is done).\n *\n * @param status\n * @returns\n */\n static isTerminal(status: VerificationStatus): boolean {\n return Flow.TERMINAL_STATUSES.includes(status)\n }\n\n /**\n * Map a terminal session status to the decision the integrator cares about.\n * Non-decision terminals (`expired`/`cancelled`) and in-flight statuses map to\n * `null`.\n */\n static statusToDecision(status: VerificationStatus): VerificationDecision | null {\n switch (status) {\n case 'approved':\n return 'approved'\n case 'rejected':\n return 'rejected'\n case 'requires_review':\n return 'requires_review'\n default:\n return null\n }\n }\n}\n","/**\n * In-browser face analysis for selfie auto-capture and active-liveness detection.\n *\n * The real implementation loads MediaPipe's FaceLandmarker (landmarks +\n * blendshapes) lazily from a CDN at runtime — it is NOT bundled, and never\n * touched unless a live camera screen actually asks for it. Everything is\n * feature-detected and wrapped so that on any failure (no WebGL/WASM, offline,\n * a non-browser/test host) `ready()` resolves `false` and callers fall back to\n * the manual flow. The widget's pure, fake-DOM tests therefore never load it.\n */\nimport type { LivenessChallenge } from '@arkyc/types'\n\n/** A normalized read of the current frame's face. */\nexport interface FaceSample {\n present: boolean\n /** Face bounding-box centre, normalized 0–1. */\n centerX: number\n centerY: number\n /** Face bounding-box height, normalized 0–1 (proxy for distance). */\n scale: number\n /** Head turn: <0 toward one side, >0 the other (approx, from landmark asymmetry). */\n turn: number\n /** Head pitch proxy: nose-to-eye offset over face height (relative changes matter). */\n pitch: number\n /** Eyes-closed score 0–1 (blendshape). */\n blink: number\n /** Smile score 0–1 (blendshape). */\n smile: number\n}\n\nexport interface FaceAnalyzer {\n /** Load models. Resolves `false` if unavailable — callers then go manual. */\n ready(): Promise<boolean>\n /** Analyze the current video frame, or `null` if it can't be read. */\n analyze(video: HTMLVideoElement): FaceSample | null\n /** Release resources. */\n close(): void\n}\n\n// CDN asset locations. Built at runtime (not string literals) so bundlers leave\n// the dynamic import live instead of trying to resolve/inline it.\nconst TASKS_VERSION = '0.10.20'\nconst npm = (path: string) => 'https://cdn.jsdelivr.net/npm/' + path\nconst MODEL_URL =\n 'https://storage.googleapis.com/mediapipe-models/face_landmarker/face_landmarker/float16/1/face_landmarker.task'\n\n// MediaPipe FaceMesh canonical landmark indices.\nconst NOSE = 1\nconst LEFT_EYE = 33\nconst RIGHT_EYE = 263\nconst LEFT_EDGE = 234\nconst RIGHT_EDGE = 454\nconst CHIN = 152\n\ninterface Pt {\n x: number\n y: number\n}\ninterface LmResult {\n faceLandmarks: Pt[][]\n faceBlendshapes?: { categories: { categoryName: string; score: number }[] }[]\n}\n\nfunction blend(cats: { categoryName: string; score: number }[] | undefined, name: string): number {\n return cats?.find((c) => c.categoryName === name)?.score ?? 0\n}\n\nfunction now(): number {\n const p = (globalThis as { performance?: { now?: () => number } }).performance\n return p?.now ? p.now() : 0\n}\n\nclass MediapipeFaceAnalyzer implements FaceAnalyzer {\n private landmarker: { detectForVideo(v: HTMLVideoElement, t: number): LmResult; close(): void } | null = null\n private state: 'idle' | 'loading' | 'ready' | 'failed' = 'idle'\n private loading: Promise<boolean> | null = null\n\n async ready(): Promise<boolean> {\n if (this.state === 'ready') return true\n if (this.state === 'failed') return false\n if (this.loading) return this.loading\n this.loading = this.load()\n return this.loading\n }\n\n private async load(): Promise<boolean> {\n this.state = 'loading'\n try {\n if (typeof document === 'undefined') throw new Error('no document')\n // Bail early if WebGL2 isn't available — MediaPipe needs it.\n const probe = document.createElement('canvas')\n if (!probe.getContext('webgl2')) throw new Error('no webgl2')\n\n const visionUrl = npm(`@mediapipe/tasks-vision@${TASKS_VERSION}/vision_bundle.mjs`)\n const vision = (await import(/* @vite-ignore */ visionUrl)) as {\n FilesetResolver: { forVisionTasks(url: string): Promise<unknown> }\n FaceLandmarker: { createFromOptions(fileset: unknown, opts: unknown): Promise<unknown> }\n }\n const fileset = await vision.FilesetResolver.forVisionTasks(npm(`@mediapipe/tasks-vision@${TASKS_VERSION}/wasm`))\n this.landmarker = (await vision.FaceLandmarker.createFromOptions(fileset, {\n baseOptions: { modelAssetPath: MODEL_URL, delegate: 'GPU' },\n outputFaceBlendshapes: true,\n runningMode: 'VIDEO',\n numFaces: 1,\n })) as MediapipeFaceAnalyzer['landmarker']\n this.state = 'ready'\n return true\n } catch {\n this.state = 'failed'\n return false\n }\n }\n\n analyze(video: HTMLVideoElement): FaceSample | null {\n if (this.state !== 'ready' || !this.landmarker || !video.videoWidth) return null\n let res: LmResult\n try {\n res = this.landmarker.detectForVideo(video, now())\n } catch {\n return null\n }\n const lm = res.faceLandmarks?.[0]\n if (!lm || lm.length === 0) {\n return { present: false, centerX: 0.5, centerY: 0.5, scale: 0, turn: 0, pitch: 0, blink: 0, smile: 0 }\n }\n\n let minX = 1\n let maxX = 0\n let minY = 1\n let maxY = 0\n for (const p of lm) {\n if (p.x < minX) minX = p.x\n if (p.x > maxX) maxX = p.x\n if (p.y < minY) minY = p.y\n if (p.y > maxY) maxY = p.y\n }\n const height = Math.max(1e-3, maxY - minY)\n\n const nose = lm[NOSE]!\n const leftEye = lm[LEFT_EYE]!\n const rightEye = lm[RIGHT_EYE]!\n const leftEdge = lm[LEFT_EDGE]!\n const rightEdge = lm[RIGHT_EDGE]!\n const chin = lm[CHIN]!\n\n // Turn: horizontal asymmetry of the nose between the two face edges. Signed\n // (empirically, against a real front camera) so that turning the head right\n // yields turn>0 and left yields turn<0 — matching the turn_left/turn_right\n // prompts. Computed on the raw frame; the preview's CSS mirror is cosmetic.\n const dLeft = nose.x - leftEdge.x\n const dRight = rightEdge.x - nose.x\n const turn = (dRight - dLeft) / Math.max(1e-3, dLeft + dRight)\n\n // Pitch proxy: nose vertical position between the eye line and the chin.\n const eyeY = (leftEye.y + rightEye.y) / 2\n const pitch = (nose.y - eyeY) / Math.max(1e-3, chin.y - eyeY)\n\n const cats = res.faceBlendshapes?.[0]?.categories\n const blink = Math.max(blend(cats, 'eyeBlinkLeft'), blend(cats, 'eyeBlinkRight'))\n const smile = (blend(cats, 'mouthSmileLeft') + blend(cats, 'mouthSmileRight')) / 2\n\n return {\n present: true,\n centerX: (minX + maxX) / 2,\n centerY: (minY + maxY) / 2,\n scale: height,\n turn,\n pitch,\n blink,\n smile,\n }\n }\n\n close(): void {\n try {\n this.landmarker?.close()\n } catch {\n /* ignore */\n }\n this.landmarker = null\n this.state = 'failed'\n }\n}\n\n/** The default (real, MediaPipe-backed) analyzer. */\nexport function createDefaultFaceAnalyzer(): FaceAnalyzer {\n return new MediapipeFaceAnalyzer()\n}\n\n/** A challenge detector: fed frame samples, returns `true` once satisfied. */\nexport interface ChallengeDetector {\n feed(sample: FaceSample): boolean\n /**\n * 0–1 progress toward satisfying the challenge, updated on each `feed` — drives\n * the UI's hold-progress ring. Multi-stage gestures (blink/nod) step through\n * intermediate values; sustained gestures ramp with the hold streak.\n */\n readonly progress: number\n}\n\n/**\n * Detection thresholds. These are the knobs to tune against a real camera —\n * use the calibration harness (`playground/calibration.html`) to read live\n * signal values and adjust. All are overridable per-widget via `faceTuning`.\n */\nexport interface FaceTuning {\n /** |turn| asymmetry needed to count as a head turn. */\n turn: number\n /** Mouth-smile blendshape score needed to count as a smile. */\n smile: number\n /** Eye-blink score above which the eyes count as closed. */\n blinkClosed: number\n /** Eye-blink score below which they count as re-opened. */\n blinkOpen: number\n /** Consecutive frames a condition must hold before it fires. */\n hold: number\n /** Pitch increase (looking down) needed to arm a nod. */\n nodDown: number\n /** Pitch return delta (back up) that completes a nod. */\n nodReturn: number\n /** Face must grow past `baseline * closerFactor` for move-closer. */\n closerFactor: number\n /** Selfie framing tolerances (distance from frame centre / size window). */\n selfieCenterTol: number\n selfieCenterYTol: number\n selfieMinScale: number\n selfieMaxScale: number\n}\n\nexport const DEFAULT_TUNING: FaceTuning = {\n turn: 0.18,\n smile: 0.5,\n blinkClosed: 0.55,\n blinkOpen: 0.25,\n hold: 3,\n nodDown: 0.06,\n nodReturn: 0.02,\n closerFactor: 1.22,\n selfieCenterTol: 0.2,\n selfieCenterYTol: 0.25,\n selfieMinScale: 0.28,\n selfieMaxScale: 0.85,\n}\n\n/**\n * Build a stateful detector for a single active-liveness challenge.\n *\n * @param challenge\n * @param t\n * @returns\n */\nexport function makeChallengeDetector(challenge: LivenessChallenge, t: FaceTuning = DEFAULT_TUNING): ChallengeDetector {\n // A sustained gesture: a condition that must hold for `t.hold` frames. Progress\n // ramps with the streak.\n const sustained = (ok: (s: FaceSample) => boolean): ChallengeDetector => {\n let n = 0\n return {\n feed(s) {\n n = s.present && ok(s) ? n + 1 : 0\n return n >= t.hold\n },\n get progress() {\n return Math.min(1, n / Math.max(1, t.hold))\n },\n }\n }\n\n // A two-stage gesture: reach an extreme, then return. Progress is 0 → ~0.6 (mid)\n // → 1 (done).\n const twoStage = (\n pick: (s: FaceSample) => number,\n extreme: (v: number, base: number) => boolean,\n settled: (v: number, base: number) => boolean,\n ): ChallengeDetector => {\n let base: number | null = null\n let reached = false\n let done = false\n return {\n feed(s) {\n if (!s.present) return false\n const v = pick(s)\n if (base === null) {\n base = v\n return false\n }\n if (extreme(v, base)) reached = true\n else if (reached && settled(v, base)) {\n done = true\n return true\n }\n return false\n },\n get progress() {\n return done ? 1 : reached ? 0.6 : 0\n },\n }\n }\n\n switch (challenge) {\n case 'blink': {\n // No baseline: eyes must close (absolute) then re-open. Processed from the\n // first frame, unlike the baseline-relative two-stage gestures.\n let closed = false\n let done = false\n return {\n feed(s) {\n if (!s.present) return false\n if (s.blink > t.blinkClosed) closed = true\n else if (closed && s.blink < t.blinkOpen) {\n done = true\n return true\n }\n return false\n },\n get progress() {\n return done ? 1 : closed ? 0.6 : 0\n },\n }\n }\n case 'smile':\n return sustained((s) => s.smile > t.smile)\n case 'turn_left':\n return sustained((s) => s.turn < -t.turn)\n case 'turn_right':\n return sustained((s) => s.turn > t.turn)\n case 'nod':\n return twoStage(\n (s) => s.pitch,\n (v, base) => v > base + t.nodDown,\n (v, base) => v < base + t.nodReturn,\n )\n case 'move_closer': {\n let base: number | null = null\n let n = 0\n return {\n feed(s) {\n if (!s.present) return false\n if (base === null) {\n base = s.scale\n return false\n }\n n = s.scale > base * t.closerFactor ? n + 1 : 0\n return n >= t.hold\n },\n get progress() {\n return Math.min(1, n / Math.max(1, t.hold))\n },\n }\n }\n }\n}\n\n/** Whether a face is well-framed for a selfie (present, centred, right distance). */\nexport function isSelfieReady(s: FaceSample, t: FaceTuning = DEFAULT_TUNING): boolean {\n return (\n s.present &&\n Math.abs(s.centerX - 0.5) < t.selfieCenterTol &&\n Math.abs(s.centerY - 0.5) < t.selfieCenterYTol &&\n s.scale > t.selfieMinScale &&\n s.scale < t.selfieMaxScale\n )\n}\n","/**\n * In-browser document detection for the capture screens. Pure JavaScript, no\n * dependency: it draws the current frame to a small canvas and runs Sobel edge\n * projection to locate the document's four borders, then judges whether a real,\n * well-framed, in-focus document is present before auto-capturing.\n *\n * Like the face analyzer it is feature-detected and wrapped so that on any\n * failure (no 2D canvas, a non-browser/test host) `ready()` resolves `false` and\n * the caller falls back to the simpler brightness heuristic. The detection core\n * (`analyzeDocumentGray` / `documentGuidance`) is a set of pure functions over a\n * grayscale buffer, so it is unit-testable without a real canvas or camera.\n */\n\n/** Detected document rectangle, normalized 0–1 within the frame. */\nexport interface DocRect {\n x: number\n y: number\n w: number\n h: number\n}\n\n/**\n * A normalized read of the current frame's document candidate.\n */\nexport interface DocumentSample {\n /** A plausible rectangular document border was found. */\n present: boolean\n /** The detected border rectangle (normalized 0–1). */\n rect: DocRect\n /** Rectangle area as a fraction of the frame (proxy for distance). */\n fill: number\n centerX: number\n centerY: number\n /** Weakest of the four border edges, 0–1 (how convincingly bordered it is). */\n edgeStrength: number\n /** Variance of the Laplacian over the frame — a focus/blur proxy (higher = sharper). */\n sharpness: number\n /** Mean luminance, 0–1. */\n brightness: number\n}\n\nexport interface DocumentAnalyzer {\n /** Prepare the canvas. Resolves `false` if unavailable — callers go manual. */\n ready(): Promise<boolean>\n /** Analyze the current video frame, or `null` if it can't be read. */\n analyze(video: HTMLVideoElement): DocumentSample | null\n /** Release resources. */\n close(): void\n}\n\n/**\n * Detection thresholds. Tunable per-widget via `documentTuning`. Like the face\n * tuning, the geometric/strength knobs benefit from calibration against real\n * devices and lighting.\n */\nexport interface DocumentTuning {\n /** Width (px) the frame is downscaled to before analysis. */\n sampleWidth: number\n /** Min / max rectangle area (fraction of frame) — too small = far, too big = cropped. */\n minFill: number\n maxFill: number\n /** Max distance of the document centre from the frame centre (0–1). */\n centerTol: number\n /** Min weakest-border strength to count as a real document edge (0–1). */\n minEdgeStrength: number\n /** Min Laplacian variance to count as in-focus. */\n minSharpness: number\n /** Each border must sit at least this far (0–1) inside the frame (not cropped). */\n borderMargin: number\n /** Below this mean luminance the frame is treated as too dark. */\n minBrightness: number\n /** Consecutive \"ready\" frames before auto-capture fires. */\n hold: number\n}\n\nexport const DEFAULT_DOCUMENT_TUNING: DocumentTuning = {\n sampleWidth: 320,\n // Edge-projection underestimates the document rectangle when the strongest\n // borders sit inside the card, so a demanding minFill reads as a constant\n // \"move closer\". Keep it modest; framing is still gated by maxFill + margins.\n minFill: 0.18,\n maxFill: 0.97,\n centerTol: 0.22,\n minEdgeStrength: 0.1,\n minSharpness: 8,\n borderMargin: 0.012,\n minBrightness: 0.18,\n hold: 5,\n}\n\n/**\n * The four border insets of a rect from the frame edges (top, right, bottom, left).\n *\n * @param rect\n * @returns\n */\nfunction margins(rect: DocRect): [number, number, number, number] {\n return [rect.y, 1 - (rect.x + rect.w), 1 - (rect.y + rect.h), rect.x]\n}\n\nfunction peak(arr: Float64Array, lo: number, hi: number): { i: number; v: number } {\n let bi = lo\n let bv = -1\n for (let i = lo; i < hi; i += 1) {\n const v = arr[i]!\n if (v > bv) {\n bv = v\n bi = i\n }\n }\n return { i: bi, v: bv }\n}\n\n/**\n * Locate the dominant rectangle in a grayscale frame via Sobel edge projection,\n * and measure focus and brightness. Pure — operates on a grayscale buffer.\n *\n * @param tuning\n * @returns\n */\nexport function analyzeDocumentGray(gray: ArrayLike<number>, w: number, h: number): DocumentSample {\n const empty: DocumentSample = {\n present: false,\n rect: { x: 0, y: 0, w: 0, h: 0 },\n fill: 0,\n centerX: 0.5,\n centerY: 0.5,\n edgeStrength: 0,\n sharpness: 0,\n brightness: 0,\n }\n if (w < 8 || h < 8 || gray.length < w * h) return empty\n\n // Per-row horizontal-edge energy (|gy|) and per-column vertical-edge energy (|gx|).\n const rowH = new Float64Array(h)\n const colV = new Float64Array(w)\n let lapSum = 0\n let lapSumSq = 0\n let lapN = 0\n let lumSum = 0\n for (let i = 0; i < w * h; i += 1) lumSum += gray[i]!\n const brightness = lumSum / (w * h * 255)\n\n for (let y = 1; y < h - 1; y += 1) {\n for (let x = 1; x < w - 1; x += 1) {\n const i = y * w + x\n const tl = gray[i - w - 1]!\n const tc = gray[i - w]!\n const tr = gray[i - w + 1]!\n const ml = gray[i - 1]!\n const c = gray[i]!\n const mr = gray[i + 1]!\n const bl = gray[i + w - 1]!\n const bc = gray[i + w]!\n const br = gray[i + w + 1]!\n const gx = tr + 2 * mr + br - (tl + 2 * ml + bl)\n const gy = bl + 2 * bc + br - (tl + 2 * tc + tr)\n rowH[y]! += Math.abs(gy)\n colV[x]! += Math.abs(gx)\n const lap = 4 * c - ml - mr - tc - bc\n lapSum += lap\n lapSumSq += lap * lap\n lapN += 1\n }\n }\n const sharpness = lapN ? lapSumSq / lapN - (lapSum / lapN) ** 2 : 0\n\n const bandH = Math.max(1, Math.floor(h * 0.05))\n const bandW = Math.max(1, Math.floor(w * 0.05))\n const midY = Math.floor(h / 2)\n const midX = Math.floor(w / 2)\n\n // Top/bottom borders are the strongest horizontal edges in the upper/lower half;\n // left/right borders the strongest vertical edges in the left/right half.\n const top = peak(rowH, bandH, midY)\n const bottom = peak(rowH, midY, h - bandH)\n const left = peak(colV, bandW, midX)\n const right = peak(colV, midX, w - bandW)\n\n const x0 = left.i / w\n const x1 = right.i / w\n const y0 = top.i / h\n const y1 = bottom.i / h\n const rect: DocRect = { x: x0, y: y0, w: Math.max(0, x1 - x0), h: Math.max(0, y1 - y0) }\n\n // Normalize each border by its own length (max |sobel| ≈ 4·255), so strength\n // measures how cleanly bordered the edge is, independent of document size —\n // size is judged separately by `fill`.\n const topLenPx = Math.max(1, rect.w * w)\n const sideLenPx = Math.max(1, rect.h * h)\n const edgeStrength = Math.min(\n top.v / (topLenPx * 1020),\n bottom.v / (topLenPx * 1020),\n left.v / (sideLenPx * 1020),\n right.v / (sideLenPx * 1020),\n )\n const present = rect.w > 0.12 && rect.h > 0.12 && edgeStrength > 0.04\n\n return {\n present,\n rect,\n fill: rect.w * rect.h,\n centerX: (x0 + x1) / 2,\n centerY: (y0 + y1) / 2,\n edgeStrength,\n sharpness,\n brightness,\n }\n}\n\n/**\n * Whether a document is present, well-framed and in focus, with a guidance hint.\n *\n * @param tuning\n * @returns\n */\nexport function documentGuidance(\n s: DocumentSample,\n t: DocumentTuning = DEFAULT_DOCUMENT_TUNING,\n): { ready: boolean; hint: string } {\n if (s.brightness < t.minBrightness) return { ready: false, hint: 'Too dark — find better lighting' }\n if (!s.present || s.edgeStrength < t.minEdgeStrength) {\n return { ready: false, hint: 'Fit your document inside the frame' }\n }\n if (s.fill > t.maxFill || Math.min(...margins(s.rect)) < t.borderMargin) {\n return { ready: false, hint: 'Move back a little — fit the whole document' }\n }\n if (s.fill < t.minFill) return { ready: false, hint: 'Move closer' }\n if (Math.abs(s.centerX - 0.5) > t.centerTol || Math.abs(s.centerY - 0.5) > t.centerTol) {\n return { ready: false, hint: 'Center the document' }\n }\n if (s.sharpness < t.minSharpness) return { ready: false, hint: 'Hold steady to focus' }\n return { ready: true, hint: 'Looks good — hold steady' }\n}\n\n/**\n * Whether the sample is a well-framed, in-focus document ready to capture.\n *\n * @param s\n * @param t\n * @returns\n */\nexport function isDocumentReady(s: DocumentSample, t: DocumentTuning = DEFAULT_DOCUMENT_TUNING): boolean {\n return documentGuidance(s, t).ready\n}\n\nclass CanvasDocumentAnalyzer implements DocumentAnalyzer {\n private canvas: HTMLCanvasElement | null = null\n private ctx: CanvasRenderingContext2D | null = null\n\n constructor(private readonly tuning: DocumentTuning) {}\n\n ready(): Promise<boolean> {\n try {\n if (typeof document === 'undefined') return Promise.resolve(false)\n const canvas = document.createElement('canvas')\n const ctx = canvas.getContext('2d', { willReadFrequently: true })\n if (!ctx) return Promise.resolve(false)\n this.canvas = canvas\n this.ctx = ctx\n return Promise.resolve(true)\n } catch {\n return Promise.resolve(false)\n }\n }\n\n analyze(video: HTMLVideoElement): DocumentSample | null {\n if (!this.ctx || !this.canvas || !video.videoWidth) return null\n const tw = this.tuning.sampleWidth\n const th = Math.max(1, Math.round((tw * video.videoHeight) / video.videoWidth))\n this.canvas.width = tw\n this.canvas.height = th\n let data: Uint8ClampedArray\n try {\n this.ctx.drawImage(video, 0, 0, tw, th)\n data = this.ctx.getImageData(0, 0, tw, th).data\n } catch {\n return null\n }\n const gray = new Float32Array(tw * th)\n for (let i = 0, p = 0; i < gray.length; i += 1, p += 4) {\n gray[i] = 0.299 * data[p]! + 0.587 * data[p + 1]! + 0.114 * data[p + 2]!\n }\n return analyzeDocumentGray(gray, tw, th)\n }\n\n close(): void {\n this.canvas = null\n this.ctx = null\n }\n}\n\n/**\n * The default (canvas edge-projection) document analyzer.\n *\n * @param tuning\n * @returns\n */\nexport function createDefaultDocumentAnalyzer(tuning: DocumentTuning = DEFAULT_DOCUMENT_TUNING): DocumentAnalyzer {\n return new CanvasDocumentAnalyzer(tuning)\n}\n","export const countries = [\n {\n name: 'United States',\n iso2: 'US',\n flag: '🇺🇸',\n },\n {\n name: 'Canada',\n iso2: 'CA',\n flag: '🇨🇦',\n },\n {\n name: 'Brazil',\n iso2: 'BR',\n flag: '🇧🇷',\n },\n {\n name: 'United Kingdom',\n iso2: 'GB',\n flag: '🇬🇧',\n },\n {\n name: 'Germany',\n iso2: 'DE',\n flag: '🇩🇪',\n },\n {\n name: 'France',\n iso2: 'FR',\n flag: '🇫🇷',\n },\n {\n name: 'China',\n iso2: 'CN',\n flag: '🇨🇳',\n },\n {\n name: 'Japan',\n iso2: 'JP',\n flag: '🇯🇵',\n },\n {\n name: 'India',\n iso2: 'IN',\n flag: '🇮🇳',\n },\n {\n name: 'Australia',\n iso2: 'AU',\n flag: '🇦🇺',\n },\n {\n name: 'South Africa',\n iso2: 'ZA',\n flag: '🇿🇦',\n },\n {\n name: 'Russia',\n iso2: 'RU',\n flag: '🇷🇺',\n },\n {\n name: 'Saudi Arabia',\n iso2: 'SA',\n flag: '🇸🇦',\n },\n {\n name: 'Afghanistan',\n iso2: 'AF',\n flag: '🇦🇫',\n },\n {\n name: 'Albania',\n iso2: 'AL',\n flag: '🇦🇱',\n },\n {\n name: 'Algeria',\n iso2: 'DZ',\n flag: '🇩🇿',\n },\n {\n name: 'Andorra',\n iso2: 'AD',\n flag: '🇦🇩',\n },\n {\n name: 'Angola',\n iso2: 'AO',\n flag: '🇦🇴',\n },\n {\n name: 'Antigua and Barbuda',\n iso2: 'AG',\n flag: '🇦🇬',\n },\n {\n name: 'Argentina',\n iso2: 'AR',\n flag: '🇦🇷',\n },\n {\n name: 'Armenia',\n iso2: 'AM',\n flag: '🇦🇲',\n },\n {\n name: 'Austria',\n iso2: 'AT',\n flag: '🇦🇹',\n },\n {\n name: 'Azerbaijan',\n iso2: 'AZ',\n flag: '🇦🇿',\n },\n {\n name: 'Bahamas',\n iso2: 'BS',\n flag: '🇧🇸',\n },\n {\n name: 'Bahrain',\n iso2: 'BH',\n flag: '🇧🇭',\n },\n {\n name: 'Bangladesh',\n iso2: 'BD',\n flag: '🇧🇩',\n },\n {\n name: 'Barbados',\n iso2: 'BB',\n flag: '🇧🇧',\n },\n {\n name: 'Belarus',\n iso2: 'BY',\n flag: '🇧🇾',\n },\n {\n name: 'Belgium',\n iso2: 'BE',\n flag: '🇧🇪',\n },\n {\n name: 'Belize',\n iso2: 'BZ',\n flag: '🇧🇿',\n },\n {\n name: 'Benin',\n iso2: 'BJ',\n flag: '🇧🇯',\n },\n {\n name: 'Bhutan',\n iso2: 'BT',\n flag: '🇧🇹',\n },\n {\n name: 'Bolivia',\n iso2: 'BO',\n flag: '🇧🇴',\n },\n {\n name: 'Bosnia and Herzegovina',\n iso2: 'BA',\n flag: '🇧🇦',\n },\n {\n name: 'Botswana',\n iso2: 'BW',\n flag: '🇧🇼',\n },\n {\n name: 'Brunei',\n iso2: 'BN',\n flag: '🇧🇳',\n },\n {\n name: 'Bulgaria',\n iso2: 'BG',\n flag: '🇧🇬',\n },\n {\n name: 'Burkina Faso',\n iso2: 'BF',\n flag: '🇧🇫',\n },\n {\n name: 'Burundi',\n iso2: 'BI',\n flag: '🇧🇮',\n },\n {\n name: 'Cabo Verde',\n iso2: 'CV',\n flag: '🇨🇻',\n },\n {\n name: 'Cambodia',\n iso2: 'KH',\n flag: '🇰🇭',\n },\n {\n name: 'Cameroon',\n iso2: 'CM',\n flag: '🇨🇲',\n },\n {\n name: 'Central African Republic',\n iso2: 'CF',\n flag: '🇨🇫',\n },\n {\n name: 'Chad',\n iso2: 'TD',\n flag: '🇹🇩',\n },\n {\n name: 'Chile',\n iso2: 'CL',\n flag: '🇨🇱',\n },\n {\n name: 'Colombia',\n iso2: 'CO',\n flag: '🇨🇴',\n },\n {\n name: 'Comoros',\n iso2: 'KM',\n flag: '🇰🇲',\n },\n {\n name: 'Congo (Congo-Brazzaville)',\n iso2: 'CG',\n flag: '🇨🇬',\n },\n {\n name: 'Congo (Congo-Kinshasa)',\n iso2: 'CD',\n flag: '🇨🇩',\n },\n {\n name: 'Costa Rica',\n iso2: 'CR',\n flag: '🇨🇷',\n },\n {\n name: 'Croatia',\n iso2: 'HR',\n flag: '🇭🇷',\n },\n {\n name: 'Cuba',\n iso2: 'CU',\n flag: '🇨🇺',\n },\n {\n name: 'Cyprus',\n iso2: 'CY',\n flag: '🇨🇾',\n },\n {\n name: 'Czech Republic',\n iso2: 'CZ',\n flag: '🇨🇿',\n },\n {\n name: 'Denmark',\n iso2: 'DK',\n flag: '🇩🇰',\n },\n {\n name: 'Djibouti',\n iso2: 'DJ',\n flag: '🇩🇯',\n },\n {\n name: 'Dominica',\n iso2: 'DM',\n flag: '🇩🇲',\n },\n {\n name: 'Dominican Republic',\n iso2: 'DO',\n flag: '🇩🇴',\n },\n {\n name: 'Ecuador',\n iso2: 'EC',\n flag: '🇪🇨',\n },\n {\n name: 'Egypt',\n iso2: 'EG',\n flag: '🇪🇬',\n },\n {\n name: 'El Salvador',\n iso2: 'SV',\n flag: '🇸🇻',\n },\n {\n name: 'Equatorial Guinea',\n iso2: 'GQ',\n flag: '🇬🇶',\n },\n {\n name: 'Eritrea',\n iso2: 'ER',\n flag: '🇪🇷',\n },\n {\n name: 'Estonia',\n iso2: 'EE',\n flag: '🇪🇪',\n },\n {\n name: 'Eswatini',\n iso2: 'SZ',\n flag: '🇸🇿',\n },\n {\n name: 'Ethiopia',\n iso2: 'ET',\n flag: '🇪🇹',\n },\n {\n name: 'Fiji',\n iso2: 'FJ',\n flag: '🇫🇯',\n },\n {\n name: 'Finland',\n iso2: 'FI',\n flag: '🇫🇮',\n },\n {\n name: 'Gabon',\n iso2: 'GA',\n flag: '🇬🇦',\n },\n {\n name: 'Gambia',\n iso2: 'GM',\n flag: '🇬🇲',\n },\n {\n name: 'Georgia',\n iso2: 'GE',\n flag: '🇬🇪',\n },\n {\n name: 'Ghana',\n iso2: 'GH',\n flag: '🇬🇭',\n },\n {\n name: 'Greece',\n iso2: 'GR',\n flag: '🇬🇷',\n },\n {\n name: 'Grenada',\n iso2: 'GD',\n flag: '🇬🇩',\n },\n {\n name: 'Guatemala',\n iso2: 'GT',\n flag: '🇬🇹',\n },\n {\n name: 'Guinea',\n iso2: 'GN',\n flag: '🇬🇳',\n },\n {\n name: 'Guinea-Bissau',\n iso2: 'GW',\n flag: '🇬🇼',\n },\n {\n name: 'Guyana',\n iso2: 'GY',\n flag: '🇬🇾',\n },\n {\n name: 'Haiti',\n iso2: 'HT',\n flag: '🇭🇹',\n },\n {\n name: 'Honduras',\n iso2: 'HN',\n flag: '🇭🇳',\n },\n {\n name: 'Hungary',\n iso2: 'HU',\n flag: '🇭🇺',\n },\n {\n name: 'Iceland',\n iso2: 'IS',\n flag: '🇮🇸',\n },\n {\n name: 'Indonesia',\n iso2: 'ID',\n flag: '🇮🇩',\n },\n {\n name: 'Iran',\n iso2: 'IR',\n flag: '🇮🇷',\n },\n {\n name: 'Iraq',\n iso2: 'IQ',\n flag: '🇮🇶',\n },\n {\n name: 'Ireland',\n iso2: 'IE',\n flag: '🇮🇪',\n },\n {\n name: 'Israel',\n iso2: 'IL',\n flag: '🇮🇱',\n },\n {\n name: 'Italy',\n iso2: 'IT',\n flag: '🇮🇹',\n },\n {\n name: 'Jamaica',\n iso2: 'JM',\n flag: '🇯🇲',\n },\n {\n name: 'Jordan',\n iso2: 'JO',\n flag: '🇯🇴',\n },\n {\n name: 'Kazakhstan',\n iso2: 'KZ',\n flag: '🇰🇿',\n },\n {\n name: 'Kenya',\n iso2: 'KE',\n flag: '🇰🇪',\n },\n {\n name: 'Kiribati',\n iso2: 'KI',\n flag: '🇰🇮',\n },\n {\n name: 'Kuwait',\n iso2: 'KW',\n flag: '🇰🇼',\n },\n {\n name: 'Kyrgyzstan',\n iso2: 'KG',\n flag: '🇰🇬',\n },\n {\n name: 'Laos',\n iso2: 'LA',\n flag: '🇱🇦',\n },\n {\n name: 'Latvia',\n iso2: 'LV',\n flag: '🇱🇻',\n },\n {\n name: 'Lebanon',\n iso2: 'LB',\n flag: '🇱🇧',\n },\n {\n name: 'Lesotho',\n iso2: 'LS',\n flag: '🇱🇸',\n },\n {\n name: 'Liberia',\n iso2: 'LR',\n flag: '🇱🇷',\n },\n {\n name: 'Libya',\n iso2: 'LY',\n flag: '🇱🇾',\n },\n {\n name: 'Liechtenstein',\n iso2: 'LI',\n flag: '🇱🇮',\n },\n {\n name: 'Lithuania',\n iso2: 'LT',\n flag: '🇱🇹',\n },\n {\n name: 'Luxembourg',\n iso2: 'LU',\n flag: '🇱🇺',\n },\n {\n name: 'Madagascar',\n iso2: 'MG',\n flag: '🇲🇬',\n },\n {\n name: 'Malawi',\n iso2: 'MW',\n flag: '🇲🇼',\n },\n {\n name: 'Malaysia',\n iso2: 'MY',\n flag: '🇲🇾',\n },\n {\n name: 'Maldives',\n iso2: 'MV',\n flag: '🇲🇻',\n },\n {\n name: 'Mali',\n iso2: 'ML',\n flag: '🇲🇱',\n },\n {\n name: 'Malta',\n iso2: 'MT',\n flag: '🇲🇹',\n },\n {\n name: 'Marshall Islands',\n iso2: 'MH',\n flag: '🇲🇭',\n },\n {\n name: 'Mauritania',\n iso2: 'MR',\n flag: '🇲🇷',\n },\n {\n name: 'Mauritius',\n iso2: 'MU',\n flag: '🇲🇺',\n },\n {\n name: 'Mexico',\n iso2: 'MX',\n flag: '🇲🇽',\n },\n {\n name: 'Micronesia',\n iso2: 'FM',\n flag: '🇫🇲',\n },\n {\n name: 'Moldova',\n iso2: 'MD',\n flag: '🇲🇩',\n },\n {\n name: 'Monaco',\n iso2: 'MC',\n flag: '🇲🇨',\n },\n {\n name: 'Mongolia',\n iso2: 'MN',\n flag: '🇲🇳',\n },\n {\n name: 'Montenegro',\n iso2: 'ME',\n flag: '🇲🇪',\n },\n {\n name: 'Morocco',\n iso2: 'MA',\n flag: '🇲🇦',\n },\n {\n name: 'Mozambique',\n iso2: 'MZ',\n flag: '🇲🇿',\n },\n {\n name: 'Myanmar',\n iso2: 'MM',\n flag: '🇲🇲',\n },\n {\n name: 'Namibia',\n iso2: 'NA',\n flag: '🇳🇦',\n },\n {\n name: 'Nauru',\n iso2: 'NR',\n flag: '🇳🇷',\n },\n {\n name: 'Nepal',\n iso2: 'NP',\n flag: '🇳🇵',\n },\n {\n name: 'Netherlands',\n iso2: 'NL',\n flag: '🇳🇱',\n },\n {\n name: 'New Zealand',\n iso2: 'NZ',\n flag: '🇳🇿',\n },\n {\n name: 'Nicaragua',\n iso2: 'NI',\n flag: '🇳🇮',\n },\n {\n name: 'Niger',\n iso2: 'NE',\n flag: '🇳🇪',\n },\n {\n name: 'Nigeria',\n iso2: 'NG',\n flag: '🇳🇬',\n },\n {\n name: 'North Korea',\n iso2: 'KP',\n flag: '🇰🇵',\n },\n {\n name: 'North Macedonia',\n iso2: 'MK',\n flag: '🇲🇰',\n },\n {\n name: 'Norway',\n iso2: 'NO',\n flag: '🇳🇴',\n },\n {\n name: 'Oman',\n iso2: 'OM',\n flag: '🇴🇲',\n },\n {\n name: 'Pakistan',\n iso2: 'PK',\n flag: '🇵🇰',\n },\n {\n name: 'Palau',\n iso2: 'PW',\n flag: '🇵🇼',\n },\n {\n name: 'Panama',\n iso2: 'PA',\n flag: '🇵🇦',\n },\n {\n name: 'Papua New Guinea',\n iso2: 'PG',\n flag: '🇵🇬',\n },\n {\n name: 'Paraguay',\n iso2: 'PY',\n flag: '🇵🇾',\n },\n {\n name: 'Peru',\n iso2: 'PE',\n flag: '🇵🇪',\n },\n {\n name: 'Philippines',\n iso2: 'PH',\n flag: '🇵🇭',\n },\n {\n name: 'Poland',\n iso2: 'PL',\n flag: '🇵🇱',\n },\n {\n name: 'Portugal',\n iso2: 'PT',\n flag: '🇵🇹',\n },\n {\n name: 'Qatar',\n iso2: 'QA',\n flag: '🇶🇦',\n },\n {\n name: 'Romania',\n iso2: 'RO',\n flag: '🇷🇴',\n },\n {\n name: 'Rwanda',\n iso2: 'RW',\n flag: '🇷🇼',\n },\n {\n name: 'Saint Kitts and Nevis',\n iso2: 'KN',\n flag: '🇰🇳',\n },\n {\n name: 'Saint Lucia',\n iso2: 'LC',\n flag: '🇱🇨',\n },\n {\n name: 'Saint Vincent and the Grenadines',\n iso2: 'VC',\n flag: '🇻🇨',\n },\n {\n name: 'Samoa',\n iso2: 'WS',\n flag: '🇼🇸',\n },\n {\n name: 'San Marino',\n iso2: 'SM',\n flag: '🇸🇲',\n },\n {\n name: 'Sao Tome and Principe',\n iso2: 'ST',\n flag: '🇸🇹',\n },\n {\n name: 'Senegal',\n iso2: 'SN',\n flag: '🇸🇳',\n },\n {\n name: 'Serbia',\n iso2: 'RS',\n flag: '🇷🇸',\n },\n {\n name: 'Seychelles',\n iso2: 'SC',\n flag: '🇸🇨',\n },\n {\n name: 'Sierra Leone',\n iso2: 'SL',\n flag: '🇸🇱',\n },\n {\n name: 'Singapore',\n iso2: 'SG',\n flag: '🇸🇬',\n },\n {\n name: 'Slovakia',\n iso2: 'SK',\n flag: '🇸🇰',\n },\n {\n name: 'Slovenia',\n iso2: 'SI',\n flag: '🇸🇮',\n },\n {\n name: 'Solomon Islands',\n iso2: 'SB',\n flag: '🇸🇧',\n },\n {\n name: 'Somalia',\n iso2: 'SO',\n flag: '🇸🇴',\n },\n {\n name: 'South Korea',\n iso2: 'KR',\n flag: '🇰🇷',\n },\n {\n name: 'South Sudan',\n iso2: 'SS',\n flag: '🇸🇸',\n },\n {\n name: 'Spain',\n iso2: 'ES',\n flag: '🇪🇸',\n },\n {\n name: 'Sri Lanka',\n iso2: 'LK',\n flag: '🇱🇰',\n },\n {\n name: 'Sudan',\n iso2: 'SD',\n flag: '🇸🇩',\n },\n {\n name: 'Suriname',\n iso2: 'SR',\n flag: '🇸🇷',\n },\n {\n name: 'Sweden',\n iso2: 'SE',\n flag: '🇸🇪',\n },\n {\n name: 'Switzerland',\n iso2: 'CH',\n flag: '🇨🇭',\n },\n {\n name: 'Syria',\n iso2: 'SY',\n flag: '🇸🇾',\n },\n {\n name: 'Tajikistan',\n iso2: 'TJ',\n flag: '🇹🇯',\n },\n {\n name: 'Tanzania',\n iso2: 'TZ',\n flag: '🇹🇿',\n },\n {\n name: 'Thailand',\n iso2: 'TH',\n flag: '🇹🇭',\n },\n {\n name: 'Togo',\n iso2: 'TG',\n flag: '🇹🇬',\n },\n {\n name: 'Tonga',\n iso2: 'TO',\n flag: '🇹🇴',\n },\n {\n name: 'Trinidad and Tobago',\n iso2: 'TT',\n flag: '🇹🇹',\n },\n {\n name: 'Tunisia',\n iso2: 'TN',\n flag: '🇹🇳',\n },\n {\n name: 'Turkey',\n iso2: 'TR',\n flag: '🇹🇷',\n },\n {\n name: 'Turkmenistan',\n iso2: 'TM',\n flag: '🇹🇲',\n },\n {\n name: 'Tuvalu',\n iso2: 'TV',\n flag: '🇹🇻',\n },\n {\n name: 'Uganda',\n iso2: 'UG',\n flag: '🇺🇬',\n },\n {\n name: 'Ukraine',\n iso2: 'UA',\n flag: '🇺🇦',\n },\n {\n name: 'United Arab Emirates',\n iso2: 'AE',\n flag: '🇦🇪',\n },\n {\n name: 'Uruguay',\n iso2: 'UY',\n flag: '🇺🇾',\n },\n {\n name: 'Uzbekistan',\n iso2: 'UZ',\n flag: '🇺🇿',\n },\n {\n name: 'Vanuatu',\n iso2: 'VU',\n flag: '🇻🇺',\n },\n {\n name: 'Venezuela',\n iso2: 'VE',\n flag: '🇻🇪',\n },\n {\n name: 'Vietnam',\n iso2: 'VN',\n flag: '🇻🇳',\n },\n {\n name: 'Yemen',\n iso2: 'YE',\n flag: '🇾🇪',\n },\n {\n name: 'Zambia',\n iso2: 'ZM',\n flag: '🇿🇲',\n },\n {\n name: 'Zimbabwe',\n iso2: 'ZW',\n flag: '🇿🇼',\n },\n {\n name: 'Timor-Leste',\n iso2: 'TL',\n flag: '🇹🇱',\n },\n] as const\n","/**\n * Tiny dependency-free DOM hyperscript — the widget's deliberate alternative to\n * a virtual-DOM library (the widget is a lightweight, framework-agnostic embed,\n * so it ships no UI framework).\n *\n * `h(tag, props, children)` builds an element in one expression; `append` adds\n * children to an existing node. Both are bound to a `Document` so they work\n * against the real DOM in the browser and against an injected fake in tests.\n *\n * ```ts\n * const { h } = createDom(document)\n * const card = h('div', { class: 'card', on: { click: onClick } }, [\n * h('h2', { text: 'Title' }),\n * subtitle && h('p', { text: subtitle }), // falsy children are skipped\n * ])\n * ```\n */\n\n/** A child accepted by {@link Dom.h}: a node, text, or a falsy value to skip. */\nexport type ElChild = Node | string | false | null | undefined\n\n/** Props for {@link Dom.h}: class/text/html, known DOM properties, attributes, and `on` listeners. */\nexport interface ElProps {\n class?: string\n text?: string\n html?: string\n type?: string\n src?: string\n accept?: string\n placeholder?: string\n value?: string\n /** Event listeners keyed by event name, e.g. `{ click: () => … }`. */\n on?: Record<string, EventListener>\n [attr: string]: string | Record<string, EventListener> | undefined\n}\n\n/** A `<select>` choice: a bare value, or a value with a distinct display label. */\nexport type FieldChoice = string | { value: string; label?: string }\n\n/** Options for {@link Dom.field}. With `choices`, a `<select>` is built; otherwise a text `<input>`. */\nexport interface FieldOptions {\n /** CSS class (defaults to `arkyc-addr-input`). */\n class?: string\n name?: string\n /** Input type (text inputs only; ignored for selects). */\n type?: string\n autocomplete?: string\n value?: string\n /** When present, render a `<select>` with `placeholder` as the leading empty option, then these. */\n choices?: FieldChoice[]\n}\n\n/** The hyperscript helpers bound to a {@link Document}. */\nexport interface Dom {\n h<T extends HTMLElement = HTMLElement>(tag: string, props?: ElProps, children?: ElChild | ElChild[]): T\n append(parent: HTMLElement, children?: ElChild | ElChild[]): void\n /**\n * Build a form control: a text `<input>`, or a `<select>` when `opts.choices`\n * is given (with `placeholder` as the leading empty option). Returns the\n * element — the caller appends it.\n *\n * @param placeholder\n * @param opts\n */\n field(placeholder: string, opts?: FieldOptions): HTMLInputElement | HTMLSelectElement\n}\n\n/**\n * Bind the hyperscript helpers to a specific `Document`. Pass the real\n * `document` in the browser, or an injected fake in tests.\n *\n * @param doc\n * @returns\n */\nexport function createDom(doc: Document): Dom {\n function append(parent: HTMLElement, children?: ElChild | ElChild[]): void {\n for (const child of Array.isArray(children) ? children : [children]) {\n if (child == null || child === false) continue\n parent.appendChild(typeof child === 'string' ? doc.createTextNode(child) : child)\n }\n }\n\n function h<T extends HTMLElement = HTMLElement>(tag: string, props: ElProps = {}, children?: ElChild | ElChild[]): T {\n const node = doc.createElement(tag) as T\n for (const [key, value] of Object.entries(props)) {\n if (value == null) continue\n if (key === 'on') {\n for (const [event, handler] of Object.entries(value as Record<string, EventListener>)) {\n node.addEventListener(event, handler)\n }\n } else if (key === 'class') node.className = value as string\n else if (key === 'text') node.textContent = value as string\n else if (key === 'html') node.innerHTML = value as string\n else if (key === 'value' || key === 'src' || key === 'type' || key === 'accept' || key === 'placeholder') {\n ;(node as unknown as Record<string, string>)[key] = value as string\n } else node.setAttribute(key, value as string)\n }\n append(node, children)\n return node\n }\n\n function field(placeholder: string, opts: FieldOptions = {}): HTMLInputElement | HTMLSelectElement {\n const cls = opts.class ?? 'arkyc-addr-input'\n if (opts.choices) {\n return h<HTMLSelectElement>(\n 'select',\n { class: cls, name: opts.name, autocomplete: opts.autocomplete, 'aria-label': opts.name ?? placeholder },\n [\n h('option', { value: '', text: placeholder }),\n ...opts.choices.map((choice) => {\n const value = typeof choice === 'string' ? choice : choice.value\n const label = typeof choice === 'string' ? choice : (choice.label ?? choice.value)\n return h('option', { value, text: label })\n }),\n ],\n )\n }\n return h<HTMLInputElement>('input', {\n class: cls,\n type: opts.type ?? 'text',\n placeholder,\n name: opts.name,\n autocomplete: opts.autocomplete,\n value: opts.value,\n })\n }\n\n return { h, append, field }\n}\n\n/**\n * Browser-default helpers, bound lazily to `globalThis.document` for\n * non-test call sites.\n */\nlet browser: Dom | undefined\nconst lazy = (): Dom => (browser ??= createDom(globalThis.document))\n\n/**\n * {@link Dom.h} bound to the browser `document`.\n * Import this from any browser-only module.\n *\n * @param tag\n * @param props\n * @param children\n * @returns\n */\nexport const h = <T extends HTMLElement = HTMLElement>(\n tag: string,\n props?: ElProps,\n children?: ElChild | ElChild[],\n): T => lazy().h<T>(tag, props, children)\n\n/**\n * {@link Dom.append} bound to the browser `document`.\n *\n * @param parent\n * @param children\n * @returns\n */\nexport const append = (parent: HTMLElement, children?: ElChild | ElChild[]): void => lazy().append(parent, children)\n\n/**\n * {@link Dom.field} bound to the browser `document`.\n *\n * @param placeholder\n * @param opts\n * @returns\n */\nexport const field = (placeholder: string, opts?: FieldOptions): HTMLInputElement | HTMLSelectElement =>\n lazy().field(placeholder, opts)\n","import type {\n AddressMethod,\n DocumentType,\n LivenessChallenge,\n ProjectBranding,\n VerificationDecision,\n VerificationStatus,\n WidgetStep,\n} from '@arkyc/types'\n\n/** The data the address-entry screen collects before submission. */\nexport interface AddressFormData {\n line1: string | null\n line2: string | null\n city: string | null\n region: string | null\n postalCode: string | null\n country: string | null\n /** Proof-of-address image, when the `poa_document` method is configured. */\n poa: Blob | null\n /** Whether the user opted to share device location (`device_location` method). */\n useLocation: boolean\n}\n\nimport { Camera } from './capture'\nimport type { Facing } from './capture'\nimport {\n createDefaultDocumentAnalyzer,\n DEFAULT_DOCUMENT_TUNING,\n documentGuidance,\n type DocRect,\n type DocumentAnalyzer,\n type DocumentTuning,\n} from './document'\nimport {\n createDefaultFaceAnalyzer,\n DEFAULT_TUNING,\n isSelfieReady,\n makeChallengeDetector,\n type FaceAnalyzer,\n type FaceTuning,\n} from './face'\nimport { Theme } from './theme'\nimport { countries } from './countries'\nimport { createDom, type Dom } from './h'\nimport type { ViewHandlers } from './types'\n\n/** Per-render data the view needs for the current step. */\nexport interface ViewState {\n step: WidgetStep\n documentType: DocumentType | null\n decision?: VerificationDecision | null\n /** The session status (drives the close-only terminal notice). */\n status?: VerificationStatus\n /** Render the result as a close-only notice (session was already terminal on load). */\n terminalNotice?: boolean\n statusLabel?: string\n errorMessage?: string\n /** Show a \"Skip\" affordance on capture screens (demo / mock-driver flows). */\n allowSkip?: boolean\n /** The challenge sequence to prompt for the active-liveness screen. */\n livenessChallenges?: LivenessChallenge[]\n /** The address methods to collect for, on the address-entry screen. */\n addressMethods?: AddressMethod[]\n /**\n * Capture model demands a live camera (`capture_model === 'active'`). When set,\n * the active-liveness screen must NOT offer a manual/file fallback on\n * unsupported devices — it shows an \"unsupported device\" message instead.\n */\n requireLiveCamera?: boolean\n /**\n * The session runs the active flow (resolved liveness is `active`). Document\n * capture is then strict: detection-gated auto-capture only — no manual capture\n * button, no permissive brightness/upload fallback that could bypass detection.\n */\n strictCapture?: boolean\n /** Offer a \"Continue on your phone\" affordance on the welcome screen (handoff). */\n handoffAvailable?: boolean\n}\n\nconst DOCUMENT_LABELS: Record<DocumentType, string> = {\n passport: 'Passport',\n id_card: 'ID Card',\n drivers_license: \"Driver's License\",\n residence_permit: 'Residence Permit',\n}\n\nconst CHALLENGE_LABELS: Record<LivenessChallenge, string> = {\n turn_left: 'Slowly turn your head to the left, and hold',\n turn_right: 'Slowly turn your head to the right, and hold',\n blink: 'Blink slowly',\n smile: 'Smile, and hold it',\n nod: 'Slowly nod your head',\n move_closer: 'Slowly move closer to the camera',\n}\n\ninterface Notice {\n cls: string\n icon: string\n title: string\n copy: string\n}\n\n/** Fallback notice for an expired/unknown terminal session. */\nconst EXPIRED_NOTICE: Notice = {\n cls: 'warn',\n icon: '⏳',\n title: 'Link expired',\n copy: 'This verification link has expired.',\n}\n\n/** Close-only notice copy for a session that was already terminal on load. */\nconst TERMINAL_NOTICE: Partial<Record<VerificationStatus, Notice>> = {\n approved: { cls: 'ok', icon: '✓', title: 'Already complete', copy: 'This verification has already been completed.' },\n rejected: { cls: 'ok', icon: '✓', title: 'Already complete', copy: 'This verification has already been completed.' },\n requires_review: {\n cls: 'ok',\n icon: '✓',\n title: 'Already complete',\n copy: 'This verification has already been submitted and is being reviewed.',\n },\n expired: EXPIRED_NOTICE,\n cancelled: { cls: 'warn', icon: '⏳', title: 'Cancelled', copy: 'This verification was cancelled.' },\n}\n\nconst SVG = (body: string) =>\n `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${body}</svg>`\n\n/** Per-challenge directional cue icons, animated via CSS over the preview. */\nconst CUE_ICONS: Record<LivenessChallenge, string> = {\n turn_right: SVG('<path d=\"M5 12h14M13 6l6 6-6 6\"/>'),\n turn_left: SVG('<path d=\"M19 12H5M11 6l-6 6 6 6\"/>'),\n nod: SVG('<path d=\"M12 5v14M6 13l6 6 6-6\"/>'),\n move_closer: SVG('<circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M12 2v3M12 19v3M2 12h3M19 12h3\"/>'),\n blink: SVG('<path d=\"M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/>'),\n smile: SVG('<path d=\"M8 14s1.5 2 4 2 4-2 4-2\"/><path d=\"M9 9h.01M15 9h.01\"/>'),\n}\n\nconst CHECK_ICON = SVG('<path d=\"M20 6 9 17l-5-5\"/>')\n\n/** Larger line-art illustration used to dress the informative / lead-in screens. */\nconst ART = (body: string) =>\n `<svg viewBox=\"0 0 64 64\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${body}</svg>`\n\n/** Per-screen decorative illustrations, keyed by step (plus a welcome hero). */\nconst STEP_ART: Partial<Record<WidgetStep | 'welcome', string>> = {\n // Shield with a check — trust / \"verify your identity\".\n welcome: ART(\n '<path d=\"M32 7 52 14v14c0 12.5-8.2 21.6-20 25.6C20.2 49.6 12 40.5 12 28V14z\"/><path d=\"M23 30.5l6.2 6.2L41 24.5\"/>',\n ),\n // ID card with a portrait + text lines.\n front_capture: ART(\n '<rect x=\"7\" y=\"15\" width=\"50\" height=\"34\" rx=\"5\"/><circle cx=\"22\" cy=\"28\" r=\"5\"/><path d=\"M14 42c1-5 5-7 8-7s7 2 8 7\"/><path d=\"M38 27h12M38 34h12M38 41h8\"/>',\n ),\n // ID card flipped: magnetic stripe + MRZ lines.\n back_capture: ART(\n '<rect x=\"7\" y=\"15\" width=\"50\" height=\"34\" rx=\"5\"/><rect x=\"7\" y=\"20\" width=\"50\" height=\"6\" fill=\"currentColor\" stroke=\"none\" opacity=\".18\"/><path d=\"M14 34h36M14 41h24\"/>',\n ),\n // A person centred in a camera viewfinder (corner brackets).\n selfie_capture: ART(\n '<path d=\"M10 20v-6a4 4 0 0 1 4-4h6\"/><path d=\"M44 10h6a4 4 0 0 1 4 4v6\"/><path d=\"M54 44v6a4 4 0 0 1-4 4h-6\"/><path d=\"M20 54h-6a4 4 0 0 1-4-4v-6\"/><circle cx=\"32\" cy=\"27\" r=\"8\"/><path d=\"M19 50c0-7 6-11 13-11s13 4 13 11\"/>',\n ),\n // A smiling face with turn-your-head arrows on each side.\n active_liveness: ART(\n '<circle cx=\"32\" cy=\"30\" r=\"13\"/><circle cx=\"27\" cy=\"27\" r=\"1.2\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"37\" cy=\"27\" r=\"1.2\" fill=\"currentColor\" stroke=\"none\"/><path d=\"M26 34c2 2.5 10 2.5 12 0\"/><path d=\"M13 30H6M10 26l-4 4 4 4\"/><path d=\"M51 30h7M54 26l4 4-4 4\"/>',\n ),\n}\n\n/** Handles for driving the circular preview overlay (ring + cue + success check). */\ninterface FaceStage {\n stage: HTMLElement\n /** 0–1 fill of the progress ring. */\n setProgress(p: number): void\n /** Visual state: searching, holding (green), or completed (check). */\n setState(state: 'wait' | 'good' | 'done'): void\n /** Show a challenge cue icon (or clear it with `null`). */\n setCue(challenge: LivenessChallenge | null): void\n}\n\n/** Handles for driving the document preview overlay (bracket frame + scan line). */\ninterface DocStage {\n stage: HTMLElement\n /** Tint the frame for the current capture quality. */\n setQuality(quality: 'wait' | 'good' | 'bad'): void\n /** Flag whether a document is currently detected (brightens the fixed guide). */\n setFrame(rect: DocRect | null): void\n}\n\n/** Handles for driving the liveness step-progress dots. */\ninterface StepDots {\n el: HTMLElement\n /** Mark the given step index as the active one. */\n setActive(index: number): void\n /** Mark the given step index as completed. */\n markDone(index: number): void\n}\n\n/**\n * Renders the widget's screens into a host element. DOM- and camera-injectable\n * so it can run under a fake DOM in tests. The view owns capture-screen camera\n * mechanics and raises only high-level events to the controller.\n */\nexport class WidgetView {\n private readonly root: HTMLElement\n private readonly body: HTMLElement\n private readonly footer: HTMLElement\n /** The `<style>` carrying the theme's CSS vars; swapped on runtime re-brand. */\n private readonly styleEl: HTMLElement\n /** The header brand group (logo/name/title); rebuilt on runtime re-brand. */\n private readonly brandEl: HTMLElement\n private readonly camera: Camera\n private readonly analyzer: FaceAnalyzer | null\n private readonly tuning: FaceTuning\n private readonly docAnalyzer: DocumentAnalyzer | null\n private readonly docTuning: DocumentTuning\n /** Interval ids for live quality/recording timers, cleared on re-render. */\n private timers: ReturnType<typeof setInterval>[] = []\n /** Extra teardown run on each re-render (cancels in-flight detection loops). */\n private cleanups: (() => void)[] = []\n /** DOM hyperscript helpers (`h`/`append`/`field`) bound to this view's document (see {@link createDom}). */\n private readonly dom: Dom\n\n constructor(\n private readonly doc: Document,\n private theme: Theme,\n private readonly handlers: ViewHandlers,\n nav: Navigator = globalThis.navigator,\n analyzer: FaceAnalyzer | null = createDefaultFaceAnalyzer(),\n tuning: FaceTuning = DEFAULT_TUNING,\n docAnalyzer: DocumentAnalyzer | null = createDefaultDocumentAnalyzer(),\n docTuning: DocumentTuning = DEFAULT_DOCUMENT_TUNING,\n ) {\n this.dom = createDom(doc)\n this.camera = new Camera(doc, nav)\n this.analyzer = analyzer\n this.tuning = tuning\n this.docAnalyzer = docAnalyzer\n this.docTuning = docTuning\n this.root = this.dom.h('div', { class: 'arkyc-root' })\n\n this.styleEl = this.dom.h('style', { text: theme.stylesheet() })\n this.root.appendChild(this.styleEl)\n\n this.brandEl = this.dom.h('div', { class: 'arkyc-brand' })\n this.fillBrand()\n this.body = this.dom.h('div', { class: 'arkyc-body' })\n this.footer = this.dom.h('div', { class: 'arkyc-footer' })\n\n const header = this.dom.h('div', { class: 'arkyc-header' }, [\n this.brandEl,\n this.dom.h('button', {\n class: 'arkyc-close',\n html: '&times;',\n 'aria-label': 'Close',\n on: { click: () => this.handlers.onClose() },\n }),\n ])\n\n this.root.appendChild(this.dom.h('div', { class: 'arkyc-card' }, [header, this.body, this.footer]))\n }\n\n /**\n * Populate the header brand group from the current theme: the project logo\n * and/or name when branding is shown, otherwise a neutral title.\n */\n private fillBrand(): void {\n this.clear(this.brandEl)\n const lastTenMins = Date.now() - Math.floor(Math.random() * (10 * 60 * 1000))\n const branded = this.theme.showBranding && (this.theme.logoUrl || this.theme.name)\n\n this.dom.append(\n this.brandEl,\n branded\n ? [\n this.theme.logoUrl &&\n this.dom.h('img', { class: 'arkyc-logo', src: `${this.theme.logoUrl}?stamp=${lastTenMins}` }),\n this.theme.name && this.dom.h('span', { class: 'arkyc-brand-name', text: this.theme.name }),\n ]\n : this.dom.h('p', { class: 'arkyc-title', text: 'Verify your identity' }),\n )\n }\n\n /**\n * Re-theme the widget at runtime from project branding (resolved server-side):\n * swap the CSS-variable stylesheet (colours/radius) and rebuild the header\n * brand (logo/name). Cascades to every already-rendered element via the vars.\n */\n applyBranding(branding: ProjectBranding | null): void {\n this.theme = new Theme(branding)\n this.styleEl.textContent = this.theme.stylesheet()\n this.fillBrand()\n }\n\n /**\n * The widget's root element — append this to the overlay / container.\n */\n get element(): HTMLElement {\n return this.root\n }\n\n /**\n * Whether live camera capture is available (drives the active-liveness branch).\n */\n get cameraSupported(): boolean {\n return this.camera.supported\n }\n\n /**\n * Release any active camera stream and clear live timers.\n */\n destroy(): void {\n this.timers.forEach((id) => clearInterval(id))\n this.timers = []\n this.cleanups.forEach((fn) => fn())\n this.cleanups = []\n this.camera.stop()\n }\n\n /**\n * Render the screen for the given state.\n *\n * @param state\n * @returns\n */\n render(state: ViewState): void {\n this.destroy()\n this.clear(this.body)\n this.clear(this.footer)\n this.root.classList.remove('arkyc-handoff')\n\n switch (state.step) {\n case 'welcome':\n return this.renderWelcome(state.handoffAvailable)\n case 'document_selection':\n return this.renderDocumentSelection()\n case 'front_capture':\n return this.renderCapture('Front of document', 'environment', state.allowSkip, false, state.strictCapture)\n case 'back_capture':\n return this.renderCapture('Back of document', 'environment', state.allowSkip, false, state.strictCapture)\n case 'selfie_capture':\n return this.renderCapture('Take a selfie', 'user', state.allowSkip, true, state.strictCapture)\n case 'active_liveness':\n return this.renderActiveLiveness(state.livenessChallenges ?? [], state.allowSkip, state.requireLiveCamera)\n case 'ocr_processing':\n return this.renderProcessing('Reading your document…')\n case 'address_entry':\n return this.renderAddressForm(state.addressMethods ?? [])\n case 'address_processing':\n return this.renderProcessing('Verifying your address…')\n case 'passive_liveness':\n return this.renderProcessing('Checking liveness…')\n case 'face_match':\n return this.renderProcessing('Matching your face…')\n case 'processing':\n return this.renderProcessing(state.statusLabel ?? 'Finalising verification…')\n case 'result':\n return this.renderResult(state.decision ?? null, state.errorMessage, {\n terminal: state.terminalNotice,\n status: state.status,\n })\n }\n }\n\n /** Prepend a decorative illustration for the given screen, when one exists. */\n private appendArt(key: WidgetStep | 'welcome'): void {\n const art = STEP_ART[key]\n if (art) this.body.appendChild(this.dom.h('div', { class: 'arkyc-illus', html: art }))\n }\n\n private renderWelcome(handoffAvailable?: boolean): void {\n this.appendArt('welcome')\n this.dom.append(this.body, [\n this.dom.h('h2', { class: 'arkyc-h', text: 'Verify your identity' }),\n this.dom.h('p', {\n class: 'arkyc-p',\n text: 'You will need a government-issued ID and a moment to take a selfie. Your data is processed securely.',\n }),\n ])\n this.dom.append(this.footer, [\n this.button('Get started', () => this.handlers.onStart()),\n handoffAvailable && this.button('Continue on your phone', () => this.handlers.onUsePhone(), 'arkyc-btn-ghost'),\n ])\n }\n\n /** A neutral connecting screen shown while the widget bootstraps the session. */\n renderLoading(label = 'Loading…'): void {\n this.destroy()\n this.clear(this.body)\n this.clear(this.footer)\n this.root.classList.remove('arkyc-handoff')\n this.renderProcessing(label)\n }\n\n /**\n * An interstitial that tells the user what the next step is, with a single\n * Continue button — so each step starts deliberately rather than the camera\n * springing to life unannounced.\n */\n renderInstruction(step: WidgetStep, title: string, body: string, cta: string, onContinue: () => void): void {\n this.destroy()\n this.clear(this.body)\n this.clear(this.footer)\n this.root.classList.remove('arkyc-handoff')\n this.appendArt(step)\n this.dom.append(this.body, [\n this.dom.h('h2', { class: 'arkyc-h', text: title }),\n this.dom.h('p', { class: 'arkyc-p', text: body }),\n ])\n this.footer.appendChild(this.button(cta, onContinue))\n }\n\n /**\n * Show the cross-device handoff QR: the user scans it to resume this same\n * session on their phone. The widget then waits for the other device to finish.\n * `allowContinueHere` offers an escape hatch to keep verifying on this device.\n */\n renderHandoff(qrSvg: string, allowContinueHere: boolean): void {\n this.destroy()\n this.clear(this.body)\n this.clear(this.footer)\n // Keep the QR prominent (edge-to-edge in fullscreen) rather than a small dialog.\n this.root.classList.add('arkyc-handoff')\n this.dom.append(this.body, [\n this.dom.h('h2', { class: 'arkyc-h', text: 'Continue on your phone' }),\n this.dom.h('p', { class: 'arkyc-p', text: 'Scan this code with your phone camera to finish verifying there.' }),\n this.dom.h('div', { class: 'arkyc-qr', html: qrSvg }),\n this.dom.h('div', { class: 'arkyc-handoff-wait' }, [\n this.dom.h('div', { class: 'arkyc-spinner sm' }),\n this.dom.h('span', { text: 'Waiting for your phone…' }),\n ]),\n ])\n if (allowContinueHere) {\n this.footer.appendChild(\n this.button('Continue on this device', () => this.handlers.onContinueHere(), 'arkyc-btn-ghost'),\n )\n }\n }\n\n private renderDocumentSelection(): void {\n this.body.appendChild(this.dom.h('h2', { class: 'arkyc-h', text: 'Select your document' }))\n const country = this.dom.field('Country', {\n class: 'arkyc-btn arkyc-btn-ghost arkyc-text-center',\n name: 'country',\n autocomplete: 'country',\n choices: countries.map(({ name, iso2, flag }) => ({ value: iso2, label: `${flag} ${name}` })),\n })\n\n const buttons = (Object.keys(DOCUMENT_LABELS) as DocumentType[]).map((type) => {\n const btn = this.button(DOCUMENT_LABELS[type], () =>\n this.handlers.onDocumentSelected(type, (country.value || '').trim().toUpperCase()),\n )\n btn.classList.add('arkyc-btn-ghost')\n return btn\n })\n\n this.body.appendChild(this.dom.h('div', { class: 'arkyc-choices' }, [country, ...buttons]))\n }\n\n private renderCapture(title: string, facing: Facing, allowSkip?: boolean, selfie = false, strict = false): void {\n // Documents in the active flow are strict: detection-gated only (no manual\n // bypass). Selfies are always pure auto, so strictness only changes documents.\n const strictDoc = strict && !selfie\n const fileInput = this.dom.h<HTMLInputElement>('input', {\n type: 'file',\n accept: 'image/*',\n class: 'arkyc-hidden',\n on: { change: () => this.handlers.onImage(Camera.fileFromInput(fileInput)) },\n })\n this.dom.append(this.body, [\n this.dom.h('h2', { class: 'arkyc-h', text: title }),\n this.dom.h('p', { class: 'arkyc-p', text: 'Position it clearly in frame, then capture.' }),\n fileInput,\n ])\n\n if (this.camera.supported) {\n const video = this.dom.h('video', {\n class: `arkyc-preview${selfie ? ' selfie' : ''}`,\n }) as HTMLVideoElement\n\n // Wrap the preview in its animated overlay (circular ring for selfies,\n // bracket frame for documents).\n const face = selfie ? this.buildFaceStage(video) : null\n const doc = selfie ? null : this.buildDocStage(video)\n const mount = face?.stage ?? doc!.stage\n this.body.appendChild(mount)\n\n // Live guidance hint (quality for documents, framing for selfies).\n const hint = this.dom.h('p', { class: 'arkyc-p arkyc-hint' }) as HTMLParagraphElement\n this.body.appendChild(hint)\n\n // After a capture, wait for an explicit \"Continue\" so the user can review\n // and get ready for the next step — never auto-advance. Swap the live\n // preview for a still of the captured frame: this shows exactly what was\n // captured and removes the overlay (brackets / scan line / ring) entirely,\n // rather than leaving a stopped (black) video with animations still running.\n const confirmCapture = (blob: Blob | null) => {\n this.destroy() // stop the camera + detection timers\n if (blob) {\n const url = URL.createObjectURL(blob)\n const still = this.dom.h('img', {\n class: `arkyc-preview${selfie ? ' selfie' : ''}`,\n src: url,\n }) as HTMLImageElement\n mount.replaceWith(still)\n this.cleanups.push(() => URL.revokeObjectURL(url))\n } else {\n mount.classList.add('arkyc-hidden')\n }\n this.clear(this.footer)\n hint.textContent = '✓ Captured'\n this.footer.appendChild(this.button('Continue', () => this.handlers.onImage(blob)))\n const retake = this.button('Retake', () => {\n this.destroy()\n this.clear(this.body)\n this.clear(this.footer)\n this.renderCapture(title, facing, allowSkip, selfie, strict)\n })\n retake.classList.add('arkyc-btn-ghost')\n this.footer.appendChild(retake)\n }\n\n const onCapture = () => void this.camera.grabFrame(video).then(confirmCapture)\n\n void this.camera.start(video, facing).catch(() => {\n mount.classList.add('arkyc-hidden')\n if (strictDoc) {\n // Strict document capture: no file fallback — a live camera is required.\n hint.textContent = 'Camera access is required to scan your document. Please allow access and try again.'\n return\n }\n // Camera denied/unavailable — fall back to the file input.\n fileInput.click()\n })\n\n if (selfie) {\n // Pure auto-capture: face detection grabs the frame when the user is\n // framed. The manual button only appears if the detector can't load.\n this.runSelfieAutoCapture(video, hint, onCapture, face!)\n } else {\n this.runDocumentAutoCapture(video, hint, doc!, strictDoc, onCapture)\n // Passive model only: a manual capture button as a reliable override.\n // The active flow is detection-gated — no manual bypass.\n if (!strictDoc) this.footer.appendChild(this.button('Capture', onCapture))\n }\n } else if (strictDoc) {\n // Strict document capture with no camera — surface as unsupported.\n this.dom.append(this.body, [\n this.dom.h('div', { class: 'arkyc-badge err', html: '!' }),\n this.dom.h('p', {\n class: 'arkyc-p',\n text: 'This step needs a working camera to scan your document. Please retry on a device with a camera.',\n }),\n ])\n } else {\n const upload = this.button('Upload photo', () => fileInput.click())\n this.footer.appendChild(upload)\n }\n\n if (allowSkip) {\n const skip = this.button('Skip (demo)', () => this.handlers.onImage(null))\n skip.classList.add('arkyc-btn-ghost')\n this.footer.appendChild(skip)\n }\n }\n\n /**\n * Run `cb` once the live camera feed appears (the video has frames). The\n * detection model may still be downloading at that point, so callers use this\n * to replace the \"starting camera\" hint with a neutral one.\n *\n * @param video\n * @param cb\n */\n private onCameraLive(video: HTMLVideoElement, cb: () => void): void {\n if ((video.readyState ?? 0) >= 2) {\n cb()\n return\n }\n video.addEventListener('playing', cb, { once: true })\n }\n\n /**\n * Document capture: detect a real, well-framed, in-focus document (edge\n * projection) and auto-grab only once it's been held steady. Falls back to the\n * brightness/glare heuristic when the detector can't run.\n *\n * @param video\n * @returns\n */\n private runDocumentAutoCapture(\n video: HTMLVideoElement,\n hint: HTMLElement,\n doc: DocStage,\n strict: boolean,\n capture: () => void,\n ): void {\n // In strict mode the permissive brightness heuristic is disabled — it can't\n // tell a document from a well-lit blank frame, which would defeat detection.\n const onNoDetector = () => {\n if (strict) {\n hint.textContent = 'Document scanning isn’t available on this device.'\n return\n }\n this.runDocumentBrightnessCapture(video, hint, doc, capture)\n }\n\n const analyzer = this.docAnalyzer\n if (!analyzer) return onNoDetector()\n\n hint.textContent = 'Starting camera…'\n let cancelled = false\n let modelReady = false\n this.cleanups.push(() => {\n cancelled = true\n })\n // The camera feed appears before the document scanner model finishes loading;\n // once the video is live, stop implying the camera is still starting.\n this.onCameraLive(video, () => {\n if (!cancelled && !modelReady) hint.textContent = 'Getting ready…'\n })\n void analyzer.ready().then((ok) => {\n modelReady = true\n if (cancelled) return\n if (!ok) {\n onNoDetector()\n return\n }\n let goodStreak = 0\n // Smooth the noisiest geometry signals (fill/edge strength) across frames so a\n // single jittery edge-projection read doesn't flip the hint to \"move closer\"\n // and reset the streak. Exponential moving average; null until the first frame.\n let fillEma: number | null = null\n let edgeEma: number | null = null\n const ema = (prev: number | null, next: number) => (prev == null ? next : prev * 0.6 + next * 0.4)\n const timer = setInterval(() => {\n const sample = analyzer.analyze(video)\n if (!sample) return\n fillEma = ema(fillEma, sample.fill)\n edgeEma = ema(edgeEma, sample.edgeStrength)\n const smoothed = { ...sample, fill: fillEma, edgeStrength: edgeEma }\n const { ready, hint: message } = documentGuidance(smoothed, this.docTuning)\n hint.textContent = message\n doc.setFrame(sample.present ? sample.rect : null)\n doc.setQuality(ready ? 'good' : sample.present ? 'wait' : 'bad')\n // Soft reset: a single off frame nudges the streak down rather than zeroing\n // it, so transient detector noise doesn't perpetually restart the hold.\n goodStreak = ready ? goodStreak + 1 : Math.max(0, goodStreak - 1)\n // Auto-capture once a framed, focused document has held for ~1.25s.\n if (goodStreak >= this.docTuning.hold) {\n clearInterval(timer)\n doc.setQuality('good')\n capture()\n }\n }, 250)\n this.timers.push(timer)\n })\n }\n\n /**\n * Coarse fallback: brightness/glare heuristic, used when detection can't run.\n *\n * @param video\n * @param hint\n * @param doc\n */\n private runDocumentBrightnessCapture(\n video: HTMLVideoElement,\n hint: HTMLElement,\n doc: DocStage,\n capture: () => void,\n ): void {\n let goodStreak = 0\n const timer = setInterval(() => {\n const quality = this.camera.sampleQuality(video)\n if (!quality) return\n if (quality.tooDark) {\n hint.textContent = 'Too dark — find better lighting'\n goodStreak = 0\n doc.setQuality('bad')\n } else if (quality.glare) {\n hint.textContent = 'Reduce glare on the document'\n goodStreak = 0\n doc.setQuality('bad')\n } else {\n hint.textContent = 'Looks good — hold steady'\n goodStreak += 1\n doc.setQuality('good')\n }\n // Auto-capture a steady document after ~1.5s of good quality.\n if (goodStreak >= 5) {\n clearInterval(timer)\n capture()\n }\n }, 300)\n this.timers.push(timer)\n }\n\n /**\n * Selfie capture: when face detection is available, auto-grab once a centred\n * face is held steady. Falls back to a brightness hint (manual capture) when\n * the detector can't load (unsupported browser / offline / test host).\n *\n * @param video\n * @param hint\n * @param capture\n * @returns\n */\n private runSelfieAutoCapture(video: HTMLVideoElement, hint: HTMLElement, capture: () => void, face: FaceStage): void {\n const analyzer = this.analyzer\n const addManualCapture = () => this.footer.appendChild(this.button('Capture', capture))\n if (!analyzer) {\n // No detector available — fall back to a manual capture button.\n hint.textContent = 'Center your face, then capture'\n addManualCapture()\n return\n }\n hint.textContent = 'Starting camera…'\n let cancelled = false\n let modelReady = false\n this.cleanups.push(() => {\n cancelled = true\n })\n // The camera feed appears before the detection model (MediaPipe WASM, lazily\n // fetched from a CDN) finishes loading. Once the video is live, stop implying\n // the camera is still starting.\n this.onCameraLive(video, () => {\n if (!cancelled && !modelReady) hint.textContent = 'Getting ready…'\n })\n void analyzer.ready().then((ok) => {\n modelReady = true\n if (cancelled) return\n if (!ok) {\n // Detector failed to load — guide with brightness and offer manual capture.\n hint.textContent = 'Center your face, then capture'\n addManualCapture()\n return\n }\n const need = 4\n let streak = 0\n const timer = setInterval(() => {\n const sample = analyzer.analyze(video)\n if (!sample || !sample.present) {\n hint.textContent = 'Position your face in the circle'\n streak = 0\n face.setState('wait')\n face.setProgress(0)\n return\n }\n if (isSelfieReady(sample, this.tuning)) {\n hint.textContent = 'Hold still…'\n streak += 1\n face.setState('good')\n face.setProgress(streak / need)\n } else {\n hint.textContent = sample.scale <= this.tuning.selfieMinScale ? 'Move a little closer' : 'Center your face'\n streak = 0\n face.setState('wait')\n face.setProgress(0)\n }\n if (streak >= need) {\n clearInterval(timer)\n face.setState('done')\n face.setProgress(1)\n capture()\n }\n }, 180)\n this.timers.push(timer)\n })\n }\n\n /**\n * Guided active-liveness screen: live front-camera preview, a recorded video,\n * and a sequence of challenge prompts the user advances through. The performed\n * sequence (the prompts shown, in order) is submitted for the driver to verify.\n *\n * @param video\n * @returns\n */\n private renderActiveLiveness(\n challenges: LivenessChallenge[],\n allowSkip?: boolean,\n requireLiveCamera?: boolean,\n ): void {\n const prompt = this.dom.h('p', {\n class: 'arkyc-p',\n text: 'Follow the on-screen prompts. Keep your face centred in the circle.',\n })\n this.dom.append(this.body, [this.dom.h('h2', { class: 'arkyc-h', text: 'Liveness check' }), prompt])\n\n const fileFallback = !this.camera.supported || !this.camera.canRecord\n\n if (fileFallback) {\n if (requireLiveCamera) {\n // capture_model = active: a live camera is mandatory. Do NOT offer a\n // manual \"I did it\" path — surface the device as unsupported instead.\n this.body.appendChild(this.dom.h('div', { class: 'arkyc-badge err', html: '!' }))\n prompt.textContent =\n 'This check needs camera access on a supported device. Please retry on a device with a working camera.'\n if (allowSkip) {\n const skip = this.button('Skip (demo)', () => this.handlers.onActiveLiveness(null, challenges))\n skip.classList.add('arkyc-btn-ghost')\n this.footer.appendChild(skip)\n }\n return\n }\n // No camera/recorder — let the user finish (or skip) without a video.\n const finish = this.button('I performed the steps', () => this.handlers.onActiveLiveness(null, challenges))\n this.footer.appendChild(finish)\n if (allowSkip) {\n const skip = this.button('Skip (demo)', () => this.handlers.onActiveLiveness(null, challenges))\n skip.classList.add('arkyc-btn-ghost')\n this.footer.appendChild(skip)\n }\n return\n }\n\n const video = this.dom.h<HTMLVideoElement>('video', { class: 'arkyc-preview selfie' })\n const face = this.buildFaceStage(video)\n const dots = this.buildDots(challenges.length)\n this.dom.append(this.body, [challenges.length > 1 && dots.el, face.stage])\n\n let recording: { stop(): Promise<Blob> } | null = null\n let index = 0\n // The challenges the user actually completed, in order (detected or advanced).\n const performed: LivenessChallenge[] = []\n let detector = makeChallengeDetector(challenges[0] ?? 'blink', this.tuning)\n\n const showPrompt = (done = false) => {\n const challenge = challenges[index]\n if (!challenge) {\n prompt.textContent = 'Hold still…'\n return\n }\n prompt.textContent = done\n ? `✓ ${CHALLENGE_LABELS[challenge]}`\n : `Step ${index + 1} of ${challenges.length}: ${CHALLENGE_LABELS[challenge]}`\n }\n\n // Arm the overlay for the current challenge: show its cue, reset the ring,\n // and highlight the active step dot.\n const armChallenge = () => {\n face.setCue(challenges[index] ?? null)\n face.setState('wait')\n face.setProgress(0)\n dots.setActive(index)\n }\n\n const finish = () => {\n advance.setAttribute('disabled', 'true')\n // Grab a still selfie from the live video before stopping the recorder, so\n // active liveness yields a face image for review + face matching.\n void this.camera\n .grabFrame(video)\n .then((selfie) =>\n Promise.resolve(recording?.stop() ?? Promise.resolve(null)).then((blob) =>\n this.handlers.onActiveLiveness(blob, performed, selfie),\n ),\n )\n }\n\n const advanceStep = () => {\n if (index >= challenges.length) return\n const current = challenges[index]\n if (current) performed.push(current)\n dots.markDone(index)\n index += 1\n if (index >= challenges.length) {\n finish()\n return\n }\n detector = makeChallengeDetector(challenges[index]!, this.tuning)\n showPrompt()\n armChallenge()\n if (index === challenges.length - 1) advance.textContent = 'Finish'\n }\n\n // Manual advance is only revealed as a fallback when detection can't run.\n const advance = this.button('Next', () => advanceStep())\n if (challenges.length <= 1) advance.textContent = 'Finish'\n let manualShown = false\n const showManualAdvance = () => {\n if (manualShown) return\n manualShown = true\n this.footer.appendChild(advance)\n }\n\n void this.camera\n .start(video, 'user')\n .then((stream) => {\n recording = this.camera.recordStart(stream)\n showPrompt()\n armChallenge()\n\n // Real detection when available: auto-advance only when the prompted\n // challenge is actually performed. Reveals the manual button if the\n // detector is absent or fails to load.\n const analyzer = this.analyzer\n if (!analyzer) {\n showManualAdvance()\n return\n }\n let cancelled = false\n this.cleanups.push(() => {\n cancelled = true\n })\n void analyzer.ready().then((ok) => {\n if (cancelled) return\n if (!ok) {\n showManualAdvance()\n return\n }\n // While the success check is held, pause detection so the next cue\n // doesn't flash in before the user sees the confirmation.\n let flashing = false\n const timer = setInterval(() => {\n if (index >= challenges.length) {\n clearInterval(timer)\n return\n }\n if (flashing) return\n const sample = analyzer.analyze(video)\n if (!sample) return\n const hit = detector.feed(sample)\n face.setProgress(detector.progress)\n if (hit) {\n face.setState('done')\n showPrompt(true)\n flashing = true\n const to = setTimeout(() => {\n flashing = false\n advanceStep()\n }, 650)\n this.cleanups.push(() => clearTimeout(to))\n } else {\n face.setState(detector.progress > 0 ? 'good' : 'wait')\n }\n }, 160)\n this.timers.push(timer)\n })\n })\n .catch(() => {\n face.stage.classList.add('arkyc-hidden')\n if (requireLiveCamera) {\n // Mandatory live camera was denied — require a retry, don't fall back.\n prompt.textContent = 'Camera access is required to continue. Please allow access and try again.'\n return\n }\n this.handlers.onActiveLiveness(null, challenges)\n })\n\n if (allowSkip) {\n const skip = this.button('Skip (demo)', () => this.handlers.onActiveLiveness(null, challenges))\n skip.classList.add('arkyc-btn-ghost')\n this.footer.appendChild(skip)\n }\n }\n\n /**\n * Build the circular selfie/liveness preview overlay: an SVG progress ring, a\n * gesture-cue layer, and a success checkmark — driven via the returned handles.\n *\n * @param video\n * @returns\n */\n private buildFaceStage(video: HTMLVideoElement): FaceStage {\n const ring = this.dom.h('div', {\n class: 'arkyc-ring',\n html: '<svg viewBox=\"0 0 100 100\"><circle class=\"arkyc-ring-track\" cx=\"50\" cy=\"50\" r=\"46\"/><circle class=\"arkyc-ring-arc\" cx=\"50\" cy=\"50\" r=\"46\"/></svg>',\n })\n const cue = this.dom.h('div', { class: 'arkyc-cue' })\n const stage = this.dom.h('div', { class: 'arkyc-stage', 'data-state': 'wait' }, [\n video,\n ring,\n cue,\n this.dom.h('div', { class: 'arkyc-check', html: CHECK_ICON }),\n ])\n\n const arc = ring.querySelector('.arkyc-ring-arc') as SVGCircleElement | null\n const circumference = 2 * Math.PI * 46\n if (arc) {\n arc.style.strokeDasharray = String(circumference)\n arc.style.strokeDashoffset = String(circumference)\n }\n\n return {\n stage,\n setProgress: (p) => {\n if (arc) arc.style.strokeDashoffset = String(circumference * (1 - Math.max(0, Math.min(1, p))))\n },\n setState: (state) => stage.setAttribute('data-state', state),\n setCue: (challenge) => {\n cue.className = 'arkyc-cue' + (challenge ? ` show arkyc-cue-${challenge}` : '')\n cue.innerHTML = challenge ? CUE_ICONS[challenge] : ''\n },\n }\n }\n\n /**\n * Build the liveness step-progress dots (one per challenge).\n *\n * @param video\n * @param hint\n * @param doc\n */\n private buildDots(count: number): StepDots {\n const dots = Array.from({ length: count }, () => this.dom.h('div', { class: 'arkyc-dot' }))\n const el = this.dom.h('div', { class: 'arkyc-dots' }, dots)\n return {\n el,\n setActive: (index) =>\n dots.forEach((d, i) => d.classList.toggle('active', i === index && !d.classList.contains('done'))),\n markDone: (index) => {\n const d = dots[index]\n if (d) {\n d.classList.remove('active')\n d.classList.add('done')\n }\n },\n }\n }\n\n /**\n * Build the document preview overlay: a fixed card-shaped alignment guide\n * (corner brackets + border) with an animated scan line. The guide is a target,\n * not a tracker — it stays put so the user aligns the card to it; detection only\n * tints it for quality and brightens it once a document is in view.\n *\n * @param video\n * @returns\n */\n private buildDocStage(video: HTMLVideoElement): DocStage {\n const frame = this.dom.h('div', { class: 'arkyc-doc-frame' }, [\n ...['tl', 'tr', 'bl', 'br'].map((corner) => this.dom.h('span', { class: `arkyc-corner ${corner}` })),\n this.dom.h('div', { class: 'arkyc-scan' }),\n ])\n const stage = this.dom.h('div', { class: 'arkyc-doc', 'data-q': 'wait' }, [video, frame])\n return {\n stage,\n setQuality: (quality) => stage.setAttribute('data-q', quality),\n // The guide never moves; a detected document only brightens it as feedback.\n setFrame: (rect) => stage.setAttribute('data-detected', rect ? 'true' : 'false'),\n }\n }\n\n private renderProcessing(label: string): void {\n this.dom.append(this.body, [\n this.dom.h('div', { class: 'arkyc-spinner' }),\n this.dom.h('p', { class: 'arkyc-p', text: label }),\n ])\n }\n\n private renderResult(\n decision: VerificationDecision | null,\n errorMessage?: string,\n opts: { terminal?: boolean; status?: VerificationStatus } = {},\n ): void {\n if (errorMessage) {\n this.dom.append(this.body, [\n this.dom.h('div', { class: 'arkyc-badge err', html: '!' }),\n this.dom.h('h2', { class: 'arkyc-h', text: 'Something went wrong' }),\n this.dom.h('p', { class: 'arkyc-p', text: errorMessage }),\n ])\n } else if (opts.terminal) {\n // The session was already finished/expired when this device opened it (e.g.\n // a stale handoff link). Show a notice, not the live result — and only Close.\n const n = TERMINAL_NOTICE[opts.status ?? 'expired'] ?? EXPIRED_NOTICE\n this.dom.append(this.body, [\n this.dom.h('div', { class: `arkyc-badge ${n.cls}`, text: n.icon }),\n this.dom.h('h2', { class: 'arkyc-h', text: n.title }),\n this.dom.h('p', { class: 'arkyc-p', text: n.copy }),\n ])\n this.footer.appendChild(this.button('Close', () => this.handlers.onClose()))\n return\n } else {\n const map = {\n approved: {\n cls: 'ok',\n icon: '✓',\n title: 'Verified',\n copy: 'Your identity has been verified.',\n },\n requires_review: {\n cls: 'warn',\n icon: '⏳',\n title: 'Under review',\n copy: 'Your verification is being reviewed. We will be in touch shortly.',\n },\n rejected: {\n cls: 'err',\n icon: '✕',\n title: 'Not verified',\n copy: 'We could not verify your identity. Please try again.',\n },\n } as const\n const r = map[decision ?? 'requires_review'] ?? map.requires_review\n this.dom.append(this.body, [\n this.dom.h('div', { class: `arkyc-badge ${r.cls}`, text: r.icon }),\n this.dom.h('h2', { class: 'arkyc-h', text: r.title }),\n this.dom.h('p', { class: 'arkyc-p', text: r.copy }),\n ])\n }\n this.footer.appendChild(this.button('Done', () => this.handlers.onAcknowledge()))\n }\n\n /**\n * The address-entry form (opt-in address stage). Inputs shown depend on methods.\n *\n * @param methods\n */\n private renderAddressForm(methods: AddressMethod[]): void {\n this.body.appendChild(this.dom.h('h2', { class: 'arkyc-h', text: 'Your address' }))\n this.body.appendChild(\n this.dom.h('p', { class: 'arkyc-p', text: 'Enter your residential address so we can verify it.' }),\n )\n\n const line1 = this.dom.field('Address line 1', { autocomplete: 'address-line1', name: 'street' })\n const line2 = this.dom.field('Address line 2 (optional)', { autocomplete: 'address-line2', name: 'town' })\n const city = this.dom.field('City', { autocomplete: 'address-level2', name: 'city' })\n const region = this.dom.field('State / region', { autocomplete: 'address-level1', name: 'state' })\n const postal = this.dom.field('ZIP/Postal code', { autocomplete: 'postal-code', name: 'zip' })\n const country = this.dom.field('Country', {\n name: 'country_iso2',\n choices: countries.map((e) => ({\n value: e.iso2,\n label: `${e.flag} ${e.name}`,\n })),\n })\n this.body.appendChild(\n this.dom.h('div', { class: 'arkyc-addr-form' }, [line1, line2, city, region, postal, country]),\n )\n\n let poa: Blob | null = null\n if (methods.includes('poa_document')) {\n const file = this.dom.h<HTMLInputElement>('input', {\n class: 'arkyc-addr-input',\n type: 'file',\n accept: 'image/*',\n on: { change: () => (poa = file.files?.[0] ?? null) },\n })\n this.dom.append(this.body, [\n this.dom.h('p', { class: 'arkyc-p', text: 'Upload a proof of address (utility bill or bank statement).' }),\n file,\n ])\n }\n\n let useLocation = false\n const requiresLocation = methods.includes('device_location')\n\n const submit = this.button('Continue', () =>\n this.handlers.onAddress({\n line1: line1.value.trim() || null,\n line2: line2.value.trim() || null,\n city: city.value.trim() || null,\n region: region.value.trim() || null,\n postalCode: postal.value.trim() || null,\n country: country.value.trim().toUpperCase() || null,\n poa,\n useLocation,\n }),\n )\n\n if (requiresLocation) {\n const status = this.dom.h('p', { class: 'arkyc-p' })\n const cb = this.dom.h<HTMLInputElement>('input', {\n type: 'checkbox',\n // Request location the moment they opt in, so the browser permission\n // prompt appears immediately (not silently at submit) — and show the result.\n on: {\n change: () => {\n if (!cb.checked) {\n useLocation = false\n status.textContent = ''\n submit.setAttribute('disabled', 'true')\n return\n }\n status.textContent = 'Requesting your location…'\n submit.setAttribute('disabled', 'true')\n void Promise.resolve(this.handlers.onShareLocation()).then((ok) => {\n useLocation = ok\n cb.checked = ok\n if (ok) submit.removeAttribute('disabled')\n else submit.setAttribute('disabled', 'true')\n status.textContent = ok\n ? 'Location shared ✓'\n : 'Couldn’t access your location, allow location access to continue.'\n })\n },\n },\n })\n // Continue stays disabled until the user opts in and we actually capture a\n // location fix — this method can't run without coordinates.\n submit.setAttribute('disabled', 'true')\n this.body.appendChild(\n this.dom.h('label', { class: 'arkyc-addr-opt' }, [\n cb,\n this.dom.h('span', { text: 'Allow access to my current location to confirm my address' }),\n ]),\n )\n this.body.appendChild(status)\n }\n\n this.footer.appendChild(submit)\n }\n\n private button(label: string, onClick: () => void, extraClass?: string): HTMLButtonElement {\n const cls = extraClass ? `arkyc-btn ${extraClass}` : 'arkyc-btn'\n const btn = this.dom.h('button', { class: cls, text: label }) as HTMLButtonElement\n // Guard against accidental double-clicks: a button fires once, then disables\n // and shows an inline loader while its (usually async) handler runs. The next\n // screen re-renders a fresh button, so this only spans the in-flight gap.\n let fired = false\n btn.addEventListener('click', () => {\n if (fired) return\n fired = true\n btn.setAttribute('disabled', 'true')\n btn.classList.add('arkyc-busy')\n onClick()\n })\n return btn\n }\n\n private clear(node: HTMLElement): void {\n while (node.firstChild) node.removeChild(node.firstChild)\n }\n}\n","/**\n * Coarse desktop/mobile detection used to decide whether to offer cross-device\n * handoff. Handoff is most useful when the user starts on a desktop (no good\n * camera) and continues on a phone, so projects can restrict it to desktops.\n */\nexport function isDesktopDevice(nav: Navigator): boolean {\n const ua = nav.userAgent || ''\n // Require a positive desktop signal: an unknown/empty UA is treated as\n // non-desktop so the QR-first handoff flow never triggers on uncertainty.\n if (!ua) return false\n const mobile = /Android|iPhone|iPad|iPod|Opera Mini|IEMobile|Mobile|BlackBerry|Windows Phone/i.test(ua)\n // iPadOS 13+ masquerades as desktop Safari but reports touch points.\n const iPadOS = nav.platform === 'MacIntel' && (nav.maxTouchPoints ?? 0) > 1\n return !mobile && !iPadOS\n}\n","//---------------------------------------------------------------------\n//\n// QR Code Generator for JavaScript\n//\n// Copyright (c) 2009 Kazuhiko Arase\n//\n// URL: http://www.d-project.com/\n//\n// Licensed under the MIT license:\n// http://www.opensource.org/licenses/mit-license.php\n//\n// The word 'QR Code' is registered trademark of\n// DENSO WAVE INCORPORATED\n// http://www.denso-wave.com/qrcode/faqpatent-e.html\n//\n//---------------------------------------------------------------------\n\nvar qrcode = function() {\n\n //---------------------------------------------------------------------\n // qrcode\n //---------------------------------------------------------------------\n\n /**\n * qrcode\n * @param typeNumber 1 to 40\n * @param errorCorrectionLevel 'L','M','Q','H'\n */\n var qrcode = function(typeNumber, errorCorrectionLevel) {\n\n var PAD0 = 0xEC;\n var PAD1 = 0x11;\n\n var _typeNumber = typeNumber;\n var _errorCorrectionLevel = QRErrorCorrectionLevel[errorCorrectionLevel];\n var _modules = null;\n var _moduleCount = 0;\n var _dataCache = null;\n var _dataList = [];\n\n var _this = {};\n\n var makeImpl = function(test, maskPattern) {\n\n _moduleCount = _typeNumber * 4 + 17;\n _modules = function(moduleCount) {\n var modules = new Array(moduleCount);\n for (var row = 0; row < moduleCount; row += 1) {\n modules[row] = new Array(moduleCount);\n for (var col = 0; col < moduleCount; col += 1) {\n modules[row][col] = null;\n }\n }\n return modules;\n }(_moduleCount);\n\n setupPositionProbePattern(0, 0);\n setupPositionProbePattern(_moduleCount - 7, 0);\n setupPositionProbePattern(0, _moduleCount - 7);\n setupPositionAdjustPattern();\n setupTimingPattern();\n setupTypeInfo(test, maskPattern);\n\n if (_typeNumber >= 7) {\n setupTypeNumber(test);\n }\n\n if (_dataCache == null) {\n _dataCache = createData(_typeNumber, _errorCorrectionLevel, _dataList);\n }\n\n mapData(_dataCache, maskPattern);\n };\n\n var setupPositionProbePattern = function(row, col) {\n\n for (var r = -1; r <= 7; r += 1) {\n\n if (row + r <= -1 || _moduleCount <= row + r) continue;\n\n for (var c = -1; c <= 7; c += 1) {\n\n if (col + c <= -1 || _moduleCount <= col + c) continue;\n\n if ( (0 <= r && r <= 6 && (c == 0 || c == 6) )\n || (0 <= c && c <= 6 && (r == 0 || r == 6) )\n || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {\n _modules[row + r][col + c] = true;\n } else {\n _modules[row + r][col + c] = false;\n }\n }\n }\n };\n\n var getBestMaskPattern = function() {\n\n var minLostPoint = 0;\n var pattern = 0;\n\n for (var i = 0; i < 8; i += 1) {\n\n makeImpl(true, i);\n\n var lostPoint = QRUtil.getLostPoint(_this);\n\n if (i == 0 || minLostPoint > lostPoint) {\n minLostPoint = lostPoint;\n pattern = i;\n }\n }\n\n return pattern;\n };\n\n var setupTimingPattern = function() {\n\n for (var r = 8; r < _moduleCount - 8; r += 1) {\n if (_modules[r][6] != null) {\n continue;\n }\n _modules[r][6] = (r % 2 == 0);\n }\n\n for (var c = 8; c < _moduleCount - 8; c += 1) {\n if (_modules[6][c] != null) {\n continue;\n }\n _modules[6][c] = (c % 2 == 0);\n }\n };\n\n var setupPositionAdjustPattern = function() {\n\n var pos = QRUtil.getPatternPosition(_typeNumber);\n\n for (var i = 0; i < pos.length; i += 1) {\n\n for (var j = 0; j < pos.length; j += 1) {\n\n var row = pos[i];\n var col = pos[j];\n\n if (_modules[row][col] != null) {\n continue;\n }\n\n for (var r = -2; r <= 2; r += 1) {\n\n for (var c = -2; c <= 2; c += 1) {\n\n if (r == -2 || r == 2 || c == -2 || c == 2\n || (r == 0 && c == 0) ) {\n _modules[row + r][col + c] = true;\n } else {\n _modules[row + r][col + c] = false;\n }\n }\n }\n }\n }\n };\n\n var setupTypeNumber = function(test) {\n\n var bits = QRUtil.getBCHTypeNumber(_typeNumber);\n\n for (var i = 0; i < 18; i += 1) {\n var mod = (!test && ( (bits >> i) & 1) == 1);\n _modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod;\n }\n\n for (var i = 0; i < 18; i += 1) {\n var mod = (!test && ( (bits >> i) & 1) == 1);\n _modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod;\n }\n };\n\n var setupTypeInfo = function(test, maskPattern) {\n\n var data = (_errorCorrectionLevel << 3) | maskPattern;\n var bits = QRUtil.getBCHTypeInfo(data);\n\n // vertical\n for (var i = 0; i < 15; i += 1) {\n\n var mod = (!test && ( (bits >> i) & 1) == 1);\n\n if (i < 6) {\n _modules[i][8] = mod;\n } else if (i < 8) {\n _modules[i + 1][8] = mod;\n } else {\n _modules[_moduleCount - 15 + i][8] = mod;\n }\n }\n\n // horizontal\n for (var i = 0; i < 15; i += 1) {\n\n var mod = (!test && ( (bits >> i) & 1) == 1);\n\n if (i < 8) {\n _modules[8][_moduleCount - i - 1] = mod;\n } else if (i < 9) {\n _modules[8][15 - i - 1 + 1] = mod;\n } else {\n _modules[8][15 - i - 1] = mod;\n }\n }\n\n // fixed module\n _modules[_moduleCount - 8][8] = (!test);\n };\n\n var mapData = function(data, maskPattern) {\n\n var inc = -1;\n var row = _moduleCount - 1;\n var bitIndex = 7;\n var byteIndex = 0;\n var maskFunc = QRUtil.getMaskFunction(maskPattern);\n\n for (var col = _moduleCount - 1; col > 0; col -= 2) {\n\n if (col == 6) col -= 1;\n\n while (true) {\n\n for (var c = 0; c < 2; c += 1) {\n\n if (_modules[row][col - c] == null) {\n\n var dark = false;\n\n if (byteIndex < data.length) {\n dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);\n }\n\n var mask = maskFunc(row, col - c);\n\n if (mask) {\n dark = !dark;\n }\n\n _modules[row][col - c] = dark;\n bitIndex -= 1;\n\n if (bitIndex == -1) {\n byteIndex += 1;\n bitIndex = 7;\n }\n }\n }\n\n row += inc;\n\n if (row < 0 || _moduleCount <= row) {\n row -= inc;\n inc = -inc;\n break;\n }\n }\n }\n };\n\n var createBytes = function(buffer, rsBlocks) {\n\n var offset = 0;\n\n var maxDcCount = 0;\n var maxEcCount = 0;\n\n var dcdata = new Array(rsBlocks.length);\n var ecdata = new Array(rsBlocks.length);\n\n for (var r = 0; r < rsBlocks.length; r += 1) {\n\n var dcCount = rsBlocks[r].dataCount;\n var ecCount = rsBlocks[r].totalCount - dcCount;\n\n maxDcCount = Math.max(maxDcCount, dcCount);\n maxEcCount = Math.max(maxEcCount, ecCount);\n\n dcdata[r] = new Array(dcCount);\n\n for (var i = 0; i < dcdata[r].length; i += 1) {\n dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset];\n }\n offset += dcCount;\n\n var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);\n var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1);\n\n var modPoly = rawPoly.mod(rsPoly);\n ecdata[r] = new Array(rsPoly.getLength() - 1);\n for (var i = 0; i < ecdata[r].length; i += 1) {\n var modIndex = i + modPoly.getLength() - ecdata[r].length;\n ecdata[r][i] = (modIndex >= 0)? modPoly.getAt(modIndex) : 0;\n }\n }\n\n var totalCodeCount = 0;\n for (var i = 0; i < rsBlocks.length; i += 1) {\n totalCodeCount += rsBlocks[i].totalCount;\n }\n\n var data = new Array(totalCodeCount);\n var index = 0;\n\n for (var i = 0; i < maxDcCount; i += 1) {\n for (var r = 0; r < rsBlocks.length; r += 1) {\n if (i < dcdata[r].length) {\n data[index] = dcdata[r][i];\n index += 1;\n }\n }\n }\n\n for (var i = 0; i < maxEcCount; i += 1) {\n for (var r = 0; r < rsBlocks.length; r += 1) {\n if (i < ecdata[r].length) {\n data[index] = ecdata[r][i];\n index += 1;\n }\n }\n }\n\n return data;\n };\n\n var createData = function(typeNumber, errorCorrectionLevel, dataList) {\n\n var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectionLevel);\n\n var buffer = qrBitBuffer();\n\n for (var i = 0; i < dataList.length; i += 1) {\n var data = dataList[i];\n buffer.put(data.getMode(), 4);\n buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );\n data.write(buffer);\n }\n\n // calc num max data.\n var totalDataCount = 0;\n for (var i = 0; i < rsBlocks.length; i += 1) {\n totalDataCount += rsBlocks[i].dataCount;\n }\n\n if (buffer.getLengthInBits() > totalDataCount * 8) {\n throw 'code length overflow. ('\n + buffer.getLengthInBits()\n + '>'\n + totalDataCount * 8\n + ')';\n }\n\n // end code\n if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {\n buffer.put(0, 4);\n }\n\n // padding\n while (buffer.getLengthInBits() % 8 != 0) {\n buffer.putBit(false);\n }\n\n // padding\n while (true) {\n\n if (buffer.getLengthInBits() >= totalDataCount * 8) {\n break;\n }\n buffer.put(PAD0, 8);\n\n if (buffer.getLengthInBits() >= totalDataCount * 8) {\n break;\n }\n buffer.put(PAD1, 8);\n }\n\n return createBytes(buffer, rsBlocks);\n };\n\n _this.addData = function(data, mode) {\n\n mode = mode || 'Byte';\n\n var newData = null;\n\n switch(mode) {\n case 'Numeric' :\n newData = qrNumber(data);\n break;\n case 'Alphanumeric' :\n newData = qrAlphaNum(data);\n break;\n case 'Byte' :\n newData = qr8BitByte(data);\n break;\n case 'Kanji' :\n newData = qrKanji(data);\n break;\n default :\n throw 'mode:' + mode;\n }\n\n _dataList.push(newData);\n _dataCache = null;\n };\n\n _this.isDark = function(row, col) {\n if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) {\n throw row + ',' + col;\n }\n return _modules[row][col];\n };\n\n _this.getModuleCount = function() {\n return _moduleCount;\n };\n\n _this.make = function() {\n if (_typeNumber < 1) {\n var typeNumber = 1;\n\n for (; typeNumber < 40; typeNumber++) {\n var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, _errorCorrectionLevel);\n var buffer = qrBitBuffer();\n\n for (var i = 0; i < _dataList.length; i++) {\n var data = _dataList[i];\n buffer.put(data.getMode(), 4);\n buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );\n data.write(buffer);\n }\n\n var totalDataCount = 0;\n for (var i = 0; i < rsBlocks.length; i++) {\n totalDataCount += rsBlocks[i].dataCount;\n }\n\n if (buffer.getLengthInBits() <= totalDataCount * 8) {\n break;\n }\n }\n\n _typeNumber = typeNumber;\n }\n\n makeImpl(false, getBestMaskPattern() );\n };\n\n _this.createTableTag = function(cellSize, margin) {\n\n cellSize = cellSize || 2;\n margin = (typeof margin == 'undefined')? cellSize * 4 : margin;\n\n var qrHtml = '';\n\n qrHtml += '<table style=\"';\n qrHtml += ' border-width: 0px; border-style: none;';\n qrHtml += ' border-collapse: collapse;';\n qrHtml += ' padding: 0px; margin: ' + margin + 'px;';\n qrHtml += '\">';\n qrHtml += '<tbody>';\n\n for (var r = 0; r < _this.getModuleCount(); r += 1) {\n\n qrHtml += '<tr>';\n\n for (var c = 0; c < _this.getModuleCount(); c += 1) {\n qrHtml += '<td style=\"';\n qrHtml += ' border-width: 0px; border-style: none;';\n qrHtml += ' border-collapse: collapse;';\n qrHtml += ' padding: 0px; margin: 0px;';\n qrHtml += ' width: ' + cellSize + 'px;';\n qrHtml += ' height: ' + cellSize + 'px;';\n qrHtml += ' background-color: ';\n qrHtml += _this.isDark(r, c)? '#000000' : '#ffffff';\n qrHtml += ';';\n qrHtml += '\"/>';\n }\n\n qrHtml += '</tr>';\n }\n\n qrHtml += '</tbody>';\n qrHtml += '</table>';\n\n return qrHtml;\n };\n\n _this.createSvgTag = function(cellSize, margin, alt, title) {\n\n var opts = {};\n if (typeof arguments[0] == 'object') {\n // Called by options.\n opts = arguments[0];\n // overwrite cellSize and margin.\n cellSize = opts.cellSize;\n margin = opts.margin;\n alt = opts.alt;\n title = opts.title;\n }\n\n cellSize = cellSize || 2;\n margin = (typeof margin == 'undefined')? cellSize * 4 : margin;\n\n // Compose alt property surrogate\n alt = (typeof alt === 'string') ? {text: alt} : alt || {};\n alt.text = alt.text || null;\n alt.id = (alt.text) ? alt.id || 'qrcode-description' : null;\n\n // Compose title property surrogate\n title = (typeof title === 'string') ? {text: title} : title || {};\n title.text = title.text || null;\n title.id = (title.text) ? title.id || 'qrcode-title' : null;\n\n var size = _this.getModuleCount() * cellSize + margin * 2;\n var c, mc, r, mr, qrSvg='', rect;\n\n rect = 'l' + cellSize + ',0 0,' + cellSize +\n ' -' + cellSize + ',0 0,-' + cellSize + 'z ';\n\n qrSvg += '<svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\"';\n qrSvg += !opts.scalable ? ' width=\"' + size + 'px\" height=\"' + size + 'px\"' : '';\n qrSvg += ' viewBox=\"0 0 ' + size + ' ' + size + '\" ';\n qrSvg += ' preserveAspectRatio=\"xMinYMin meet\"';\n qrSvg += (title.text || alt.text) ? ' role=\"img\" aria-labelledby=\"' +\n escapeXml([title.id, alt.id].join(' ').trim() ) + '\"' : '';\n qrSvg += '>';\n qrSvg += (title.text) ? '<title id=\"' + escapeXml(title.id) + '\">' +\n escapeXml(title.text) + '</title>' : '';\n qrSvg += (alt.text) ? '<description id=\"' + escapeXml(alt.id) + '\">' +\n escapeXml(alt.text) + '</description>' : '';\n qrSvg += '<rect width=\"100%\" height=\"100%\" fill=\"white\" cx=\"0\" cy=\"0\"/>';\n qrSvg += '<path d=\"';\n\n for (r = 0; r < _this.getModuleCount(); r += 1) {\n mr = r * cellSize + margin;\n for (c = 0; c < _this.getModuleCount(); c += 1) {\n if (_this.isDark(r, c) ) {\n mc = c*cellSize+margin;\n qrSvg += 'M' + mc + ',' + mr + rect;\n }\n }\n }\n\n qrSvg += '\" stroke=\"transparent\" fill=\"black\"/>';\n qrSvg += '</svg>';\n\n return qrSvg;\n };\n\n _this.createDataURL = function(cellSize, margin) {\n\n cellSize = cellSize || 2;\n margin = (typeof margin == 'undefined')? cellSize * 4 : margin;\n\n var size = _this.getModuleCount() * cellSize + margin * 2;\n var min = margin;\n var max = size - margin;\n\n return createDataURL(size, size, function(x, y) {\n if (min <= x && x < max && min <= y && y < max) {\n var c = Math.floor( (x - min) / cellSize);\n var r = Math.floor( (y - min) / cellSize);\n return _this.isDark(r, c)? 0 : 1;\n } else {\n return 1;\n }\n } );\n };\n\n _this.createImgTag = function(cellSize, margin, alt) {\n\n cellSize = cellSize || 2;\n margin = (typeof margin == 'undefined')? cellSize * 4 : margin;\n\n var size = _this.getModuleCount() * cellSize + margin * 2;\n\n var img = '';\n img += '<img';\n img += '\\u0020src=\"';\n img += _this.createDataURL(cellSize, margin);\n img += '\"';\n img += '\\u0020width=\"';\n img += size;\n img += '\"';\n img += '\\u0020height=\"';\n img += size;\n img += '\"';\n if (alt) {\n img += '\\u0020alt=\"';\n img += escapeXml(alt);\n img += '\"';\n }\n img += '/>';\n\n return img;\n };\n\n var escapeXml = function(s) {\n var escaped = '';\n for (var i = 0; i < s.length; i += 1) {\n var c = s.charAt(i);\n switch(c) {\n case '<': escaped += '&lt;'; break;\n case '>': escaped += '&gt;'; break;\n case '&': escaped += '&amp;'; break;\n case '\"': escaped += '&quot;'; break;\n default : escaped += c; break;\n }\n }\n return escaped;\n };\n\n var _createHalfASCII = function(margin) {\n var cellSize = 1;\n margin = (typeof margin == 'undefined')? cellSize * 2 : margin;\n\n var size = _this.getModuleCount() * cellSize + margin * 2;\n var min = margin;\n var max = size - margin;\n\n var y, x, r1, r2, p;\n\n var blocks = {\n '██': '█',\n '█ ': '▀',\n ' █': '▄',\n ' ': ' '\n };\n\n var blocksLastLineNoMargin = {\n '██': '▀',\n '█ ': '▀',\n ' █': ' ',\n ' ': ' '\n };\n\n var ascii = '';\n for (y = 0; y < size; y += 2) {\n r1 = Math.floor((y - min) / cellSize);\n r2 = Math.floor((y + 1 - min) / cellSize);\n for (x = 0; x < size; x += 1) {\n p = '█';\n\n if (min <= x && x < max && min <= y && y < max && _this.isDark(r1, Math.floor((x - min) / cellSize))) {\n p = ' ';\n }\n\n if (min <= x && x < max && min <= y+1 && y+1 < max && _this.isDark(r2, Math.floor((x - min) / cellSize))) {\n p += ' ';\n }\n else {\n p += '█';\n }\n\n // Output 2 characters per pixel, to create full square. 1 character per pixels gives only half width of square.\n ascii += (margin < 1 && y+1 >= max) ? blocksLastLineNoMargin[p] : blocks[p];\n }\n\n ascii += '\\n';\n }\n\n if (size % 2 && margin > 0) {\n return ascii.substring(0, ascii.length - size - 1) + Array(size+1).join('▀');\n }\n\n return ascii.substring(0, ascii.length-1);\n };\n\n _this.createASCII = function(cellSize, margin) {\n cellSize = cellSize || 1;\n\n if (cellSize < 2) {\n return _createHalfASCII(margin);\n }\n\n cellSize -= 1;\n margin = (typeof margin == 'undefined')? cellSize * 2 : margin;\n\n var size = _this.getModuleCount() * cellSize + margin * 2;\n var min = margin;\n var max = size - margin;\n\n var y, x, r, p;\n\n var white = Array(cellSize+1).join('██');\n var black = Array(cellSize+1).join(' ');\n\n var ascii = '';\n var line = '';\n for (y = 0; y < size; y += 1) {\n r = Math.floor( (y - min) / cellSize);\n line = '';\n for (x = 0; x < size; x += 1) {\n p = 1;\n\n if (min <= x && x < max && min <= y && y < max && _this.isDark(r, Math.floor((x - min) / cellSize))) {\n p = 0;\n }\n\n // Output 2 characters per pixel, to create full square. 1 character per pixels gives only half width of square.\n line += p ? white : black;\n }\n\n for (r = 0; r < cellSize; r += 1) {\n ascii += line + '\\n';\n }\n }\n\n return ascii.substring(0, ascii.length-1);\n };\n\n _this.renderTo2dContext = function(context, cellSize) {\n cellSize = cellSize || 2;\n var length = _this.getModuleCount();\n for (var row = 0; row < length; row++) {\n for (var col = 0; col < length; col++) {\n context.fillStyle = _this.isDark(row, col) ? 'black' : 'white';\n context.fillRect(row * cellSize, col * cellSize, cellSize, cellSize);\n }\n }\n }\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // qrcode.stringToBytes\n //---------------------------------------------------------------------\n\n qrcode.stringToBytesFuncs = {\n 'default' : function(s) {\n var bytes = [];\n for (var i = 0; i < s.length; i += 1) {\n var c = s.charCodeAt(i);\n bytes.push(c & 0xff);\n }\n return bytes;\n }\n };\n\n qrcode.stringToBytes = qrcode.stringToBytesFuncs['default'];\n\n //---------------------------------------------------------------------\n // qrcode.createStringToBytes\n //---------------------------------------------------------------------\n\n /**\n * @param unicodeData base64 string of byte array.\n * [16bit Unicode],[16bit Bytes], ...\n * @param numChars\n */\n qrcode.createStringToBytes = function(unicodeData, numChars) {\n\n // create conversion map.\n\n var unicodeMap = function() {\n\n var bin = base64DecodeInputStream(unicodeData);\n var read = function() {\n var b = bin.read();\n if (b == -1) throw 'eof';\n return b;\n };\n\n var count = 0;\n var unicodeMap = {};\n while (true) {\n var b0 = bin.read();\n if (b0 == -1) break;\n var b1 = read();\n var b2 = read();\n var b3 = read();\n var k = String.fromCharCode( (b0 << 8) | b1);\n var v = (b2 << 8) | b3;\n unicodeMap[k] = v;\n count += 1;\n }\n if (count != numChars) {\n throw count + ' != ' + numChars;\n }\n\n return unicodeMap;\n }();\n\n var unknownChar = '?'.charCodeAt(0);\n\n return function(s) {\n var bytes = [];\n for (var i = 0; i < s.length; i += 1) {\n var c = s.charCodeAt(i);\n if (c < 128) {\n bytes.push(c);\n } else {\n var b = unicodeMap[s.charAt(i)];\n if (typeof b == 'number') {\n if ( (b & 0xff) == b) {\n // 1byte\n bytes.push(b);\n } else {\n // 2bytes\n bytes.push(b >>> 8);\n bytes.push(b & 0xff);\n }\n } else {\n bytes.push(unknownChar);\n }\n }\n }\n return bytes;\n };\n };\n\n //---------------------------------------------------------------------\n // QRMode\n //---------------------------------------------------------------------\n\n var QRMode = {\n MODE_NUMBER : 1 << 0,\n MODE_ALPHA_NUM : 1 << 1,\n MODE_8BIT_BYTE : 1 << 2,\n MODE_KANJI : 1 << 3\n };\n\n //---------------------------------------------------------------------\n // QRErrorCorrectionLevel\n //---------------------------------------------------------------------\n\n var QRErrorCorrectionLevel = {\n L : 1,\n M : 0,\n Q : 3,\n H : 2\n };\n\n //---------------------------------------------------------------------\n // QRMaskPattern\n //---------------------------------------------------------------------\n\n var QRMaskPattern = {\n PATTERN000 : 0,\n PATTERN001 : 1,\n PATTERN010 : 2,\n PATTERN011 : 3,\n PATTERN100 : 4,\n PATTERN101 : 5,\n PATTERN110 : 6,\n PATTERN111 : 7\n };\n\n //---------------------------------------------------------------------\n // QRUtil\n //---------------------------------------------------------------------\n\n var QRUtil = function() {\n\n var PATTERN_POSITION_TABLE = [\n [],\n [6, 18],\n [6, 22],\n [6, 26],\n [6, 30],\n [6, 34],\n [6, 22, 38],\n [6, 24, 42],\n [6, 26, 46],\n [6, 28, 50],\n [6, 30, 54],\n [6, 32, 58],\n [6, 34, 62],\n [6, 26, 46, 66],\n [6, 26, 48, 70],\n [6, 26, 50, 74],\n [6, 30, 54, 78],\n [6, 30, 56, 82],\n [6, 30, 58, 86],\n [6, 34, 62, 90],\n [6, 28, 50, 72, 94],\n [6, 26, 50, 74, 98],\n [6, 30, 54, 78, 102],\n [6, 28, 54, 80, 106],\n [6, 32, 58, 84, 110],\n [6, 30, 58, 86, 114],\n [6, 34, 62, 90, 118],\n [6, 26, 50, 74, 98, 122],\n [6, 30, 54, 78, 102, 126],\n [6, 26, 52, 78, 104, 130],\n [6, 30, 56, 82, 108, 134],\n [6, 34, 60, 86, 112, 138],\n [6, 30, 58, 86, 114, 142],\n [6, 34, 62, 90, 118, 146],\n [6, 30, 54, 78, 102, 126, 150],\n [6, 24, 50, 76, 102, 128, 154],\n [6, 28, 54, 80, 106, 132, 158],\n [6, 32, 58, 84, 110, 136, 162],\n [6, 26, 54, 82, 110, 138, 166],\n [6, 30, 58, 86, 114, 142, 170]\n ];\n var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0);\n var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0);\n var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1);\n\n var _this = {};\n\n var getBCHDigit = function(data) {\n var digit = 0;\n while (data != 0) {\n digit += 1;\n data >>>= 1;\n }\n return digit;\n };\n\n _this.getBCHTypeInfo = function(data) {\n var d = data << 10;\n while (getBCHDigit(d) - getBCHDigit(G15) >= 0) {\n d ^= (G15 << (getBCHDigit(d) - getBCHDigit(G15) ) );\n }\n return ( (data << 10) | d) ^ G15_MASK;\n };\n\n _this.getBCHTypeNumber = function(data) {\n var d = data << 12;\n while (getBCHDigit(d) - getBCHDigit(G18) >= 0) {\n d ^= (G18 << (getBCHDigit(d) - getBCHDigit(G18) ) );\n }\n return (data << 12) | d;\n };\n\n _this.getPatternPosition = function(typeNumber) {\n return PATTERN_POSITION_TABLE[typeNumber - 1];\n };\n\n _this.getMaskFunction = function(maskPattern) {\n\n switch (maskPattern) {\n\n case QRMaskPattern.PATTERN000 :\n return function(i, j) { return (i + j) % 2 == 0; };\n case QRMaskPattern.PATTERN001 :\n return function(i, j) { return i % 2 == 0; };\n case QRMaskPattern.PATTERN010 :\n return function(i, j) { return j % 3 == 0; };\n case QRMaskPattern.PATTERN011 :\n return function(i, j) { return (i + j) % 3 == 0; };\n case QRMaskPattern.PATTERN100 :\n return function(i, j) { return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; };\n case QRMaskPattern.PATTERN101 :\n return function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; };\n case QRMaskPattern.PATTERN110 :\n return function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; };\n case QRMaskPattern.PATTERN111 :\n return function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; };\n\n default :\n throw 'bad maskPattern:' + maskPattern;\n }\n };\n\n _this.getErrorCorrectPolynomial = function(errorCorrectLength) {\n var a = qrPolynomial([1], 0);\n for (var i = 0; i < errorCorrectLength; i += 1) {\n a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0) );\n }\n return a;\n };\n\n _this.getLengthInBits = function(mode, type) {\n\n if (1 <= type && type < 10) {\n\n // 1 - 9\n\n switch(mode) {\n case QRMode.MODE_NUMBER : return 10;\n case QRMode.MODE_ALPHA_NUM : return 9;\n case QRMode.MODE_8BIT_BYTE : return 8;\n case QRMode.MODE_KANJI : return 8;\n default :\n throw 'mode:' + mode;\n }\n\n } else if (type < 27) {\n\n // 10 - 26\n\n switch(mode) {\n case QRMode.MODE_NUMBER : return 12;\n case QRMode.MODE_ALPHA_NUM : return 11;\n case QRMode.MODE_8BIT_BYTE : return 16;\n case QRMode.MODE_KANJI : return 10;\n default :\n throw 'mode:' + mode;\n }\n\n } else if (type < 41) {\n\n // 27 - 40\n\n switch(mode) {\n case QRMode.MODE_NUMBER : return 14;\n case QRMode.MODE_ALPHA_NUM : return 13;\n case QRMode.MODE_8BIT_BYTE : return 16;\n case QRMode.MODE_KANJI : return 12;\n default :\n throw 'mode:' + mode;\n }\n\n } else {\n throw 'type:' + type;\n }\n };\n\n _this.getLostPoint = function(qrcode) {\n\n var moduleCount = qrcode.getModuleCount();\n\n var lostPoint = 0;\n\n // LEVEL1\n\n for (var row = 0; row < moduleCount; row += 1) {\n for (var col = 0; col < moduleCount; col += 1) {\n\n var sameCount = 0;\n var dark = qrcode.isDark(row, col);\n\n for (var r = -1; r <= 1; r += 1) {\n\n if (row + r < 0 || moduleCount <= row + r) {\n continue;\n }\n\n for (var c = -1; c <= 1; c += 1) {\n\n if (col + c < 0 || moduleCount <= col + c) {\n continue;\n }\n\n if (r == 0 && c == 0) {\n continue;\n }\n\n if (dark == qrcode.isDark(row + r, col + c) ) {\n sameCount += 1;\n }\n }\n }\n\n if (sameCount > 5) {\n lostPoint += (3 + sameCount - 5);\n }\n }\n };\n\n // LEVEL2\n\n for (var row = 0; row < moduleCount - 1; row += 1) {\n for (var col = 0; col < moduleCount - 1; col += 1) {\n var count = 0;\n if (qrcode.isDark(row, col) ) count += 1;\n if (qrcode.isDark(row + 1, col) ) count += 1;\n if (qrcode.isDark(row, col + 1) ) count += 1;\n if (qrcode.isDark(row + 1, col + 1) ) count += 1;\n if (count == 0 || count == 4) {\n lostPoint += 3;\n }\n }\n }\n\n // LEVEL3\n\n for (var row = 0; row < moduleCount; row += 1) {\n for (var col = 0; col < moduleCount - 6; col += 1) {\n if (qrcode.isDark(row, col)\n && !qrcode.isDark(row, col + 1)\n && qrcode.isDark(row, col + 2)\n && qrcode.isDark(row, col + 3)\n && qrcode.isDark(row, col + 4)\n && !qrcode.isDark(row, col + 5)\n && qrcode.isDark(row, col + 6) ) {\n lostPoint += 40;\n }\n }\n }\n\n for (var col = 0; col < moduleCount; col += 1) {\n for (var row = 0; row < moduleCount - 6; row += 1) {\n if (qrcode.isDark(row, col)\n && !qrcode.isDark(row + 1, col)\n && qrcode.isDark(row + 2, col)\n && qrcode.isDark(row + 3, col)\n && qrcode.isDark(row + 4, col)\n && !qrcode.isDark(row + 5, col)\n && qrcode.isDark(row + 6, col) ) {\n lostPoint += 40;\n }\n }\n }\n\n // LEVEL4\n\n var darkCount = 0;\n\n for (var col = 0; col < moduleCount; col += 1) {\n for (var row = 0; row < moduleCount; row += 1) {\n if (qrcode.isDark(row, col) ) {\n darkCount += 1;\n }\n }\n }\n\n var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;\n lostPoint += ratio * 10;\n\n return lostPoint;\n };\n\n return _this;\n }();\n\n //---------------------------------------------------------------------\n // QRMath\n //---------------------------------------------------------------------\n\n var QRMath = function() {\n\n var EXP_TABLE = new Array(256);\n var LOG_TABLE = new Array(256);\n\n // initialize tables\n for (var i = 0; i < 8; i += 1) {\n EXP_TABLE[i] = 1 << i;\n }\n for (var i = 8; i < 256; i += 1) {\n EXP_TABLE[i] = EXP_TABLE[i - 4]\n ^ EXP_TABLE[i - 5]\n ^ EXP_TABLE[i - 6]\n ^ EXP_TABLE[i - 8];\n }\n for (var i = 0; i < 255; i += 1) {\n LOG_TABLE[EXP_TABLE[i] ] = i;\n }\n\n var _this = {};\n\n _this.glog = function(n) {\n\n if (n < 1) {\n throw 'glog(' + n + ')';\n }\n\n return LOG_TABLE[n];\n };\n\n _this.gexp = function(n) {\n\n while (n < 0) {\n n += 255;\n }\n\n while (n >= 256) {\n n -= 255;\n }\n\n return EXP_TABLE[n];\n };\n\n return _this;\n }();\n\n //---------------------------------------------------------------------\n // qrPolynomial\n //---------------------------------------------------------------------\n\n function qrPolynomial(num, shift) {\n\n if (typeof num.length == 'undefined') {\n throw num.length + '/' + shift;\n }\n\n var _num = function() {\n var offset = 0;\n while (offset < num.length && num[offset] == 0) {\n offset += 1;\n }\n var _num = new Array(num.length - offset + shift);\n for (var i = 0; i < num.length - offset; i += 1) {\n _num[i] = num[i + offset];\n }\n return _num;\n }();\n\n var _this = {};\n\n _this.getAt = function(index) {\n return _num[index];\n };\n\n _this.getLength = function() {\n return _num.length;\n };\n\n _this.multiply = function(e) {\n\n var num = new Array(_this.getLength() + e.getLength() - 1);\n\n for (var i = 0; i < _this.getLength(); i += 1) {\n for (var j = 0; j < e.getLength(); j += 1) {\n num[i + j] ^= QRMath.gexp(QRMath.glog(_this.getAt(i) ) + QRMath.glog(e.getAt(j) ) );\n }\n }\n\n return qrPolynomial(num, 0);\n };\n\n _this.mod = function(e) {\n\n if (_this.getLength() - e.getLength() < 0) {\n return _this;\n }\n\n var ratio = QRMath.glog(_this.getAt(0) ) - QRMath.glog(e.getAt(0) );\n\n var num = new Array(_this.getLength() );\n for (var i = 0; i < _this.getLength(); i += 1) {\n num[i] = _this.getAt(i);\n }\n\n for (var i = 0; i < e.getLength(); i += 1) {\n num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i) ) + ratio);\n }\n\n // recursive call\n return qrPolynomial(num, 0).mod(e);\n };\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // QRRSBlock\n //---------------------------------------------------------------------\n\n var QRRSBlock = function() {\n\n var RS_BLOCK_TABLE = [\n\n // L\n // M\n // Q\n // H\n\n // 1\n [1, 26, 19],\n [1, 26, 16],\n [1, 26, 13],\n [1, 26, 9],\n\n // 2\n [1, 44, 34],\n [1, 44, 28],\n [1, 44, 22],\n [1, 44, 16],\n\n // 3\n [1, 70, 55],\n [1, 70, 44],\n [2, 35, 17],\n [2, 35, 13],\n\n // 4\n [1, 100, 80],\n [2, 50, 32],\n [2, 50, 24],\n [4, 25, 9],\n\n // 5\n [1, 134, 108],\n [2, 67, 43],\n [2, 33, 15, 2, 34, 16],\n [2, 33, 11, 2, 34, 12],\n\n // 6\n [2, 86, 68],\n [4, 43, 27],\n [4, 43, 19],\n [4, 43, 15],\n\n // 7\n [2, 98, 78],\n [4, 49, 31],\n [2, 32, 14, 4, 33, 15],\n [4, 39, 13, 1, 40, 14],\n\n // 8\n [2, 121, 97],\n [2, 60, 38, 2, 61, 39],\n [4, 40, 18, 2, 41, 19],\n [4, 40, 14, 2, 41, 15],\n\n // 9\n [2, 146, 116],\n [3, 58, 36, 2, 59, 37],\n [4, 36, 16, 4, 37, 17],\n [4, 36, 12, 4, 37, 13],\n\n // 10\n [2, 86, 68, 2, 87, 69],\n [4, 69, 43, 1, 70, 44],\n [6, 43, 19, 2, 44, 20],\n [6, 43, 15, 2, 44, 16],\n\n // 11\n [4, 101, 81],\n [1, 80, 50, 4, 81, 51],\n [4, 50, 22, 4, 51, 23],\n [3, 36, 12, 8, 37, 13],\n\n // 12\n [2, 116, 92, 2, 117, 93],\n [6, 58, 36, 2, 59, 37],\n [4, 46, 20, 6, 47, 21],\n [7, 42, 14, 4, 43, 15],\n\n // 13\n [4, 133, 107],\n [8, 59, 37, 1, 60, 38],\n [8, 44, 20, 4, 45, 21],\n [12, 33, 11, 4, 34, 12],\n\n // 14\n [3, 145, 115, 1, 146, 116],\n [4, 64, 40, 5, 65, 41],\n [11, 36, 16, 5, 37, 17],\n [11, 36, 12, 5, 37, 13],\n\n // 15\n [5, 109, 87, 1, 110, 88],\n [5, 65, 41, 5, 66, 42],\n [5, 54, 24, 7, 55, 25],\n [11, 36, 12, 7, 37, 13],\n\n // 16\n [5, 122, 98, 1, 123, 99],\n [7, 73, 45, 3, 74, 46],\n [15, 43, 19, 2, 44, 20],\n [3, 45, 15, 13, 46, 16],\n\n // 17\n [1, 135, 107, 5, 136, 108],\n [10, 74, 46, 1, 75, 47],\n [1, 50, 22, 15, 51, 23],\n [2, 42, 14, 17, 43, 15],\n\n // 18\n [5, 150, 120, 1, 151, 121],\n [9, 69, 43, 4, 70, 44],\n [17, 50, 22, 1, 51, 23],\n [2, 42, 14, 19, 43, 15],\n\n // 19\n [3, 141, 113, 4, 142, 114],\n [3, 70, 44, 11, 71, 45],\n [17, 47, 21, 4, 48, 22],\n [9, 39, 13, 16, 40, 14],\n\n // 20\n [3, 135, 107, 5, 136, 108],\n [3, 67, 41, 13, 68, 42],\n [15, 54, 24, 5, 55, 25],\n [15, 43, 15, 10, 44, 16],\n\n // 21\n [4, 144, 116, 4, 145, 117],\n [17, 68, 42],\n [17, 50, 22, 6, 51, 23],\n [19, 46, 16, 6, 47, 17],\n\n // 22\n [2, 139, 111, 7, 140, 112],\n [17, 74, 46],\n [7, 54, 24, 16, 55, 25],\n [34, 37, 13],\n\n // 23\n [4, 151, 121, 5, 152, 122],\n [4, 75, 47, 14, 76, 48],\n [11, 54, 24, 14, 55, 25],\n [16, 45, 15, 14, 46, 16],\n\n // 24\n [6, 147, 117, 4, 148, 118],\n [6, 73, 45, 14, 74, 46],\n [11, 54, 24, 16, 55, 25],\n [30, 46, 16, 2, 47, 17],\n\n // 25\n [8, 132, 106, 4, 133, 107],\n [8, 75, 47, 13, 76, 48],\n [7, 54, 24, 22, 55, 25],\n [22, 45, 15, 13, 46, 16],\n\n // 26\n [10, 142, 114, 2, 143, 115],\n [19, 74, 46, 4, 75, 47],\n [28, 50, 22, 6, 51, 23],\n [33, 46, 16, 4, 47, 17],\n\n // 27\n [8, 152, 122, 4, 153, 123],\n [22, 73, 45, 3, 74, 46],\n [8, 53, 23, 26, 54, 24],\n [12, 45, 15, 28, 46, 16],\n\n // 28\n [3, 147, 117, 10, 148, 118],\n [3, 73, 45, 23, 74, 46],\n [4, 54, 24, 31, 55, 25],\n [11, 45, 15, 31, 46, 16],\n\n // 29\n [7, 146, 116, 7, 147, 117],\n [21, 73, 45, 7, 74, 46],\n [1, 53, 23, 37, 54, 24],\n [19, 45, 15, 26, 46, 16],\n\n // 30\n [5, 145, 115, 10, 146, 116],\n [19, 75, 47, 10, 76, 48],\n [15, 54, 24, 25, 55, 25],\n [23, 45, 15, 25, 46, 16],\n\n // 31\n [13, 145, 115, 3, 146, 116],\n [2, 74, 46, 29, 75, 47],\n [42, 54, 24, 1, 55, 25],\n [23, 45, 15, 28, 46, 16],\n\n // 32\n [17, 145, 115],\n [10, 74, 46, 23, 75, 47],\n [10, 54, 24, 35, 55, 25],\n [19, 45, 15, 35, 46, 16],\n\n // 33\n [17, 145, 115, 1, 146, 116],\n [14, 74, 46, 21, 75, 47],\n [29, 54, 24, 19, 55, 25],\n [11, 45, 15, 46, 46, 16],\n\n // 34\n [13, 145, 115, 6, 146, 116],\n [14, 74, 46, 23, 75, 47],\n [44, 54, 24, 7, 55, 25],\n [59, 46, 16, 1, 47, 17],\n\n // 35\n [12, 151, 121, 7, 152, 122],\n [12, 75, 47, 26, 76, 48],\n [39, 54, 24, 14, 55, 25],\n [22, 45, 15, 41, 46, 16],\n\n // 36\n [6, 151, 121, 14, 152, 122],\n [6, 75, 47, 34, 76, 48],\n [46, 54, 24, 10, 55, 25],\n [2, 45, 15, 64, 46, 16],\n\n // 37\n [17, 152, 122, 4, 153, 123],\n [29, 74, 46, 14, 75, 47],\n [49, 54, 24, 10, 55, 25],\n [24, 45, 15, 46, 46, 16],\n\n // 38\n [4, 152, 122, 18, 153, 123],\n [13, 74, 46, 32, 75, 47],\n [48, 54, 24, 14, 55, 25],\n [42, 45, 15, 32, 46, 16],\n\n // 39\n [20, 147, 117, 4, 148, 118],\n [40, 75, 47, 7, 76, 48],\n [43, 54, 24, 22, 55, 25],\n [10, 45, 15, 67, 46, 16],\n\n // 40\n [19, 148, 118, 6, 149, 119],\n [18, 75, 47, 31, 76, 48],\n [34, 54, 24, 34, 55, 25],\n [20, 45, 15, 61, 46, 16]\n ];\n\n var qrRSBlock = function(totalCount, dataCount) {\n var _this = {};\n _this.totalCount = totalCount;\n _this.dataCount = dataCount;\n return _this;\n };\n\n var _this = {};\n\n var getRsBlockTable = function(typeNumber, errorCorrectionLevel) {\n\n switch(errorCorrectionLevel) {\n case QRErrorCorrectionLevel.L :\n return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];\n case QRErrorCorrectionLevel.M :\n return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];\n case QRErrorCorrectionLevel.Q :\n return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];\n case QRErrorCorrectionLevel.H :\n return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];\n default :\n return undefined;\n }\n };\n\n _this.getRSBlocks = function(typeNumber, errorCorrectionLevel) {\n\n var rsBlock = getRsBlockTable(typeNumber, errorCorrectionLevel);\n\n if (typeof rsBlock == 'undefined') {\n throw 'bad rs block @ typeNumber:' + typeNumber +\n '/errorCorrectionLevel:' + errorCorrectionLevel;\n }\n\n var length = rsBlock.length / 3;\n\n var list = [];\n\n for (var i = 0; i < length; i += 1) {\n\n var count = rsBlock[i * 3 + 0];\n var totalCount = rsBlock[i * 3 + 1];\n var dataCount = rsBlock[i * 3 + 2];\n\n for (var j = 0; j < count; j += 1) {\n list.push(qrRSBlock(totalCount, dataCount) );\n }\n }\n\n return list;\n };\n\n return _this;\n }();\n\n //---------------------------------------------------------------------\n // qrBitBuffer\n //---------------------------------------------------------------------\n\n var qrBitBuffer = function() {\n\n var _buffer = [];\n var _length = 0;\n\n var _this = {};\n\n _this.getBuffer = function() {\n return _buffer;\n };\n\n _this.getAt = function(index) {\n var bufIndex = Math.floor(index / 8);\n return ( (_buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;\n };\n\n _this.put = function(num, length) {\n for (var i = 0; i < length; i += 1) {\n _this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);\n }\n };\n\n _this.getLengthInBits = function() {\n return _length;\n };\n\n _this.putBit = function(bit) {\n\n var bufIndex = Math.floor(_length / 8);\n if (_buffer.length <= bufIndex) {\n _buffer.push(0);\n }\n\n if (bit) {\n _buffer[bufIndex] |= (0x80 >>> (_length % 8) );\n }\n\n _length += 1;\n };\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // qrNumber\n //---------------------------------------------------------------------\n\n var qrNumber = function(data) {\n\n var _mode = QRMode.MODE_NUMBER;\n var _data = data;\n\n var _this = {};\n\n _this.getMode = function() {\n return _mode;\n };\n\n _this.getLength = function(buffer) {\n return _data.length;\n };\n\n _this.write = function(buffer) {\n\n var data = _data;\n\n var i = 0;\n\n while (i + 2 < data.length) {\n buffer.put(strToNum(data.substring(i, i + 3) ), 10);\n i += 3;\n }\n\n if (i < data.length) {\n if (data.length - i == 1) {\n buffer.put(strToNum(data.substring(i, i + 1) ), 4);\n } else if (data.length - i == 2) {\n buffer.put(strToNum(data.substring(i, i + 2) ), 7);\n }\n }\n };\n\n var strToNum = function(s) {\n var num = 0;\n for (var i = 0; i < s.length; i += 1) {\n num = num * 10 + chatToNum(s.charAt(i) );\n }\n return num;\n };\n\n var chatToNum = function(c) {\n if ('0' <= c && c <= '9') {\n return c.charCodeAt(0) - '0'.charCodeAt(0);\n }\n throw 'illegal char :' + c;\n };\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // qrAlphaNum\n //---------------------------------------------------------------------\n\n var qrAlphaNum = function(data) {\n\n var _mode = QRMode.MODE_ALPHA_NUM;\n var _data = data;\n\n var _this = {};\n\n _this.getMode = function() {\n return _mode;\n };\n\n _this.getLength = function(buffer) {\n return _data.length;\n };\n\n _this.write = function(buffer) {\n\n var s = _data;\n\n var i = 0;\n\n while (i + 1 < s.length) {\n buffer.put(\n getCode(s.charAt(i) ) * 45 +\n getCode(s.charAt(i + 1) ), 11);\n i += 2;\n }\n\n if (i < s.length) {\n buffer.put(getCode(s.charAt(i) ), 6);\n }\n };\n\n var getCode = function(c) {\n\n if ('0' <= c && c <= '9') {\n return c.charCodeAt(0) - '0'.charCodeAt(0);\n } else if ('A' <= c && c <= 'Z') {\n return c.charCodeAt(0) - 'A'.charCodeAt(0) + 10;\n } else {\n switch (c) {\n case ' ' : return 36;\n case '$' : return 37;\n case '%' : return 38;\n case '*' : return 39;\n case '+' : return 40;\n case '-' : return 41;\n case '.' : return 42;\n case '/' : return 43;\n case ':' : return 44;\n default :\n throw 'illegal char :' + c;\n }\n }\n };\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // qr8BitByte\n //---------------------------------------------------------------------\n\n var qr8BitByte = function(data) {\n\n var _mode = QRMode.MODE_8BIT_BYTE;\n var _data = data;\n var _bytes = qrcode.stringToBytes(data);\n\n var _this = {};\n\n _this.getMode = function() {\n return _mode;\n };\n\n _this.getLength = function(buffer) {\n return _bytes.length;\n };\n\n _this.write = function(buffer) {\n for (var i = 0; i < _bytes.length; i += 1) {\n buffer.put(_bytes[i], 8);\n }\n };\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // qrKanji\n //---------------------------------------------------------------------\n\n var qrKanji = function(data) {\n\n var _mode = QRMode.MODE_KANJI;\n var _data = data;\n\n var stringToBytes = qrcode.stringToBytesFuncs['SJIS'];\n if (!stringToBytes) {\n throw 'sjis not supported.';\n }\n !function(c, code) {\n // self test for sjis support.\n var test = stringToBytes(c);\n if (test.length != 2 || ( (test[0] << 8) | test[1]) != code) {\n throw 'sjis not supported.';\n }\n }('\\u53cb', 0x9746);\n\n var _bytes = stringToBytes(data);\n\n var _this = {};\n\n _this.getMode = function() {\n return _mode;\n };\n\n _this.getLength = function(buffer) {\n return ~~(_bytes.length / 2);\n };\n\n _this.write = function(buffer) {\n\n var data = _bytes;\n\n var i = 0;\n\n while (i + 1 < data.length) {\n\n var c = ( (0xff & data[i]) << 8) | (0xff & data[i + 1]);\n\n if (0x8140 <= c && c <= 0x9FFC) {\n c -= 0x8140;\n } else if (0xE040 <= c && c <= 0xEBBF) {\n c -= 0xC140;\n } else {\n throw 'illegal char at ' + (i + 1) + '/' + c;\n }\n\n c = ( (c >>> 8) & 0xff) * 0xC0 + (c & 0xff);\n\n buffer.put(c, 13);\n\n i += 2;\n }\n\n if (i < data.length) {\n throw 'illegal char at ' + (i + 1);\n }\n };\n\n return _this;\n };\n\n //=====================================================================\n // GIF Support etc.\n //\n\n //---------------------------------------------------------------------\n // byteArrayOutputStream\n //---------------------------------------------------------------------\n\n var byteArrayOutputStream = function() {\n\n var _bytes = [];\n\n var _this = {};\n\n _this.writeByte = function(b) {\n _bytes.push(b & 0xff);\n };\n\n _this.writeShort = function(i) {\n _this.writeByte(i);\n _this.writeByte(i >>> 8);\n };\n\n _this.writeBytes = function(b, off, len) {\n off = off || 0;\n len = len || b.length;\n for (var i = 0; i < len; i += 1) {\n _this.writeByte(b[i + off]);\n }\n };\n\n _this.writeString = function(s) {\n for (var i = 0; i < s.length; i += 1) {\n _this.writeByte(s.charCodeAt(i) );\n }\n };\n\n _this.toByteArray = function() {\n return _bytes;\n };\n\n _this.toString = function() {\n var s = '';\n s += '[';\n for (var i = 0; i < _bytes.length; i += 1) {\n if (i > 0) {\n s += ',';\n }\n s += _bytes[i];\n }\n s += ']';\n return s;\n };\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // base64EncodeOutputStream\n //---------------------------------------------------------------------\n\n var base64EncodeOutputStream = function() {\n\n var _buffer = 0;\n var _buflen = 0;\n var _length = 0;\n var _base64 = '';\n\n var _this = {};\n\n var writeEncoded = function(b) {\n _base64 += String.fromCharCode(encode(b & 0x3f) );\n };\n\n var encode = function(n) {\n if (n < 0) {\n // error.\n } else if (n < 26) {\n return 0x41 + n;\n } else if (n < 52) {\n return 0x61 + (n - 26);\n } else if (n < 62) {\n return 0x30 + (n - 52);\n } else if (n == 62) {\n return 0x2b;\n } else if (n == 63) {\n return 0x2f;\n }\n throw 'n:' + n;\n };\n\n _this.writeByte = function(n) {\n\n _buffer = (_buffer << 8) | (n & 0xff);\n _buflen += 8;\n _length += 1;\n\n while (_buflen >= 6) {\n writeEncoded(_buffer >>> (_buflen - 6) );\n _buflen -= 6;\n }\n };\n\n _this.flush = function() {\n\n if (_buflen > 0) {\n writeEncoded(_buffer << (6 - _buflen) );\n _buffer = 0;\n _buflen = 0;\n }\n\n if (_length % 3 != 0) {\n // padding\n var padlen = 3 - _length % 3;\n for (var i = 0; i < padlen; i += 1) {\n _base64 += '=';\n }\n }\n };\n\n _this.toString = function() {\n return _base64;\n };\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // base64DecodeInputStream\n //---------------------------------------------------------------------\n\n var base64DecodeInputStream = function(str) {\n\n var _str = str;\n var _pos = 0;\n var _buffer = 0;\n var _buflen = 0;\n\n var _this = {};\n\n _this.read = function() {\n\n while (_buflen < 8) {\n\n if (_pos >= _str.length) {\n if (_buflen == 0) {\n return -1;\n }\n throw 'unexpected end of file./' + _buflen;\n }\n\n var c = _str.charAt(_pos);\n _pos += 1;\n\n if (c == '=') {\n _buflen = 0;\n return -1;\n } else if (c.match(/^\\s$/) ) {\n // ignore if whitespace.\n continue;\n }\n\n _buffer = (_buffer << 6) | decode(c.charCodeAt(0) );\n _buflen += 6;\n }\n\n var n = (_buffer >>> (_buflen - 8) ) & 0xff;\n _buflen -= 8;\n return n;\n };\n\n var decode = function(c) {\n if (0x41 <= c && c <= 0x5a) {\n return c - 0x41;\n } else if (0x61 <= c && c <= 0x7a) {\n return c - 0x61 + 26;\n } else if (0x30 <= c && c <= 0x39) {\n return c - 0x30 + 52;\n } else if (c == 0x2b) {\n return 62;\n } else if (c == 0x2f) {\n return 63;\n } else {\n throw 'c:' + c;\n }\n };\n\n return _this;\n };\n\n //---------------------------------------------------------------------\n // gifImage (B/W)\n //---------------------------------------------------------------------\n\n var gifImage = function(width, height) {\n\n var _width = width;\n var _height = height;\n var _data = new Array(width * height);\n\n var _this = {};\n\n _this.setPixel = function(x, y, pixel) {\n _data[y * _width + x] = pixel;\n };\n\n _this.write = function(out) {\n\n //---------------------------------\n // GIF Signature\n\n out.writeString('GIF87a');\n\n //---------------------------------\n // Screen Descriptor\n\n out.writeShort(_width);\n out.writeShort(_height);\n\n out.writeByte(0x80); // 2bit\n out.writeByte(0);\n out.writeByte(0);\n\n //---------------------------------\n // Global Color Map\n\n // black\n out.writeByte(0x00);\n out.writeByte(0x00);\n out.writeByte(0x00);\n\n // white\n out.writeByte(0xff);\n out.writeByte(0xff);\n out.writeByte(0xff);\n\n //---------------------------------\n // Image Descriptor\n\n out.writeString(',');\n out.writeShort(0);\n out.writeShort(0);\n out.writeShort(_width);\n out.writeShort(_height);\n out.writeByte(0);\n\n //---------------------------------\n // Local Color Map\n\n //---------------------------------\n // Raster Data\n\n var lzwMinCodeSize = 2;\n var raster = getLZWRaster(lzwMinCodeSize);\n\n out.writeByte(lzwMinCodeSize);\n\n var offset = 0;\n\n while (raster.length - offset > 255) {\n out.writeByte(255);\n out.writeBytes(raster, offset, 255);\n offset += 255;\n }\n\n out.writeByte(raster.length - offset);\n out.writeBytes(raster, offset, raster.length - offset);\n out.writeByte(0x00);\n\n //---------------------------------\n // GIF Terminator\n out.writeString(';');\n };\n\n var bitOutputStream = function(out) {\n\n var _out = out;\n var _bitLength = 0;\n var _bitBuffer = 0;\n\n var _this = {};\n\n _this.write = function(data, length) {\n\n if ( (data >>> length) != 0) {\n throw 'length over';\n }\n\n while (_bitLength + length >= 8) {\n _out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) );\n length -= (8 - _bitLength);\n data >>>= (8 - _bitLength);\n _bitBuffer = 0;\n _bitLength = 0;\n }\n\n _bitBuffer = (data << _bitLength) | _bitBuffer;\n _bitLength = _bitLength + length;\n };\n\n _this.flush = function() {\n if (_bitLength > 0) {\n _out.writeByte(_bitBuffer);\n }\n };\n\n return _this;\n };\n\n var getLZWRaster = function(lzwMinCodeSize) {\n\n var clearCode = 1 << lzwMinCodeSize;\n var endCode = (1 << lzwMinCodeSize) + 1;\n var bitLength = lzwMinCodeSize + 1;\n\n // Setup LZWTable\n var table = lzwTable();\n\n for (var i = 0; i < clearCode; i += 1) {\n table.add(String.fromCharCode(i) );\n }\n table.add(String.fromCharCode(clearCode) );\n table.add(String.fromCharCode(endCode) );\n\n var byteOut = byteArrayOutputStream();\n var bitOut = bitOutputStream(byteOut);\n\n // clear code\n bitOut.write(clearCode, bitLength);\n\n var dataIndex = 0;\n\n var s = String.fromCharCode(_data[dataIndex]);\n dataIndex += 1;\n\n while (dataIndex < _data.length) {\n\n var c = String.fromCharCode(_data[dataIndex]);\n dataIndex += 1;\n\n if (table.contains(s + c) ) {\n\n s = s + c;\n\n } else {\n\n bitOut.write(table.indexOf(s), bitLength);\n\n if (table.size() < 0xfff) {\n\n if (table.size() == (1 << bitLength) ) {\n bitLength += 1;\n }\n\n table.add(s + c);\n }\n\n s = c;\n }\n }\n\n bitOut.write(table.indexOf(s), bitLength);\n\n // end code\n bitOut.write(endCode, bitLength);\n\n bitOut.flush();\n\n return byteOut.toByteArray();\n };\n\n var lzwTable = function() {\n\n var _map = {};\n var _size = 0;\n\n var _this = {};\n\n _this.add = function(key) {\n if (_this.contains(key) ) {\n throw 'dup key:' + key;\n }\n _map[key] = _size;\n _size += 1;\n };\n\n _this.size = function() {\n return _size;\n };\n\n _this.indexOf = function(key) {\n return _map[key];\n };\n\n _this.contains = function(key) {\n return typeof _map[key] != 'undefined';\n };\n\n return _this;\n };\n\n return _this;\n };\n\n var createDataURL = function(width, height, getPixel) {\n var gif = gifImage(width, height);\n for (var y = 0; y < height; y += 1) {\n for (var x = 0; x < width; x += 1) {\n gif.setPixel(x, y, getPixel(x, y) );\n }\n }\n\n var b = byteArrayOutputStream();\n gif.write(b);\n\n var base64 = base64EncodeOutputStream();\n var bytes = b.toByteArray();\n for (var i = 0; i < bytes.length; i += 1) {\n base64.writeByte(bytes[i]);\n }\n base64.flush();\n\n return 'data:image/gif;base64,' + base64;\n };\n\n //---------------------------------------------------------------------\n // returns qrcode function.\n\n return qrcode;\n}();\n\n// multibyte support\n!function() {\n\n qrcode.stringToBytesFuncs['UTF-8'] = function(s) {\n // http://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array\n function toUTF8Array(str) {\n var utf8 = [];\n for (var i=0; i < str.length; i++) {\n var charcode = str.charCodeAt(i);\n if (charcode < 0x80) utf8.push(charcode);\n else if (charcode < 0x800) {\n utf8.push(0xc0 | (charcode >> 6),\n 0x80 | (charcode & 0x3f));\n }\n else if (charcode < 0xd800 || charcode >= 0xe000) {\n utf8.push(0xe0 | (charcode >> 12),\n 0x80 | ((charcode>>6) & 0x3f),\n 0x80 | (charcode & 0x3f));\n }\n // surrogate pair\n else {\n i++;\n // UTF-16 encodes 0x10000-0x10FFFF by\n // subtracting 0x10000 and splitting the\n // 20 bits of 0x0-0xFFFFF into two halves\n charcode = 0x10000 + (((charcode & 0x3ff)<<10)\n | (str.charCodeAt(i) & 0x3ff));\n utf8.push(0xf0 | (charcode >>18),\n 0x80 | ((charcode>>12) & 0x3f),\n 0x80 | ((charcode>>6) & 0x3f),\n 0x80 | (charcode & 0x3f));\n }\n }\n return utf8;\n }\n return toUTF8Array(s);\n };\n\n}();\n\n(function (factory) {\n if (typeof define === 'function' && define.amd) {\n define([], factory);\n } else if (typeof exports === 'object') {\n module.exports = factory();\n }\n}(function () {\n return qrcode;\n}));\n","import qrcode from 'qrcode-generator'\n\n/**\n * Encode `text` as a QR code and return a self-contained, scalable SVG string\n * (black modules on white) suitable for injecting via `innerHTML`. Type number 0\n * auto-sizes to the data; error-correction level \"M\" tolerates camera noise while\n * keeping the code dense enough to scan from a screen.\n */\nexport function renderQrSvg(text: string): string {\n const qr = qrcode(0, 'M')\n qr.addData(text)\n qr.make()\n return qr.createSvgTag({ cellSize: 6, margin: 4, scalable: true })\n}\n","import type {\n DocumentType,\n LivenessChallenge,\n LivenessMode,\n SessionTransitionEvent,\n VerificationStatus,\n WidgetResult,\n WidgetStep,\n WorkflowConfig,\n} from '@arkyc/types'\nimport { REALTIME_EVENT, workflowAddressConfig } from '@arkyc/types'\nimport { ArkycClient, type ClientHandoff, type ClientRealtime, type ClientSession, WidgetApiError } from './client'\nimport { Flow } from './flow'\nimport { Theme } from './theme'\nimport { WidgetView, type AddressFormData } from './ui'\nimport { isDesktopDevice } from './device'\nimport { renderQrSvg } from './qr'\nimport { createWidgetRealtimeClient, type WidgetRealtimeClient } from './realtime'\nimport type { BaseWidgetOptions, ViewHandlers, WidgetControllerConfig, WidgetEventListener } from './types'\n\n/** Per-step lead-in copy shown before each capture/liveness step. */\nconst STEP_INSTRUCTIONS: Partial<Record<WidgetStep, { title: string; body: string; cta?: string }>> = {\n front_capture: {\n title: 'Front of your document',\n body: 'Place the front of your ID flat and fully inside the frame. We’ll capture it automatically.',\n },\n back_capture: {\n title: 'Back of your document',\n body: 'Now turn your ID over and show the back, fully inside the frame.',\n },\n selfie_capture: {\n title: 'Take a selfie',\n body: 'Look straight at the camera in good light and hold still — we’ll capture it automatically.',\n },\n active_liveness: {\n title: 'Quick liveness check',\n body: 'Follow the on-screen prompts (such as turn your head, blink or smile). This confirms you’re really here.',\n },\n}\n\n/**\n * Drives the full verification flow: renders each screen via {@link WidgetView},\n * advances through {@link flow}, and calls the Client API at each step. Cosmetic\n * processing screens auto-advance; capture screens wait for an image. On a\n * terminal result it surfaces the outcome and (in hosted mode) posts\n * `arkyc:complete` / `arkyc:error` / `arkyc:close` to the parent window.\n */\n/**\n * Re-base the server-resolved project logo onto the API origin the widget is\n * actually talking to. The stored `logo_url` carries the API's own host, which a\n * handed-off phone cannot reach — it reaches the API through the absolute\n * `baseUrl` passed in the handoff link. Rewriting the origin (keeping the path)\n * makes the logo load on whatever device runs the widget. Only applied when\n * `baseUrl` is absolute; the integrator's own branding is never re-based.\n */\nfunction rebaseBrandingLogo<T extends { logo_url?: string | null }>(branding: T, baseUrl: string | undefined): T {\n const logo = branding.logo_url\n if (!logo || !baseUrl || !/^https?:\\/\\//i.test(baseUrl)) return branding\n try {\n const base = new URL(baseUrl)\n const resolved = new URL(logo, base)\n if (resolved.origin === base.origin) return branding\n return { ...branding, logo_url: `${base.origin}${resolved.pathname}${resolved.search}${resolved.hash}` }\n } catch {\n return branding\n }\n}\n\nexport class WidgetController {\n private readonly client: ArkycClient\n private readonly view: WidgetView\n private readonly win: Window\n private readonly nav: Navigator\n private readonly postToParent: boolean\n private readonly scheduler: (fn: () => void, ms: number) => void\n private readonly transientMs: number\n private readonly pollMs: number\n private readonly maxPolls: number\n private readonly maxHandoffPolls: number\n\n /** Cross-device handoff: project config + whether the offer/QR is showing. */\n private handoffConfig: ClientHandoff = { enabled: false, allow_desktop: true, url: '' }\n private handoffReady = false\n private handoffActive = false\n\n /** This session's id + how to watch it live (push transport vs. polling). */\n private sessionId = ''\n private realtimeConfig: ClientRealtime | null = null\n private rtClient: WidgetRealtimeClient | null = null\n private rtResolved = false\n /** The last status observed, so a transition only emits once per change. */\n private lastStatus: VerificationStatus | null = null\n /** Per-name event listeners registered via {@link on}. */\n private listeners = new Map<string, Set<WidgetEventListener>>()\n /** Cancels the active session watch (e.g. continue-on-this-device). */\n private stopWatch: (() => void) | undefined\n\n private step: WidgetStep = 'welcome'\n private documentType: DocumentType | null = null\n private country: string | null = null\n private selfie: Blob | null = null\n private livenessMode: LivenessMode = 'passive'\n /** The session's capture model; `active` mandates a live camera (no fallback). */\n private captureModel: 'passive' | 'active' | 'both' = 'passive'\n private livenessChallenges: LivenessChallenge[] = []\n /** The address-entry form data, captured before the address submission. */\n private addressData: AddressFormData | null = null\n /** Device coordinates resolved on the address step (when the user opts in). */\n private addressCoords: { latitude: number; longitude: number } | null = null\n /** The applied workflow (orders/toggles stages, skip_ocr), or null for the default flow. */\n private workflow: WorkflowConfig | null = null\n private result: WidgetResult | null = null\n /** The session was already terminal when the widget loaded (show a close-only notice). */\n private terminalOnLoad = false\n /** Whether the current step's instruction interstitial has been acknowledged. */\n private instructionAcked = false\n private pendingError: Error | null = null\n private settled = false\n\n constructor(private readonly config: WidgetControllerConfig) {\n const doc = config.doc ?? globalThis.document\n const win = config.win ?? globalThis.window\n if (!doc || !win) throw new Error('The Arkyc widget must run in a browser environment.')\n this.win = win\n this.nav = config.nav ?? globalThis.navigator\n\n this.client = new ArkycClient({\n token: config.token,\n baseUrl: config.baseUrl,\n fetch: config.fetch,\n })\n const theme = new Theme(config.branding)\n this.view = new WidgetView(\n doc,\n theme,\n this.handlers(),\n config.nav ?? globalThis.navigator,\n config.faceAnalyzer,\n config.faceTuning,\n config.documentAnalyzer,\n config.documentTuning,\n )\n\n this.postToParent = config.postToParent ?? (!!win.parent && win.parent !== win)\n this.scheduler = config.scheduler ?? ((fn, ms) => setTimeout(fn, ms))\n this.transientMs = config.transientMs ?? 700\n this.pollMs = config.pollMs ?? 1500\n this.maxPolls = config.maxPolls ?? 40\n // A handed-off session is bounded by its TTL (~15 min); poll generously.\n this.maxHandoffPolls = config.maxHandoffPolls ?? 600\n }\n\n /** The widget's root element — append it to an overlay or inline container. */\n get element(): HTMLElement {\n return this.view.element\n }\n\n /** Connect to the session, then route to the result, the QR, or the welcome flow. */\n start(): void {\n this.view.renderLoading()\n void this.run(() => this.bootstrap())\n }\n\n /** Tear down the view and release the camera (does not fire callbacks). */\n destroy(): void {\n this.view.destroy()\n }\n\n /** Close the widget as if the user dismissed it (fires `onClose`/`onSettle`). */\n close(): void {\n this.finishClose()\n }\n\n /**\n * Subscribe to a named widget event; returns an unsubscribe function. Having a\n * listener (here or via `onEvent`) is what activates the event stream.\n */\n on(event: string, listener: WidgetEventListener): () => void {\n const set = this.listeners.get(event) ?? new Set<WidgetEventListener>()\n set.add(listener)\n this.listeners.set(event, set)\n\n return () => set.delete(listener)\n }\n\n /** Whether anyone is listening for `name` (the firehose or a named listener). */\n private hasListener(name: string): boolean {\n if (this.config.onEvent) return true\n const set = this.listeners.get(name)\n\n return !!set && set.size > 0\n }\n\n /**\n * Surface an event: to local listeners (firehose + `on`), and — in hosted\n * iframe mode — to the embedding parent as `arkyc:event` so the SDK's\n * `handle.on(...)` works across the frame.\n */\n private dispatch(name: string, data?: unknown): void {\n this.emit(name, data)\n // The parent window is the consumer in iframe mode, so forwarding there isn't\n // gated on a local listener (post() already no-ops when not embedding).\n this.post('arkyc:event', { name, data })\n }\n\n /** Emit an event to the firehose + named listeners — but only if one is active. */\n private emit(name: string, data?: unknown): void {\n if (!this.hasListener(name)) return\n try {\n this.config.onEvent?.({ name, data })\n } catch {\n // A consumer callback threw — never let it break the flow.\n }\n const set = this.listeners.get(name)\n if (set) {\n for (const listener of [...set]) {\n try {\n listener(data)\n } catch {\n // ditto\n }\n }\n }\n }\n\n /** Record an observed status, emitting `session.transition` on a real change. */\n private observe(status: VerificationStatus): void {\n if (status === this.lastStatus) return\n const previous = this.lastStatus\n this.lastStatus = status\n this.dispatch(REALTIME_EVENT.sessionTransition, {\n session_id: this.sessionId,\n status,\n previous_status: previous,\n } satisfies Partial<SessionTransitionEvent>)\n }\n\n /**\n * Lazily connect the push transport for this session (once). Returns null for\n * `polling`/`off`/`memory` or when the transport SDK can't load — the caller\n * then polls instead.\n */\n private async resolveRealtime(): Promise<WidgetRealtimeClient | null> {\n if (this.rtResolved) return this.rtClient\n this.rtResolved = true\n const cfg = this.realtimeConfig\n if (!cfg || cfg.transport === 'polling' || cfg.transport === 'off' || cfg.transport === 'memory') return null\n\n const factory = this.config.realtimeFactory ?? createWidgetRealtimeClient\n const apiBase = (this.config.baseUrl ?? '').replace(/\\/$/, '')\n try {\n this.rtClient = await factory(cfg, {\n authEndpoint: `${apiBase}/v1/client/realtime/auth`,\n token: this.config.token,\n })\n } catch {\n this.rtClient = null\n }\n\n return this.rtClient\n }\n\n private handlers(): ViewHandlers {\n return {\n onClose: () => this.finishClose(),\n // The session was already fetched + resolved during bootstrap; just advance.\n onStart: () => void this.run(() => this.enter(this.next())),\n onDocumentSelected: (type, country) => {\n this.documentType = type\n this.country = country || null\n void this.run(() => this.enter('front_capture'))\n },\n onImage: (blob) => void this.run(() => this.onImage(blob)),\n onActiveLiveness: (video, performed, selfie) =>\n void this.run(async () => {\n await this.client.submitLiveness({\n selfie,\n video,\n mode: 'active',\n challenges: performed,\n signals: this.config.signals,\n })\n await this.enter(this.next())\n }),\n onAddress: (data) => void this.run(() => this.onAddress(data)),\n onShareLocation: () => this.shareLocation(),\n onAcknowledge: () => this.finishResult(),\n onUsePhone: () => void this.run(() => this.startHandoff()),\n onContinueHere: () => {\n this.handoffActive = false\n this.stopWatch?.()\n this.step = 'welcome'\n this.render()\n },\n }\n }\n\n /**\n * Fetch the session and route: an already-terminal session (e.g. a stale handoff\n * link, or one finished on another device) shows a close-only notice; on a\n * desktop with handoff enabled we lead with the QR; otherwise the welcome flow.\n */\n private async bootstrap(): Promise<void> {\n if (this.settled) return\n const session = await this.client.getSession()\n if (this.settled) return\n this.sessionId = session.id\n this.realtimeConfig = session.realtime ?? null\n this.workflow = session.workflow ?? null\n // Theme from the project's branding (server-resolved) unless the integrator\n // passed branding explicitly — their value wins.\n if (this.config.branding == null && session.branding)\n this.view.applyBranding(rebaseBrandingLogo(session.branding, this.config.baseUrl))\n this.observe(session.status)\n if (Flow.isTerminal(session.status)) return this.showTerminal(session.status)\n this.resolveLiveness(session)\n if (session.handoff) this.handoffConfig = session.handoff\n const canHandoff =\n this.config.handoff !== false && isDesktopDevice(this.nav) && this.handoffConfig.enabled && !!this.handoffTarget()\n if (canHandoff) {\n this.handoffReady = true\n await this.startHandoff()\n } else {\n this.step = 'welcome'\n this.render()\n }\n }\n\n /** The hosted handoff page URL: a consumer override, else the server-provided one. */\n private handoffTarget(): string {\n return (this.config.handoffUrl ?? this.handoffConfig.url ?? '').trim()\n }\n\n /** Render the QR for this session and wait for the other device to finish. */\n private async startHandoff(): Promise<void> {\n const target = this.handoffTarget()\n if (!target) return\n this.handoffActive = true\n // Offer \"continue on this device\" only when the project permits it.\n this.view.renderHandoff(renderQrSvg(this.buildHandoffUrl(target)), this.handoffConfig.allow_desktop)\n await this.pollHandoff()\n }\n\n /** Build the hosted-page URL the QR encodes (carries the session token).\n *\n * @param target\n * @returns\n */\n private buildHandoffUrl(target: string): string {\n const sep = target.includes('?') ? '&' : '?'\n let url = `${target}${sep}token=${encodeURIComponent(this.config.token)}`\n // The hosted page supplies its own API base; only pass one when ours is\n // absolute, so a custom cross-origin host can still reach the right API.\n const apiBase = (this.config.baseUrl ?? '').trim()\n if (/^https?:\\/\\//i.test(apiBase)) url += `&baseUrl=${encodeURIComponent(apiBase)}`\n return url\n }\n\n /**\n * Watch the session while the user verifies on the other\n * device; mirror the result.\n *\n * @returns\n */\n private async pollHandoff(): Promise<void> {\n const rt = await this.resolveRealtime()\n if (rt) {\n const status = await this.pushWatch(rt, this.maxHandoffPolls, () => this.handoffActive && !this.settled)\n if (status) {\n this.handoffActive = false\n return this.showResult(status)\n }\n\n return // cancelled (continue here) or budget elapsed → the QR persists\n }\n\n let errors = 0\n for (let i = 0; i < this.maxHandoffPolls && this.handoffActive && !this.settled; i++) {\n await this.delay(this.pollMs)\n if (!this.handoffActive || this.settled) return\n try {\n const session = await this.client.getSession()\n errors = 0\n this.observe(session.status)\n if (Flow.isTerminal(session.status)) {\n this.handoffActive = false\n return this.showResult(session.status)\n }\n } catch (error) {\n // The session/token can expire mid-wait (401) — stop and reflect that.\n if (error instanceof WidgetApiError && error.status === 401) {\n this.handoffActive = false\n return this.showResult('expired')\n }\n if (++errors >= 5) return\n }\n }\n }\n\n /**\n * Await a terminal status over the push transport. Resolves to the terminal\n * status, or null if `active()` went false or the tick budget elapsed (push can\n * miss events / disconnect; the budget bounds the wait). An initial fetch\n * catches a session that finished before we subscribed.\n *\n * @param rt\n * @param budget\n * @param active\n * @returns\n */\n private pushWatch(\n rt: WidgetRealtimeClient,\n budget: number,\n active: () => boolean,\n ): Promise<VerificationStatus | null> {\n return new Promise((resolve) => {\n let done = false\n const finish = (status: VerificationStatus | null) => {\n if (done) return\n done = true\n this.stopWatch = undefined\n unsubscribe()\n resolve(status)\n }\n const channel = this.realtimeConfig!.channel\n const unsubscribe = rt.subscribe(channel, (event, data) => {\n if (event !== REALTIME_EVENT.sessionTransition) return\n const status = (data as SessionTransitionEvent).status\n this.observe(status)\n if (Flow.isTerminal(status)) finish(status)\n })\n this.stopWatch = () => finish(null)\n // Catch a race where the session already finished before we subscribed.\n void this.client\n .getSession()\n .then((session) => {\n this.observe(session.status)\n if (Flow.isTerminal(session.status)) finish(session.status)\n })\n .catch((error) => {\n if (error instanceof WidgetApiError && error.status === 401) finish('expired')\n })\n // Bound the wait by the same tick budget the poller would use.\n const countdown = async (n: number): Promise<void> => {\n if (done) return\n if (!active() || n >= budget) return finish(null)\n await this.delay(this.pollMs)\n void countdown(n + 1)\n }\n void countdown(0)\n })\n }\n\n /**\n * Resolve which liveness flow to run from the session's capture model.\n *\n * @param session\n */\n private resolveLiveness(session: ClientSession): void {\n this.livenessChallenges = session.liveness_challenges ?? []\n const model = session.capture_model ?? 'passive'\n this.captureModel = model\n const wantsActive = model === 'active' || model === 'both'\n // `active` is honoured even without a live camera — the active-liveness\n // screen then shows the device as unsupported (no fallback). `both` falls\n // back to passive when the camera/recorder isn't available.\n this.livenessMode = wantsActive && (model === 'active' || this.view.cameraSupported) ? 'active' : 'passive'\n }\n\n private async onImage(blob: Blob | null): Promise<void> {\n const signals = this.config.signals\n switch (this.step) {\n case 'front_capture':\n await this.client.submitDocumentFront({\n image: blob,\n country: this.country,\n documentType: this.documentType,\n signals,\n })\n return this.enter(this.next())\n case 'back_capture':\n await this.client.submitDocumentBack({\n image: blob,\n country: this.country,\n documentType: this.documentType,\n })\n return this.enter('ocr_processing')\n case 'selfie_capture':\n this.selfie = blob\n return this.enter('passive_liveness')\n }\n }\n\n /**\n * Enter a step: render it, and drive any automatic (processing) work.\n *\n * @param step\n * @returns\n */\n private async enter(step: WidgetStep): Promise<void> {\n if (this.settled) return\n this.step = step\n\n // Lead each capture/liveness step with an instruction screen so the user\n // knows what's next and starts it deliberately. The Continue button re-enters\n // the same step with the instruction acknowledged.\n const instruction = STEP_INSTRUCTIONS[step]\n if (instruction && !this.instructionAcked) {\n this.view.renderInstruction(step, instruction.title, instruction.body, instruction.cta ?? 'Continue', () => {\n this.instructionAcked = true\n void this.run(() => this.enter(step))\n })\n return\n }\n this.instructionAcked = false\n this.render()\n\n switch (step) {\n case 'ocr_processing':\n await this.delay(this.transientMs)\n return this.enter(this.next())\n case 'address_processing':\n await this.submitAddress()\n return this.enter(this.next())\n case 'passive_liveness':\n await this.client.submitLiveness({ selfie: this.selfie, signals: this.config.signals })\n return this.enter(this.next())\n case 'face_match':\n await this.client.complete({ signals: this.config.signals })\n return this.enter(this.next())\n case 'processing':\n return this.poll()\n }\n }\n\n /** Watch the session until it reaches a terminal status (then show the result).\n *\n * @returns\n */\n private async poll(): Promise<void> {\n const rt = await this.resolveRealtime()\n if (rt) {\n const status = await this.pushWatch(rt, this.maxPolls, () => !this.settled)\n\n return this.showResult(status ?? 'requires_review')\n }\n\n for (let i = 0; i < this.maxPolls && !this.settled; i++) {\n const session = await this.client.getSession()\n this.observe(session.status)\n if (Flow.isTerminal(session.status)) return this.showResult(session.status)\n await this.delay(this.pollMs)\n }\n // Still processing after the poll budget — surface as pending review.\n this.showResult('requires_review')\n }\n\n private showResult(status: VerificationStatus): void {\n this.result = { status, decision: Flow.statusToDecision(status) }\n this.step = 'result'\n this.render()\n }\n\n /**\n * A session that was already terminal on load: a notice with only a Close button.\n *\n * @param status\n */\n private showTerminal(status: VerificationStatus): void {\n this.result = { status, decision: Flow.statusToDecision(status) }\n this.step = 'result'\n this.terminalOnLoad = true\n this.render()\n }\n\n private render(): void {\n this.view.render({\n step: this.step,\n documentType: this.documentType,\n decision: this.result?.decision,\n status: this.result?.status,\n terminalNotice: this.terminalOnLoad,\n allowSkip: !!this.config.signals,\n livenessChallenges: this.livenessChallenges,\n requireLiveCamera: this.captureModel === 'active',\n // The active flow is strict end-to-end: documents must be detected, not\n // manually waved through.\n strictCapture: this.livenessMode === 'active',\n handoffAvailable: this.handoffReady,\n addressMethods: workflowAddressConfig(this.workflow)?.methods ?? [],\n })\n }\n\n /**\n * Store the entered address, resolve device location if opted in, then verify.\n *\n * @param data\n * @returns\n */\n private async onAddress(data: AddressFormData): Promise<void> {\n this.addressData = data\n // Coordinates are normally resolved up front by `shareLocation` when the user\n // ticks \"use my location\" (so the prompt is immediate); geolocate here only as\n // a fallback, and clear them if they opted out.\n if (!data.useLocation) this.addressCoords = null\n else if (!this.addressCoords) this.addressCoords = await this.geolocate()\n\n return this.enter('address_processing')\n }\n\n /** Request the device's location (from the address-entry \"use my location\" opt-in). */\n private async shareLocation(): Promise<boolean> {\n this.addressCoords = await this.geolocate()\n\n return !!this.addressCoords\n }\n\n /**\n * Submit the captured address evidence to the Client API.\n *\n * @returns\n */\n private async submitAddress(): Promise<void> {\n const data = this.addressData\n if (!data) return\n\n await this.client.submitAddress({\n line1: data.line1,\n line2: data.line2,\n city: data.city,\n region: data.region,\n postalCode: data.postalCode,\n country: data.country,\n poa: data.poa,\n latitude: this.addressCoords?.latitude ?? null,\n longitude: this.addressCoords?.longitude ?? null,\n signals: this.config.signals,\n })\n }\n\n /**\n * Resolve the device's coordinates via the Geolocation API. Resolves to `null`\n * on denial/unavailability/timeout — the `device_location` method then simply\n * has no coordinates to check (routing the session to review).\n *\n * @returns\n */\n private geolocate(): Promise<{ latitude: number; longitude: number } | null> {\n const geo = this.nav?.geolocation\n if (!geo) return Promise.resolve(null)\n\n return new Promise((resolve) => {\n geo.getCurrentPosition(\n (pos) => resolve({ latitude: pos.coords.latitude, longitude: pos.coords.longitude }),\n () => resolve(null),\n { enableHighAccuracy: false, timeout: 10_000, maximumAge: 60_000 },\n )\n })\n }\n\n private next(): WidgetStep {\n return Flow.nextStep(this.step, {\n documentType: this.documentType,\n livenessMode: this.livenessMode,\n workflow: this.workflow,\n })\n }\n\n private delay(ms: number): Promise<void> {\n return new Promise((resolve) => this.scheduler(resolve, ms))\n }\n\n /** Run an async step, routing any failure to the error screen. */\n private async run(fn: () => Promise<void> | void): Promise<void> {\n try {\n await fn()\n } catch (error) {\n this.fail(error)\n }\n }\n\n private fail(error: unknown): void {\n if (this.settled) return\n const err = error instanceof Error ? error : new Error(String(error))\n this.step = 'result'\n\n this.view.render({\n step: 'result',\n documentType: this.documentType,\n errorMessage: err.message,\n })\n\n this.pendingError = err\n }\n\n private finishResult(): void {\n if (this.settled) return\n this.settled = true\n this.teardownRealtime()\n\n if (this.pendingError) {\n this.post('arkyc:error', { error: serializeError(this.pendingError) })\n this.dispatch('error', { message: this.pendingError.message })\n this.config.onError?.(this.pendingError)\n } else if (this.result) {\n this.post('arkyc:complete', { payload: this.result })\n this.dispatch('complete', this.result)\n this.config.onComplete?.(this.result)\n }\n\n this.destroy()\n this.config.onSettle?.()\n }\n\n private finishClose(): void {\n if (this.settled) return\n\n this.settled = true\n this.teardownRealtime()\n this.post('arkyc:close', {})\n this.dispatch('close')\n this.config.onClose?.()\n this.destroy()\n this.config.onSettle?.()\n }\n\n /** Stop any active session watch + disconnect the push transport. */\n private teardownRealtime(): void {\n this.stopWatch?.()\n this.rtClient?.disconnect()\n this.rtClient = null\n }\n\n private post(type: string, extra: Record<string, unknown>): void {\n if (!this.postToParent) return\n try {\n this.win.parent?.postMessage({ type, ...extra }, '*')\n } catch {\n // Cross-origin parent without access — nothing more we can do.\n }\n }\n}\n\nfunction serializeError(error: Error): { message: string; name: string } {\n return { message: error.message, name: error.name }\n}\n\nexport const resolveContainer = (container: string | HTMLElement, doc: Document): HTMLElement => {\n const el = typeof container === 'string' ? doc.querySelector<HTMLElement>(container) : container\n if (!el) throw new Error(`ArkycWidget.mount: container \"${String(container)}\" not found.`)\n return el\n}\n\nexport const buildController = (options: BaseWidgetOptions, onSettle: () => void): WidgetController => {\n if (!options.token) throw new Error('ArkycWidget requires a client `token`.')\n return new WidgetController({\n token: options.token,\n baseUrl: options.baseUrl,\n handoff: options.handoff,\n handoffUrl: options.handoffUrl,\n branding: options.branding,\n signals: options.signals,\n onComplete: options.onComplete,\n onError: options.onError,\n onClose: options.onClose,\n onEvent: options.onEvent,\n onSettle,\n fetch: options.fetch,\n doc: options.doc,\n win: options.win,\n nav: options.nav,\n faceAnalyzer: options.faceAnalyzer,\n faceTuning: options.faceTuning,\n documentAnalyzer: options.documentAnalyzer,\n documentTuning: options.documentTuning,\n })\n}\n","import type { WidgetController } from './controller'\nimport type { WidgetEventListener, WidgetHandle } from './types'\n\nexport class WidgetHandler implements WidgetHandle {\n constructor(private controller: WidgetController) {}\n\n /**\n * Close the widget and release the camera (fires `onClose`).\n */\n close(): void {\n return this.controller.close()\n }\n /**\n * Subscribe to a named widget event (e.g. `session.transition`, `complete`).\n * Returns an unsubscribe function. Registering a listener activates the event\n * stream (events are only delivered while at least one listener is active).\n *\n * @param event\n * @param listener\n */\n on(event: string, listener: WidgetEventListener): () => void {\n return this.controller.on(event, listener)\n }\n}\n","import type { BaseWidgetOptions, MountWidgetOptions, WidgetHandle } from './types'\nimport { buildController, resolveContainer } from './controller'\n\nimport { WidgetHandler } from './WidgetHandler'\n\n/**\n * @arkyc/widget\n *\n * Framework-agnostic, embeddable identity-verification widget. Drives a single\n * session through the Arkyc Client/Widget API with a short-lived client token.\n *\n * ```ts\n * import { ArkycWidget } from '@arkyc/widget'\n *\n * // Overlay modal:\n * ArkycWidget.open({ token, onComplete: (r) => console.log(r.status) })\n *\n * // Inline (mounted into a container):\n * ArkycWidget.mount({ token, container: '#verify' })\n *\n * // Hosted page (reads ?token= and posts results to the parent window):\n * ArkycWidget.hosted()\n * ```\n */\nexport class ArkycWidget {\n /**\n * Open the widget as a full-screen overlay modal. Returns a close handle.\n *\n * @param options\n * @returns\n */\n static open(options: BaseWidgetOptions): WidgetHandle {\n const doc = options.doc ?? globalThis.document\n const overlay = doc.createElement('div')\n\n overlay.setAttribute('data-arkyc-widget', '')\n // Fullscreen: edge-to-edge with no backdrop gap. Otherwise a centred modal\n // over a dimmed backdrop.\n // Both modes use a dimmed, centred backdrop. Fullscreen fills the viewport on\n // mobile but renders as a large centred dialog on desktop (see the card CSS);\n // the dimmed backdrop is what's visible around that dialog.\n overlay.style.cssText = options.fullscreen\n ? 'position:fixed;inset:0;z-index:2147483647;background:rgba(0,0,0,0.55);display:flex;align-items:center;justify-content:center;padding:0;'\n : 'position:fixed;inset:0;z-index:2147483647;background:rgba(0,0,0,0.6);display:flex;align-items:center;justify-content:center;padding:16px;'\n\n const controller = buildController(options, () => overlay.remove())\n // Mark overlay mode so a handoff QR can take over the whole viewport here\n // (it escapes the dimmed backdrop) without doing the same when inline-mounted.\n controller.element.classList.add('arkyc-overlay')\n if (options.fullscreen) controller.element.classList.add('arkyc-fullscreen')\n overlay.appendChild(controller.element)\n ;(doc.body ?? doc.documentElement).appendChild(overlay)\n controller.start()\n\n return new WidgetHandler(controller)\n }\n\n /**\n * Mount the widget inline into a container element. Returns a close handle.\n *\n * @param options\n * @returns\n */\n static mount(options: MountWidgetOptions): WidgetHandle {\n const doc = options.doc ?? globalThis.document\n const container = resolveContainer(options.container, doc)\n const controller = buildController(options, () => controller.element.remove())\n\n container.appendChild(controller.element)\n controller.start()\n\n return new WidgetHandler(controller)\n }\n\n /**\n * Bootstrap the widget on its hosted page: read the client `token` (and\n * optional `baseUrl`) from the query string and run in overlay mode, posting\n * `arkyc:*` results to the parent (iframe) window.\n *\n * @param options\n * @returns\n */\n static hosted(options: Partial<BaseWidgetOptions> = {}): WidgetHandle {\n const win = options.win ?? globalThis.window\n const params = new URLSearchParams(win.location.search)\n const token = options.token ?? params.get('token') ?? ''\n const baseUrl = options.baseUrl ?? params.get('baseUrl') ?? undefined\n\n return ArkycWidget.open({ ...options, token, baseUrl })\n }\n}\n","export const PACKAGE_NAME = '@arkyc/widget'\nexport const VERSION = '0.1.0'\n\nexport type { WidgetController } from './controller'\nexport { ArkycClient, WidgetApiError } from './client'\nexport type { ClientSession, ClientRealtime, ProviderSignalHints, ArkycClientOptions } from './client'\nexport { createWidgetRealtimeClient } from './realtime'\nexport type { WidgetRealtimeClient, WidgetRealtimeFactory, WidgetRealtimeHandler } from './realtime'\nexport { Theme } from './theme'\nexport { Camera } from './capture'\nexport type { Facing } from './capture'\nexport { Flow } from './flow'\nexport type { FlowContext } from './flow'\nexport { createDefaultFaceAnalyzer, DEFAULT_TUNING, makeChallengeDetector, isSelfieReady } from './face'\nexport type { FaceAnalyzer, FaceSample, FaceTuning, ChallengeDetector } from './face'\nexport {\n createDefaultDocumentAnalyzer,\n DEFAULT_DOCUMENT_TUNING,\n analyzeDocumentGray,\n documentGuidance,\n isDocumentReady,\n} from './document'\nexport type { DocumentAnalyzer, DocumentSample, DocumentTuning, DocRect } from './document'\nexport type { WidgetResult } from '@arkyc/types'\nexport { ArkycWidget } from './ArkycWidget'\nexport { WidgetHandler } from './WidgetHandler'\nexport * from './types'\n"],"x_google_ignoreList":[13],"mappings":"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AK,CAAE,EACrC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAG,EAAI,EAAK,OAAQ,GAAK,EAAG,GAAK,EACnD,EAAK,GAAK,KAAQ,EAAK,GAAM,KAAQ,EAAK,EAAI,GAAM,KAAQ,EAAK,EAAI,GAEvE,OAAO,EAAoB,EAAM,EAAI,CAAE,CACzC,CAEA,OAAc,CACZ,KAAK,OAAS,KACd,KAAK,IAAM,IACb,CACF,EAQA,SAAgB,EAA8B,EAAyB,EAA2C,CAChH,OAAO,IAAI,GAAuB,CAAM,CAC1C,CC5SA,IAAa,EAAY,CACvB,CACE,KAAM,gBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,iBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,eACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,eACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,sBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,yBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,eACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,2BACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,4BACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,yBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,iBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,qBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,oBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,gBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,gBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,mBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,kBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,mBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,OACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,wBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,mCACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,wBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,eACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,kBACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,UACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,YACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,SACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,cACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,QACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,aACN,KAAM,KACN,KAAM,MACR,EACA,CACE,KAAM,WACN,KAAM,KACN,KAAM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"}