@tokshare/pick 0.1.0 → 0.1.1
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.
- package/LICENSE +1 -1
- package/README.md +28 -3
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/picker.global.js +1 -1
- package/package.json +12 -3
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../../protocol/src/limits.ts","../../protocol/src/errors.ts","../../protocol/src/filename.ts","../../protocol/src/mime.ts","../src/config.ts","../src/direct.ts","../src/announce.ts","../src/i18n.ts","../../../node_modules/.pnpm/uqr@0.1.3/node_modules/uqr/dist/index.mjs","../src/qr.ts","../src/theme.ts","../src/styles.ts","../src/modal.ts","../src/session.ts","../src/picker.ts","../src/fieldStyles.ts","../src/field.ts"],"sourcesContent":["export { attach, open, pick } from \"./picker\";\nexport { defineFieldElement, mountField, parseSize } from \"./field\";\nexport type { FieldController, FieldOptions } from \"./field\";\nexport type { AttachOptions, PickController, PickEvents, PickOptions, ProgressInfo } from \"./picker\";\nexport { PickError } from \"@tokshare/pick-protocol\";\nexport type { ErrorCode, FileMeta, PhoneInfo } from \"@tokshare/pick-protocol\";\nexport { DEFAULT_RELAY, SDK_VERSION } from \"./config\";\n\nimport { defineFieldElement, mountField } from \"./field\";\nimport { attach, open, pick } from \"./picker\";\n/** The same functions as one object: TokSharePick.pick({ key }). */\nexport const TokSharePick = { pick, open, attach, mountField, defineFieldElement };\n","// Limits shared by the relay, the phone page and the SDK. The relay is the authority; the others use\n// these to explain a refusal before trying.\n\nexport const MiB = 1024 * 1024;\n\nexport const LIMITS = {\n /** Free tier ceilings, in decimal megabytes as phones show sizes. A site can ask for less, never more. */\n maxFileBytes: 50_000_000,\n maxFiles: 20,\n maxSessionBytes: 200_000_000,\n /** Up to this size a file goes up in one presigned PUT; above it, multipart. */\n singlePutBytes: 16 * MiB,\n /** Multipart parts are all the same size (R2), at least 5 MiB; we use 8 MiB. */\n minPartBytes: 8 * MiB,\n maxParts: 10_000,\n /** How many part URLs the phone may ask for at once. */\n partBatch: 10,\n /** Session lifetime. */\n idleMs: 30 * 60_000,\n absoluteMs: 2 * 60 * 60_000,\n /** A ready file is deleted this long after it arrived, downloaded or not. */\n fileTtlMs: 10 * 60_000,\n /** The typed short code works for this long after the session is created. */\n codeTtlMs: 10 * 60_000,\n /** Times the desktop may download one file (retries after a dropped connection). */\n maxDownloads: 3,\n /** Presigned URLs expire after this many seconds. */\n presignSeconds: 15 * 60,\n /** Bytes of a finished upload read back to check its real type. */\n sniffBytes: 4096,\n /** Direct (local network) transfers: bytes per data-channel message, how long the phone waits for\n * the link before using the cloud, and for the website's \"got\" after the last byte. */\n directChunkBytes: 64 * 1024,\n directConnectMs: 8_000,\n directWaitMs: 2_500,\n directConfirmMs: 20_000,\n /** Largest WebRTC setup message the relay passes on. */\n maxSignalBytes: 16_384,\n} as const;\n\n/** Part size for a multipart upload: equal parts of at least minPartBytes, at most maxParts of them. */\nexport function partPlan(size: number): { partSize: number; partCount: number } {\n const partSize = Math.max(LIMITS.minPartBytes, Math.ceil(size / LIMITS.maxParts));\n return { partSize, partCount: Math.max(1, Math.ceil(size / partSize)) };\n}\n","// Error codes the relay returns ({ error: code, message }) and the SDK throws as PickError.\n\nexport type ErrorCode =\n | \"bad_request\"\n | \"key_invalid\"\n | \"origin_not_allowed\"\n | \"rate_limited\"\n | \"quota_exceeded\"\n | \"not_found\"\n | \"unauthorized\"\n | \"already_claimed\"\n | \"expired\"\n | \"closed\"\n | \"limit_reached\"\n | \"file_too_large\"\n | \"session_too_large\"\n | \"type_rejected\"\n | \"size_mismatch\"\n | \"upload_incomplete\"\n | \"download_limit\"\n | \"network\"\n | \"internal\";\n\nexport class PickError extends Error {\n readonly code: ErrorCode;\n readonly status: number;\n constructor(code: ErrorCode, message?: string, status = 400) {\n super(message || code);\n this.name = \"PickError\";\n this.code = code;\n this.status = status;\n }\n}\n\nexport const STATUS: Partial<Record<ErrorCode, number>> = {\n key_invalid: 401,\n unauthorized: 401,\n origin_not_allowed: 403,\n not_found: 404,\n already_claimed: 409,\n limit_reached: 409,\n expired: 410,\n closed: 410,\n file_too_large: 413,\n session_too_large: 413,\n type_rejected: 415,\n rate_limited: 429,\n quota_exceeded: 429,\n internal: 500,\n};\n","// File names come from phones and end up in someone else's page and disk: keep the name, drop\n// anything that could hide an extension or break a path.\n\nconst CONTROL = /[\\u0000-\\u001f\\u007f-\\u009f]/g;\n// Right-to-left override and friends can make \"photogpj.exe\" read as \"photoexe.jpg\".\nconst BIDI = /[--]/g;\nconst RESERVED = /[<>:\"/\\\\|?*]/g;\n\nexport function sanitizeFilename(name: string, fallback = \"file\"): string {\n let clean = String(name ?? \"\")\n .normalize(\"NFC\")\n .replace(CONTROL, \"\")\n .replace(BIDI, \"\");\n // Only the last path segment: a picker should never send folders, but don't trust it.\n clean = clean.split(/[\\\\/]/).pop() ?? \"\";\n clean = clean.replace(RESERVED, \"_\").replace(/^[.\\s]+|[.\\s]+$/g, \"\");\n if (!clean) return fallback;\n if (clean.length <= 200) return clean;\n // Keep the extension when cutting a long name.\n const dot = clean.lastIndexOf(\".\");\n const extension = dot > 0 && clean.length - dot <= 16 ? clean.slice(dot) : \"\";\n return clean.slice(0, 200 - extension.length) + extension;\n}\n\nexport function extensionOf(name: string): string {\n const dot = name.lastIndexOf(\".\");\n return dot > 0 ? name.slice(dot).toLowerCase() : \"\";\n}\n","// File types: matching a site's accept list (the same rules as <input accept>) and recognizing a\n// file's real type from its first bytes, so a renamed program can't pass as a photo.\nimport { extensionOf } from \"./filename\";\n\nexport interface AcceptRule {\n extensions: string[];\n types: string[];\n wildcards: string[];\n}\n\nexport function parseAccept(accept = \"\"): AcceptRule {\n const rule: AcceptRule = { extensions: [], types: [], wildcards: [] };\n for (const raw of accept.split(\",\")) {\n const token = raw.trim().toLowerCase();\n if (!token) continue;\n if (token.startsWith(\".\")) rule.extensions.push(token);\n else if (/^[a-z0-9.+-]+\\/\\*$/.test(token)) rule.wildcards.push(token.slice(0, -1));\n else if (/^[a-z0-9.+-]+\\/[a-z0-9.+-]+$/.test(token)) rule.types.push(token);\n }\n return rule;\n}\n\nexport function acceptsAnything(accept = \"\"): boolean {\n const rule = parseAccept(accept);\n return !rule.extensions.length && !rule.types.length && !rule.wildcards.length;\n}\n\nfunction typeMatches(rule: AcceptRule, type: string): boolean {\n const lower = type.toLowerCase();\n return rule.types.includes(lower) || rule.wildcards.some((prefix) => lower.startsWith(prefix));\n}\n\n/** Whether a picked file fits the accept list, by its extension or its declared type. */\nexport function matchesAccept(accept: string, name: string, type: string): boolean {\n const rule = parseAccept(accept);\n if (!rule.extensions.length && !rule.types.length && !rule.wildcards.length) return true;\n return rule.extensions.includes(extensionOf(name)) || (Boolean(type) && typeMatches(rule, type));\n}\n\nconst ascii = (bytes: Uint8Array, start: number, length: number) =>\n String.fromCharCode(...bytes.subarray(start, start + length));\nconst starts = (bytes: Uint8Array, signature: number[], offset = 0) =>\n signature.every((value, index) => bytes[offset + index] === value);\n\n/** The real type of a file from its first bytes, or null when it isn't one we recognize. */\nexport function sniff(bytes: Uint8Array): string | null {\n if (bytes.length < 4) return null;\n if (starts(bytes, [0xff, 0xd8, 0xff])) return \"image/jpeg\";\n if (starts(bytes, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])) return \"image/png\";\n if (ascii(bytes, 0, 4) === \"GIF8\") return \"image/gif\";\n if (ascii(bytes, 0, 4) === \"RIFF\" && ascii(bytes, 8, 4) === \"WEBP\") return \"image/webp\";\n if (ascii(bytes, 0, 4) === \"RIFF\" && ascii(bytes, 8, 4) === \"WAVE\") return \"audio/wav\";\n if (ascii(bytes, 0, 4) === \"RIFF\" && ascii(bytes, 8, 4) === \"AVI \") return \"video/x-msvideo\";\n if (ascii(bytes, 4, 4) === \"ftyp\") {\n const brand = ascii(bytes, 8, 4);\n if (/^(heic|heix|hevc|hevx|heim|heis)$/.test(brand)) return \"image/heic\";\n if (brand === \"mif1\" || brand === \"msf1\") return \"image/heif\";\n if (brand === \"avif\" || brand === \"avis\") return \"image/avif\";\n if (brand === \"qt \") return \"video/quicktime\";\n if (/^(M4A |M4B )$/.test(brand)) return \"audio/mp4\";\n if (/^3g/.test(brand)) return \"video/3gpp\";\n return \"video/mp4\";\n }\n if (ascii(bytes, 0, 5) === \"%PDF-\") return \"application/pdf\";\n if (starts(bytes, [0x50, 0x4b, 0x03, 0x04]) || starts(bytes, [0x50, 0x4b, 0x05, 0x06])) return \"application/zip\";\n if (starts(bytes, [0x1f, 0x8b])) return \"application/gzip\";\n if (starts(bytes, [0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c])) return \"application/x-7z-compressed\";\n if (ascii(bytes, 0, 4) === \"Rar!\") return \"application/vnd.rar\";\n if (ascii(bytes, 0, 3) === \"ID3\" || starts(bytes, [0xff, 0xfb]) || starts(bytes, [0xff, 0xf3])) return \"audio/mpeg\";\n if (ascii(bytes, 0, 4) === \"OggS\") return \"audio/ogg\";\n if (ascii(bytes, 0, 4) === \"fLaC\") return \"audio/flac\";\n if (starts(bytes, [0x1a, 0x45, 0xdf, 0xa3])) return \"video/webm\";\n if (starts(bytes, [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1])) return \"application/x-ole-storage\";\n if (ascii(bytes, 0, 2) === \"MZ\") return \"application/x-msdownload\";\n if (starts(bytes, [0x7f, 0x45, 0x4c, 0x46])) return \"application/x-elf\";\n if (starts(bytes, [0xcf, 0xfa, 0xed, 0xfe]) || starts(bytes, [0xfe, 0xed, 0xfa, 0xcf])) return \"application/x-mach-binary\";\n const head = ascii(bytes, 0, Math.min(bytes.length, 256)).replace(/^/, \"\").trimStart().toLowerCase();\n if (head.startsWith(\"<svg\") || (head.startsWith(\"<?xml\") && head.includes(\"<svg\"))) return \"image/svg+xml\";\n if (head.startsWith(\"<!doctype html\") || head.startsWith(\"<html\")) return \"text/html\";\n return null;\n}\n\n// Containers whose declared types are many: a .docx, .xlsx, .apk or .epub is a zip inside.\nconst ZIP_FAMILY = /^(application\\/(zip|x-zip-compressed|epub\\+zip|vnd\\.android\\.package-archive|java-archive|vnd\\.openxmlformats-officedocument\\..+|vnd\\.oasis\\.opendocument\\..+))$/;\nconst OLE_FAMILY = /^application\\/(msword|vnd\\.ms-excel|vnd\\.ms-powerpoint|vnd\\.ms-outlook|x-ole-storage)$/;\nconst DANGEROUS = new Set([\"application/x-msdownload\", \"application/x-elf\", \"application/x-mach-binary\", \"text/html\", \"image/svg+xml\"]);\n\n/** Whether a finished upload's real type is acceptable. Rejects a file whose bytes say \"program\"\n * or \"web page\" when its name or the accept list said otherwise, and a type the accept list's MIME\n * rules exclude. Unknown bytes (plain text, rare formats) pass on the name/type check alone. */\nexport function checkSniffed(accept: string, name: string, declared: string, sniffed: string | null): boolean {\n if (!sniffed) return true;\n const rule = parseAccept(accept);\n const declaredLower = declared.toLowerCase();\n const compatible = (type: string) =>\n type === sniffed ||\n (sniffed === \"application/zip\" && ZIP_FAMILY.test(type)) ||\n (sniffed === \"application/x-ole-storage\" && OLE_FAMILY.test(type)) ||\n (sniffed === \"image/heif\" && type === \"image/heic\") ||\n (sniffed === \"video/mp4\" && /^(video|audio)\\//.test(type));\n if (DANGEROUS.has(sniffed)) {\n // Only when the site asked for exactly this kind of file.\n return rule.types.includes(sniffed) || (sniffed === \"image/svg+xml\" && rule.extensions.includes(\".svg\"));\n }\n if (!rule.types.length && !rule.wildcards.length) return true;\n if (rule.types.some(compatible)) return true;\n if (rule.wildcards.some((prefix) => sniffed.startsWith(prefix))) return true;\n // The site listed MIME rules but also extensions: the extension check already passed at init.\n return rule.extensions.includes(extensionOf(name)) && (compatible(declaredLower) || !declaredLower);\n}\n","/** The hosted relay. Override with the `relay` option or a script tag's data-relay attribute\n * (local development: \"http://localhost:8788\").\n * 0.1.x uses the relay's workers.dev address; a later version moves to the TokShare domain. That\n * address must stay up for sites still on 0.1.x (wrangler.jsonc keeps workers_dev on). */\nexport const DEFAULT_RELAY = \"https://tokshare-pick.pjturki.workers.dev\";\n\nexport const SDK_VERSION = \"0.1.0\";\n","// The website's end of the direct link: answers the phone's WebRTC offer (made through the relay's\n// sockets) and receives files over the data channel. Same network only: no STUN or TURN servers, so\n// only local-network candidates (hidden behind .local names by browsers) can connect.\nimport { checkSniffed, type DirectMessage, type FileMeta, LIMITS, type RtcSignal, sniff } from \"@tokshare/pick-protocol\";\n\nexport interface DirectHandlers {\n /** A file's bytes are arriving. */\n progress(id: string, received: number, total: number): void;\n /** All bytes are in: check and keep the file. Resolves with what to tell the phone. */\n complete(id: string, chunks: Uint8Array[], size: number): Promise<{ ok: true } | { ok: false; code: string }>;\n /** The link opened or closed. */\n state(open: boolean): void;\n}\n\n/** The checks the relay runs on a cloud upload, run here on a file that came over the direct link:\n * the exact announced size, and contents that match an accepted type. */\nexport function verifyDirectFile(meta: FileMeta, chunks: Uint8Array[], size: number, accept: string, maxBytes: number):\n { ok: true; file: File; sniffed: string | null } | { ok: false; code: \"size_mismatch\" | \"type_rejected\" } {\n if (size !== meta.size || size > maxBytes) return { ok: false, code: \"size_mismatch\" };\n const head = new Uint8Array(Math.min(size, LIMITS.sniffBytes));\n let filled = 0;\n for (const chunk of chunks) {\n if (filled >= head.length) break;\n const take = chunk.subarray(0, head.length - filled);\n head.set(take, filled);\n filled += take.length;\n }\n const sniffed = sniff(head);\n if (!checkSniffed(accept, meta.name, meta.type, sniffed)) return { ok: false, code: \"type_rejected\" };\n const file = new File(chunks as BlobPart[], meta.name, { type: meta.type || sniffed || \"\", lastModified: meta.lastModified });\n return { ok: true, file, sniffed };\n}\n\nexport class DirectReceiver {\n private pc: RTCPeerConnection | null = null;\n private channel: RTCDataChannel | null = null;\n private id = \"\";\n private isOpen = false;\n private current: { id: string; size: number; chunks: Uint8Array[]; received: number } | null = null;\n\n constructor(private readonly signal: (d: RtcSignal) => void, private readonly handlers: DirectHandlers) {}\n\n static supported(): boolean {\n return typeof RTCPeerConnection === \"function\";\n }\n\n onSignal(d: RtcSignal): void {\n if (d.kind === \"offer\" && d.sdp) { this.answer(d.pc, d.sdp); return; }\n if (d.pc !== this.id || !this.pc) return;\n if (d.kind === \"ice\" && d.candidate) this.pc.addIceCandidate(d.candidate).catch(() => undefined);\n else if (d.kind === \"bye\") this.close();\n }\n\n /** A new offer replaces any earlier link (the phone reloaded, or retried after a network change). */\n private answer(id: string, sdp: string): void {\n if (!DirectReceiver.supported()) return;\n this.close();\n this.id = id;\n const pc = new RTCPeerConnection({ iceServers: [] });\n this.pc = pc;\n pc.onicecandidate = (event) => {\n if (this.id === id) this.signal({ pc: id, kind: \"ice\", candidate: event.candidate ? event.candidate.toJSON() as RtcSignal[\"candidate\"] : null });\n };\n pc.onconnectionstatechange = () => {\n if (this.id === id && (pc.connectionState === \"failed\" || pc.connectionState === \"closed\")) this.close();\n };\n pc.ondatachannel = (event) => {\n if (this.id !== id) return;\n const channel = event.channel;\n channel.binaryType = \"arraybuffer\";\n this.channel = channel;\n const opened = () => { if (this.channel === channel && !this.isOpen) { this.isOpen = true; this.handlers.state(true); } };\n channel.onopen = opened;\n channel.onclose = () => { if (this.channel === channel) this.close(); };\n channel.onmessage = (message) => this.onMessage(channel, message.data);\n if (channel.readyState === \"open\") opened();\n };\n pc.setRemoteDescription({ type: \"offer\", sdp })\n .then(() => pc.createAnswer())\n .then((answer) => pc.setLocalDescription(answer))\n .then(() => { if (this.id === id) this.signal({ pc: id, kind: \"answer\", sdp: pc.localDescription!.sdp }); })\n .catch(() => this.close());\n }\n\n private onMessage(channel: RTCDataChannel, data: unknown): void {\n if (typeof data !== \"string\") {\n const current = this.current;\n if (!current || !(data instanceof ArrayBuffer)) return;\n current.chunks.push(new Uint8Array(data));\n current.received += data.byteLength;\n // More than announced: stop collecting, it will fail the size check.\n if (current.received > current.size) { current.chunks = []; return; }\n this.handlers.progress(current.id, current.received, current.size);\n return;\n }\n let message: DirectMessage;\n try { message = JSON.parse(data); } catch { return; }\n if (message.t === \"file\" && typeof message.id === \"string\" && Number.isSafeInteger(message.size)) {\n this.current = { id: message.id, size: message.size, chunks: [], received: 0 };\n } else if (message.t === \"end\" && this.current?.id === message.id) {\n const { id, chunks, received } = this.current;\n this.current = null;\n this.handlers.complete(id, chunks, received)\n .then((result) => result, () => ({ ok: false as const, code: \"failed\" }))\n .then((result) => {\n const reply: DirectMessage = result.ok ? { t: \"got\", id } : { t: \"bad\", id, code: result.code };\n try { channel.send(JSON.stringify(reply)); } catch {}\n });\n }\n }\n\n close(): void {\n const wasOpen = this.isOpen;\n this.isOpen = false;\n const { pc, channel } = this;\n this.pc = null;\n this.channel = null;\n this.current = null;\n try { channel?.close(); } catch {}\n try { pc?.close(); } catch {}\n if (wasOpen) this.handlers.state(false);\n }\n}\n","// A small line about TokShare for desktop, under the phone QR in the field and the modal. Sites turn it\n// off with announce: false; a visitor hides it once and it stays hidden (per site, in localStorage).\nconst HIDDEN_KEY = \"tokshare.announce.hidden\";\nconst LINK = \"https://tokshare.vercel.app/?ref=pick\";\n\nconst hidden = (): boolean => {\n try { return localStorage.getItem(HIDDEN_KEY) === \"1\"; } catch { return false; }\n};\n\n/** The element, or null when the site turned it off or the visitor hid it. */\nexport function announcement(enabled: boolean | undefined, t: (key: \"announceText\" | \"announceLink\" | \"announceHide\") => string): HTMLElement | null {\n if (enabled === false || hidden()) return null;\n const box = document.createElement(\"p\");\n box.className = \"announce\";\n const dot = document.createElement(\"i\");\n dot.setAttribute(\"aria-hidden\", \"true\");\n const text = document.createElement(\"span\");\n text.textContent = `${t(\"announceText\")} `;\n const link = document.createElement(\"a\");\n link.href = LINK;\n link.target = \"_blank\";\n link.rel = \"noopener\";\n link.textContent = t(\"announceLink\");\n text.append(link);\n const hide = document.createElement(\"button\");\n hide.type = \"button\";\n hide.className = \"announce-hide\";\n hide.textContent = \"×\";\n hide.setAttribute(\"aria-label\", t(\"announceHide\"));\n hide.addEventListener(\"click\", () => {\n try { localStorage.setItem(HIDDEN_KEY, \"1\"); } catch {}\n box.remove();\n });\n box.append(dot, text, hide);\n return box;\n}\n","import type { Locale } from \"@tokshare/pick-protocol\";\n\nconst en = {\n title: \"Pick files from your phone\",\n titleOne: \"Pick a file from your phone\",\n scan: \"Scan with your phone's camera\",\n orType: \"No camera? Open {host} on your phone and type\",\n loading: \"Getting a code…\",\n waiting: \"Waiting for your phone…\",\n connected: \"Connected: {label}\",\n connectedDirect: \"Connected over Wi-Fi: {label}\",\n disconnect: \"Not you? Disconnect\",\n phoneLeft: \"Your phone disconnected. It reconnects by itself when the page is open.\",\n approveTitle: \"Approve this phone?\",\n approveMatch: \"Your phone should show {match}.\",\n approve: \"Approve\",\n reject: \"Reject\",\n sending: \"Sending from phone {percent}%\",\n receiving: \"Receiving {percent}%\",\n received: \"Received\",\n failed: \"Not received\",\n cancel: \"Cancel\",\n done: \"Done\",\n useFiles: \"Use {count} files\",\n useFile: \"Use this file\",\n expired: \"This code expired.\",\n newCode: \"Get a new code\",\n error: \"Couldn't start: {message}\",\n tryAgain: \"Try again\",\n close: \"Close\",\n privacy: \"Files go straight to this site and are deleted from TokShare once received.\",\n // Upload field\n dropTitle: \"Drag & drop files here\",\n dropTitleOne: \"Drag & drop a file here\",\n dropActive: \"Drop to add\",\n or: \"or\",\n browse: \"Browse files\",\n usePhone: \"Use your phone\",\n hintTypes: \"{types} · up to {size}\",\n hintAny: \"Any file · up to {size}\",\n hintCount: \"Up to {count} files\",\n phoneTitle: \"Scan with your phone\",\n phoneStep1: \"Open your phone's camera and scan the code\",\n phoneStep2: \"Pick photos or files on your phone\",\n phoneStep3: \"They appear here as they arrive\",\n phoneCode: \"No camera? Open {host} and type\",\n back: \"Back\",\n doneWithPhone: \"Done\",\n sourcePhone: \"From phone\",\n sourceDevice: \"This device\",\n remove: \"Remove {name}\",\n tooLarge: \"{name} is larger than {size}.\",\n wrongType: \"{name} isn't an accepted file type.\",\n tooMany: \"You can add up to {count} files.\",\n fileCount: \"{count} files\",\n clearAll: \"Remove all\",\n // TokShare for desktop\n announceText: \"Move photos between your phone and your own PC anytime, over Wi-Fi.\",\n announceLink: \"Get TokShare for desktop\",\n announceHide: \"Hide\",\n};\ntype Strings = typeof en;\n\nconst ar: Strings = {\n title: \"اختر ملفات من هاتفك\",\n titleOne: \"اختر ملفًا من هاتفك\",\n scan: \"امسح الرمز بكاميرا هاتفك\",\n orType: \"لا توجد كاميرا؟ افتح {host} على هاتفك واكتب\",\n loading: \"جارٍ تجهيز الرمز…\",\n waiting: \"في انتظار هاتفك…\",\n connected: \"متصل: {label}\",\n connectedDirect: \"متصل عبر Wi-Fi: {label}\",\n disconnect: \"ليس هاتفك؟ افصله\",\n phoneLeft: \"انقطع اتصال هاتفك. سيعود تلقائيًا ما دامت الصفحة مفتوحة عليه.\",\n approveTitle: \"هل توافق على هذا الهاتف؟\",\n approveMatch: \"يجب أن يعرض هاتفك الرقم {match}.\",\n approve: \"موافقة\",\n reject: \"رفض\",\n sending: \"جارٍ الإرسال من الهاتف {percent}%\",\n receiving: \"جارٍ الاستلام {percent}%\",\n received: \"تم الاستلام\",\n failed: \"لم يُستلم\",\n cancel: \"إلغاء\",\n done: \"تم\",\n useFiles: \"استخدم {count} ملفات\",\n useFile: \"استخدم هذا الملف\",\n expired: \"انتهت صلاحية هذا الرمز.\",\n newCode: \"احصل على رمز جديد\",\n error: \"تعذّر البدء: {message}\",\n tryAgain: \"حاول مرة أخرى\",\n close: \"إغلاق\",\n privacy: \"تصل الملفات مباشرة إلى هذا الموقع، ويحذفها TokShare فور استلامها.\",\n dropTitle: \"اسحب الملفات وأفلتها هنا\",\n dropTitleOne: \"اسحب ملفًا وأفلته هنا\",\n dropActive: \"أفلت للإضافة\",\n or: \"أو\",\n browse: \"تصفّح الملفات\",\n usePhone: \"استخدم هاتفك\",\n hintTypes: \"{types} · حتى {size}\",\n hintAny: \"أي ملف · حتى {size}\",\n hintCount: \"حتى {count} ملفات\",\n phoneTitle: \"امسح الرمز بهاتفك\",\n phoneStep1: \"افتح كاميرا هاتفك وامسح الرمز\",\n phoneStep2: \"اختر الصور أو الملفات على هاتفك\",\n phoneStep3: \"تظهر هنا فور وصولها\",\n phoneCode: \"لا توجد كاميرا؟ افتح {host} واكتب\",\n back: \"رجوع\",\n doneWithPhone: \"تم\",\n sourcePhone: \"من الهاتف\",\n sourceDevice: \"هذا الجهاز\",\n remove: \"إزالة {name}\",\n tooLarge: \"{name} أكبر من {size}.\",\n wrongType: \"{name} ليس من أنواع الملفات المقبولة.\",\n tooMany: \"يمكنك إضافة {count} ملفات كحد أقصى.\",\n fileCount: \"{count} ملفات\",\n clearAll: \"إزالة الكل\",\n announceText: \"انقل الصور بين هاتفك وكمبيوترك في أي وقت عبر Wi-Fi.\",\n announceLink: \"حمّل TokShare للكمبيوتر\",\n announceHide: \"إخفاء\",\n};\n\nexport const STRINGS: Record<Locale, Strings> = { en, ar };\nexport type StringKey = keyof Strings;\n\nexport function resolveLocale(requested: Locale | \"auto\" | undefined): Locale {\n if (requested === \"en\" || requested === \"ar\") return requested;\n const page = typeof document !== \"undefined\" ? document.documentElement.lang : \"\";\n const language = page || (typeof navigator !== \"undefined\" ? navigator.language : \"en\");\n return /^ar\\b/i.test(language) ? \"ar\" : \"en\";\n}\n\nexport function translator(locale: Locale, overrides: Partial<Strings> = {}) {\n return (key: StringKey, values: Record<string, string | number> = {}) =>\n (overrides[key] ?? STRINGS[locale][key]).replace(/\\{(\\w+)\\}/g, (_, name: string) => String(values[name] ?? \"\"));\n}\n\nexport function formatBytes(bytes: number, locale: Locale): string {\n const units = locale === \"ar\" ? [\"بايت\", \"ك.ب\", \"م.ب\", \"ج.ب\"] : [\"B\", \"KB\", \"MB\", \"GB\"];\n let value = bytes;\n let unit = 0;\n while (value >= 1000 && unit < units.length - 1) { value /= 1000; unit++; }\n return `${(value >= 100 || unit === 0 ? Math.round(value) : Math.round(value * 10) / 10).toLocaleString(locale)} ${units[unit]}`;\n}\n","var QrCodeDataType = /* @__PURE__ */ ((QrCodeDataType2) => {\n QrCodeDataType2[QrCodeDataType2[\"Border\"] = -1] = \"Border\";\n QrCodeDataType2[QrCodeDataType2[\"Data\"] = 0] = \"Data\";\n QrCodeDataType2[QrCodeDataType2[\"Function\"] = 1] = \"Function\";\n QrCodeDataType2[QrCodeDataType2[\"Position\"] = 2] = \"Position\";\n QrCodeDataType2[QrCodeDataType2[\"Timing\"] = 3] = \"Timing\";\n QrCodeDataType2[QrCodeDataType2[\"Alignment\"] = 4] = \"Alignment\";\n return QrCodeDataType2;\n})(QrCodeDataType || {});\n\nconst LOW = [0, 1];\nconst MEDIUM = [1, 0];\nconst QUARTILE = [2, 3];\nconst HIGH = [3, 2];\nconst EccMap = {\n L: LOW,\n M: MEDIUM,\n Q: QUARTILE,\n H: HIGH\n};\nconst NUMERIC_REGEX = /^\\d*$/;\nconst ALPHANUMERIC_REGEX = /^[A-Z0-9 $%*+./:-]*$/;\nconst ALPHANUMERIC_CHARSET = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:\";\nconst MIN_VERSION = 1;\nconst MAX_VERSION = 40;\nconst PENALTY_N1 = 3;\nconst PENALTY_N2 = 3;\nconst PENALTY_N3 = 40;\nconst PENALTY_N4 = 10;\nconst ECC_CODEWORDS_PER_BLOCK = [\n // Version: (note that index 0 is for padding, and is set to an illegal value)\n // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level\n [-1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],\n // Low\n [-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28],\n // Medium\n [-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],\n // Quartile\n [-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]\n // High\n];\nconst NUM_ERROR_CORRECTION_BLOCKS = [\n // Version: (note that index 0 is for padding, and is set to an illegal value)\n // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level\n [-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25],\n // Low\n [-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49],\n // Medium\n [-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68],\n // Quartile\n [-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81]\n // High\n];\nclass QrCode {\n /* -- Constructor (low level) and fields -- */\n // Creates a new QR Code with the given version number,\n // error correction level, data codeword bytes, and mask number.\n // This is a low-level API that most users should not use directly.\n // A mid-level API is the encodeSegments() function.\n constructor(version, ecc, dataCodewords, msk) {\n this.version = version;\n this.ecc = ecc;\n if (version < MIN_VERSION || version > MAX_VERSION)\n throw new RangeError(\"Version value out of range\");\n if (msk < -1 || msk > 7)\n throw new RangeError(\"Mask value out of range\");\n this.size = version * 4 + 17;\n const row = Array.from({ length: this.size }).fill(false);\n for (let i = 0; i < this.size; i++) {\n this.modules.push(row.slice());\n this.types.push(row.map(() => 0));\n }\n this.drawFunctionPatterns();\n const allCodewords = this.addEccAndInterleave(dataCodewords);\n this.drawCodewords(allCodewords);\n if (msk === -1) {\n let minPenalty = 1e9;\n for (let i = 0; i < 8; i++) {\n this.applyMask(i);\n this.drawFormatBits(i);\n const penalty = this.getPenaltyScore();\n if (penalty < minPenalty) {\n msk = i;\n minPenalty = penalty;\n }\n this.applyMask(i);\n }\n }\n this.mask = msk;\n this.applyMask(msk);\n this.drawFormatBits(msk);\n }\n /* -- Fields -- */\n // The width and height of this QR Code, measured in modules, between\n // 21 and 177 (inclusive). This is equal to version * 4 + 17.\n size;\n // The index of the mask pattern used in this QR Code, which is between 0 and 7 (inclusive).\n // Even if a QR Code is created with automatic masking requested (mask = -1),\n // the resulting object still has a mask value between 0 and 7.\n mask;\n // The modules of this QR Code (false = light, true = dark).\n // Immutable after constructor finishes. Accessed through getModule().\n modules = [];\n types = [];\n /* -- Accessor methods -- */\n // Returns the color of the module (pixel) at the given coordinates, which is false\n // for light or true for dark. The top left corner has the coordinates (x=0, y=0).\n // If the given coordinates are out of bounds, then false (light) is returned.\n getModule(x, y) {\n return x >= 0 && x < this.size && y >= 0 && y < this.size && this.modules[y][x];\n }\n /* -- Private helper methods for constructor: Drawing function modules -- */\n // Reads this object's version field, and draws and marks all function modules.\n drawFunctionPatterns() {\n for (let i = 0; i < this.size; i++) {\n this.setFunctionModule(6, i, i % 2 === 0, QrCodeDataType.Timing);\n this.setFunctionModule(i, 6, i % 2 === 0, QrCodeDataType.Timing);\n }\n this.drawFinderPattern(3, 3);\n this.drawFinderPattern(this.size - 4, 3);\n this.drawFinderPattern(3, this.size - 4);\n const alignPatPos = this.getAlignmentPatternPositions();\n const numAlign = alignPatPos.length;\n for (let i = 0; i < numAlign; i++) {\n for (let j = 0; j < numAlign; j++) {\n if (!(i === 0 && j === 0 || i === 0 && j === numAlign - 1 || i === numAlign - 1 && j === 0))\n this.drawAlignmentPattern(alignPatPos[i], alignPatPos[j]);\n }\n }\n this.drawFormatBits(0);\n this.drawVersion();\n }\n // Draws two copies of the format bits (with its own error correction code)\n // based on the given mask and this object's error correction level field.\n drawFormatBits(mask) {\n const data = this.ecc[1] << 3 | mask;\n let rem = data;\n for (let i = 0; i < 10; i++)\n rem = rem << 1 ^ (rem >>> 9) * 1335;\n const bits = (data << 10 | rem) ^ 21522;\n for (let i = 0; i <= 5; i++)\n this.setFunctionModule(8, i, getBit(bits, i));\n this.setFunctionModule(8, 7, getBit(bits, 6));\n this.setFunctionModule(8, 8, getBit(bits, 7));\n this.setFunctionModule(7, 8, getBit(bits, 8));\n for (let i = 9; i < 15; i++)\n this.setFunctionModule(14 - i, 8, getBit(bits, i));\n for (let i = 0; i < 8; i++)\n this.setFunctionModule(this.size - 1 - i, 8, getBit(bits, i));\n for (let i = 8; i < 15; i++)\n this.setFunctionModule(8, this.size - 15 + i, getBit(bits, i));\n this.setFunctionModule(8, this.size - 8, true);\n }\n // Draws two copies of the version bits (with its own error correction code),\n // based on this object's version field, iff 7 <= version <= 40.\n drawVersion() {\n if (this.version < 7)\n return;\n let rem = this.version;\n for (let i = 0; i < 12; i++)\n rem = rem << 1 ^ (rem >>> 11) * 7973;\n const bits = this.version << 12 | rem;\n for (let i = 0; i < 18; i++) {\n const color = getBit(bits, i);\n const a = this.size - 11 + i % 3;\n const b = Math.floor(i / 3);\n this.setFunctionModule(a, b, color);\n this.setFunctionModule(b, a, color);\n }\n }\n // Draws a 9*9 finder pattern including the border separator,\n // with the center module at (x, y). Modules can be out of bounds.\n drawFinderPattern(x, y) {\n for (let dy = -4; dy <= 4; dy++) {\n for (let dx = -4; dx <= 4; dx++) {\n const dist = Math.max(Math.abs(dx), Math.abs(dy));\n const xx = x + dx;\n const yy = y + dy;\n if (xx >= 0 && xx < this.size && yy >= 0 && yy < this.size)\n this.setFunctionModule(xx, yy, dist !== 2 && dist !== 4, QrCodeDataType.Position);\n }\n }\n }\n // Draws a 5*5 alignment pattern, with the center module\n // at (x, y). All modules must be in bounds.\n drawAlignmentPattern(x, y) {\n for (let dy = -2; dy <= 2; dy++) {\n for (let dx = -2; dx <= 2; dx++) {\n this.setFunctionModule(\n x + dx,\n y + dy,\n Math.max(Math.abs(dx), Math.abs(dy)) !== 1,\n QrCodeDataType.Alignment\n );\n }\n }\n }\n // Sets the color of a module and marks it as a function module.\n // Only used by the constructor. Coordinates must be in bounds.\n setFunctionModule(x, y, isDark, type = QrCodeDataType.Function) {\n this.modules[y][x] = isDark;\n this.types[y][x] = type;\n }\n /* -- Private helper methods for constructor: Codewords and masking -- */\n // Returns a new byte string representing the given data with the appropriate error correction\n // codewords appended to it, based on this object's version and error correction level.\n addEccAndInterleave(data) {\n const ver = this.version;\n const ecl = this.ecc;\n if (data.length !== getNumDataCodewords(ver, ecl))\n throw new RangeError(\"Invalid argument\");\n const numBlocks = NUM_ERROR_CORRECTION_BLOCKS[ecl[0]][ver];\n const blockEccLen = ECC_CODEWORDS_PER_BLOCK[ecl[0]][ver];\n const rawCodewords = Math.floor(getNumRawDataModules(ver) / 8);\n const numShortBlocks = numBlocks - rawCodewords % numBlocks;\n const shortBlockLen = Math.floor(rawCodewords / numBlocks);\n const blocks = [];\n const rsDiv = reedSolomonComputeDivisor(blockEccLen);\n for (let i = 0, k = 0; i < numBlocks; i++) {\n const dat = data.slice(k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1));\n k += dat.length;\n const ecc = reedSolomonComputeRemainder(dat, rsDiv);\n if (i < numShortBlocks)\n dat.push(0);\n blocks.push(dat.concat(ecc));\n }\n const result = [];\n for (let i = 0; i < blocks[0].length; i++) {\n blocks.forEach((block, j) => {\n if (i !== shortBlockLen - blockEccLen || j >= numShortBlocks)\n result.push(block[i]);\n });\n }\n return result;\n }\n // Draws the given sequence of 8-bit codewords (data and error correction) onto the entire\n // data area of this QR Code. Function modules need to be marked off before this is called.\n drawCodewords(data) {\n if (data.length !== Math.floor(getNumRawDataModules(this.version) / 8))\n throw new RangeError(\"Invalid argument\");\n let i = 0;\n for (let right = this.size - 1; right >= 1; right -= 2) {\n if (right === 6)\n right = 5;\n for (let vert = 0; vert < this.size; vert++) {\n for (let j = 0; j < 2; j++) {\n const x = right - j;\n const upward = (right + 1 & 2) === 0;\n const y = upward ? this.size - 1 - vert : vert;\n if (!this.types[y][x] && i < data.length * 8) {\n this.modules[y][x] = getBit(data[i >>> 3], 7 - (i & 7));\n i++;\n }\n }\n }\n }\n }\n // XORs the codeword modules in this QR Code with the given mask pattern.\n // The function modules must be marked and the codeword bits must be drawn\n // before masking. Due to the arithmetic of XOR, calling applyMask() with\n // the same mask value a second time will undo the mask. A final well-formed\n // QR Code needs exactly one (not zero, two, etc.) mask applied.\n applyMask(mask) {\n if (mask < 0 || mask > 7)\n throw new RangeError(\"Mask value out of range\");\n for (let y = 0; y < this.size; y++) {\n for (let x = 0; x < this.size; x++) {\n let invert;\n switch (mask) {\n case 0:\n invert = (x + y) % 2 === 0;\n break;\n case 1:\n invert = y % 2 === 0;\n break;\n case 2:\n invert = x % 3 === 0;\n break;\n case 3:\n invert = (x + y) % 3 === 0;\n break;\n case 4:\n invert = (Math.floor(x / 3) + Math.floor(y / 2)) % 2 === 0;\n break;\n case 5:\n invert = x * y % 2 + x * y % 3 === 0;\n break;\n case 6:\n invert = (x * y % 2 + x * y % 3) % 2 === 0;\n break;\n case 7:\n invert = ((x + y) % 2 + x * y % 3) % 2 === 0;\n break;\n default:\n throw new Error(\"Unreachable\");\n }\n if (!this.types[y][x] && invert)\n this.modules[y][x] = !this.modules[y][x];\n }\n }\n }\n // Calculates and returns the penalty score based on state of this QR Code's current modules.\n // This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.\n getPenaltyScore() {\n let result = 0;\n for (let y = 0; y < this.size; y++) {\n let runColor = false;\n let runX = 0;\n const runHistory = [0, 0, 0, 0, 0, 0, 0];\n for (let x = 0; x < this.size; x++) {\n if (this.modules[y][x] === runColor) {\n runX++;\n if (runX === 5)\n result += PENALTY_N1;\n else if (runX > 5)\n result++;\n } else {\n this.finderPenaltyAddHistory(runX, runHistory);\n if (!runColor)\n result += this.finderPenaltyCountPatterns(runHistory) * PENALTY_N3;\n runColor = this.modules[y][x];\n runX = 1;\n }\n }\n result += this.finderPenaltyTerminateAndCount(runColor, runX, runHistory) * PENALTY_N3;\n }\n for (let x = 0; x < this.size; x++) {\n let runColor = false;\n let runY = 0;\n const runHistory = [0, 0, 0, 0, 0, 0, 0];\n for (let y = 0; y < this.size; y++) {\n if (this.modules[y][x] === runColor) {\n runY++;\n if (runY === 5)\n result += PENALTY_N1;\n else if (runY > 5)\n result++;\n } else {\n this.finderPenaltyAddHistory(runY, runHistory);\n if (!runColor)\n result += this.finderPenaltyCountPatterns(runHistory) * PENALTY_N3;\n runColor = this.modules[y][x];\n runY = 1;\n }\n }\n result += this.finderPenaltyTerminateAndCount(runColor, runY, runHistory) * PENALTY_N3;\n }\n for (let y = 0; y < this.size - 1; y++) {\n for (let x = 0; x < this.size - 1; x++) {\n const color = this.modules[y][x];\n if (color === this.modules[y][x + 1] && color === this.modules[y + 1][x] && color === this.modules[y + 1][x + 1]) {\n result += PENALTY_N2;\n }\n }\n }\n let dark = 0;\n for (const row of this.modules)\n dark = row.reduce((sum, color) => sum + (color ? 1 : 0), dark);\n const total = this.size * this.size;\n const k = Math.ceil(Math.abs(dark * 20 - total * 10) / total) - 1;\n result += k * PENALTY_N4;\n return result;\n }\n /* -- Private helper functions -- */\n // Returns an ascending list of positions of alignment patterns for this version number.\n // Each position is in the range [0,177), and are used on both the x and y axes.\n // This could be implemented as lookup table of 40 variable-length lists of integers.\n getAlignmentPatternPositions() {\n if (this.version === 1) {\n return [];\n } else {\n const numAlign = Math.floor(this.version / 7) + 2;\n const step = this.version === 32 ? 26 : Math.ceil((this.version * 4 + 4) / (numAlign * 2 - 2)) * 2;\n const result = [6];\n for (let pos = this.size - 7; result.length < numAlign; pos -= step)\n result.splice(1, 0, pos);\n return result;\n }\n }\n // Can only be called immediately after a light run is added, and\n // returns either 0, 1, or 2. A helper function for getPenaltyScore().\n finderPenaltyCountPatterns(runHistory) {\n const n = runHistory[1];\n const core = n > 0 && runHistory[2] === n && runHistory[3] === n * 3 && runHistory[4] === n && runHistory[5] === n;\n return (core && runHistory[0] >= n * 4 && runHistory[6] >= n ? 1 : 0) + (core && runHistory[6] >= n * 4 && runHistory[0] >= n ? 1 : 0);\n }\n // Must be called at the end of a line (row or column) of modules. A helper function for getPenaltyScore().\n finderPenaltyTerminateAndCount(currentRunColor, currentRunLength, runHistory) {\n if (currentRunColor) {\n this.finderPenaltyAddHistory(currentRunLength, runHistory);\n currentRunLength = 0;\n }\n currentRunLength += this.size;\n this.finderPenaltyAddHistory(currentRunLength, runHistory);\n return this.finderPenaltyCountPatterns(runHistory);\n }\n // Pushes the given value to the front and drops the last value. A helper function for getPenaltyScore().\n finderPenaltyAddHistory(currentRunLength, runHistory) {\n if (runHistory[0] === 0)\n currentRunLength += this.size;\n runHistory.pop();\n runHistory.unshift(currentRunLength);\n }\n}\nfunction appendBits(val, len, bb) {\n if (len < 0 || len > 31 || val >>> len !== 0)\n throw new RangeError(\"Value out of range\");\n for (let i = len - 1; i >= 0; i--)\n bb.push(val >>> i & 1);\n}\nfunction getBit(x, i) {\n return (x >>> i & 1) !== 0;\n}\nclass QrSegment {\n // Creates a new QR Code segment with the given attributes and data.\n // The character count (numChars) must agree with the mode and the bit buffer length,\n // but the constraint isn't checked. The given bit buffer is cloned and stored.\n constructor(mode, numChars, bitData) {\n this.mode = mode;\n this.numChars = numChars;\n this.bitData = bitData;\n if (numChars < 0)\n throw new RangeError(\"Invalid argument\");\n this.bitData = bitData.slice();\n }\n /* -- Methods -- */\n // Returns a new copy of the data bits of this segment.\n getData() {\n return this.bitData.slice();\n }\n}\nconst MODE_NUMERIC = [1, 10, 12, 14];\nconst MODE_ALPHANUMERIC = [2, 9, 11, 13];\nconst MODE_BYTE = [4, 8, 16, 16];\nfunction numCharCountBits(mode, ver) {\n return mode[Math.floor((ver + 7) / 17) + 1];\n}\nfunction makeBytes(data) {\n const bb = [];\n for (const b of data)\n appendBits(b, 8, bb);\n return new QrSegment(MODE_BYTE, data.length, bb);\n}\nfunction makeNumeric(digits) {\n if (!isNumeric(digits))\n throw new RangeError(\"String contains non-numeric characters\");\n const bb = [];\n for (let i = 0; i < digits.length; ) {\n const n = Math.min(digits.length - i, 3);\n appendBits(Number.parseInt(digits.substring(i, i + n), 10), n * 3 + 1, bb);\n i += n;\n }\n return new QrSegment(MODE_NUMERIC, digits.length, bb);\n}\nfunction makeAlphanumeric(text) {\n if (!isAlphanumeric(text))\n throw new RangeError(\"String contains unencodable characters in alphanumeric mode\");\n const bb = [];\n let i;\n for (i = 0; i + 2 <= text.length; i += 2) {\n let temp = ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)) * 45;\n temp += ALPHANUMERIC_CHARSET.indexOf(text.charAt(i + 1));\n appendBits(temp, 11, bb);\n }\n if (i < text.length)\n appendBits(ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)), 6, bb);\n return new QrSegment(MODE_ALPHANUMERIC, text.length, bb);\n}\nfunction makeSegments(text) {\n if (text === \"\")\n return [];\n else if (isNumeric(text))\n return [makeNumeric(text)];\n else if (isAlphanumeric(text))\n return [makeAlphanumeric(text)];\n else\n return [makeBytes(toUtf8ByteArray(text))];\n}\nfunction isNumeric(text) {\n return NUMERIC_REGEX.test(text);\n}\nfunction isAlphanumeric(text) {\n return ALPHANUMERIC_REGEX.test(text);\n}\nfunction getTotalBits(segs, version) {\n let result = 0;\n for (const seg of segs) {\n const ccbits = numCharCountBits(seg.mode, version);\n if (seg.numChars >= 1 << ccbits)\n return Number.POSITIVE_INFINITY;\n result += 4 + ccbits + seg.bitData.length;\n }\n return result;\n}\nfunction toUtf8ByteArray(str) {\n str = encodeURI(str);\n const result = [];\n for (let i = 0; i < str.length; i++) {\n if (str.charAt(i) !== \"%\") {\n result.push(str.charCodeAt(i));\n } else {\n result.push(Number.parseInt(str.substring(i + 1, i + 3), 16));\n i += 2;\n }\n }\n return result;\n}\nfunction getNumRawDataModules(ver) {\n if (ver < MIN_VERSION || ver > MAX_VERSION)\n throw new RangeError(\"Version number out of range\");\n let result = (16 * ver + 128) * ver + 64;\n if (ver >= 2) {\n const numAlign = Math.floor(ver / 7) + 2;\n result -= (25 * numAlign - 10) * numAlign - 55;\n if (ver >= 7)\n result -= 36;\n }\n return result;\n}\nfunction getNumDataCodewords(ver, ecl) {\n return Math.floor(getNumRawDataModules(ver) / 8) - ECC_CODEWORDS_PER_BLOCK[ecl[0]][ver] * NUM_ERROR_CORRECTION_BLOCKS[ecl[0]][ver];\n}\nfunction reedSolomonComputeDivisor(degree) {\n if (degree < 1 || degree > 255)\n throw new RangeError(\"Degree out of range\");\n const result = [];\n for (let i = 0; i < degree - 1; i++)\n result.push(0);\n result.push(1);\n let root = 1;\n for (let i = 0; i < degree; i++) {\n for (let j = 0; j < result.length; j++) {\n result[j] = reedSolomonMultiply(result[j], root);\n if (j + 1 < result.length)\n result[j] ^= result[j + 1];\n }\n root = reedSolomonMultiply(root, 2);\n }\n return result;\n}\nfunction reedSolomonComputeRemainder(data, divisor) {\n const result = divisor.map((_) => 0);\n for (const b of data) {\n const factor = b ^ result.shift();\n result.push(0);\n divisor.forEach((coef, i) => result[i] ^= reedSolomonMultiply(coef, factor));\n }\n return result;\n}\nfunction reedSolomonMultiply(x, y) {\n if (x >>> 8 !== 0 || y >>> 8 !== 0)\n throw new RangeError(\"Byte out of range\");\n let z = 0;\n for (let i = 7; i >= 0; i--) {\n z = z << 1 ^ (z >>> 7) * 285;\n z ^= (y >>> i & 1) * x;\n }\n return z;\n}\nfunction encodeSegments(segs, ecl, minVersion = 1, maxVersion = 40, mask = -1, boostEcl = true) {\n if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7) {\n throw new RangeError(\"Invalid value\");\n }\n let version;\n let dataUsedBits;\n for (version = minVersion; ; version++) {\n const dataCapacityBits2 = getNumDataCodewords(version, ecl) * 8;\n const usedBits = getTotalBits(segs, version);\n if (usedBits <= dataCapacityBits2) {\n dataUsedBits = usedBits;\n break;\n }\n if (version >= maxVersion)\n throw new RangeError(\"Data too long\");\n }\n for (const newEcl of [MEDIUM, QUARTILE, HIGH]) {\n if (boostEcl && dataUsedBits <= getNumDataCodewords(version, newEcl) * 8)\n ecl = newEcl;\n }\n const bb = [];\n for (const seg of segs) {\n appendBits(seg.mode[0], 4, bb);\n appendBits(seg.numChars, numCharCountBits(seg.mode, version), bb);\n for (const b of seg.getData())\n bb.push(b);\n }\n const dataCapacityBits = getNumDataCodewords(version, ecl) * 8;\n appendBits(0, Math.min(4, dataCapacityBits - bb.length), bb);\n appendBits(0, (8 - bb.length % 8) % 8, bb);\n for (let padByte = 236; bb.length < dataCapacityBits; padByte ^= 236 ^ 17)\n appendBits(padByte, 8, bb);\n const dataCodewords = Array.from({ length: Math.ceil(bb.length / 8) }, () => 0);\n bb.forEach((b, i) => dataCodewords[i >>> 3] |= b << 7 - (i & 7));\n return new QrCode(version, ecl, dataCodewords, mask);\n}\n\nfunction encode(data, options) {\n const {\n ecc = \"L\",\n boostEcc = false,\n minVersion = 1,\n maxVersion = 40,\n maskPattern = -1,\n border = 1\n } = options || {};\n const segment = typeof data === \"string\" ? makeSegments(data) : Array.isArray(data) ? [makeBytes(data)] : void 0;\n if (!segment)\n throw new Error(`uqr only supports encoding string and binary data, but got: ${typeof data}`);\n const qr = encodeSegments(\n segment,\n EccMap[ecc],\n minVersion,\n maxVersion,\n maskPattern,\n boostEcc\n );\n const result = addBorder({\n version: qr.version,\n maskPattern: qr.mask,\n size: qr.size,\n data: qr.modules,\n types: qr.types\n }, border);\n if (options?.invert)\n result.data = result.data.map((row) => row.map((mod) => !mod));\n options?.onEncoded?.(result);\n return result;\n}\nfunction addBorder(input, border = 1) {\n if (!border)\n return input;\n const { size } = input;\n const newSize = size + border * 2;\n input.size = newSize;\n input.data.forEach((row) => {\n for (let i = 0; i < border; i++) {\n row.unshift(false);\n row.push(false);\n }\n });\n for (let i = 0; i < border; i++) {\n input.data.unshift(Array.from({ length: newSize }, (_) => false));\n input.data.push(Array.from({ length: newSize }, (_) => false));\n }\n const b = QrCodeDataType.Border;\n input.types.forEach((row) => {\n for (let i = 0; i < border; i++) {\n row.unshift(b);\n row.push(b);\n }\n });\n for (let i = 0; i < border; i++) {\n input.types.unshift(Array.from({ length: newSize }, (_) => b));\n input.types.push(Array.from({ length: newSize }, (_) => b));\n }\n return input;\n}\nfunction getDataAt(data, x, y, defaults = false) {\n if (x < 0 || y < 0 || x >= data.length || y >= data.length)\n return defaults;\n return data[y][x];\n}\n\nfunction renderUnicode(data, options = {}) {\n const {\n whiteChar = \"\\u2588\",\n blackChar = \"\\u2591\"\n } = options;\n const result = encode(data, options);\n return result.data.map((row) => {\n return row.map((mod) => mod ? blackChar : whiteChar).join(\"\");\n }).join(\"\\n\");\n}\nfunction renderANSI(data, options = {}) {\n return renderUnicode(data, {\n ...options,\n blackChar: \"\\x1B[40m\\u3000\\x1B[0m\",\n whiteChar: \"\\x1B[47m\\u3000\\x1B[0m\"\n });\n}\nfunction renderUnicodeCompact(data, options = {}) {\n const palette = {\n WHITE_ALL: \"\\u2588\",\n WHITE_BLACK: \"\\u2580\",\n BLACK_WHITE: \"\\u2584\",\n BLACK_ALL: \" \"\n };\n const result = encode(data, options);\n const WHITE = false;\n const BLACK = true;\n const at = (x, y) => getDataAt(result.data, x, y, true);\n const lines = [];\n let line = \"\";\n for (let row = 0; row < result.size; row += 2) {\n for (let col = 0; col < result.size; col++) {\n if (at(col, row) === WHITE && at(col, row + 1) === WHITE)\n line += palette.WHITE_ALL;\n else if (at(col, row) === WHITE && at(col, row + 1) === BLACK)\n line += palette.WHITE_BLACK;\n else if (at(col, row) === BLACK && at(col, row + 1) === WHITE)\n line += palette.BLACK_WHITE;\n else\n line += palette.BLACK_ALL;\n }\n lines.push(line);\n line = \"\";\n }\n return lines.join(\"\\n\");\n}\n\nfunction escapeAttr(value) {\n return value.replace(/&/g, \"&\").replace(/\"/g, \""\").replace(/</g, \"<\").replace(/>/g, \">\");\n}\nfunction renderSVG(data, options = {}) {\n const result = encode(data, options);\n const {\n pixelSize = 10,\n whiteColor = \"white\",\n blackColor = \"black\"\n } = options;\n const height = result.size * pixelSize;\n const width = result.size * pixelSize;\n let svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\">`;\n const paths = [];\n for (let row = 0; row < result.size; row++) {\n for (let col = 0; col < result.size; col++) {\n const x = col * pixelSize;\n const y = row * pixelSize;\n if (result.data[row][col])\n paths.push(`M${x},${y}h${pixelSize}v${pixelSize}h-${pixelSize}z`);\n }\n }\n svg += `<rect fill=\"${escapeAttr(whiteColor)}\" width=\"${width}\" height=\"${height}\"/>`;\n svg += `<path fill=\"${escapeAttr(blackColor)}\" d=\"${paths.join(\"\")}\"/>`;\n svg += \"</svg>\";\n return svg;\n}\n\nexport { QrCodeDataType, encode, renderANSI, renderSVG, renderUnicode, renderUnicodeCompact };\n","import { encode } from \"uqr\";\n\n/** Draws a QR code for `text` on a canvas (no images, so strict CSPs are fine). */\nexport function drawQr(canvas: HTMLCanvasElement, text: string, cssSize: number): void {\n const qr = encode(text, { ecc: \"M\", border: 2 });\n const scale = Math.max(1, Math.min(window.devicePixelRatio || 1, 3));\n canvas.width = canvas.height = Math.round(cssSize * scale);\n const context = canvas.getContext(\"2d\");\n if (!context) return;\n const cell = canvas.width / qr.size;\n context.fillStyle = \"#fff\";\n context.fillRect(0, 0, canvas.width, canvas.height);\n context.fillStyle = \"#000\";\n qr.data.forEach((line, y) => line.forEach((dark, x) => {\n if (dark) context.fillRect(Math.floor(x * cell), Math.floor(y * cell), Math.ceil(cell), Math.ceil(cell));\n }));\n}\n\n/** \"K7Q29XHM\" → \"K7Q2-9XHM\". */\nexport const formatCode = (code: string) => `${code.slice(0, 4)}-${code.slice(4)}`;\n","// \"auto\" matches the page the component sits on, not the computer's dark-mode setting: a light page in\n// dark mode still gets a light field. Reads the first solid background behind the element.\n\nfunction luminance(color: string): number | null {\n const match = /rgba?\\(([\\d.]+)[,\\s]+([\\d.]+)[,\\s]+([\\d.]+)(?:[,\\s/]+([\\d.]+%?))?\\)/.exec(color);\n if (!match) return null;\n const alpha = match[4] === undefined ? 1 : match[4].endsWith(\"%\") ? Number.parseFloat(match[4]) / 100 : Number(match[4]);\n if (alpha < 0.5) return null;\n const [r, g, b] = [match[1], match[2], match[3]].map((value) => {\n const channel = Number(value) / 255;\n return channel <= 0.03928 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4;\n }) as [number, number, number];\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n\nexport function pageTheme(element: Element | null): \"light\" | \"dark\" {\n for (let node: Element | null = element; node; node = node.parentElement) {\n const value = luminance(getComputedStyle(node).backgroundColor);\n if (value !== null) return value < 0.3 ? \"dark\" : \"light\";\n }\n // Nothing painted: the canvas follows the page's color-scheme.\n const scheme = getComputedStyle(document.documentElement).colorScheme || \"\";\n if (/\\bdark\\b/.test(scheme) && !/\\blight\\b/.test(scheme)) return \"dark\";\n if (/\\blight\\b/.test(scheme) && /\\bdark\\b/.test(scheme)) return matchMedia?.(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\";\n return \"light\";\n}\n\nexport function resolveTheme(requested: \"light\" | \"dark\" | \"auto\" | undefined, element: Element | null): \"light\" | \"dark\" {\n return requested === \"light\" || requested === \"dark\" ? requested : pageTheme(element);\n}\n","// The modal's styles, in TokShare's colors: lime buttons with ink text, violet highlights. Customize from\n// the host page with CSS variables on the host element, e.g.\n// [data-tokshare-pick] { --tsp-accent: #0b6bcb; --tsp-accent-text: #fff; --tsp-radius: 12px; }\n// --tsp-accent fills buttons and progress; --tsp-accent-ink (links, focus rings) follows it unless set.\nexport const STYLES = `\n:host { all: initial; }\n.overlay {\n /* Light. Lime is unreadable as text on white, so links and focus rings use a deeper violet. */\n --accent: var(--tsp-accent, #c8ff4d);\n --accent-text: var(--tsp-accent-text, #0b0d12);\n --accent-ink: var(--tsp-accent-ink, var(--tsp-accent, #6b4fe0));\n --accent-2: var(--tsp-accent-2, var(--tsp-accent, #8a6cf5));\n --button-edge: rgba(11, 13, 18, .1);\n --bg: var(--tsp-bg, #fff);\n --text: var(--tsp-text, #0b0d12);\n --muted: var(--tsp-muted, #5d6270);\n --line: var(--tsp-line, rgba(11, 13, 18, .12));\n --track: rgba(11, 13, 18, .08);\n --ok: #1a8a4c;\n --error: #c42f3d;\n --radius: var(--tsp-radius, 18px);\n position: fixed; inset: 0; z-index: 2147483000;\n display: grid; place-items: center; padding: 16px;\n background: rgba(9, 11, 16, .6);\n font: 15px/1.5 var(--tsp-font, Inter, system-ui, -apple-system, \"Segoe UI\", Roboto, \"Noto Sans Arabic\", sans-serif);\n color: var(--text);\n animation: fade .15s ease-out;\n}\n@media (prefers-color-scheme: dark) {\n .overlay[data-theme=\"auto\"] { --accent-ink: var(--tsp-accent-ink, var(--tsp-accent, #c8ff4d)); --accent-2: var(--tsp-accent-2, var(--tsp-accent, #9a7cff)); --button-edge: transparent; --bg: var(--tsp-bg, #12151c); --text: var(--tsp-text, #f4f4f5); --muted: var(--tsp-muted, #9297a4); --line: var(--tsp-line, rgba(255,255,255,.09)); --track: rgba(255,255,255,.08); --ok: #c8ff4d; --error: #ff8a94; }\n}\n.overlay[data-theme=\"dark\"] { --accent-ink: var(--tsp-accent-ink, var(--tsp-accent, #c8ff4d)); --accent-2: var(--tsp-accent-2, var(--tsp-accent, #9a7cff)); --button-edge: transparent; --bg: var(--tsp-bg, #12151c); --text: var(--tsp-text, #f4f4f5); --muted: var(--tsp-muted, #9297a4); --line: var(--tsp-line, rgba(255,255,255,.09)); --track: rgba(255,255,255,.08); --ok: #c8ff4d; --error: #ff8a94; }\n* { box-sizing: border-box; }\n[hidden] { display: none !important; }\n.dialog {\n width: min(420px, 100%); max-height: calc(100dvh - 32px); overflow: auto;\n background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius);\n box-shadow: 0 30px 80px rgba(0, 0, 0, .35); padding: 20px; display: grid; gap: 14px; outline: none;\n}\n.header { display: flex; align-items: center; justify-content: space-between; gap: 12px; }\n.title { margin: 0; font-size: 18px; font-weight: 700; line-height: 1.3; }\n.icon-button { all: unset; cursor: pointer; width: 32px; height: 32px; display: grid; place-items: center; border-radius: 50%; font-size: 22px; color: var(--muted); }\n.icon-button:hover { background: var(--track); color: var(--text); }\n.qr-block { display: grid; justify-items: center; gap: 8px; text-align: center; }\n.qr { width: 220px; height: 220px; border-radius: 12px; background: #fff; border: 1px solid var(--line); image-rendering: pixelated; }\n.lead { margin: 4px 0 0; font-weight: 600; }\n.muted { margin: 0; color: var(--muted); font-size: 13.5px; }\n.small { font-size: 12px; }\n.code { display: inline-block; direction: ltr; font: 700 15px/1.3 ui-monospace, \"SF Mono\", Menlo, Consolas, monospace; letter-spacing: 1.5px; color: var(--text); padding: 2px 8px; border-radius: 6px; background: var(--track); }\n.status { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 4px 10px; text-align: center; font-size: 14px; min-height: 22px; }\n.approval { display: grid; gap: 8px; width: 100%; padding: 14px; border: 1px solid var(--line); border-radius: 14px; text-align: center; }\n.files { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }\n.files:empty { display: none; }\n.file { display: grid; gap: 3px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px; }\n.file .name { font-weight: 600; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.file .meta { color: var(--muted); font-size: 12px; }\n.file .bar { height: 4px; border-radius: 4px; background: var(--track); overflow: hidden; margin-top: 3px; }\n.file .fill { display: block; height: 100%; width: 0; background: linear-gradient(90deg, var(--accent-2), var(--accent)); transition: width .2s; }\n.file.received .meta { color: var(--ok); }\n.file.received .fill { background: var(--ok); }\n.file.failed .meta { color: var(--error); }\n.file.failed .bar { display: none; }\n.footer { display: grid; gap: 12px; }\n.buttons { display: flex; gap: 10px; justify-content: flex-end; }\nbutton.primary, button.secondary { font: inherit; font-weight: 600; cursor: pointer; border-radius: 12px; padding: 10px 16px; min-height: 42px; border: 1px solid transparent; }\nbutton.primary { background: var(--accent); color: var(--accent-text); border-color: var(--button-edge); box-shadow: inset 0 1px 0 rgba(255,255,255,.45), 0 8px 24px -8px color-mix(in srgb, var(--accent) 60%, transparent); }\nbutton.primary:hover:not(:disabled) { background: color-mix(in srgb, var(--accent) 85%, #fff); }\nbutton.primary:disabled { opacity: .45; cursor: default; box-shadow: none; }\nbutton.secondary { background: transparent; color: var(--text); border-color: var(--line); }\nbutton.secondary:hover { background: var(--track); }\nbutton.link { all: unset; cursor: pointer; color: var(--accent-ink); font-weight: 600; font-size: 13.5px; text-decoration: underline; text-underline-offset: 3px; }\nbutton:focus-visible, .icon-button:focus-visible { outline: 3px solid var(--accent-ink); outline-offset: 2px; }\n/* ---- TokShare for desktop ---- */\n.announce { margin: 0; display: flex; align-items: center; gap: 10px; padding: 9px 8px 9px 12px; border-radius: 12px; border: 1px solid var(--line); background: color-mix(in srgb, var(--accent-2) 7%, transparent); color: var(--muted); font-size: 12.5px; line-height: 1.45; text-align: start; }\n.announce i { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--accent-2); }\n.announce span { flex: 1; min-width: 0; }\n.announce a { color: var(--accent-ink); font-weight: 650; text-decoration: underline; text-underline-offset: 2px; white-space: nowrap; }\n.announce-hide { all: unset; cursor: pointer; flex: none; width: 24px; height: 24px; display: grid; place-items: center; border-radius: 50%; font-size: 16px; color: var(--muted); }\n.announce-hide:hover { background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--text); }\n.announce-hide:focus-visible, .announce a:focus-visible { outline: 3px solid color-mix(in srgb, var(--accent-ink) 60%, transparent); outline-offset: 2px; }\n@keyframes fade { from { opacity: 0; } }\n@media (prefers-reduced-motion: reduce) { .overlay { animation: none; } .file .fill { transition: none; } }\n`;\n","// The built-in modal, in a Shadow DOM so the host page's styles can't break it (and it can't break\n// them). Styles go in through a constructable stylesheet and the QR is drawn on a canvas, so a strict\n// Content-Security-Policy on the host page needs nothing extra beyond connect-src for the relay.\nimport type { FileMeta } from \"@tokshare/pick-protocol\";\nimport { announcement } from \"./announce\";\nimport { formatBytes, resolveLocale, translator } from \"./i18n\";\nimport { drawQr } from \"./qr\";\nimport { resolveTheme } from \"./theme\";\nimport type { PickController, PickOptions } from \"./picker\";\nimport { STYLES } from \"./styles\";\n\ninterface Row { element: HTMLLIElement; meta: FileMeta; state: \"sending\" | \"receiving\" | \"received\" | \"failed\"; percent: number }\n\nexport function mountModal(controller: PickController, options: PickOptions): void {\n const locale = resolveLocale(options.locale);\n const t = translator(locale, options.strings);\n const previousFocus = document.activeElement as HTMLElement | null;\n const host = document.createElement(\"div\");\n host.setAttribute(\"data-tokshare-pick\", \"\");\n const root = host.attachShadow({ mode: \"open\" });\n if (\"adoptedStyleSheets\" in Document.prototype && \"replaceSync\" in CSSStyleSheet.prototype) {\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(STYLES);\n root.adoptedStyleSheets = [sheet];\n } else {\n const style = document.createElement(\"style\");\n style.textContent = STYLES;\n root.append(style);\n }\n\n const el = <K extends keyof HTMLElementTagNameMap>(tag: K, className = \"\", text = \"\") => {\n const node = document.createElement(tag);\n if (className) node.className = className;\n if (text) node.textContent = text;\n return node;\n };\n\n const overlay = el(\"div\", \"overlay\");\n overlay.dataset.theme = resolveTheme(options.theme, document.body);\n const dialog = el(\"div\", \"dialog\");\n dialog.setAttribute(\"role\", \"dialog\");\n dialog.setAttribute(\"aria-modal\", \"true\");\n dialog.setAttribute(\"aria-labelledby\", \"tsp-title\");\n dialog.dir = locale === \"ar\" ? \"rtl\" : \"ltr\";\n dialog.lang = locale;\n dialog.tabIndex = -1;\n\n const header = el(\"div\", \"header\");\n const title = el(\"h2\", \"title\", t(options.multiple === false ? \"titleOne\" : \"title\"));\n title.id = \"tsp-title\";\n const closeButton = el(\"button\", \"icon-button\", \"×\");\n closeButton.type = \"button\";\n closeButton.setAttribute(\"aria-label\", t(\"close\"));\n header.append(title, closeButton);\n\n const qrBlock = el(\"div\", \"qr-block\");\n const canvas = el(\"canvas\", \"qr\");\n canvas.setAttribute(\"role\", \"img\");\n canvas.setAttribute(\"aria-label\", t(\"scan\"));\n const scan = el(\"p\", \"lead\", t(\"scan\"));\n const typeLine = el(\"p\", \"muted\");\n const code = el(\"span\", \"code\");\n qrBlock.append(canvas, scan, typeLine);\n\n const status = el(\"div\", \"status\");\n status.setAttribute(\"role\", \"status\");\n status.setAttribute(\"aria-live\", \"polite\");\n const list = el(\"ul\", \"files\");\n const footer = el(\"div\", \"footer\");\n const privacy = el(\"p\", \"muted small\", t(\"privacy\"));\n const buttons = el(\"div\", \"buttons\");\n const cancelButton = el(\"button\", \"secondary\", t(\"cancel\"));\n cancelButton.type = \"button\";\n const doneButton = el(\"button\", \"primary\", t(\"done\"));\n doneButton.type = \"button\";\n doneButton.disabled = true;\n buttons.append(cancelButton, doneButton);\n const promo = announcement(options.announce, t);\n footer.append(...(promo ? [promo] : []), privacy, buttons);\n dialog.append(header, qrBlock, status, list, footer);\n overlay.append(dialog);\n root.append(overlay);\n document.body.append(host);\n dialog.focus();\n\n const rows = new Map<string, Row>();\n let phoneLabel = \"\";\n\n const setStatus = (text: string, extra?: HTMLElement) => {\n status.replaceChildren(el(\"span\", \"\", text), ...(extra ? [extra] : []));\n };\n\n const showQr = (claimUrl: string, value: string) => {\n drawQr(canvas, claimUrl, 220);\n const host = new URL(claimUrl).host;\n code.textContent = `${value.slice(0, 4)}-${value.slice(4)}`;\n typeLine.replaceChildren(document.createTextNode(`${t(\"orType\", { host })} `), code);\n qrBlock.hidden = false;\n setStatus(t(\"waiting\"));\n };\n\n const updateDone = () => {\n const count = controller.files.length;\n doneButton.disabled = count === 0;\n doneButton.textContent = count === 0 ? t(\"done\") : count === 1 ? t(\"useFile\") : t(\"useFiles\", { count });\n };\n\n const renderRow = (row: Row) => {\n const label = row.state === \"sending\" ? t(\"sending\", { percent: row.percent })\n : row.state === \"receiving\" ? t(\"receiving\", { percent: row.percent })\n : t(row.state);\n row.element.className = `file ${row.state}`;\n const bar = el(\"span\", \"bar\");\n const fill = el(\"i\", \"fill\");\n fill.style.width = `${row.state === \"received\" ? 100 : row.percent}%`;\n bar.append(fill);\n row.element.replaceChildren(el(\"span\", \"name\", row.meta.name), el(\"span\", \"meta\", `${formatBytes(row.meta.size, locale)} · ${label}`), bar);\n };\n\n const rowFor = (meta: FileMeta): Row => {\n let row = rows.get(meta.id);\n if (!row) {\n row = { element: el(\"li\"), meta, state: \"sending\", percent: 0 };\n rows.set(meta.id, row);\n list.append(row.element);\n }\n return row;\n };\n\n let direct = false;\n const showConnected = () => {\n const disconnect = el(\"button\", \"link\", t(\"disconnect\"));\n disconnect.type = \"button\";\n disconnect.addEventListener(\"click\", () => { controller.disconnect().catch(() => undefined); });\n setStatus(t(direct ? \"connectedDirect\" : \"connected\", { label: phoneLabel }), disconnect);\n };\n\n const closeModal = () => {\n document.removeEventListener(\"keydown\", onKey, true);\n host.remove();\n previousFocus?.focus?.();\n };\n const onKey = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") { event.stopPropagation(); controller.cancel(); }\n if (event.key === \"Tab\") {\n // Keep focus inside the dialog.\n const focusable = [...root.querySelectorAll<HTMLElement>(\"button:not([disabled])\")];\n if (!focusable.length) return;\n const first = focusable[0]!;\n const last = focusable[focusable.length - 1]!;\n const active = root.activeElement;\n if (event.shiftKey && (active === first || active === dialog)) { event.preventDefault(); last.focus(); }\n else if (!event.shiftKey && active === last) { event.preventDefault(); first.focus(); }\n }\n };\n document.addEventListener(\"keydown\", onKey, true);\n closeButton.addEventListener(\"click\", () => controller.cancel());\n cancelButton.addEventListener(\"click\", () => controller.cancel());\n doneButton.addEventListener(\"click\", () => controller.finish());\n overlay.addEventListener(\"click\", (event) => { if (event.target === overlay) controller.cancel(); });\n\n qrBlock.hidden = true;\n setStatus(t(\"loading\"));\n\n controller.on(\"ready\", ({ claimUrl, code: value }) => showQr(claimUrl, value));\n controller.on(\"phone\", ({ phone, needsApproval, match }) => {\n phoneLabel = phone.label;\n qrBlock.hidden = true;\n if (needsApproval) {\n const box = el(\"div\", \"approval\");\n const approve = el(\"button\", \"primary\", t(\"approve\"));\n const reject = el(\"button\", \"secondary\", t(\"reject\"));\n approve.type = reject.type = \"button\";\n approve.addEventListener(\"click\", () => { controller.approve(); showConnected(); });\n reject.addEventListener(\"click\", () => controller.reject());\n box.append(el(\"strong\", \"\", t(\"approveTitle\")), el(\"span\", \"muted\", `${phone.label} · ${t(\"approveMatch\", { match: match ?? \"\" })}`), el(\"div\", \"buttons\", \"\"));\n box.lastElementChild!.append(reject, approve);\n status.replaceChildren(box);\n approve.focus();\n } else showConnected();\n });\n controller.on(\"phone_left\", () => { direct = false; setStatus(t(\"phoneLeft\")); });\n controller.on(\"direct\", ({ connected }) => { direct = connected; if (phoneLabel) showConnected(); });\n controller.on(\"file_started\", (meta) => renderRow(rowFor(meta)));\n controller.on(\"progress\", (progress) => {\n const row = rows.get(progress.id);\n if (!row) return;\n row.state = progress.phase === \"upload\" ? \"sending\" : \"receiving\";\n row.percent = progress.total ? Math.floor((progress.sent / progress.total) * 100) : 0;\n renderRow(row);\n });\n controller.on(\"received\", ({ id }) => {\n const row = rows.get(id);\n if (row) { row.state = \"received\"; renderRow(row); }\n updateDone();\n });\n controller.on(\"file_failed\", ({ id }) => {\n const row = rows.get(id);\n if (row) { row.state = \"failed\"; renderRow(row); }\n });\n controller.on(\"error\", (error) => {\n qrBlock.hidden = true;\n const retry = el(\"button\", \"link\", t(\"tryAgain\"));\n retry.type = \"button\";\n retry.addEventListener(\"click\", () => { setStatus(t(\"loading\")); controller.restart(); });\n setStatus(t(\"error\", { message: error.message }), retry);\n });\n controller.on(\"close\", (reason) => {\n if (reason === \"finished\" || reason === \"canceled\" || controller.files.length) return closeModal();\n qrBlock.hidden = true;\n const again = el(\"button\", \"link\", t(\"newCode\"));\n again.type = \"button\";\n again.addEventListener(\"click\", () => { setStatus(t(\"loading\")); controller.restart(); });\n setStatus(t(\"expired\"), again);\n });\n controller.done.then(closeModal);\n}\n","// The website's side of a relay session: create it, keep its WebSocket alive (replaying anything\n// missed after a drop), stream finished files into File objects, and close it.\nimport {\n type CreateSessionResponse, type DesktopCommand, type DesktopEvent, type ErrorCode, type FileMeta,\n PickError, type SessionOptions,\n} from \"@tokshare/pick-protocol\";\nimport { SDK_VERSION } from \"./config\";\n\n/** Requests are text/plain JSON: \"simple\" requests, so the browser sends no CORS preflight. */\nasync function post(url: string, body: unknown): Promise<Response> {\n let response: Response;\n try {\n response = await fetch(url, { method: \"POST\", headers: { \"Content-Type\": \"text/plain\" }, body: JSON.stringify(body), cache: \"no-store\", credentials: \"omit\" });\n } catch {\n throw new PickError(\"network\", \"Can't reach TokShare Pick.\", 0);\n }\n if (!response.ok) {\n const data = await response.json().catch(() => ({}));\n throw new PickError((data.error as ErrorCode) || \"internal\", data.message || `HTTP ${response.status}`, response.status);\n }\n return response;\n}\n\nexport class RelaySession {\n readonly info: CreateSessionResponse;\n private readonly relay: string;\n private ws: WebSocket | null = null;\n private lastSeq = 0;\n private closed = false;\n private attempt = 0;\n private pinger: ReturnType<typeof setInterval> | undefined;\n private readonly onEvent: (event: DesktopEvent) => void;\n\n private constructor(relay: string, info: CreateSessionResponse, onEvent: (event: DesktopEvent) => void) {\n this.relay = relay;\n this.info = info;\n this.onEvent = onEvent;\n }\n\n static async create(relay: string, key: string, options: SessionOptions, onEvent: (event: DesktopEvent) => void): Promise<RelaySession> {\n const response = await post(`${relay}/v1/sessions`, { key, options, client: `sdk/${SDK_VERSION}` });\n const session = new RelaySession(relay, (await response.json()) as CreateSessionResponse, onEvent);\n session.connect();\n return session;\n }\n\n private connect(): void {\n if (this.closed) return;\n const ws = new WebSocket(this.info.wsUrl);\n this.ws = ws;\n ws.addEventListener(\"open\", () => {\n this.attempt = 0;\n ws.send(JSON.stringify({ t: \"auth\", token: this.info.desktopToken, lastSeq: this.lastSeq } satisfies DesktopCommand));\n this.pinger = setInterval(() => { if (ws.readyState === WebSocket.OPEN) ws.send(\"ping\"); }, 25_000);\n });\n ws.addEventListener(\"message\", (message) => {\n if (message.data === \"pong\") return;\n let event: DesktopEvent;\n try { event = JSON.parse(message.data as string); } catch { return; }\n if (\"seq\" in event && event.t !== \"hello\") {\n if (event.seq <= this.lastSeq) return;\n this.lastSeq = event.seq;\n }\n if (event.t === \"closed\") this.closed = true;\n this.onEvent(event);\n });\n ws.addEventListener(\"close\", (event) => {\n clearInterval(this.pinger);\n if (this.closed || event.code === 4401) return;\n setTimeout(() => this.connect(), Math.min(10_000, 400 * 2 ** this.attempt++));\n });\n }\n\n send(command: DesktopCommand): void {\n if (this.ws?.readyState === WebSocket.OPEN) this.ws.send(JSON.stringify(command));\n }\n\n /** Streams a finished file from the relay. Reports bytes received; retries a dropped stream. */\n async download(meta: FileMeta, onProgress: (received: number) => void): Promise<File> {\n for (let attempt = 0; ; attempt++) {\n try {\n const response = await post(`${this.relay}/v1/sessions/${this.info.sid}/files/${meta.id}/download`, { token: this.info.desktopToken });\n const reader = response.body!.getReader();\n const chunks: Uint8Array[] = [];\n let received = 0;\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n received += value.byteLength;\n onProgress(received);\n }\n if (received !== meta.size) throw new PickError(\"network\", \"Incomplete download.\", 0);\n return new File(chunks as BlobPart[], meta.name, { type: meta.type || meta.sniffed || \"\", lastModified: meta.lastModified });\n } catch (error) {\n if (!(error instanceof PickError && error.code === \"network\") || attempt >= 2) throw error;\n await new Promise((resolve) => setTimeout(resolve, 600 * (attempt + 1)));\n }\n }\n }\n\n /** A file that came over the direct link: delivered (counted, phone told), or refused and why. */\n directResult(id: string, ok: boolean, code?: string): Promise<unknown> {\n return post(`${this.relay}/v1/sessions/${this.info.sid}/files/${id}/direct`, { token: this.info.desktopToken, ok, ...(code ? { code } : {}) }).catch(() => undefined);\n }\n\n ack(id: string): Promise<unknown> {\n return post(`${this.relay}/v1/sessions/${this.info.sid}/files/${id}/ack`, { token: this.info.desktopToken }).catch(() => undefined);\n }\n\n /** Forget the connected phone and get a new QR and code. */\n async rekey(): Promise<{ claimUrl: string; code: string }> {\n const response = await post(`${this.relay}/v1/sessions/${this.info.sid}/rekey`, { token: this.info.desktopToken });\n const fresh = (await response.json()) as { claimUrl: string; code: string };\n Object.assign(this.info, fresh);\n return fresh;\n }\n\n /** Ends the session: the relay deletes anything left. Uses a beacon while the page is unloading. */\n close(unloading = false): void {\n if (this.closed) return;\n this.closed = true;\n clearInterval(this.pinger);\n const url = `${this.relay}/v1/sessions/${this.info.sid}/close`;\n const body = JSON.stringify({ token: this.info.desktopToken });\n if (unloading && typeof navigator !== \"undefined\" && navigator.sendBeacon) navigator.sendBeacon(url, new Blob([body], { type: \"text/plain\" }));\n else post(url, { token: this.info.desktopToken }).catch(() => undefined);\n try { this.ws?.close(1000, \"closed\"); } catch {}\n }\n\n get isClosed(): boolean {\n return this.closed;\n }\n}\n","// The picker: one relay session, its events, and the files it collects. The modal (modal.ts) is one\n// way to show it; `ui: false` gives the same controller with no UI.\nimport { type CloseReason, type DesktopEvent, type FileMeta, type Locale, PickError, type PhoneInfo, type SessionOptions } from \"@tokshare/pick-protocol\";\nimport { DEFAULT_RELAY } from \"./config\";\nimport type { StringKey } from \"./i18n\";\nimport { DirectReceiver, verifyDirectFile } from \"./direct\";\nimport { mountModal } from \"./modal\";\nimport { RelaySession } from \"./session\";\n\nexport interface PickOptions extends Omit<SessionOptions, \"locale\"> {\n /** Your publishable key (pk_live_… or pk_test_…). */\n key: string;\n /** Relay URL. Defaults to the hosted relay. */\n relay?: string;\n /** \"auto\" follows the page's lang attribute, then the browser. */\n locale?: Locale | \"auto\";\n /** false: no modal; use the controller's events, claimUrl and code to build your own UI. */\n ui?: boolean;\n theme?: \"light\" | \"dark\" | \"auto\";\n /** Replace any of the modal's strings. */\n strings?: Partial<Record<StringKey, string>>;\n /** A small, dismissible line about TokShare for desktop in the modal and the field. Default true. */\n announce?: boolean;\n signal?: AbortSignal;\n}\n\nexport interface ProgressInfo {\n id: string;\n name: string;\n sent: number;\n total: number;\n /** \"upload\": phone → relay (or straight to this page over Wi-Fi). \"download\": relay → this page. */\n phase: \"upload\" | \"download\";\n}\n\nexport interface PickEvents {\n ready: { claimUrl: string; code: string };\n phone: { phone: PhoneInfo; needsApproval: boolean; match?: string };\n phone_left: undefined;\n /** The phone is on the same network and files come straight to this page (true), or not any more. */\n direct: { connected: boolean };\n file_started: FileMeta;\n progress: ProgressInfo;\n file: File;\n /** The same file, with the relay id its progress events used. */\n received: { id: string; file: File };\n file_failed: { id: string; code: string };\n error: PickError;\n close: CloseReason | \"canceled\" | \"finished\";\n}\n\nexport interface PickController {\n /** Resolves with the received files when the person finishes; [] if canceled before any arrived. */\n readonly done: Promise<File[]>;\n /** Files received so far. */\n readonly files: readonly File[];\n readonly claimUrl: string | null;\n readonly code: string | null;\n on<E extends keyof PickEvents>(event: E, handler: (detail: PickEvents[E]) => void): () => void;\n /** Use the files received so far. */\n finish(): void;\n /** Close without files. */\n cancel(): void;\n approve(): void;\n reject(): void;\n /** Forget the connected phone and show a new code. */\n disconnect(): Promise<void>;\n /** Start over with a new session (after an expiry or error). */\n restart(): void;\n}\n\nexport function open(options: PickOptions): PickController {\n if (!options || typeof options.key !== \"string\") throw new PickError(\"key_invalid\", \"Pass your publishable key: open({ key: 'pk_live_…' }).\");\n const relay = (options.relay || DEFAULT_RELAY).replace(/\\/+$/, \"\");\n const handlers = new Map<keyof PickEvents, Set<(detail: any) => void>>();\n const emit = <E extends keyof PickEvents>(event: E, detail: PickEvents[E]) => {\n for (const handler of handlers.get(event) ?? []) { try { handler(detail); } catch (error) { console.error(error); } }\n };\n const files: File[] = [];\n const handled = new Set<string>();\n const metas = new Map<string, FileMeta>();\n const pending = new Set<Promise<unknown>>();\n /** Files that came over the direct link (a late cloud copy of one is just cleaned up). */\n const directDone = new Set<string>();\n const metaWaiters = new Map<string, (meta: FileMeta) => void>();\n let session: RelaySession | null = null;\n let receiver: DirectReceiver | null = null;\n let settled = false;\n let resolveDone!: (files: File[]) => void;\n const done = new Promise<File[]>((resolve) => { resolveDone = resolve; });\n const multiple = options.multiple !== false;\n const sessionOptions: SessionOptions = {\n ...(options.accept !== undefined ? { accept: options.accept } : {}),\n multiple,\n ...(options.maxFiles !== undefined ? { maxFiles: options.maxFiles } : {}),\n ...(options.maxFileBytes !== undefined ? { maxFileBytes: options.maxFileBytes } : {}),\n ...(options.resizeImages ? { resizeImages: options.resizeImages } : {}),\n ...(options.confirmPhone ? { confirmPhone: true } : {}),\n ...(options.siteName ? { siteName: options.siteName } : {}),\n ...(options.locale === \"ar\" || options.locale === \"en\" ? { locale: options.locale } : {}),\n ...(options.direct === false ? { direct: false } : {}),\n };\n let maxFiles = multiple ? options.maxFiles ?? 20 : 1;\n\n const settle = (reason: PickEvents[\"close\"], result: File[]) => {\n if (settled) return;\n settled = true;\n removeEventListener(\"pagehide\", onPageHide);\n receiver?.close();\n session?.close();\n emit(\"close\", reason);\n resolveDone(result);\n };\n const onPageHide = () => session?.close(true);\n\n const receive = (meta: FileMeta) => {\n // Already here over Wi-Fi, but the phone also sent it through the cloud (it gave up waiting for\n // our answer): just let the relay delete the copy.\n if (directDone.has(meta.id)) { session?.ack(meta.id); return; }\n if (handled.has(meta.id) || !session) return;\n handled.add(meta.id);\n const current = session;\n const task = current.download(meta, (received) => emit(\"progress\", { id: meta.id, name: meta.name, sent: received, total: meta.size, phase: \"download\" }))\n .then(async (file) => {\n await current.ack(meta.id);\n if (settled) return;\n files.push(file);\n emit(\"received\", { id: meta.id, file });\n emit(\"file\", file);\n if (files.length >= maxFiles) controller.finish();\n })\n .catch((error) => emit(\"file_failed\", { id: meta.id, code: error instanceof PickError ? error.code : \"network\" }))\n .finally(() => pending.delete(task));\n pending.add(task);\n };\n\n const knownMeta = (id: string): Promise<FileMeta | null> => {\n const meta = metas.get(id);\n if (meta) return Promise.resolve(meta);\n // The bytes can beat the relay's file_started event: wait for it a little.\n return new Promise((resolve) => {\n const timer = setTimeout(() => { metaWaiters.delete(id); resolve(null); }, 10_000);\n metaWaiters.set(id, (value) => { clearTimeout(timer); metaWaiters.delete(id); resolve(value); });\n });\n };\n\n /** A file that came over the direct link: same checks as the relay, then keep it and tell the relay. */\n const completeDirect = async (id: string, chunks: Uint8Array[], size: number): Promise<{ ok: true } | { ok: false; code: string }> => {\n const current = session;\n const meta = await knownMeta(id);\n if (!current || !meta || settled || handled.has(id)) return { ok: false, code: \"failed\" };\n const result = verifyDirectFile(meta, chunks, size, current.info.options.accept, current.info.options.maxFileBytes);\n if (!result.ok) {\n current.directResult(id, false, result.code);\n return result;\n }\n handled.add(id);\n directDone.add(id);\n current.directResult(id, true);\n files.push(result.file);\n emit(\"received\", { id, file: result.file });\n emit(\"file\", result.file);\n if (files.length >= maxFiles) controller.finish();\n return { ok: true };\n };\n\n const directReceiver = (current: RelaySession): DirectReceiver | null => {\n if (options.direct === false || !DirectReceiver.supported()) return null;\n if (!receiver) {\n receiver = new DirectReceiver((d) => current.send({ t: \"rtc\", d }), {\n progress: (id, received, total) => emit(\"progress\", { id, name: metas.get(id)?.name ?? \"\", sent: received, total, phase: \"upload\" }),\n complete: completeDirect,\n state: (connected) => emit(\"direct\", { connected }),\n });\n }\n return receiver;\n };\n\n const onEvent = (event: DesktopEvent) => {\n switch (event.t) {\n case \"rtc\": if (session) directReceiver(session)?.onSignal(event.d); break;\n case \"hello\":\n // Files that finished while this page was disconnected: announce, then fetch them.\n for (const meta of event.files) {\n if (!handled.has(meta.id)) { metas.set(meta.id, meta); emit(\"file_started\", meta); }\n receive(meta);\n }\n break;\n case \"phone\": emit(\"phone\", { phone: event.phone, needsApproval: event.needsApproval, ...(event.match ? { match: event.match } : {}) }); break;\n case \"phone_left\": receiver?.close(); emit(\"phone_left\", undefined); break;\n case \"file_started\":\n metas.set(event.file.id, event.file);\n metaWaiters.get(event.file.id)?.(event.file);\n emit(\"file_started\", event.file);\n break;\n case \"progress\": emit(\"progress\", { id: event.id, name: metas.get(event.id)?.name ?? \"\", sent: event.sent, total: event.total, phase: \"upload\" }); break;\n case \"file_ready\": receive(event.file); break;\n case \"file_failed\": emit(\"file_failed\", { id: event.id, code: event.code }); break;\n case \"phone_done\": if (files.length || pending.size) controller.finish(); break;\n case \"closed\":\n // The relay ended it (expiry, rejection): keep what arrived, otherwise let the UI offer a new code.\n if (files.length) settle(event.reason, [...files]);\n else emit(\"close\", event.reason);\n break;\n }\n };\n\n const start = () => {\n RelaySession.create(relay, options.key, sessionOptions, onEvent).then((created) => {\n if (settled) { created.close(); return; }\n session = created;\n maxFiles = created.info.options.maxFiles;\n emit(\"ready\", { claimUrl: created.info.claimUrl, code: created.info.code });\n }, (error: PickError) => emit(\"error\", error));\n };\n\n const controller: PickController = {\n done,\n get files() { return files; },\n get claimUrl() { return session?.info.claimUrl ?? null; },\n get code() { return session?.info.code ?? null; },\n on(event, handler) {\n if (!handlers.has(event)) handlers.set(event, new Set());\n handlers.get(event)!.add(handler);\n return () => handlers.get(event)?.delete(handler);\n },\n finish() {\n if (settled) return;\n // Let downloads that are already under way land first.\n Promise.allSettled([...pending]).then(() => settle(\"finished\", [...files]));\n },\n cancel() { settle(\"canceled\", []); },\n approve() { session?.send({ t: \"approve\" }); },\n reject() { session?.send({ t: \"reject\" }); },\n async disconnect() {\n if (!session) return;\n receiver?.close();\n const fresh = await session.rekey();\n emit(\"ready\", fresh);\n },\n restart() {\n if (settled) return;\n receiver?.close();\n receiver = null;\n session?.close();\n session = null;\n start();\n },\n };\n\n addEventListener(\"pagehide\", onPageHide);\n options.signal?.addEventListener(\"abort\", () => controller.cancel(), { once: true });\n if (options.ui !== false) mountModal(controller, options);\n start();\n return controller;\n}\n\n/** Opens the picker and resolves with the files the person sent ([] if they canceled). */\nexport function pick(options: PickOptions): Promise<File[]> {\n return open(options).done;\n}\n\nexport interface AttachOptions extends Omit<PickOptions, \"accept\" | \"multiple\"> {\n /** \"replace\" (default) sets the input's files; \"append\" adds to what it already has. */\n mode?: \"replace\" | \"append\";\n}\n\n/** Fills an existing <input type=\"file\"> with files from the phone, firing input and change events,\n * so forms and frameworks that listen to the input keep working. Returns a function that does it. */\nexport function attach(input: HTMLInputElement, options: AttachOptions): () => Promise<File[]> {\n if (!(input instanceof HTMLInputElement) || input.type !== \"file\") throw new PickError(\"bad_request\", \"attach() needs an <input type=\\\"file\\\">.\");\n return async () => {\n const received = await pick({ ...options, accept: input.accept, multiple: input.multiple });\n if (!received.length) return received;\n const transfer = new DataTransfer();\n if (options.mode === \"append\" && input.multiple) for (const file of Array.from(input.files ?? [])) transfer.items.add(file);\n for (const file of input.multiple ? received : received.slice(0, 1)) transfer.items.add(file);\n input.files = transfer.files;\n input.dispatchEvent(new Event(\"input\", { bubbles: true }));\n input.dispatchEvent(new Event(\"change\", { bubbles: true }));\n return received;\n };\n}\n","// The upload field's styles, in TokShare's colors: lime buttons with ink text, violet highlights. Override\n// from the page with CSS variables on the field, e.g.\n// [data-tokshare-pick-field] { --tsp-accent: #0b6bcb; --tsp-accent-text: #fff; --tsp-radius: 14px; }\n// --tsp-accent fills buttons and progress; --tsp-accent-ink (borders, links, focus rings) follows it unless set.\nexport const FIELD_STYLES = `\n:host { display: block; }\n* { box-sizing: border-box; }\n[hidden] { display: none !important; }\n.wrap {\n /* Light. Lime is unreadable as text or a thin line on white, so those use a deeper violet. */\n --accent: var(--tsp-accent, #c8ff4d);\n --accent-text: var(--tsp-accent-text, #0b0d12);\n --accent-ink: var(--tsp-accent-ink, var(--tsp-accent, #6b4fe0));\n --accent-2: var(--tsp-accent-2, var(--tsp-accent, #8a6cf5));\n --button-edge: rgba(11, 13, 18, .1);\n --bg: var(--tsp-bg, #ffffff);\n --surface: var(--tsp-surface, #f6f7f9);\n --text: var(--tsp-text, #0b0d12);\n --muted: var(--tsp-muted, #5d6270);\n --line: var(--tsp-line, rgba(11, 13, 18, .12));\n --ok: #1a8a4c;\n --error: #c42f3d;\n --radius: var(--tsp-radius, 18px);\n container-type: inline-size;\n font: 14px/1.5 var(--tsp-font, Inter, system-ui, -apple-system, \"Segoe UI\", Roboto, \"Noto Sans Arabic\", sans-serif);\n color: var(--text);\n}\n@media (prefers-color-scheme: dark) {\n .wrap[data-theme=\"auto\"] { --accent-ink: var(--tsp-accent-ink, var(--tsp-accent, #c8ff4d)); --accent-2: var(--tsp-accent-2, var(--tsp-accent, #9a7cff)); --button-edge: transparent; --bg: var(--tsp-bg, #171a22); --surface: var(--tsp-surface, #12151c); --text: var(--tsp-text, #f4f4f5); --muted: var(--tsp-muted, #9297a4); --line: var(--tsp-line, rgba(255,255,255,.09)); --ok: #c8ff4d; --error: #ff8a94; }\n}\n.wrap[data-theme=\"dark\"] { --accent-ink: var(--tsp-accent-ink, var(--tsp-accent, #c8ff4d)); --accent-2: var(--tsp-accent-2, var(--tsp-accent, #9a7cff)); --button-edge: transparent; --bg: var(--tsp-bg, #171a22); --surface: var(--tsp-surface, #12151c); --text: var(--tsp-text, #f4f4f5); --muted: var(--tsp-muted, #9297a4); --line: var(--tsp-line, rgba(255,255,255,.09)); --ok: #c8ff4d; --error: #ff8a94; }\n\n/* ---- drop zone ---- */\n.zone {\n position: relative;\n border: 1.5px dashed color-mix(in srgb, var(--accent-ink) 42%, transparent);\n border-radius: var(--radius);\n background:\n radial-gradient(120% 90% at 50% 0%, color-mix(in srgb, var(--accent-2) 12%, transparent), transparent 70%),\n var(--surface);\n padding: 30px 22px;\n min-height: 232px;\n display: grid;\n align-items: center;\n transition: border-color .18s, background-color .18s, box-shadow .18s;\n}\n.zone[data-state=\"idle\"]:hover { border-color: color-mix(in srgb, var(--accent-ink) 70%, transparent); }\n.zone[data-drag] {\n border-style: solid;\n border-color: var(--accent-ink);\n background-color: color-mix(in srgb, var(--accent-ink) 8%, var(--surface));\n box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent-ink) 16%, transparent);\n}\n.zone[data-drag] .tile { transform: translateY(-3px) scale(1.06); }\n.idle { display: grid; justify-items: center; text-align: center; gap: 6px; }\n.tile {\n width: 56px; height: 56px; margin-bottom: 8px;\n display: grid; place-items: center;\n border-radius: 16px;\n background: linear-gradient(145deg, color-mix(in srgb, var(--accent) 80%, #fff), var(--accent));\n color: var(--accent-text);\n box-shadow: inset 0 1px 0 rgba(255,255,255,.45), inset 0 0 0 1px var(--button-edge), 0 12px 26px -6px color-mix(in srgb, var(--accent) 45%, transparent);\n transition: transform .2s;\n}\nsvg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; flex: none; }\n.tile svg { width: 26px; height: 26px; stroke-width: 2; }\n.title { margin: 0; font-size: 16px; font-weight: 650; letter-spacing: -.01em; }\n.hint { margin: 0; color: var(--muted); font-size: 13px; }\n.actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px; margin-top: 12px; }\n.or { color: var(--muted); font-size: 12.5px; }\n\nbutton { font: inherit; cursor: pointer; }\n.primary, .ghost {\n display: inline-flex; align-items: center; gap: 8px;\n min-height: 40px; padding: 8px 16px;\n border-radius: 11px; font-weight: 600; font-size: 14px;\n border: 1px solid transparent;\n transition: transform .12s, box-shadow .15s, background-color .15s, border-color .15s;\n}\n.primary { background: var(--accent); color: var(--accent-text); border-color: var(--button-edge); box-shadow: inset 0 1px 0 rgba(255,255,255,.45), 0 8px 22px -8px color-mix(in srgb, var(--accent) 60%, transparent); }\n.primary:hover { background: color-mix(in srgb, var(--accent) 85%, #fff); box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 12px 28px -8px color-mix(in srgb, var(--accent) 70%, transparent); }\n.ghost { background: var(--bg); color: var(--text); border-color: var(--line); }\n.ghost:hover { border-color: color-mix(in srgb, var(--accent-ink) 55%, transparent); color: var(--accent-ink); }\n.primary:active, .ghost:active { transform: translateY(1px); }\n.primary.small { min-height: 34px; padding: 6px 14px; font-size: 13px; }\n.link { all: unset; cursor: pointer; display: inline-flex; align-items: center; gap: 4px; color: var(--muted); font-weight: 600; font-size: 13px; }\n.link:hover { color: var(--text); }\nbutton:focus-visible, .link:focus-visible { outline: 3px solid color-mix(in srgb, var(--accent-ink) 60%, transparent); outline-offset: 2px; border-radius: 10px; }\n[dir=\"rtl\"] .flip { transform: scaleX(-1); }\n\n/* ---- phone, inside the field ---- */\n.phone-view { display: grid; grid-template-columns: auto 1fr; gap: 24px; align-items: center; }\n.qr-box { position: relative; width: 184px; height: 184px; padding: 8px; border-radius: 16px; background: #fff; border: 1px solid var(--line); box-shadow: 0 10px 30px rgba(15, 18, 30, .1); }\n.qr { width: 100%; height: 100%; display: block; image-rendering: pixelated; transition: opacity .25s, filter .25s; }\n.qr-box.dim .qr { opacity: .18; filter: blur(1px); }\n.qr-loading { display: none; position: absolute; inset: 8px; border-radius: 10px; background: linear-gradient(100deg, #eef0f5 30%, #f8f9fc 50%, #eef0f5 70%); background-size: 200% 100%; animation: shimmer 1.2s linear infinite; }\n.qr-box.loading .qr-loading { display: block; }\n.phone-info { display: grid; gap: 10px; min-width: 0; }\n.steps { margin: 0; padding: 0; list-style: none; counter-reset: step; display: grid; gap: 7px; }\n.steps li { counter-increment: step; display: flex; gap: 10px; align-items: baseline; color: var(--muted); font-size: 13.5px; }\n.steps li::before { content: counter(step); flex: none; width: 20px; height: 20px; display: inline-grid; place-items: center; border-radius: 50%; font-size: 11px; font-weight: 700; color: var(--accent-ink); background: color-mix(in srgb, var(--accent-ink) 14%, transparent); transform: translateY(4px); }\n.code-line { margin: 0; color: var(--muted); font-size: 12.5px; }\n.code-line b { direction: ltr; display: inline-block; font: 700 13px/1.4 ui-monospace, \"SF Mono\", Menlo, Consolas, monospace; letter-spacing: 1.2px; color: var(--text); background: var(--bg); border: 1px solid var(--line); padding: 1px 7px; border-radius: 6px; }\n.status { margin: 0; justify-self: start; display: inline-flex; align-items: center; gap: 8px; padding: 6px 12px; border-radius: 999px; background: var(--bg); border: 1px solid var(--line); font-size: 13px; font-weight: 600; }\n.status i { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); opacity: .6; }\n.status.live i { background: var(--ok); opacity: 1; box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 60%, transparent); animation: pulse 1.8s infinite; }\n.phone-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 2px; }\n.announce-slot { grid-column: 1 / -1; }\n/* ---- TokShare for desktop ---- */\n.announce { margin: 0; display: flex; align-items: center; gap: 10px; padding: 9px 8px 9px 12px; border-radius: 12px; border: 1px solid var(--line); background: color-mix(in srgb, var(--accent-2) 7%, transparent); color: var(--muted); font-size: 12.5px; line-height: 1.45; text-align: start; }\n.announce i { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--accent-2); }\n.announce span { flex: 1; min-width: 0; }\n.announce a { color: var(--accent-ink); font-weight: 650; text-decoration: underline; text-underline-offset: 2px; white-space: nowrap; }\n.announce-hide { all: unset; cursor: pointer; flex: none; width: 24px; height: 24px; display: grid; place-items: center; border-radius: 50%; font-size: 16px; color: var(--muted); }\n.announce-hide:hover { background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--text); }\n.announce-hide:focus-visible, .announce a:focus-visible { outline: 3px solid color-mix(in srgb, var(--accent-ink) 60%, transparent); outline-offset: 2px; }\n\n/* ---- messages and list ---- */\n.message { margin: 10px 2px 0; color: var(--error); font-size: 13px; }\n.list-head { display: flex; justify-content: space-between; align-items: center; margin: 14px 2px 6px; color: var(--muted); font-size: 12.5px; font-weight: 600; }\n.list { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 8px; }\n.list-head:not([hidden]) + .list { margin-top: 0; }\n.item { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 9px 10px 9px 9px; border: 1px solid var(--line); border-radius: 14px; background: var(--bg); animation: rise .2s ease-out; }\n.thumb { width: 44px; height: 44px; border-radius: 10px; overflow: hidden; display: grid; place-items: center; background: color-mix(in srgb, var(--accent-ink) 12%, transparent); color: var(--accent-ink); font-size: 10.5px; font-weight: 800; letter-spacing: .4px; }\n.thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }\n.body { display: grid; gap: 2px; min-width: 0; }\n.name { font-weight: 600; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.meta { color: var(--muted); font-size: 12px; }\n.bar { height: 4px; border-radius: 4px; margin-top: 4px; background: color-mix(in srgb, var(--accent-ink) 12%, transparent); overflow: hidden; }\n.bar i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, var(--accent-2), var(--accent)); border-radius: inherit; transition: width .2s; }\n.item.failed .meta { color: var(--error); }\n.remove { all: unset; cursor: pointer; width: 32px; height: 32px; display: grid; place-items: center; border-radius: 50%; color: var(--muted); }\n.remove:hover { background: color-mix(in srgb, var(--error) 10%, transparent); color: var(--error); }\n.remove svg { width: 16px; height: 16px; }\n\n@container (max-width: 520px) {\n .zone { padding: 24px 16px; }\n .phone-view { grid-template-columns: 1fr; justify-items: center; text-align: center; gap: 16px; }\n .steps li { text-align: start; }\n .status { justify-self: center; }\n}\n@keyframes shimmer { to { background-position: -200% 0; } }\n@keyframes pulse { 70% { box-shadow: 0 0 0 7px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }\n@keyframes rise { from { opacity: 0; transform: translateY(4px); } }\n@media (prefers-reduced-motion: reduce) { .zone, .tile, .qr, .bar i, .item { transition: none; animation: none; } .qr-loading, .status.live i { animation: none; } }\n`;\n","// A complete upload field: drop zone, Browse files, and \"Use your phone\", which opens inside the field\n// (QR, steps, live status) instead of a separate window. Files from either source land in one list\n// with thumbnails and remove buttons, and in a real <input type=\"file\" name> so forms submit them.\n//\n// mountField(\"#photos\", { key: \"pk_live_…\", name: \"photos\", accept: \"image/png,image/jpeg\", maxFileBytes: 5e6 });\n// <tokshare-pick-field key=\"pk_live_…\" name=\"photos\" accept=\"image/*\" max-size=\"5MB\" multiple></tokshare-pick-field>\nimport { announcement } from \"./announce\";\nimport { LIMITS, matchesAccept } from \"@tokshare/pick-protocol\";\nimport { FIELD_STYLES } from \"./fieldStyles\";\nimport { formatBytes, resolveLocale, translator } from \"./i18n\";\nimport { type PickController, type PickOptions, open } from \"./picker\";\nimport { drawQr, formatCode } from \"./qr\";\nimport { resolveTheme } from \"./theme\";\n\nexport interface FieldOptions extends Omit<PickOptions, \"ui\"> {\n /** Form field name: the files go into a hidden <input type=\"file\" name> inside the target. */\n name?: string;\n /** \"inline\" (default): the phone flow opens inside the field. \"modal\": in a window. false: no phone. */\n phone?: \"inline\" | \"modal\" | false;\n /** Show \"Use your phone\" even when this page itself is open on a phone. */\n phoneOnMobile?: boolean;\n /** Replaces the drop zone's title. */\n label?: string;\n}\n\nexport interface FieldController {\n readonly files: readonly File[];\n /** The hidden input the files are kept in (for forms and frameworks). */\n readonly input: HTMLInputElement;\n on(event: \"change\", handler: (files: File[]) => void): () => void;\n remove(file: File): void;\n clear(): void;\n destroy(): void;\n}\n\ntype Source = \"device\" | \"phone\";\ninterface Item { key: string; file: File | null; name: string; size: number; source: Source; percent: number; phase?: \"upload\" | \"download\"; failed?: boolean; url?: string; element?: HTMLLIElement }\n\nconst ICONS = {\n upload: '<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M12 15V4m0 0L7.5 8.5M12 4l4.5 4.5M5 14v4a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-4\"/></svg>',\n folder: '<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M3.5 7.5a2 2 0 0 1 2-2h4l2 2h7a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-13a2 2 0 0 1-2-2z\"/></svg>',\n phone: '<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><rect x=\"7\" y=\"2.5\" width=\"10\" height=\"19\" rx=\"2.5\"/><path d=\"M11 18.5h2\"/></svg>',\n close: '<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M7 7l10 10M17 7 7 17\"/></svg>',\n back: '<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" class=\"flip\"><path d=\"M14.5 6 8.5 12l6 6\"/></svg>',\n};\n\n/** \"5MB\", \"500 KB\", \"2e6\" → bytes. */\nexport function parseSize(value: string | number | null | undefined): number | undefined {\n if (value === null || value === undefined || value === \"\") return undefined;\n if (typeof value === \"number\") return value > 0 ? value : undefined;\n const match = /^\\s*([\\d.]+)\\s*(b|kb|mb|gb)?\\s*$/i.exec(value);\n if (!match) return undefined;\n const units: Record<string, number> = { b: 1, kb: 1e3, mb: 1e6, gb: 1e9 };\n const bytes = Number(match[1]) * units[(match[2] ?? \"b\").toLowerCase()]!;\n return bytes > 0 ? Math.round(bytes) : undefined;\n}\n\nfunction acceptLabel(accept: string): string {\n return accept.split(\",\").map((part) => part.trim()).filter(Boolean).map((part) => {\n if (part.endsWith(\"/*\")) return part.slice(0, -2).replace(/^./, (letter) => letter.toUpperCase()) + \"s\";\n if (part.startsWith(\".\")) return part.slice(1).toUpperCase();\n const sub = part.split(\"/\")[1] ?? part;\n return (sub === \"jpeg\" ? \"JPG\" : sub.replace(/^(x-|vnd\\.)/, \"\").split(/[.+-]/)[0]!.toUpperCase());\n }).filter((label, index, all) => all.indexOf(label) === index).join(\", \");\n}\n\nconst isPhonePage = () => typeof matchMedia === \"function\" && matchMedia(\"(pointer: coarse)\").matches && innerWidth < 820;\n\nexport function mountField(target: HTMLElement | string, options: FieldOptions): FieldController {\n const container = typeof target === \"string\" ? document.querySelector<HTMLElement>(target) : target;\n if (!container) throw new Error(`TokShare Pick: ${String(target)} not found`);\n const locale = resolveLocale(options.locale);\n const t = translator(locale, options.strings);\n const multiple = options.multiple !== false;\n const maxFiles = multiple ? Math.min(options.maxFiles ?? LIMITS.maxFiles, LIMITS.maxFiles) : 1;\n const maxBytes = Math.min(options.maxFileBytes ?? LIMITS.maxFileBytes, LIMITS.maxFileBytes);\n const accept = options.accept ?? \"\";\n const phoneMode = options.phone === false ? false : options.phone ?? \"inline\";\n const showPhone = phoneMode !== false && (options.phoneOnMobile || !isPhonePage());\n\n // The real input forms submit. Kept in the page (light DOM), hidden.\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.hidden = true;\n input.multiple = multiple;\n if (accept) input.accept = accept;\n if (options.name) input.name = options.name;\n const host = document.createElement(\"div\");\n host.setAttribute(\"data-tokshare-pick-field\", \"\");\n container.append(host, input);\n const root = host.attachShadow({ mode: \"open\" });\n if (\"adoptedStyleSheets\" in Document.prototype && \"replaceSync\" in CSSStyleSheet.prototype) {\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(FIELD_STYLES);\n root.adoptedStyleSheets = [sheet];\n } else {\n const style = document.createElement(\"style\");\n style.textContent = FIELD_STYLES;\n root.append(style);\n }\n\n const hint = [\n accept ? t(\"hintTypes\", { types: acceptLabel(accept), size: formatBytes(maxBytes, locale) }) : t(\"hintAny\", { size: formatBytes(maxBytes, locale) }),\n multiple ? t(\"hintCount\", { count: maxFiles }) : \"\",\n ].filter(Boolean).join(\" · \");\n\n const wrap = document.createElement(\"div\");\n wrap.className = \"wrap\";\n wrap.dir = locale === \"ar\" ? \"rtl\" : \"ltr\";\n wrap.lang = locale;\n // Light or dark to match the page behind the field (container is already in the page).\n wrap.dataset.theme = resolveTheme(options.theme, container);\n wrap.innerHTML = `\n <div class=\"zone\" data-state=\"idle\" role=\"group\">\n <div class=\"idle\">\n <div class=\"tile\">${ICONS.upload}</div>\n <p class=\"title\"></p>\n <p class=\"hint\"></p>\n <div class=\"actions\">\n <button type=\"button\" class=\"primary browse\">${ICONS.folder}<span></span></button>\n <span class=\"or\"></span>\n <button type=\"button\" class=\"ghost phone\">${ICONS.phone}<span></span></button>\n </div>\n </div>\n <div class=\"phone-view\" hidden>\n <div class=\"qr-box\"><canvas class=\"qr\" role=\"img\"></canvas><div class=\"qr-loading\"></div></div>\n <div class=\"phone-info\">\n <p class=\"title phone-title\"></p>\n <ol class=\"steps\"><li></li><li></li><li></li></ol>\n <p class=\"code-line\"></p>\n <p class=\"status\" role=\"status\" aria-live=\"polite\"><i></i><span></span></p>\n <div class=\"phone-actions\">\n <button type=\"button\" class=\"link back\">${ICONS.back}<span></span></button>\n <button type=\"button\" class=\"primary small done\" hidden></button>\n </div>\n </div>\n <div class=\"announce-slot\"></div>\n </div>\n <input type=\"file\" class=\"native\" hidden>\n </div>\n <p class=\"message\" role=\"alert\" hidden></p>\n <div class=\"list-head\" hidden><span class=\"count\"></span><button type=\"button\" class=\"link clear\"></button></div>\n <ul class=\"list\"></ul>`;\n root.append(wrap);\n\n const $ = <T extends Element>(selector: string) => wrap.querySelector(selector) as T;\n const zone = $<HTMLDivElement>(\".zone\");\n const native = $<HTMLInputElement>(\".native\");\n native.multiple = multiple;\n if (accept) native.accept = accept;\n $<HTMLElement>(\".idle .title\").textContent = options.label ?? t(multiple ? \"dropTitle\" : \"dropTitleOne\");\n $<HTMLElement>(\".hint\").textContent = hint;\n $<HTMLElement>(\".browse span\").textContent = t(\"browse\");\n $<HTMLElement>(\".or\").textContent = t(\"or\");\n $<HTMLElement>(\".phone span\").textContent = t(\"usePhone\");\n $<HTMLElement>(\".phone-title\").textContent = t(\"phoneTitle\");\n const steps = wrap.querySelectorAll(\".steps li\");\n [\"phoneStep1\", \"phoneStep2\", \"phoneStep3\"].forEach((key, index) => { steps[index]!.textContent = t(key as \"phoneStep1\"); });\n $<HTMLElement>(\".back span\").textContent = t(\"back\");\n $<HTMLElement>(\".done\").textContent = t(\"doneWithPhone\");\n $<HTMLElement>(\".clear\").textContent = t(\"clearAll\");\n if (!showPhone) { $<HTMLElement>(\".phone\").hidden = true; $<HTMLElement>(\".or\").hidden = true; }\n const promo = announcement(options.announce, t);\n if (promo) $<HTMLElement>(\".announce-slot\").append(promo);\n else $<HTMLElement>(\".announce-slot\").remove();\n\n const items: Item[] = [];\n const handlers = new Set<(files: File[]) => void>();\n let picker: PickController | null = null;\n let messageTimer: ReturnType<typeof setTimeout> | undefined;\n\n const files = () => items.filter((item) => item.file && !item.failed).map((item) => item.file!);\n const say = (text: string) => {\n const message = $<HTMLElement>(\".message\");\n message.textContent = text;\n message.hidden = !text;\n clearTimeout(messageTimer);\n if (text) messageTimer = setTimeout(() => { message.hidden = true; }, 6000);\n };\n\n const sync = () => {\n const transfer = new DataTransfer();\n for (const file of files()) transfer.items.add(file);\n input.files = transfer.files;\n input.dispatchEvent(new Event(\"input\", { bubbles: true }));\n input.dispatchEvent(new Event(\"change\", { bubbles: true }));\n for (const handler of handlers) handler(files());\n };\n\n const renderList = () => {\n const list = $<HTMLUListElement>(\".list\");\n const shown = items.length;\n $<HTMLElement>(\".list-head\").hidden = shown < 2;\n $<HTMLElement>(\".count\").textContent = t(\"fileCount\", { count: shown });\n for (const item of items) {\n if (!item.element) {\n item.element = document.createElement(\"li\");\n list.append(item.element);\n }\n renderItem(item);\n }\n };\n\n const renderItem = (item: Item) => {\n const row = item.element!;\n const extension = (item.name.split(\".\").pop() ?? \"\").slice(0, 4).toUpperCase();\n const pending = !item.file && !item.failed;\n row.className = `item${pending ? \" pending\" : \"\"}${item.failed ? \" failed\" : \"\"}`;\n row.replaceChildren();\n const thumb = document.createElement(\"div\");\n thumb.className = \"thumb\";\n if (item.url) {\n const image = document.createElement(\"img\");\n image.alt = \"\";\n image.src = item.url;\n image.addEventListener(\"error\", () => { image.remove(); thumb.textContent = extension; });\n thumb.append(image);\n } else thumb.textContent = extension || \"FILE\";\n const body = document.createElement(\"div\");\n body.className = \"body\";\n const name = document.createElement(\"span\");\n name.className = \"name\";\n name.textContent = item.name;\n const meta = document.createElement(\"span\");\n meta.className = \"meta\";\n const state = item.failed ? t(\"failed\") : pending ? t(item.phase === \"download\" ? \"receiving\" : \"sending\", { percent: item.percent }) : \"\";\n meta.textContent = [formatBytes(item.size, locale), item.source === \"phone\" ? t(\"sourcePhone\") : t(\"sourceDevice\"), state].filter(Boolean).join(\" · \");\n body.append(name, meta);\n if (pending) {\n const bar = document.createElement(\"span\");\n bar.className = \"bar\";\n const fill = document.createElement(\"i\");\n fill.style.width = `${item.percent}%`;\n bar.append(fill);\n body.append(bar);\n }\n const remove = document.createElement(\"button\");\n remove.type = \"button\";\n remove.className = \"remove\";\n remove.innerHTML = ICONS.close;\n remove.setAttribute(\"aria-label\", t(\"remove\", { name: item.name }));\n remove.hidden = pending;\n remove.addEventListener(\"click\", () => removeItem(item));\n row.append(thumb, body, remove);\n };\n\n const removeItem = (item: Item) => {\n const index = items.indexOf(item);\n if (index < 0) return;\n items.splice(index, 1);\n if (item.url) URL.revokeObjectURL(item.url);\n item.element?.remove();\n renderList();\n sync();\n };\n\n const makeItem = (file: File, source: Source): Item => ({\n key: Math.random().toString(36).slice(2), file, name: file.name, size: file.size, source, percent: 100,\n ...(file.type.startsWith(\"image/\") ? { url: URL.createObjectURL(file) } : {}),\n });\n\n const addFiles = (incoming: File[], source: Source) => {\n const problems: string[] = [];\n if (!multiple && incoming.length) {\n for (const item of [...items]) removeItem(item);\n incoming = incoming.slice(0, 1);\n }\n for (const file of incoming) {\n if (items.filter((item) => !item.failed).length >= maxFiles) { problems.push(t(\"tooMany\", { count: maxFiles })); break; }\n if (file.size > maxBytes) { problems.push(t(\"tooLarge\", { name: file.name, size: formatBytes(maxBytes, locale) })); continue; }\n if (!matchesAccept(accept, file.name, file.type)) { problems.push(t(\"wrongType\", { name: file.name })); continue; }\n items.push(makeItem(file, source));\n }\n say(problems.join(\" \"));\n renderList();\n sync();\n };\n\n // ---- browse and drop --------------------------------------------------------------------------\n $<HTMLButtonElement>(\".browse\").addEventListener(\"click\", () => native.click());\n native.addEventListener(\"change\", () => { addFiles(Array.from(native.files ?? []), \"device\"); native.value = \"\"; });\n let depth = 0;\n zone.addEventListener(\"dragenter\", (event) => { event.preventDefault(); depth++; if (zone.dataset.state === \"idle\") zone.dataset.drag = \"true\"; });\n zone.addEventListener(\"dragover\", (event) => { event.preventDefault(); if (event.dataTransfer) event.dataTransfer.dropEffect = \"copy\"; });\n zone.addEventListener(\"dragleave\", () => { if (--depth <= 0) { depth = 0; delete zone.dataset.drag; } });\n zone.addEventListener(\"drop\", (event) => {\n event.preventDefault();\n depth = 0;\n delete zone.dataset.drag;\n if (zone.dataset.state === \"idle\") addFiles(Array.from(event.dataTransfer?.files ?? []), \"device\");\n });\n $<HTMLElement>(\".clear\").addEventListener(\"click\", () => { for (const item of [...items]) removeItem(item); });\n\n // ---- the phone ----------------------------------------------------------------------------------\n const setStatus = (text: string, live = false) => {\n $<HTMLElement>(\".status span\").textContent = text;\n $<HTMLElement>(\".status\").classList.toggle(\"live\", live);\n };\n const showIdle = () => {\n zone.dataset.state = \"idle\";\n $<HTMLElement>(\".idle\").hidden = false;\n $<HTMLElement>(\".phone-view\").hidden = true;\n $<HTMLButtonElement>(\".phone\").focus();\n };\n const pendingByRelay = new Map<string, Item>();\n\n const openInline = () => {\n zone.dataset.state = \"phone\";\n $<HTMLElement>(\".idle\").hidden = true;\n $<HTMLElement>(\".phone-view\").hidden = false;\n $<HTMLElement>(\".qr-box\").classList.add(\"loading\");\n $<HTMLElement>(\".done\").hidden = true;\n $<HTMLElement>(\".code-line\").textContent = \"\";\n setStatus(t(\"loading\"));\n const room = Math.max(1, maxFiles - files().length);\n const current = open({ ...options, ui: false, multiple, maxFiles: multiple ? room : 1, maxFileBytes: maxBytes, accept });\n picker = current;\n current.on(\"ready\", ({ claimUrl, code }) => {\n drawQr($<HTMLCanvasElement>(\".qr\"), claimUrl, 168);\n $<HTMLCanvasElement>(\".qr\").setAttribute(\"aria-label\", t(\"phoneTitle\"));\n $<HTMLElement>(\".qr-box\").classList.remove(\"loading\", \"dim\");\n const line = $<HTMLElement>(\".code-line\");\n const strong = document.createElement(\"b\");\n strong.textContent = formatCode(code);\n line.replaceChildren(document.createTextNode(`${t(\"phoneCode\", { host: new URL(claimUrl).host })} `), strong);\n setStatus(t(\"waiting\"));\n });\n let phoneLabel = \"\";\n current.on(\"phone\", ({ phone, needsApproval }) => {\n phoneLabel = phone.label;\n $<HTMLElement>(\".qr-box\").classList.add(\"dim\");\n setStatus(t(\"connected\", { label: phone.label }), true);\n if (needsApproval) current.approve();\n });\n current.on(\"direct\", ({ connected }) => {\n if (phoneLabel) setStatus(t(connected ? \"connectedDirect\" : \"connected\", { label: phoneLabel }), true);\n });\n current.on(\"phone_left\", () => setStatus(t(\"phoneLeft\")));\n current.on(\"file_started\", (meta) => {\n const item: Item = { key: meta.id, file: null, name: meta.name, size: meta.size, source: \"phone\", percent: 0 };\n pendingByRelay.set(meta.id, item);\n items.push(item);\n renderList();\n });\n current.on(\"progress\", ({ id, sent, total, phase }) => {\n const item = pendingByRelay.get(id);\n if (!item) return;\n // The phone's upload fills the bar to 90%; the download into this page fills the rest.\n const share = total ? sent / total : 0;\n item.phase = phase;\n item.percent = Math.min(99, Math.floor(phase === \"upload\" ? share * 90 : 90 + share * 10));\n renderItem(item);\n });\n current.on(\"received\", ({ id, file }) => {\n const pending = pendingByRelay.get(id);\n pendingByRelay.delete(id);\n const ready = makeItem(file, \"phone\");\n if (pending) {\n Object.assign(pending, { file, name: file.name, size: file.size, percent: 100, ...(ready.url ? { url: ready.url } : {}) });\n if (!multiple) for (const other of items.filter((item) => item !== pending)) removeItem(other);\n renderItem(pending);\n } else items.push(ready);\n renderList();\n sync();\n $<HTMLElement>(\".done\").hidden = false;\n });\n current.on(\"file_failed\", ({ id }) => {\n const item = pendingByRelay.get(id);\n if (item) { item.failed = true; renderItem(item); }\n });\n current.on(\"error\", (error) => setStatus(t(\"error\", { message: error.message })));\n current.on(\"close\", (reason) => {\n for (const item of pendingByRelay.values()) { item.failed = true; renderItem(item); }\n pendingByRelay.clear();\n if (picker === current) picker = null;\n if (reason === \"finished\" || reason === \"canceled\") showIdle();\n else { $<HTMLElement>(\".qr-box\").classList.add(\"dim\"); setStatus(t(\"expired\")); }\n });\n };\n\n const closeInline = () => {\n if (picker) picker.finish();\n else showIdle();\n };\n\n $<HTMLButtonElement>(\".phone\").addEventListener(\"click\", () => {\n if (phoneMode === \"modal\") {\n const room = Math.max(1, maxFiles - files().length);\n open({ ...options, ui: true, multiple, maxFiles: multiple ? room : 1, maxFileBytes: maxBytes, accept }).done.then((received) => addFiles(received, \"phone\"));\n } else openInline();\n });\n $<HTMLButtonElement>(\".back\").addEventListener(\"click\", closeInline);\n $<HTMLButtonElement>(\".done\").addEventListener(\"click\", closeInline);\n wrap.addEventListener(\"keydown\", (event) => { if (event.key === \"Escape\" && zone.dataset.state === \"phone\") closeInline(); });\n\n return {\n get files() { return files(); },\n input,\n on(_event, handler) { handlers.add(handler); return () => handlers.delete(handler); },\n remove(file) { const item = items.find((candidate) => candidate.file === file); if (item) removeItem(item); },\n clear() { for (const item of [...items]) removeItem(item); },\n destroy() {\n picker?.cancel();\n for (const item of items) if (item.url) URL.revokeObjectURL(item.url);\n host.remove();\n input.remove();\n },\n };\n}\n\n/** <tokshare-pick-field key name accept multiple max-files max-size phone locale theme relay label direct announce>.\n * direct=\"off\" sends everything through the cloud; announce=\"off\" hides the TokShare for desktop line. */\nexport function defineFieldElement(defaults: Partial<FieldOptions> = {}, tag = \"tokshare-pick-field\"): void {\n if (typeof customElements === \"undefined\" || customElements.get(tag)) return;\n customElements.define(tag, class extends HTMLElement {\n private controller: FieldController | null = null;\n connectedCallback() {\n if (this.controller) return;\n const attribute = (name: string) => this.getAttribute(name) ?? undefined;\n const phone = attribute(\"phone\");\n const maxFiles = Number(attribute(\"max-files\"));\n const resize = Number(attribute(\"resize\"));\n const maxFileBytes = parseSize(attribute(\"max-size\"));\n this.controller = mountField(this, {\n ...defaults,\n key: attribute(\"key\") ?? defaults.key ?? \"\",\n ...(attribute(\"relay\") ?? defaults.relay ? { relay: attribute(\"relay\") ?? defaults.relay } : {}),\n ...(attribute(\"name\") ? { name: attribute(\"name\") } : {}),\n ...(attribute(\"accept\") ? { accept: attribute(\"accept\") } : {}),\n multiple: this.hasAttribute(\"multiple\"),\n ...(maxFiles > 0 ? { maxFiles } : {}),\n ...(maxFileBytes ? { maxFileBytes } : {}),\n ...(resize > 0 ? { resizeImages: { maxDimension: resize } } : {}),\n ...(phone === \"off\" ? { phone: false as const } : phone === \"modal\" ? { phone: \"modal\" as const } : {}),\n ...(attribute(\"locale\") ? { locale: attribute(\"locale\") as \"en\" | \"ar\" | \"auto\" } : {}),\n ...(attribute(\"theme\") ? { theme: attribute(\"theme\") as \"light\" | \"dark\" | \"auto\" } : {}),\n ...(attribute(\"label\") ? { label: attribute(\"label\") } : {}),\n ...(attribute(\"direct\") === \"off\" ? { direct: false } : {}),\n ...(attribute(\"announce\") === \"off\" ? { announce: false } : {}),\n });\n this.controller.on(\"change\", (files) => this.dispatchEvent(new CustomEvent(\"files\", { detail: files, bubbles: true })));\n }\n disconnectedCallback() { this.controller?.destroy(); this.controller = null; }\n get files() { return this.controller?.files ?? []; }\n clear() { this.controller?.clear(); }\n });\n}\n"],"mappings":"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","names":["host"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../../protocol/src/limits.ts","../../protocol/src/errors.ts","../../protocol/src/filename.ts","../../protocol/src/mime.ts","../src/config.ts","../src/direct.ts","../src/announce.ts","../src/i18n.ts","../../../node_modules/.pnpm/uqr@0.1.3/node_modules/uqr/dist/index.mjs","../src/qr.ts","../src/theme.ts","../src/styles.ts","../src/modal.ts","../src/session.ts","../src/picker.ts","../src/fieldStyles.ts","../src/field.ts"],"sourcesContent":["export { attach, open, pick } from \"./picker\";\nexport { defineFieldElement, mountField, parseSize } from \"./field\";\nexport type { FieldController, FieldOptions } from \"./field\";\nexport type { AttachOptions, PickController, PickEvents, PickOptions, ProgressInfo } from \"./picker\";\nexport { PickError } from \"@tokshare/pick-protocol\";\nexport type { ErrorCode, FileMeta, PhoneInfo } from \"@tokshare/pick-protocol\";\nexport { DEFAULT_RELAY, SDK_VERSION } from \"./config\";\n\nimport { defineFieldElement, mountField } from \"./field\";\nimport { attach, open, pick } from \"./picker\";\n/** The same functions as one object: TokSharePick.pick({ key }). */\nexport const TokSharePick = { pick, open, attach, mountField, defineFieldElement };\n","// Limits shared by the relay, the phone page and the SDK. The relay is the authority; the others use\n// these to explain a refusal before trying.\n\nexport const MiB = 1024 * 1024;\n\nexport const LIMITS = {\n /** Free tier ceilings, in decimal megabytes as phones show sizes. A site can ask for less, never more. */\n maxFileBytes: 50_000_000,\n maxFiles: 20,\n maxSessionBytes: 200_000_000,\n /** Up to this size a file goes up in one presigned PUT; above it, multipart. */\n singlePutBytes: 16 * MiB,\n /** Multipart parts are all the same size (R2), at least 5 MiB; we use 8 MiB. */\n minPartBytes: 8 * MiB,\n maxParts: 10_000,\n /** How many part URLs the phone may ask for at once. */\n partBatch: 10,\n /** Session lifetime. */\n idleMs: 30 * 60_000,\n absoluteMs: 2 * 60 * 60_000,\n /** A ready file is deleted this long after it arrived, downloaded or not. */\n fileTtlMs: 10 * 60_000,\n /** The typed short code works for this long after the session is created. */\n codeTtlMs: 10 * 60_000,\n /** Times the desktop may download one file (retries after a dropped connection). */\n maxDownloads: 3,\n /** Presigned URLs expire after this many seconds. */\n presignSeconds: 15 * 60,\n /** Bytes of a finished upload read back to check its real type. */\n sniffBytes: 4096,\n /** Direct (local network) transfers: bytes per data-channel message, how long the phone waits for\n * the link before using the cloud, and for the website's \"got\" after the last byte. */\n directChunkBytes: 64 * 1024,\n directConnectMs: 8_000,\n directWaitMs: 2_500,\n directConfirmMs: 20_000,\n /** Largest WebRTC setup message the relay passes on. */\n maxSignalBytes: 16_384,\n} as const;\n\n/** Part size for a multipart upload: equal parts of at least minPartBytes, at most maxParts of them. */\nexport function partPlan(size: number): { partSize: number; partCount: number } {\n const partSize = Math.max(LIMITS.minPartBytes, Math.ceil(size / LIMITS.maxParts));\n return { partSize, partCount: Math.max(1, Math.ceil(size / partSize)) };\n}\n","// Error codes the relay returns ({ error: code, message }) and the SDK throws as PickError.\n\nexport type ErrorCode =\n | \"bad_request\"\n | \"key_invalid\"\n | \"origin_not_allowed\"\n | \"rate_limited\"\n | \"quota_exceeded\"\n | \"not_found\"\n | \"unauthorized\"\n | \"already_claimed\"\n | \"expired\"\n | \"closed\"\n | \"limit_reached\"\n | \"file_too_large\"\n | \"session_too_large\"\n | \"type_rejected\"\n | \"size_mismatch\"\n | \"upload_incomplete\"\n | \"download_limit\"\n | \"network\"\n | \"internal\";\n\nexport class PickError extends Error {\n readonly code: ErrorCode;\n readonly status: number;\n constructor(code: ErrorCode, message?: string, status = 400) {\n super(message || code);\n this.name = \"PickError\";\n this.code = code;\n this.status = status;\n }\n}\n\nexport const STATUS: Partial<Record<ErrorCode, number>> = {\n key_invalid: 401,\n unauthorized: 401,\n origin_not_allowed: 403,\n not_found: 404,\n already_claimed: 409,\n limit_reached: 409,\n expired: 410,\n closed: 410,\n file_too_large: 413,\n session_too_large: 413,\n type_rejected: 415,\n rate_limited: 429,\n quota_exceeded: 429,\n internal: 500,\n};\n","// File names come from phones and end up in someone else's page and disk: keep the name, drop\n// anything that could hide an extension or break a path.\n\nconst CONTROL = /[\\u0000-\\u001f\\u007f-\\u009f]/g;\n// Right-to-left override and friends can make \"photogpj.exe\" read as \"photoexe.jpg\".\nconst BIDI = /[--]/g;\nconst RESERVED = /[<>:\"/\\\\|?*]/g;\n\nexport function sanitizeFilename(name: string, fallback = \"file\"): string {\n let clean = String(name ?? \"\")\n .normalize(\"NFC\")\n .replace(CONTROL, \"\")\n .replace(BIDI, \"\");\n // Only the last path segment: a picker should never send folders, but don't trust it.\n clean = clean.split(/[\\\\/]/).pop() ?? \"\";\n clean = clean.replace(RESERVED, \"_\").replace(/^[.\\s]+|[.\\s]+$/g, \"\");\n if (!clean) return fallback;\n if (clean.length <= 200) return clean;\n // Keep the extension when cutting a long name.\n const dot = clean.lastIndexOf(\".\");\n const extension = dot > 0 && clean.length - dot <= 16 ? clean.slice(dot) : \"\";\n return clean.slice(0, 200 - extension.length) + extension;\n}\n\nexport function extensionOf(name: string): string {\n const dot = name.lastIndexOf(\".\");\n return dot > 0 ? name.slice(dot).toLowerCase() : \"\";\n}\n","// File types: matching a site's accept list (the same rules as <input accept>) and recognizing a\n// file's real type from its first bytes, so a renamed program can't pass as a photo.\nimport { extensionOf } from \"./filename\";\n\nexport interface AcceptRule {\n extensions: string[];\n types: string[];\n wildcards: string[];\n}\n\nexport function parseAccept(accept = \"\"): AcceptRule {\n const rule: AcceptRule = { extensions: [], types: [], wildcards: [] };\n for (const raw of accept.split(\",\")) {\n const token = raw.trim().toLowerCase();\n if (!token) continue;\n if (token.startsWith(\".\")) rule.extensions.push(token);\n else if (/^[a-z0-9.+-]+\\/\\*$/.test(token)) rule.wildcards.push(token.slice(0, -1));\n else if (/^[a-z0-9.+-]+\\/[a-z0-9.+-]+$/.test(token)) rule.types.push(token);\n }\n return rule;\n}\n\nexport function acceptsAnything(accept = \"\"): boolean {\n const rule = parseAccept(accept);\n return !rule.extensions.length && !rule.types.length && !rule.wildcards.length;\n}\n\nfunction typeMatches(rule: AcceptRule, type: string): boolean {\n const lower = type.toLowerCase();\n return rule.types.includes(lower) || rule.wildcards.some((prefix) => lower.startsWith(prefix));\n}\n\n/** Whether a picked file fits the accept list, by its extension or its declared type. */\nexport function matchesAccept(accept: string, name: string, type: string): boolean {\n const rule = parseAccept(accept);\n if (!rule.extensions.length && !rule.types.length && !rule.wildcards.length) return true;\n return rule.extensions.includes(extensionOf(name)) || (Boolean(type) && typeMatches(rule, type));\n}\n\nconst ascii = (bytes: Uint8Array, start: number, length: number) =>\n String.fromCharCode(...bytes.subarray(start, start + length));\nconst starts = (bytes: Uint8Array, signature: number[], offset = 0) =>\n signature.every((value, index) => bytes[offset + index] === value);\n\n/** The real type of a file from its first bytes, or null when it isn't one we recognize. */\nexport function sniff(bytes: Uint8Array): string | null {\n if (bytes.length < 4) return null;\n if (starts(bytes, [0xff, 0xd8, 0xff])) return \"image/jpeg\";\n if (starts(bytes, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])) return \"image/png\";\n if (ascii(bytes, 0, 4) === \"GIF8\") return \"image/gif\";\n if (ascii(bytes, 0, 4) === \"RIFF\" && ascii(bytes, 8, 4) === \"WEBP\") return \"image/webp\";\n if (ascii(bytes, 0, 4) === \"RIFF\" && ascii(bytes, 8, 4) === \"WAVE\") return \"audio/wav\";\n if (ascii(bytes, 0, 4) === \"RIFF\" && ascii(bytes, 8, 4) === \"AVI \") return \"video/x-msvideo\";\n if (ascii(bytes, 4, 4) === \"ftyp\") {\n const brand = ascii(bytes, 8, 4);\n if (/^(heic|heix|hevc|hevx|heim|heis)$/.test(brand)) return \"image/heic\";\n if (brand === \"mif1\" || brand === \"msf1\") return \"image/heif\";\n if (brand === \"avif\" || brand === \"avis\") return \"image/avif\";\n if (brand === \"qt \") return \"video/quicktime\";\n if (/^(M4A |M4B )$/.test(brand)) return \"audio/mp4\";\n if (/^3g/.test(brand)) return \"video/3gpp\";\n return \"video/mp4\";\n }\n if (ascii(bytes, 0, 5) === \"%PDF-\") return \"application/pdf\";\n if (starts(bytes, [0x50, 0x4b, 0x03, 0x04]) || starts(bytes, [0x50, 0x4b, 0x05, 0x06])) return \"application/zip\";\n if (starts(bytes, [0x1f, 0x8b])) return \"application/gzip\";\n if (starts(bytes, [0x37, 0x7a, 0xbc, 0xaf, 0x27, 0x1c])) return \"application/x-7z-compressed\";\n if (ascii(bytes, 0, 4) === \"Rar!\") return \"application/vnd.rar\";\n if (ascii(bytes, 0, 3) === \"ID3\" || starts(bytes, [0xff, 0xfb]) || starts(bytes, [0xff, 0xf3])) return \"audio/mpeg\";\n if (ascii(bytes, 0, 4) === \"OggS\") return \"audio/ogg\";\n if (ascii(bytes, 0, 4) === \"fLaC\") return \"audio/flac\";\n if (starts(bytes, [0x1a, 0x45, 0xdf, 0xa3])) return \"video/webm\";\n if (starts(bytes, [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1])) return \"application/x-ole-storage\";\n if (ascii(bytes, 0, 2) === \"MZ\") return \"application/x-msdownload\";\n if (starts(bytes, [0x7f, 0x45, 0x4c, 0x46])) return \"application/x-elf\";\n if (starts(bytes, [0xcf, 0xfa, 0xed, 0xfe]) || starts(bytes, [0xfe, 0xed, 0xfa, 0xcf])) return \"application/x-mach-binary\";\n const head = ascii(bytes, 0, Math.min(bytes.length, 256)).replace(/^/, \"\").trimStart().toLowerCase();\n if (head.startsWith(\"<svg\") || (head.startsWith(\"<?xml\") && head.includes(\"<svg\"))) return \"image/svg+xml\";\n if (head.startsWith(\"<!doctype html\") || head.startsWith(\"<html\")) return \"text/html\";\n return null;\n}\n\n// Containers whose declared types are many: a .docx, .xlsx, .apk or .epub is a zip inside.\nconst ZIP_FAMILY = /^(application\\/(zip|x-zip-compressed|epub\\+zip|vnd\\.android\\.package-archive|java-archive|vnd\\.openxmlformats-officedocument\\..+|vnd\\.oasis\\.opendocument\\..+))$/;\nconst OLE_FAMILY = /^application\\/(msword|vnd\\.ms-excel|vnd\\.ms-powerpoint|vnd\\.ms-outlook|x-ole-storage)$/;\nconst DANGEROUS = new Set([\"application/x-msdownload\", \"application/x-elf\", \"application/x-mach-binary\", \"text/html\", \"image/svg+xml\"]);\n\n/** Whether a finished upload's real type is acceptable. Rejects a file whose bytes say \"program\"\n * or \"web page\" when its name or the accept list said otherwise, and a type the accept list's MIME\n * rules exclude. Unknown bytes (plain text, rare formats) pass on the name/type check alone. */\nexport function checkSniffed(accept: string, name: string, declared: string, sniffed: string | null): boolean {\n if (!sniffed) return true;\n const rule = parseAccept(accept);\n const declaredLower = declared.toLowerCase();\n const compatible = (type: string) =>\n type === sniffed ||\n (sniffed === \"application/zip\" && ZIP_FAMILY.test(type)) ||\n (sniffed === \"application/x-ole-storage\" && OLE_FAMILY.test(type)) ||\n (sniffed === \"image/heif\" && type === \"image/heic\") ||\n (sniffed === \"video/mp4\" && /^(video|audio)\\//.test(type));\n if (DANGEROUS.has(sniffed)) {\n // Only when the site asked for exactly this kind of file.\n return rule.types.includes(sniffed) || (sniffed === \"image/svg+xml\" && rule.extensions.includes(\".svg\"));\n }\n if (!rule.types.length && !rule.wildcards.length) return true;\n if (rule.types.some(compatible)) return true;\n if (rule.wildcards.some((prefix) => sniffed.startsWith(prefix))) return true;\n // The site listed MIME rules but also extensions: the extension check already passed at init.\n return rule.extensions.includes(extensionOf(name)) && (compatible(declaredLower) || !declaredLower);\n}\n","/** The hosted relay. Override with the `relay` option or a script tag's data-relay attribute\n * (local development: \"http://localhost:8788\").\n * 0.1.x uses the relay's workers.dev address; a later version moves to the TokShare domain. That\n * address must stay up for sites still on 0.1.x (wrangler.jsonc keeps workers_dev on). */\nexport const DEFAULT_RELAY = \"https://tokshare-pick.pjturki.workers.dev\";\n\nexport const SDK_VERSION = \"0.1.1\";\n","// The website's end of the direct link: answers the phone's WebRTC offer (made through the relay's\n// sockets) and receives files over the data channel. Same network only: no STUN or TURN servers, so\n// only local-network candidates (hidden behind .local names by browsers) can connect.\nimport { checkSniffed, type DirectMessage, type FileMeta, LIMITS, type RtcSignal, sniff } from \"@tokshare/pick-protocol\";\n\nexport interface DirectHandlers {\n /** A file's bytes are arriving. */\n progress(id: string, received: number, total: number): void;\n /** All bytes are in: check and keep the file. Resolves with what to tell the phone. */\n complete(id: string, chunks: Uint8Array[], size: number): Promise<{ ok: true } | { ok: false; code: string }>;\n /** The link opened or closed. */\n state(open: boolean): void;\n}\n\n/** The checks the relay runs on a cloud upload, run here on a file that came over the direct link:\n * the exact announced size, and contents that match an accepted type. */\nexport function verifyDirectFile(meta: FileMeta, chunks: Uint8Array[], size: number, accept: string, maxBytes: number):\n { ok: true; file: File; sniffed: string | null } | { ok: false; code: \"size_mismatch\" | \"type_rejected\" } {\n if (size !== meta.size || size > maxBytes) return { ok: false, code: \"size_mismatch\" };\n const head = new Uint8Array(Math.min(size, LIMITS.sniffBytes));\n let filled = 0;\n for (const chunk of chunks) {\n if (filled >= head.length) break;\n const take = chunk.subarray(0, head.length - filled);\n head.set(take, filled);\n filled += take.length;\n }\n const sniffed = sniff(head);\n if (!checkSniffed(accept, meta.name, meta.type, sniffed)) return { ok: false, code: \"type_rejected\" };\n const file = new File(chunks as BlobPart[], meta.name, { type: meta.type || sniffed || \"\", lastModified: meta.lastModified });\n return { ok: true, file, sniffed };\n}\n\nexport class DirectReceiver {\n private pc: RTCPeerConnection | null = null;\n private channel: RTCDataChannel | null = null;\n private id = \"\";\n private isOpen = false;\n private current: { id: string; size: number; chunks: Uint8Array[]; received: number } | null = null;\n\n constructor(private readonly signal: (d: RtcSignal) => void, private readonly handlers: DirectHandlers) {}\n\n static supported(): boolean {\n return typeof RTCPeerConnection === \"function\";\n }\n\n onSignal(d: RtcSignal): void {\n if (d.kind === \"offer\" && d.sdp) { this.answer(d.pc, d.sdp); return; }\n if (d.pc !== this.id || !this.pc) return;\n if (d.kind === \"ice\" && d.candidate) this.pc.addIceCandidate(d.candidate).catch(() => undefined);\n else if (d.kind === \"bye\") this.close();\n }\n\n /** A new offer replaces any earlier link (the phone reloaded, or retried after a network change). */\n private answer(id: string, sdp: string): void {\n if (!DirectReceiver.supported()) return;\n this.close();\n this.id = id;\n const pc = new RTCPeerConnection({ iceServers: [] });\n this.pc = pc;\n pc.onicecandidate = (event) => {\n if (this.id === id) this.signal({ pc: id, kind: \"ice\", candidate: event.candidate ? event.candidate.toJSON() as RtcSignal[\"candidate\"] : null });\n };\n pc.onconnectionstatechange = () => {\n if (this.id === id && (pc.connectionState === \"failed\" || pc.connectionState === \"closed\")) this.close();\n };\n pc.ondatachannel = (event) => {\n if (this.id !== id) return;\n const channel = event.channel;\n channel.binaryType = \"arraybuffer\";\n this.channel = channel;\n const opened = () => { if (this.channel === channel && !this.isOpen) { this.isOpen = true; this.handlers.state(true); } };\n channel.onopen = opened;\n channel.onclose = () => { if (this.channel === channel) this.close(); };\n channel.onmessage = (message) => this.onMessage(channel, message.data);\n if (channel.readyState === \"open\") opened();\n };\n pc.setRemoteDescription({ type: \"offer\", sdp })\n .then(() => pc.createAnswer())\n .then((answer) => pc.setLocalDescription(answer))\n .then(() => { if (this.id === id) this.signal({ pc: id, kind: \"answer\", sdp: pc.localDescription!.sdp }); })\n .catch(() => this.close());\n }\n\n private onMessage(channel: RTCDataChannel, data: unknown): void {\n if (typeof data !== \"string\") {\n const current = this.current;\n if (!current || !(data instanceof ArrayBuffer)) return;\n current.chunks.push(new Uint8Array(data));\n current.received += data.byteLength;\n // More than announced: stop collecting, it will fail the size check.\n if (current.received > current.size) { current.chunks = []; return; }\n this.handlers.progress(current.id, current.received, current.size);\n return;\n }\n let message: DirectMessage;\n try { message = JSON.parse(data); } catch { return; }\n if (message.t === \"file\" && typeof message.id === \"string\" && Number.isSafeInteger(message.size)) {\n this.current = { id: message.id, size: message.size, chunks: [], received: 0 };\n } else if (message.t === \"end\" && this.current?.id === message.id) {\n const { id, chunks, received } = this.current;\n this.current = null;\n this.handlers.complete(id, chunks, received)\n .then((result) => result, () => ({ ok: false as const, code: \"failed\" }))\n .then((result) => {\n const reply: DirectMessage = result.ok ? { t: \"got\", id } : { t: \"bad\", id, code: result.code };\n try { channel.send(JSON.stringify(reply)); } catch {}\n });\n }\n }\n\n close(): void {\n const wasOpen = this.isOpen;\n this.isOpen = false;\n const { pc, channel } = this;\n this.pc = null;\n this.channel = null;\n this.current = null;\n try { channel?.close(); } catch {}\n try { pc?.close(); } catch {}\n if (wasOpen) this.handlers.state(false);\n }\n}\n","// A small line about TokShare for desktop, under the phone QR in the field and the modal. Sites turn it\n// off with announce: false; a visitor hides it once and it stays hidden (per site, in localStorage).\nconst HIDDEN_KEY = \"tokshare.announce.hidden\";\nconst LINK = \"https://tokshare.vercel.app/?ref=pick\";\n\nconst hidden = (): boolean => {\n try { return localStorage.getItem(HIDDEN_KEY) === \"1\"; } catch { return false; }\n};\n\n/** The element, or null when the site turned it off or the visitor hid it. */\nexport function announcement(enabled: boolean | undefined, t: (key: \"announceText\" | \"announceLink\" | \"announceHide\") => string): HTMLElement | null {\n if (enabled === false || hidden()) return null;\n const box = document.createElement(\"p\");\n box.className = \"announce\";\n const dot = document.createElement(\"i\");\n dot.setAttribute(\"aria-hidden\", \"true\");\n const text = document.createElement(\"span\");\n text.textContent = `${t(\"announceText\")} `;\n const link = document.createElement(\"a\");\n link.href = LINK;\n link.target = \"_blank\";\n link.rel = \"noopener\";\n link.textContent = t(\"announceLink\");\n text.append(link);\n const hide = document.createElement(\"button\");\n hide.type = \"button\";\n hide.className = \"announce-hide\";\n hide.textContent = \"×\";\n hide.setAttribute(\"aria-label\", t(\"announceHide\"));\n hide.addEventListener(\"click\", () => {\n try { localStorage.setItem(HIDDEN_KEY, \"1\"); } catch {}\n box.remove();\n });\n box.append(dot, text, hide);\n return box;\n}\n","import type { Locale } from \"@tokshare/pick-protocol\";\n\nconst en = {\n title: \"Pick files from your phone\",\n titleOne: \"Pick a file from your phone\",\n scan: \"Scan with your phone's camera\",\n orType: \"No camera? Open {host} on your phone and type\",\n loading: \"Getting a code…\",\n waiting: \"Waiting for your phone…\",\n connected: \"Connected: {label}\",\n connectedDirect: \"Connected over Wi-Fi: {label}\",\n disconnect: \"Not you? Disconnect\",\n phoneLeft: \"Your phone disconnected. It reconnects by itself when the page is open.\",\n approveTitle: \"Approve this phone?\",\n approveMatch: \"Your phone should show {match}.\",\n approve: \"Approve\",\n reject: \"Reject\",\n sending: \"Sending from phone {percent}%\",\n receiving: \"Receiving {percent}%\",\n received: \"Received\",\n failed: \"Not received\",\n cancel: \"Cancel\",\n done: \"Done\",\n useFiles: \"Use {count} files\",\n useFile: \"Use this file\",\n expired: \"This code expired.\",\n newCode: \"Get a new code\",\n error: \"Couldn't start: {message}\",\n tryAgain: \"Try again\",\n close: \"Close\",\n privacy: \"Files go straight to this site and are deleted from TokShare once received.\",\n // Upload field\n dropTitle: \"Drag & drop files here\",\n dropTitleOne: \"Drag & drop a file here\",\n dropActive: \"Drop to add\",\n or: \"or\",\n browse: \"Browse files\",\n usePhone: \"Use your phone\",\n hintTypes: \"{types} · up to {size}\",\n hintAny: \"Any file · up to {size}\",\n hintCount: \"Up to {count} files\",\n phoneTitle: \"Scan with your phone\",\n phoneStep1: \"Open your phone's camera and scan the code\",\n phoneStep2: \"Pick photos or files on your phone\",\n phoneStep3: \"They appear here as they arrive\",\n phoneCode: \"No camera? Open {host} and type\",\n back: \"Back\",\n doneWithPhone: \"Done\",\n sourcePhone: \"From phone\",\n sourceDevice: \"This device\",\n remove: \"Remove {name}\",\n tooLarge: \"{name} is larger than {size}.\",\n wrongType: \"{name} isn't an accepted file type.\",\n tooMany: \"You can add up to {count} files.\",\n fileCount: \"{count} files\",\n clearAll: \"Remove all\",\n // TokShare for desktop\n announceText: \"Move photos between your phone and your own PC anytime, over Wi-Fi.\",\n announceLink: \"Get TokShare for desktop\",\n announceHide: \"Hide\",\n};\ntype Strings = typeof en;\n\nconst ar: Strings = {\n title: \"اختر ملفات من هاتفك\",\n titleOne: \"اختر ملفًا من هاتفك\",\n scan: \"امسح الرمز بكاميرا هاتفك\",\n orType: \"لا توجد كاميرا؟ افتح {host} على هاتفك واكتب\",\n loading: \"جارٍ تجهيز الرمز…\",\n waiting: \"في انتظار هاتفك…\",\n connected: \"متصل: {label}\",\n connectedDirect: \"متصل عبر Wi-Fi: {label}\",\n disconnect: \"ليس هاتفك؟ افصله\",\n phoneLeft: \"انقطع اتصال هاتفك. سيعود تلقائيًا ما دامت الصفحة مفتوحة عليه.\",\n approveTitle: \"هل توافق على هذا الهاتف؟\",\n approveMatch: \"يجب أن يعرض هاتفك الرقم {match}.\",\n approve: \"موافقة\",\n reject: \"رفض\",\n sending: \"جارٍ الإرسال من الهاتف {percent}%\",\n receiving: \"جارٍ الاستلام {percent}%\",\n received: \"تم الاستلام\",\n failed: \"لم يُستلم\",\n cancel: \"إلغاء\",\n done: \"تم\",\n useFiles: \"استخدم {count} ملفات\",\n useFile: \"استخدم هذا الملف\",\n expired: \"انتهت صلاحية هذا الرمز.\",\n newCode: \"احصل على رمز جديد\",\n error: \"تعذّر البدء: {message}\",\n tryAgain: \"حاول مرة أخرى\",\n close: \"إغلاق\",\n privacy: \"تصل الملفات مباشرة إلى هذا الموقع، ويحذفها TokShare فور استلامها.\",\n dropTitle: \"اسحب الملفات وأفلتها هنا\",\n dropTitleOne: \"اسحب ملفًا وأفلته هنا\",\n dropActive: \"أفلت للإضافة\",\n or: \"أو\",\n browse: \"تصفّح الملفات\",\n usePhone: \"استخدم هاتفك\",\n hintTypes: \"{types} · حتى {size}\",\n hintAny: \"أي ملف · حتى {size}\",\n hintCount: \"حتى {count} ملفات\",\n phoneTitle: \"امسح الرمز بهاتفك\",\n phoneStep1: \"افتح كاميرا هاتفك وامسح الرمز\",\n phoneStep2: \"اختر الصور أو الملفات على هاتفك\",\n phoneStep3: \"تظهر هنا فور وصولها\",\n phoneCode: \"لا توجد كاميرا؟ افتح {host} واكتب\",\n back: \"رجوع\",\n doneWithPhone: \"تم\",\n sourcePhone: \"من الهاتف\",\n sourceDevice: \"هذا الجهاز\",\n remove: \"إزالة {name}\",\n tooLarge: \"{name} أكبر من {size}.\",\n wrongType: \"{name} ليس من أنواع الملفات المقبولة.\",\n tooMany: \"يمكنك إضافة {count} ملفات كحد أقصى.\",\n fileCount: \"{count} ملفات\",\n clearAll: \"إزالة الكل\",\n announceText: \"انقل الصور بين هاتفك وكمبيوترك في أي وقت عبر Wi-Fi.\",\n announceLink: \"حمّل TokShare للكمبيوتر\",\n announceHide: \"إخفاء\",\n};\n\nexport const STRINGS: Record<Locale, Strings> = { en, ar };\nexport type StringKey = keyof Strings;\n\nexport function resolveLocale(requested: Locale | \"auto\" | undefined): Locale {\n if (requested === \"en\" || requested === \"ar\") return requested;\n const page = typeof document !== \"undefined\" ? document.documentElement.lang : \"\";\n const language = page || (typeof navigator !== \"undefined\" ? navigator.language : \"en\");\n return /^ar\\b/i.test(language) ? \"ar\" : \"en\";\n}\n\nexport function translator(locale: Locale, overrides: Partial<Strings> = {}) {\n return (key: StringKey, values: Record<string, string | number> = {}) =>\n (overrides[key] ?? STRINGS[locale][key]).replace(/\\{(\\w+)\\}/g, (_, name: string) => String(values[name] ?? \"\"));\n}\n\nexport function formatBytes(bytes: number, locale: Locale): string {\n const units = locale === \"ar\" ? [\"بايت\", \"ك.ب\", \"م.ب\", \"ج.ب\"] : [\"B\", \"KB\", \"MB\", \"GB\"];\n let value = bytes;\n let unit = 0;\n while (value >= 1000 && unit < units.length - 1) { value /= 1000; unit++; }\n return `${(value >= 100 || unit === 0 ? Math.round(value) : Math.round(value * 10) / 10).toLocaleString(locale)} ${units[unit]}`;\n}\n","var QrCodeDataType = /* @__PURE__ */ ((QrCodeDataType2) => {\n QrCodeDataType2[QrCodeDataType2[\"Border\"] = -1] = \"Border\";\n QrCodeDataType2[QrCodeDataType2[\"Data\"] = 0] = \"Data\";\n QrCodeDataType2[QrCodeDataType2[\"Function\"] = 1] = \"Function\";\n QrCodeDataType2[QrCodeDataType2[\"Position\"] = 2] = \"Position\";\n QrCodeDataType2[QrCodeDataType2[\"Timing\"] = 3] = \"Timing\";\n QrCodeDataType2[QrCodeDataType2[\"Alignment\"] = 4] = \"Alignment\";\n return QrCodeDataType2;\n})(QrCodeDataType || {});\n\nconst LOW = [0, 1];\nconst MEDIUM = [1, 0];\nconst QUARTILE = [2, 3];\nconst HIGH = [3, 2];\nconst EccMap = {\n L: LOW,\n M: MEDIUM,\n Q: QUARTILE,\n H: HIGH\n};\nconst NUMERIC_REGEX = /^\\d*$/;\nconst ALPHANUMERIC_REGEX = /^[A-Z0-9 $%*+./:-]*$/;\nconst ALPHANUMERIC_CHARSET = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:\";\nconst MIN_VERSION = 1;\nconst MAX_VERSION = 40;\nconst PENALTY_N1 = 3;\nconst PENALTY_N2 = 3;\nconst PENALTY_N3 = 40;\nconst PENALTY_N4 = 10;\nconst ECC_CODEWORDS_PER_BLOCK = [\n // Version: (note that index 0 is for padding, and is set to an illegal value)\n // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level\n [-1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],\n // Low\n [-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28],\n // Medium\n [-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],\n // Quartile\n [-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]\n // High\n];\nconst NUM_ERROR_CORRECTION_BLOCKS = [\n // Version: (note that index 0 is for padding, and is set to an illegal value)\n // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level\n [-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25],\n // Low\n [-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49],\n // Medium\n [-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68],\n // Quartile\n [-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81]\n // High\n];\nclass QrCode {\n /* -- Constructor (low level) and fields -- */\n // Creates a new QR Code with the given version number,\n // error correction level, data codeword bytes, and mask number.\n // This is a low-level API that most users should not use directly.\n // A mid-level API is the encodeSegments() function.\n constructor(version, ecc, dataCodewords, msk) {\n this.version = version;\n this.ecc = ecc;\n if (version < MIN_VERSION || version > MAX_VERSION)\n throw new RangeError(\"Version value out of range\");\n if (msk < -1 || msk > 7)\n throw new RangeError(\"Mask value out of range\");\n this.size = version * 4 + 17;\n const row = Array.from({ length: this.size }).fill(false);\n for (let i = 0; i < this.size; i++) {\n this.modules.push(row.slice());\n this.types.push(row.map(() => 0));\n }\n this.drawFunctionPatterns();\n const allCodewords = this.addEccAndInterleave(dataCodewords);\n this.drawCodewords(allCodewords);\n if (msk === -1) {\n let minPenalty = 1e9;\n for (let i = 0; i < 8; i++) {\n this.applyMask(i);\n this.drawFormatBits(i);\n const penalty = this.getPenaltyScore();\n if (penalty < minPenalty) {\n msk = i;\n minPenalty = penalty;\n }\n this.applyMask(i);\n }\n }\n this.mask = msk;\n this.applyMask(msk);\n this.drawFormatBits(msk);\n }\n /* -- Fields -- */\n // The width and height of this QR Code, measured in modules, between\n // 21 and 177 (inclusive). This is equal to version * 4 + 17.\n size;\n // The index of the mask pattern used in this QR Code, which is between 0 and 7 (inclusive).\n // Even if a QR Code is created with automatic masking requested (mask = -1),\n // the resulting object still has a mask value between 0 and 7.\n mask;\n // The modules of this QR Code (false = light, true = dark).\n // Immutable after constructor finishes. Accessed through getModule().\n modules = [];\n types = [];\n /* -- Accessor methods -- */\n // Returns the color of the module (pixel) at the given coordinates, which is false\n // for light or true for dark. The top left corner has the coordinates (x=0, y=0).\n // If the given coordinates are out of bounds, then false (light) is returned.\n getModule(x, y) {\n return x >= 0 && x < this.size && y >= 0 && y < this.size && this.modules[y][x];\n }\n /* -- Private helper methods for constructor: Drawing function modules -- */\n // Reads this object's version field, and draws and marks all function modules.\n drawFunctionPatterns() {\n for (let i = 0; i < this.size; i++) {\n this.setFunctionModule(6, i, i % 2 === 0, QrCodeDataType.Timing);\n this.setFunctionModule(i, 6, i % 2 === 0, QrCodeDataType.Timing);\n }\n this.drawFinderPattern(3, 3);\n this.drawFinderPattern(this.size - 4, 3);\n this.drawFinderPattern(3, this.size - 4);\n const alignPatPos = this.getAlignmentPatternPositions();\n const numAlign = alignPatPos.length;\n for (let i = 0; i < numAlign; i++) {\n for (let j = 0; j < numAlign; j++) {\n if (!(i === 0 && j === 0 || i === 0 && j === numAlign - 1 || i === numAlign - 1 && j === 0))\n this.drawAlignmentPattern(alignPatPos[i], alignPatPos[j]);\n }\n }\n this.drawFormatBits(0);\n this.drawVersion();\n }\n // Draws two copies of the format bits (with its own error correction code)\n // based on the given mask and this object's error correction level field.\n drawFormatBits(mask) {\n const data = this.ecc[1] << 3 | mask;\n let rem = data;\n for (let i = 0; i < 10; i++)\n rem = rem << 1 ^ (rem >>> 9) * 1335;\n const bits = (data << 10 | rem) ^ 21522;\n for (let i = 0; i <= 5; i++)\n this.setFunctionModule(8, i, getBit(bits, i));\n this.setFunctionModule(8, 7, getBit(bits, 6));\n this.setFunctionModule(8, 8, getBit(bits, 7));\n this.setFunctionModule(7, 8, getBit(bits, 8));\n for (let i = 9; i < 15; i++)\n this.setFunctionModule(14 - i, 8, getBit(bits, i));\n for (let i = 0; i < 8; i++)\n this.setFunctionModule(this.size - 1 - i, 8, getBit(bits, i));\n for (let i = 8; i < 15; i++)\n this.setFunctionModule(8, this.size - 15 + i, getBit(bits, i));\n this.setFunctionModule(8, this.size - 8, true);\n }\n // Draws two copies of the version bits (with its own error correction code),\n // based on this object's version field, iff 7 <= version <= 40.\n drawVersion() {\n if (this.version < 7)\n return;\n let rem = this.version;\n for (let i = 0; i < 12; i++)\n rem = rem << 1 ^ (rem >>> 11) * 7973;\n const bits = this.version << 12 | rem;\n for (let i = 0; i < 18; i++) {\n const color = getBit(bits, i);\n const a = this.size - 11 + i % 3;\n const b = Math.floor(i / 3);\n this.setFunctionModule(a, b, color);\n this.setFunctionModule(b, a, color);\n }\n }\n // Draws a 9*9 finder pattern including the border separator,\n // with the center module at (x, y). Modules can be out of bounds.\n drawFinderPattern(x, y) {\n for (let dy = -4; dy <= 4; dy++) {\n for (let dx = -4; dx <= 4; dx++) {\n const dist = Math.max(Math.abs(dx), Math.abs(dy));\n const xx = x + dx;\n const yy = y + dy;\n if (xx >= 0 && xx < this.size && yy >= 0 && yy < this.size)\n this.setFunctionModule(xx, yy, dist !== 2 && dist !== 4, QrCodeDataType.Position);\n }\n }\n }\n // Draws a 5*5 alignment pattern, with the center module\n // at (x, y). All modules must be in bounds.\n drawAlignmentPattern(x, y) {\n for (let dy = -2; dy <= 2; dy++) {\n for (let dx = -2; dx <= 2; dx++) {\n this.setFunctionModule(\n x + dx,\n y + dy,\n Math.max(Math.abs(dx), Math.abs(dy)) !== 1,\n QrCodeDataType.Alignment\n );\n }\n }\n }\n // Sets the color of a module and marks it as a function module.\n // Only used by the constructor. Coordinates must be in bounds.\n setFunctionModule(x, y, isDark, type = QrCodeDataType.Function) {\n this.modules[y][x] = isDark;\n this.types[y][x] = type;\n }\n /* -- Private helper methods for constructor: Codewords and masking -- */\n // Returns a new byte string representing the given data with the appropriate error correction\n // codewords appended to it, based on this object's version and error correction level.\n addEccAndInterleave(data) {\n const ver = this.version;\n const ecl = this.ecc;\n if (data.length !== getNumDataCodewords(ver, ecl))\n throw new RangeError(\"Invalid argument\");\n const numBlocks = NUM_ERROR_CORRECTION_BLOCKS[ecl[0]][ver];\n const blockEccLen = ECC_CODEWORDS_PER_BLOCK[ecl[0]][ver];\n const rawCodewords = Math.floor(getNumRawDataModules(ver) / 8);\n const numShortBlocks = numBlocks - rawCodewords % numBlocks;\n const shortBlockLen = Math.floor(rawCodewords / numBlocks);\n const blocks = [];\n const rsDiv = reedSolomonComputeDivisor(blockEccLen);\n for (let i = 0, k = 0; i < numBlocks; i++) {\n const dat = data.slice(k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1));\n k += dat.length;\n const ecc = reedSolomonComputeRemainder(dat, rsDiv);\n if (i < numShortBlocks)\n dat.push(0);\n blocks.push(dat.concat(ecc));\n }\n const result = [];\n for (let i = 0; i < blocks[0].length; i++) {\n blocks.forEach((block, j) => {\n if (i !== shortBlockLen - blockEccLen || j >= numShortBlocks)\n result.push(block[i]);\n });\n }\n return result;\n }\n // Draws the given sequence of 8-bit codewords (data and error correction) onto the entire\n // data area of this QR Code. Function modules need to be marked off before this is called.\n drawCodewords(data) {\n if (data.length !== Math.floor(getNumRawDataModules(this.version) / 8))\n throw new RangeError(\"Invalid argument\");\n let i = 0;\n for (let right = this.size - 1; right >= 1; right -= 2) {\n if (right === 6)\n right = 5;\n for (let vert = 0; vert < this.size; vert++) {\n for (let j = 0; j < 2; j++) {\n const x = right - j;\n const upward = (right + 1 & 2) === 0;\n const y = upward ? this.size - 1 - vert : vert;\n if (!this.types[y][x] && i < data.length * 8) {\n this.modules[y][x] = getBit(data[i >>> 3], 7 - (i & 7));\n i++;\n }\n }\n }\n }\n }\n // XORs the codeword modules in this QR Code with the given mask pattern.\n // The function modules must be marked and the codeword bits must be drawn\n // before masking. Due to the arithmetic of XOR, calling applyMask() with\n // the same mask value a second time will undo the mask. A final well-formed\n // QR Code needs exactly one (not zero, two, etc.) mask applied.\n applyMask(mask) {\n if (mask < 0 || mask > 7)\n throw new RangeError(\"Mask value out of range\");\n for (let y = 0; y < this.size; y++) {\n for (let x = 0; x < this.size; x++) {\n let invert;\n switch (mask) {\n case 0:\n invert = (x + y) % 2 === 0;\n break;\n case 1:\n invert = y % 2 === 0;\n break;\n case 2:\n invert = x % 3 === 0;\n break;\n case 3:\n invert = (x + y) % 3 === 0;\n break;\n case 4:\n invert = (Math.floor(x / 3) + Math.floor(y / 2)) % 2 === 0;\n break;\n case 5:\n invert = x * y % 2 + x * y % 3 === 0;\n break;\n case 6:\n invert = (x * y % 2 + x * y % 3) % 2 === 0;\n break;\n case 7:\n invert = ((x + y) % 2 + x * y % 3) % 2 === 0;\n break;\n default:\n throw new Error(\"Unreachable\");\n }\n if (!this.types[y][x] && invert)\n this.modules[y][x] = !this.modules[y][x];\n }\n }\n }\n // Calculates and returns the penalty score based on state of this QR Code's current modules.\n // This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.\n getPenaltyScore() {\n let result = 0;\n for (let y = 0; y < this.size; y++) {\n let runColor = false;\n let runX = 0;\n const runHistory = [0, 0, 0, 0, 0, 0, 0];\n for (let x = 0; x < this.size; x++) {\n if (this.modules[y][x] === runColor) {\n runX++;\n if (runX === 5)\n result += PENALTY_N1;\n else if (runX > 5)\n result++;\n } else {\n this.finderPenaltyAddHistory(runX, runHistory);\n if (!runColor)\n result += this.finderPenaltyCountPatterns(runHistory) * PENALTY_N3;\n runColor = this.modules[y][x];\n runX = 1;\n }\n }\n result += this.finderPenaltyTerminateAndCount(runColor, runX, runHistory) * PENALTY_N3;\n }\n for (let x = 0; x < this.size; x++) {\n let runColor = false;\n let runY = 0;\n const runHistory = [0, 0, 0, 0, 0, 0, 0];\n for (let y = 0; y < this.size; y++) {\n if (this.modules[y][x] === runColor) {\n runY++;\n if (runY === 5)\n result += PENALTY_N1;\n else if (runY > 5)\n result++;\n } else {\n this.finderPenaltyAddHistory(runY, runHistory);\n if (!runColor)\n result += this.finderPenaltyCountPatterns(runHistory) * PENALTY_N3;\n runColor = this.modules[y][x];\n runY = 1;\n }\n }\n result += this.finderPenaltyTerminateAndCount(runColor, runY, runHistory) * PENALTY_N3;\n }\n for (let y = 0; y < this.size - 1; y++) {\n for (let x = 0; x < this.size - 1; x++) {\n const color = this.modules[y][x];\n if (color === this.modules[y][x + 1] && color === this.modules[y + 1][x] && color === this.modules[y + 1][x + 1]) {\n result += PENALTY_N2;\n }\n }\n }\n let dark = 0;\n for (const row of this.modules)\n dark = row.reduce((sum, color) => sum + (color ? 1 : 0), dark);\n const total = this.size * this.size;\n const k = Math.ceil(Math.abs(dark * 20 - total * 10) / total) - 1;\n result += k * PENALTY_N4;\n return result;\n }\n /* -- Private helper functions -- */\n // Returns an ascending list of positions of alignment patterns for this version number.\n // Each position is in the range [0,177), and are used on both the x and y axes.\n // This could be implemented as lookup table of 40 variable-length lists of integers.\n getAlignmentPatternPositions() {\n if (this.version === 1) {\n return [];\n } else {\n const numAlign = Math.floor(this.version / 7) + 2;\n const step = this.version === 32 ? 26 : Math.ceil((this.version * 4 + 4) / (numAlign * 2 - 2)) * 2;\n const result = [6];\n for (let pos = this.size - 7; result.length < numAlign; pos -= step)\n result.splice(1, 0, pos);\n return result;\n }\n }\n // Can only be called immediately after a light run is added, and\n // returns either 0, 1, or 2. A helper function for getPenaltyScore().\n finderPenaltyCountPatterns(runHistory) {\n const n = runHistory[1];\n const core = n > 0 && runHistory[2] === n && runHistory[3] === n * 3 && runHistory[4] === n && runHistory[5] === n;\n return (core && runHistory[0] >= n * 4 && runHistory[6] >= n ? 1 : 0) + (core && runHistory[6] >= n * 4 && runHistory[0] >= n ? 1 : 0);\n }\n // Must be called at the end of a line (row or column) of modules. A helper function for getPenaltyScore().\n finderPenaltyTerminateAndCount(currentRunColor, currentRunLength, runHistory) {\n if (currentRunColor) {\n this.finderPenaltyAddHistory(currentRunLength, runHistory);\n currentRunLength = 0;\n }\n currentRunLength += this.size;\n this.finderPenaltyAddHistory(currentRunLength, runHistory);\n return this.finderPenaltyCountPatterns(runHistory);\n }\n // Pushes the given value to the front and drops the last value. A helper function for getPenaltyScore().\n finderPenaltyAddHistory(currentRunLength, runHistory) {\n if (runHistory[0] === 0)\n currentRunLength += this.size;\n runHistory.pop();\n runHistory.unshift(currentRunLength);\n }\n}\nfunction appendBits(val, len, bb) {\n if (len < 0 || len > 31 || val >>> len !== 0)\n throw new RangeError(\"Value out of range\");\n for (let i = len - 1; i >= 0; i--)\n bb.push(val >>> i & 1);\n}\nfunction getBit(x, i) {\n return (x >>> i & 1) !== 0;\n}\nclass QrSegment {\n // Creates a new QR Code segment with the given attributes and data.\n // The character count (numChars) must agree with the mode and the bit buffer length,\n // but the constraint isn't checked. The given bit buffer is cloned and stored.\n constructor(mode, numChars, bitData) {\n this.mode = mode;\n this.numChars = numChars;\n this.bitData = bitData;\n if (numChars < 0)\n throw new RangeError(\"Invalid argument\");\n this.bitData = bitData.slice();\n }\n /* -- Methods -- */\n // Returns a new copy of the data bits of this segment.\n getData() {\n return this.bitData.slice();\n }\n}\nconst MODE_NUMERIC = [1, 10, 12, 14];\nconst MODE_ALPHANUMERIC = [2, 9, 11, 13];\nconst MODE_BYTE = [4, 8, 16, 16];\nfunction numCharCountBits(mode, ver) {\n return mode[Math.floor((ver + 7) / 17) + 1];\n}\nfunction makeBytes(data) {\n const bb = [];\n for (const b of data)\n appendBits(b, 8, bb);\n return new QrSegment(MODE_BYTE, data.length, bb);\n}\nfunction makeNumeric(digits) {\n if (!isNumeric(digits))\n throw new RangeError(\"String contains non-numeric characters\");\n const bb = [];\n for (let i = 0; i < digits.length; ) {\n const n = Math.min(digits.length - i, 3);\n appendBits(Number.parseInt(digits.substring(i, i + n), 10), n * 3 + 1, bb);\n i += n;\n }\n return new QrSegment(MODE_NUMERIC, digits.length, bb);\n}\nfunction makeAlphanumeric(text) {\n if (!isAlphanumeric(text))\n throw new RangeError(\"String contains unencodable characters in alphanumeric mode\");\n const bb = [];\n let i;\n for (i = 0; i + 2 <= text.length; i += 2) {\n let temp = ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)) * 45;\n temp += ALPHANUMERIC_CHARSET.indexOf(text.charAt(i + 1));\n appendBits(temp, 11, bb);\n }\n if (i < text.length)\n appendBits(ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)), 6, bb);\n return new QrSegment(MODE_ALPHANUMERIC, text.length, bb);\n}\nfunction makeSegments(text) {\n if (text === \"\")\n return [];\n else if (isNumeric(text))\n return [makeNumeric(text)];\n else if (isAlphanumeric(text))\n return [makeAlphanumeric(text)];\n else\n return [makeBytes(toUtf8ByteArray(text))];\n}\nfunction isNumeric(text) {\n return NUMERIC_REGEX.test(text);\n}\nfunction isAlphanumeric(text) {\n return ALPHANUMERIC_REGEX.test(text);\n}\nfunction getTotalBits(segs, version) {\n let result = 0;\n for (const seg of segs) {\n const ccbits = numCharCountBits(seg.mode, version);\n if (seg.numChars >= 1 << ccbits)\n return Number.POSITIVE_INFINITY;\n result += 4 + ccbits + seg.bitData.length;\n }\n return result;\n}\nfunction toUtf8ByteArray(str) {\n str = encodeURI(str);\n const result = [];\n for (let i = 0; i < str.length; i++) {\n if (str.charAt(i) !== \"%\") {\n result.push(str.charCodeAt(i));\n } else {\n result.push(Number.parseInt(str.substring(i + 1, i + 3), 16));\n i += 2;\n }\n }\n return result;\n}\nfunction getNumRawDataModules(ver) {\n if (ver < MIN_VERSION || ver > MAX_VERSION)\n throw new RangeError(\"Version number out of range\");\n let result = (16 * ver + 128) * ver + 64;\n if (ver >= 2) {\n const numAlign = Math.floor(ver / 7) + 2;\n result -= (25 * numAlign - 10) * numAlign - 55;\n if (ver >= 7)\n result -= 36;\n }\n return result;\n}\nfunction getNumDataCodewords(ver, ecl) {\n return Math.floor(getNumRawDataModules(ver) / 8) - ECC_CODEWORDS_PER_BLOCK[ecl[0]][ver] * NUM_ERROR_CORRECTION_BLOCKS[ecl[0]][ver];\n}\nfunction reedSolomonComputeDivisor(degree) {\n if (degree < 1 || degree > 255)\n throw new RangeError(\"Degree out of range\");\n const result = [];\n for (let i = 0; i < degree - 1; i++)\n result.push(0);\n result.push(1);\n let root = 1;\n for (let i = 0; i < degree; i++) {\n for (let j = 0; j < result.length; j++) {\n result[j] = reedSolomonMultiply(result[j], root);\n if (j + 1 < result.length)\n result[j] ^= result[j + 1];\n }\n root = reedSolomonMultiply(root, 2);\n }\n return result;\n}\nfunction reedSolomonComputeRemainder(data, divisor) {\n const result = divisor.map((_) => 0);\n for (const b of data) {\n const factor = b ^ result.shift();\n result.push(0);\n divisor.forEach((coef, i) => result[i] ^= reedSolomonMultiply(coef, factor));\n }\n return result;\n}\nfunction reedSolomonMultiply(x, y) {\n if (x >>> 8 !== 0 || y >>> 8 !== 0)\n throw new RangeError(\"Byte out of range\");\n let z = 0;\n for (let i = 7; i >= 0; i--) {\n z = z << 1 ^ (z >>> 7) * 285;\n z ^= (y >>> i & 1) * x;\n }\n return z;\n}\nfunction encodeSegments(segs, ecl, minVersion = 1, maxVersion = 40, mask = -1, boostEcl = true) {\n if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7) {\n throw new RangeError(\"Invalid value\");\n }\n let version;\n let dataUsedBits;\n for (version = minVersion; ; version++) {\n const dataCapacityBits2 = getNumDataCodewords(version, ecl) * 8;\n const usedBits = getTotalBits(segs, version);\n if (usedBits <= dataCapacityBits2) {\n dataUsedBits = usedBits;\n break;\n }\n if (version >= maxVersion)\n throw new RangeError(\"Data too long\");\n }\n for (const newEcl of [MEDIUM, QUARTILE, HIGH]) {\n if (boostEcl && dataUsedBits <= getNumDataCodewords(version, newEcl) * 8)\n ecl = newEcl;\n }\n const bb = [];\n for (const seg of segs) {\n appendBits(seg.mode[0], 4, bb);\n appendBits(seg.numChars, numCharCountBits(seg.mode, version), bb);\n for (const b of seg.getData())\n bb.push(b);\n }\n const dataCapacityBits = getNumDataCodewords(version, ecl) * 8;\n appendBits(0, Math.min(4, dataCapacityBits - bb.length), bb);\n appendBits(0, (8 - bb.length % 8) % 8, bb);\n for (let padByte = 236; bb.length < dataCapacityBits; padByte ^= 236 ^ 17)\n appendBits(padByte, 8, bb);\n const dataCodewords = Array.from({ length: Math.ceil(bb.length / 8) }, () => 0);\n bb.forEach((b, i) => dataCodewords[i >>> 3] |= b << 7 - (i & 7));\n return new QrCode(version, ecl, dataCodewords, mask);\n}\n\nfunction encode(data, options) {\n const {\n ecc = \"L\",\n boostEcc = false,\n minVersion = 1,\n maxVersion = 40,\n maskPattern = -1,\n border = 1\n } = options || {};\n const segment = typeof data === \"string\" ? makeSegments(data) : Array.isArray(data) ? [makeBytes(data)] : void 0;\n if (!segment)\n throw new Error(`uqr only supports encoding string and binary data, but got: ${typeof data}`);\n const qr = encodeSegments(\n segment,\n EccMap[ecc],\n minVersion,\n maxVersion,\n maskPattern,\n boostEcc\n );\n const result = addBorder({\n version: qr.version,\n maskPattern: qr.mask,\n size: qr.size,\n data: qr.modules,\n types: qr.types\n }, border);\n if (options?.invert)\n result.data = result.data.map((row) => row.map((mod) => !mod));\n options?.onEncoded?.(result);\n return result;\n}\nfunction addBorder(input, border = 1) {\n if (!border)\n return input;\n const { size } = input;\n const newSize = size + border * 2;\n input.size = newSize;\n input.data.forEach((row) => {\n for (let i = 0; i < border; i++) {\n row.unshift(false);\n row.push(false);\n }\n });\n for (let i = 0; i < border; i++) {\n input.data.unshift(Array.from({ length: newSize }, (_) => false));\n input.data.push(Array.from({ length: newSize }, (_) => false));\n }\n const b = QrCodeDataType.Border;\n input.types.forEach((row) => {\n for (let i = 0; i < border; i++) {\n row.unshift(b);\n row.push(b);\n }\n });\n for (let i = 0; i < border; i++) {\n input.types.unshift(Array.from({ length: newSize }, (_) => b));\n input.types.push(Array.from({ length: newSize }, (_) => b));\n }\n return input;\n}\nfunction getDataAt(data, x, y, defaults = false) {\n if (x < 0 || y < 0 || x >= data.length || y >= data.length)\n return defaults;\n return data[y][x];\n}\n\nfunction renderUnicode(data, options = {}) {\n const {\n whiteChar = \"\\u2588\",\n blackChar = \"\\u2591\"\n } = options;\n const result = encode(data, options);\n return result.data.map((row) => {\n return row.map((mod) => mod ? blackChar : whiteChar).join(\"\");\n }).join(\"\\n\");\n}\nfunction renderANSI(data, options = {}) {\n return renderUnicode(data, {\n ...options,\n blackChar: \"\\x1B[40m\\u3000\\x1B[0m\",\n whiteChar: \"\\x1B[47m\\u3000\\x1B[0m\"\n });\n}\nfunction renderUnicodeCompact(data, options = {}) {\n const palette = {\n WHITE_ALL: \"\\u2588\",\n WHITE_BLACK: \"\\u2580\",\n BLACK_WHITE: \"\\u2584\",\n BLACK_ALL: \" \"\n };\n const result = encode(data, options);\n const WHITE = false;\n const BLACK = true;\n const at = (x, y) => getDataAt(result.data, x, y, true);\n const lines = [];\n let line = \"\";\n for (let row = 0; row < result.size; row += 2) {\n for (let col = 0; col < result.size; col++) {\n if (at(col, row) === WHITE && at(col, row + 1) === WHITE)\n line += palette.WHITE_ALL;\n else if (at(col, row) === WHITE && at(col, row + 1) === BLACK)\n line += palette.WHITE_BLACK;\n else if (at(col, row) === BLACK && at(col, row + 1) === WHITE)\n line += palette.BLACK_WHITE;\n else\n line += palette.BLACK_ALL;\n }\n lines.push(line);\n line = \"\";\n }\n return lines.join(\"\\n\");\n}\n\nfunction escapeAttr(value) {\n return value.replace(/&/g, \"&\").replace(/\"/g, \""\").replace(/</g, \"<\").replace(/>/g, \">\");\n}\nfunction renderSVG(data, options = {}) {\n const result = encode(data, options);\n const {\n pixelSize = 10,\n whiteColor = \"white\",\n blackColor = \"black\"\n } = options;\n const height = result.size * pixelSize;\n const width = result.size * pixelSize;\n let svg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\">`;\n const paths = [];\n for (let row = 0; row < result.size; row++) {\n for (let col = 0; col < result.size; col++) {\n const x = col * pixelSize;\n const y = row * pixelSize;\n if (result.data[row][col])\n paths.push(`M${x},${y}h${pixelSize}v${pixelSize}h-${pixelSize}z`);\n }\n }\n svg += `<rect fill=\"${escapeAttr(whiteColor)}\" width=\"${width}\" height=\"${height}\"/>`;\n svg += `<path fill=\"${escapeAttr(blackColor)}\" d=\"${paths.join(\"\")}\"/>`;\n svg += \"</svg>\";\n return svg;\n}\n\nexport { QrCodeDataType, encode, renderANSI, renderSVG, renderUnicode, renderUnicodeCompact };\n","import { encode } from \"uqr\";\n\n/** Draws a QR code for `text` on a canvas (no images, so strict CSPs are fine). */\nexport function drawQr(canvas: HTMLCanvasElement, text: string, cssSize: number): void {\n const qr = encode(text, { ecc: \"M\", border: 2 });\n const scale = Math.max(1, Math.min(window.devicePixelRatio || 1, 3));\n canvas.width = canvas.height = Math.round(cssSize * scale);\n const context = canvas.getContext(\"2d\");\n if (!context) return;\n const cell = canvas.width / qr.size;\n context.fillStyle = \"#fff\";\n context.fillRect(0, 0, canvas.width, canvas.height);\n context.fillStyle = \"#000\";\n qr.data.forEach((line, y) => line.forEach((dark, x) => {\n if (dark) context.fillRect(Math.floor(x * cell), Math.floor(y * cell), Math.ceil(cell), Math.ceil(cell));\n }));\n}\n\n/** \"K7Q29XHM\" → \"K7Q2-9XHM\". */\nexport const formatCode = (code: string) => `${code.slice(0, 4)}-${code.slice(4)}`;\n","// \"auto\" matches the page the component sits on, not the computer's dark-mode setting: a light page in\n// dark mode still gets a light field. Reads the first solid background behind the element.\n\nfunction luminance(color: string): number | null {\n const match = /rgba?\\(([\\d.]+)[,\\s]+([\\d.]+)[,\\s]+([\\d.]+)(?:[,\\s/]+([\\d.]+%?))?\\)/.exec(color);\n if (!match) return null;\n const alpha = match[4] === undefined ? 1 : match[4].endsWith(\"%\") ? Number.parseFloat(match[4]) / 100 : Number(match[4]);\n if (alpha < 0.5) return null;\n const [r, g, b] = [match[1], match[2], match[3]].map((value) => {\n const channel = Number(value) / 255;\n return channel <= 0.03928 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4;\n }) as [number, number, number];\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n}\n\nexport function pageTheme(element: Element | null): \"light\" | \"dark\" {\n for (let node: Element | null = element; node; node = node.parentElement) {\n const value = luminance(getComputedStyle(node).backgroundColor);\n if (value !== null) return value < 0.3 ? \"dark\" : \"light\";\n }\n // Nothing painted: the canvas follows the page's color-scheme.\n const scheme = getComputedStyle(document.documentElement).colorScheme || \"\";\n if (/\\bdark\\b/.test(scheme) && !/\\blight\\b/.test(scheme)) return \"dark\";\n if (/\\blight\\b/.test(scheme) && /\\bdark\\b/.test(scheme)) return matchMedia?.(\"(prefers-color-scheme: dark)\").matches ? \"dark\" : \"light\";\n return \"light\";\n}\n\nexport function resolveTheme(requested: \"light\" | \"dark\" | \"auto\" | undefined, element: Element | null): \"light\" | \"dark\" {\n return requested === \"light\" || requested === \"dark\" ? requested : pageTheme(element);\n}\n","// The modal's styles, in TokShare's colors: lime buttons with ink text, violet highlights. Customize from\n// the host page with CSS variables on the host element, e.g.\n// [data-tokshare-pick] { --tsp-accent: #0b6bcb; --tsp-accent-text: #fff; --tsp-radius: 12px; }\n// --tsp-accent fills buttons and progress; --tsp-accent-ink (links, focus rings) follows it unless set.\nexport const STYLES = `\n:host { all: initial; }\n.overlay {\n /* Light. Lime is unreadable as text on white, so links and focus rings use a deeper violet. */\n --accent: var(--tsp-accent, #c8ff4d);\n --accent-text: var(--tsp-accent-text, #0b0d12);\n --accent-ink: var(--tsp-accent-ink, var(--tsp-accent, #6b4fe0));\n --accent-2: var(--tsp-accent-2, var(--tsp-accent, #8a6cf5));\n --button-edge: rgba(11, 13, 18, .1);\n --bg: var(--tsp-bg, #fff);\n --text: var(--tsp-text, #0b0d12);\n --muted: var(--tsp-muted, #5d6270);\n --line: var(--tsp-line, rgba(11, 13, 18, .12));\n --track: rgba(11, 13, 18, .08);\n --ok: #1a8a4c;\n --error: #c42f3d;\n --radius: var(--tsp-radius, 18px);\n position: fixed; inset: 0; z-index: 2147483000;\n display: grid; place-items: center; padding: 16px;\n background: rgba(9, 11, 16, .6);\n font: 15px/1.5 var(--tsp-font, Inter, system-ui, -apple-system, \"Segoe UI\", Roboto, \"Noto Sans Arabic\", sans-serif);\n color: var(--text);\n animation: fade .15s ease-out;\n}\n@media (prefers-color-scheme: dark) {\n .overlay[data-theme=\"auto\"] { --accent-ink: var(--tsp-accent-ink, var(--tsp-accent, #c8ff4d)); --accent-2: var(--tsp-accent-2, var(--tsp-accent, #9a7cff)); --button-edge: transparent; --bg: var(--tsp-bg, #12151c); --text: var(--tsp-text, #f4f4f5); --muted: var(--tsp-muted, #9297a4); --line: var(--tsp-line, rgba(255,255,255,.09)); --track: rgba(255,255,255,.08); --ok: #c8ff4d; --error: #ff8a94; }\n}\n.overlay[data-theme=\"dark\"] { --accent-ink: var(--tsp-accent-ink, var(--tsp-accent, #c8ff4d)); --accent-2: var(--tsp-accent-2, var(--tsp-accent, #9a7cff)); --button-edge: transparent; --bg: var(--tsp-bg, #12151c); --text: var(--tsp-text, #f4f4f5); --muted: var(--tsp-muted, #9297a4); --line: var(--tsp-line, rgba(255,255,255,.09)); --track: rgba(255,255,255,.08); --ok: #c8ff4d; --error: #ff8a94; }\n* { box-sizing: border-box; }\n[hidden] { display: none !important; }\n.dialog {\n width: min(420px, 100%); max-height: calc(100dvh - 32px); overflow: auto;\n background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius);\n box-shadow: 0 30px 80px rgba(0, 0, 0, .35); padding: 20px; display: grid; gap: 14px; outline: none;\n}\n.header { display: flex; align-items: center; justify-content: space-between; gap: 12px; }\n.title { margin: 0; font-size: 18px; font-weight: 700; line-height: 1.3; }\n.icon-button { all: unset; cursor: pointer; width: 32px; height: 32px; display: grid; place-items: center; border-radius: 50%; font-size: 22px; color: var(--muted); }\n.icon-button:hover { background: var(--track); color: var(--text); }\n.qr-block { display: grid; justify-items: center; gap: 8px; text-align: center; }\n.qr { width: 220px; height: 220px; border-radius: 12px; background: #fff; border: 1px solid var(--line); image-rendering: pixelated; }\n.lead { margin: 4px 0 0; font-weight: 600; }\n.muted { margin: 0; color: var(--muted); font-size: 13.5px; }\n.small { font-size: 12px; }\n.code { display: inline-block; direction: ltr; font: 700 15px/1.3 ui-monospace, \"SF Mono\", Menlo, Consolas, monospace; letter-spacing: 1.5px; color: var(--text); padding: 2px 8px; border-radius: 6px; background: var(--track); }\n.status { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 4px 10px; text-align: center; font-size: 14px; min-height: 22px; }\n.approval { display: grid; gap: 8px; width: 100%; padding: 14px; border: 1px solid var(--line); border-radius: 14px; text-align: center; }\n.files { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }\n.files:empty { display: none; }\n.file { display: grid; gap: 3px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px; }\n.file .name { font-weight: 600; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.file .meta { color: var(--muted); font-size: 12px; }\n.file .bar { height: 4px; border-radius: 4px; background: var(--track); overflow: hidden; margin-top: 3px; }\n.file .fill { display: block; height: 100%; width: 0; background: linear-gradient(90deg, var(--accent-2), var(--accent)); transition: width .2s; }\n.file.received .meta { color: var(--ok); }\n.file.received .fill { background: var(--ok); }\n.file.failed .meta { color: var(--error); }\n.file.failed .bar { display: none; }\n.footer { display: grid; gap: 12px; }\n.buttons { display: flex; gap: 10px; justify-content: flex-end; }\nbutton.primary, button.secondary { font: inherit; font-weight: 600; cursor: pointer; border-radius: 12px; padding: 10px 16px; min-height: 42px; border: 1px solid transparent; }\nbutton.primary { background: var(--accent); color: var(--accent-text); border-color: var(--button-edge); box-shadow: inset 0 1px 0 rgba(255,255,255,.45), 0 8px 24px -8px color-mix(in srgb, var(--accent) 60%, transparent); }\nbutton.primary:hover:not(:disabled) { background: color-mix(in srgb, var(--accent) 85%, #fff); }\nbutton.primary:disabled { opacity: .45; cursor: default; box-shadow: none; }\nbutton.secondary { background: transparent; color: var(--text); border-color: var(--line); }\nbutton.secondary:hover { background: var(--track); }\nbutton.link { all: unset; cursor: pointer; color: var(--accent-ink); font-weight: 600; font-size: 13.5px; text-decoration: underline; text-underline-offset: 3px; }\nbutton:focus-visible, .icon-button:focus-visible { outline: 3px solid var(--accent-ink); outline-offset: 2px; }\n/* ---- TokShare for desktop ---- */\n.announce { margin: 0; display: flex; align-items: center; gap: 10px; padding: 9px 8px 9px 12px; border-radius: 12px; border: 1px solid var(--line); background: color-mix(in srgb, var(--accent-2) 7%, transparent); color: var(--muted); font-size: 12.5px; line-height: 1.45; text-align: start; }\n.announce i { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--accent-2); }\n.announce span { flex: 1; min-width: 0; }\n.announce a { color: var(--accent-ink); font-weight: 650; text-decoration: underline; text-underline-offset: 2px; white-space: nowrap; }\n.announce-hide { all: unset; cursor: pointer; flex: none; width: 24px; height: 24px; display: grid; place-items: center; border-radius: 50%; font-size: 16px; color: var(--muted); }\n.announce-hide:hover { background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--text); }\n.announce-hide:focus-visible, .announce a:focus-visible { outline: 3px solid color-mix(in srgb, var(--accent-ink) 60%, transparent); outline-offset: 2px; }\n@keyframes fade { from { opacity: 0; } }\n@media (prefers-reduced-motion: reduce) { .overlay { animation: none; } .file .fill { transition: none; } }\n`;\n","// The built-in modal, in a Shadow DOM so the host page's styles can't break it (and it can't break\n// them). Styles go in through a constructable stylesheet and the QR is drawn on a canvas, so a strict\n// Content-Security-Policy on the host page needs nothing extra beyond connect-src for the relay.\nimport type { FileMeta } from \"@tokshare/pick-protocol\";\nimport { announcement } from \"./announce\";\nimport { formatBytes, resolveLocale, translator } from \"./i18n\";\nimport { drawQr } from \"./qr\";\nimport { resolveTheme } from \"./theme\";\nimport type { PickController, PickOptions } from \"./picker\";\nimport { STYLES } from \"./styles\";\n\ninterface Row { element: HTMLLIElement; meta: FileMeta; state: \"sending\" | \"receiving\" | \"received\" | \"failed\"; percent: number }\n\nexport function mountModal(controller: PickController, options: PickOptions): void {\n const locale = resolveLocale(options.locale);\n const t = translator(locale, options.strings);\n const previousFocus = document.activeElement as HTMLElement | null;\n const host = document.createElement(\"div\");\n host.setAttribute(\"data-tokshare-pick\", \"\");\n const root = host.attachShadow({ mode: \"open\" });\n if (\"adoptedStyleSheets\" in Document.prototype && \"replaceSync\" in CSSStyleSheet.prototype) {\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(STYLES);\n root.adoptedStyleSheets = [sheet];\n } else {\n const style = document.createElement(\"style\");\n style.textContent = STYLES;\n root.append(style);\n }\n\n const el = <K extends keyof HTMLElementTagNameMap>(tag: K, className = \"\", text = \"\") => {\n const node = document.createElement(tag);\n if (className) node.className = className;\n if (text) node.textContent = text;\n return node;\n };\n\n const overlay = el(\"div\", \"overlay\");\n overlay.dataset.theme = resolveTheme(options.theme, document.body);\n const dialog = el(\"div\", \"dialog\");\n dialog.setAttribute(\"role\", \"dialog\");\n dialog.setAttribute(\"aria-modal\", \"true\");\n dialog.setAttribute(\"aria-labelledby\", \"tsp-title\");\n dialog.dir = locale === \"ar\" ? \"rtl\" : \"ltr\";\n dialog.lang = locale;\n dialog.tabIndex = -1;\n\n const header = el(\"div\", \"header\");\n const title = el(\"h2\", \"title\", t(options.multiple === false ? \"titleOne\" : \"title\"));\n title.id = \"tsp-title\";\n const closeButton = el(\"button\", \"icon-button\", \"×\");\n closeButton.type = \"button\";\n closeButton.setAttribute(\"aria-label\", t(\"close\"));\n header.append(title, closeButton);\n\n const qrBlock = el(\"div\", \"qr-block\");\n const canvas = el(\"canvas\", \"qr\");\n canvas.setAttribute(\"role\", \"img\");\n canvas.setAttribute(\"aria-label\", t(\"scan\"));\n const scan = el(\"p\", \"lead\", t(\"scan\"));\n const typeLine = el(\"p\", \"muted\");\n const code = el(\"span\", \"code\");\n qrBlock.append(canvas, scan, typeLine);\n\n const status = el(\"div\", \"status\");\n status.setAttribute(\"role\", \"status\");\n status.setAttribute(\"aria-live\", \"polite\");\n const list = el(\"ul\", \"files\");\n const footer = el(\"div\", \"footer\");\n const privacy = el(\"p\", \"muted small\", t(\"privacy\"));\n const buttons = el(\"div\", \"buttons\");\n const cancelButton = el(\"button\", \"secondary\", t(\"cancel\"));\n cancelButton.type = \"button\";\n const doneButton = el(\"button\", \"primary\", t(\"done\"));\n doneButton.type = \"button\";\n doneButton.disabled = true;\n buttons.append(cancelButton, doneButton);\n const promo = announcement(options.announce, t);\n footer.append(...(promo ? [promo] : []), privacy, buttons);\n dialog.append(header, qrBlock, status, list, footer);\n overlay.append(dialog);\n root.append(overlay);\n document.body.append(host);\n dialog.focus();\n\n const rows = new Map<string, Row>();\n let phoneLabel = \"\";\n\n const setStatus = (text: string, extra?: HTMLElement) => {\n status.replaceChildren(el(\"span\", \"\", text), ...(extra ? [extra] : []));\n };\n\n const showQr = (claimUrl: string, value: string) => {\n drawQr(canvas, claimUrl, 220);\n const host = new URL(claimUrl).host;\n code.textContent = `${value.slice(0, 4)}-${value.slice(4)}`;\n typeLine.replaceChildren(document.createTextNode(`${t(\"orType\", { host })} `), code);\n qrBlock.hidden = false;\n setStatus(t(\"waiting\"));\n };\n\n const updateDone = () => {\n const count = controller.files.length;\n doneButton.disabled = count === 0;\n doneButton.textContent = count === 0 ? t(\"done\") : count === 1 ? t(\"useFile\") : t(\"useFiles\", { count });\n };\n\n const renderRow = (row: Row) => {\n const label = row.state === \"sending\" ? t(\"sending\", { percent: row.percent })\n : row.state === \"receiving\" ? t(\"receiving\", { percent: row.percent })\n : t(row.state);\n row.element.className = `file ${row.state}`;\n const bar = el(\"span\", \"bar\");\n const fill = el(\"i\", \"fill\");\n fill.style.width = `${row.state === \"received\" ? 100 : row.percent}%`;\n bar.append(fill);\n row.element.replaceChildren(el(\"span\", \"name\", row.meta.name), el(\"span\", \"meta\", `${formatBytes(row.meta.size, locale)} · ${label}`), bar);\n };\n\n const rowFor = (meta: FileMeta): Row => {\n let row = rows.get(meta.id);\n if (!row) {\n row = { element: el(\"li\"), meta, state: \"sending\", percent: 0 };\n rows.set(meta.id, row);\n list.append(row.element);\n }\n return row;\n };\n\n let direct = false;\n const showConnected = () => {\n const disconnect = el(\"button\", \"link\", t(\"disconnect\"));\n disconnect.type = \"button\";\n disconnect.addEventListener(\"click\", () => { controller.disconnect().catch(() => undefined); });\n setStatus(t(direct ? \"connectedDirect\" : \"connected\", { label: phoneLabel }), disconnect);\n };\n\n const closeModal = () => {\n document.removeEventListener(\"keydown\", onKey, true);\n host.remove();\n previousFocus?.focus?.();\n };\n const onKey = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") { event.stopPropagation(); controller.cancel(); }\n if (event.key === \"Tab\") {\n // Keep focus inside the dialog.\n const focusable = [...root.querySelectorAll<HTMLElement>(\"button:not([disabled])\")];\n if (!focusable.length) return;\n const first = focusable[0]!;\n const last = focusable[focusable.length - 1]!;\n const active = root.activeElement;\n if (event.shiftKey && (active === first || active === dialog)) { event.preventDefault(); last.focus(); }\n else if (!event.shiftKey && active === last) { event.preventDefault(); first.focus(); }\n }\n };\n document.addEventListener(\"keydown\", onKey, true);\n closeButton.addEventListener(\"click\", () => controller.cancel());\n cancelButton.addEventListener(\"click\", () => controller.cancel());\n doneButton.addEventListener(\"click\", () => controller.finish());\n overlay.addEventListener(\"click\", (event) => { if (event.target === overlay) controller.cancel(); });\n\n qrBlock.hidden = true;\n setStatus(t(\"loading\"));\n\n controller.on(\"ready\", ({ claimUrl, code: value }) => showQr(claimUrl, value));\n controller.on(\"phone\", ({ phone, needsApproval, match }) => {\n phoneLabel = phone.label;\n qrBlock.hidden = true;\n if (needsApproval) {\n const box = el(\"div\", \"approval\");\n const approve = el(\"button\", \"primary\", t(\"approve\"));\n const reject = el(\"button\", \"secondary\", t(\"reject\"));\n approve.type = reject.type = \"button\";\n approve.addEventListener(\"click\", () => { controller.approve(); showConnected(); });\n reject.addEventListener(\"click\", () => controller.reject());\n box.append(el(\"strong\", \"\", t(\"approveTitle\")), el(\"span\", \"muted\", `${phone.label} · ${t(\"approveMatch\", { match: match ?? \"\" })}`), el(\"div\", \"buttons\", \"\"));\n box.lastElementChild!.append(reject, approve);\n status.replaceChildren(box);\n approve.focus();\n } else showConnected();\n });\n controller.on(\"phone_left\", () => { direct = false; setStatus(t(\"phoneLeft\")); });\n controller.on(\"direct\", ({ connected }) => { direct = connected; if (phoneLabel) showConnected(); });\n controller.on(\"file_started\", (meta) => renderRow(rowFor(meta)));\n controller.on(\"progress\", (progress) => {\n const row = rows.get(progress.id);\n if (!row) return;\n row.state = progress.phase === \"upload\" ? \"sending\" : \"receiving\";\n row.percent = progress.total ? Math.floor((progress.sent / progress.total) * 100) : 0;\n renderRow(row);\n });\n controller.on(\"received\", ({ id }) => {\n const row = rows.get(id);\n if (row) { row.state = \"received\"; renderRow(row); }\n updateDone();\n });\n controller.on(\"file_failed\", ({ id }) => {\n const row = rows.get(id);\n if (row) { row.state = \"failed\"; renderRow(row); }\n });\n controller.on(\"error\", (error) => {\n qrBlock.hidden = true;\n const retry = el(\"button\", \"link\", t(\"tryAgain\"));\n retry.type = \"button\";\n retry.addEventListener(\"click\", () => { setStatus(t(\"loading\")); controller.restart(); });\n setStatus(t(\"error\", { message: error.message }), retry);\n });\n controller.on(\"close\", (reason) => {\n if (reason === \"finished\" || reason === \"canceled\" || controller.files.length) return closeModal();\n qrBlock.hidden = true;\n const again = el(\"button\", \"link\", t(\"newCode\"));\n again.type = \"button\";\n again.addEventListener(\"click\", () => { setStatus(t(\"loading\")); controller.restart(); });\n setStatus(t(\"expired\"), again);\n });\n controller.done.then(closeModal);\n}\n","// The website's side of a relay session: create it, keep its WebSocket alive (replaying anything\n// missed after a drop), stream finished files into File objects, and close it.\nimport {\n type CreateSessionResponse, type DesktopCommand, type DesktopEvent, type ErrorCode, type FileMeta,\n PickError, type SessionOptions,\n} from \"@tokshare/pick-protocol\";\nimport { SDK_VERSION } from \"./config\";\n\n/** Requests are text/plain JSON: \"simple\" requests, so the browser sends no CORS preflight. */\nasync function post(url: string, body: unknown): Promise<Response> {\n let response: Response;\n try {\n response = await fetch(url, { method: \"POST\", headers: { \"Content-Type\": \"text/plain\" }, body: JSON.stringify(body), cache: \"no-store\", credentials: \"omit\" });\n } catch {\n throw new PickError(\"network\", \"Can't reach TokShare Pick.\", 0);\n }\n if (!response.ok) {\n const data = await response.json().catch(() => ({}));\n throw new PickError((data.error as ErrorCode) || \"internal\", data.message || `HTTP ${response.status}`, response.status);\n }\n return response;\n}\n\nexport class RelaySession {\n readonly info: CreateSessionResponse;\n private readonly relay: string;\n private ws: WebSocket | null = null;\n private lastSeq = 0;\n private closed = false;\n private attempt = 0;\n private pinger: ReturnType<typeof setInterval> | undefined;\n private readonly onEvent: (event: DesktopEvent) => void;\n\n private constructor(relay: string, info: CreateSessionResponse, onEvent: (event: DesktopEvent) => void) {\n this.relay = relay;\n this.info = info;\n this.onEvent = onEvent;\n }\n\n static async create(relay: string, key: string, options: SessionOptions, onEvent: (event: DesktopEvent) => void): Promise<RelaySession> {\n const response = await post(`${relay}/v1/sessions`, { key, options, client: `sdk/${SDK_VERSION}` });\n const session = new RelaySession(relay, (await response.json()) as CreateSessionResponse, onEvent);\n session.connect();\n return session;\n }\n\n private connect(): void {\n if (this.closed) return;\n const ws = new WebSocket(this.info.wsUrl);\n this.ws = ws;\n ws.addEventListener(\"open\", () => {\n this.attempt = 0;\n ws.send(JSON.stringify({ t: \"auth\", token: this.info.desktopToken, lastSeq: this.lastSeq } satisfies DesktopCommand));\n this.pinger = setInterval(() => { if (ws.readyState === WebSocket.OPEN) ws.send(\"ping\"); }, 25_000);\n });\n ws.addEventListener(\"message\", (message) => {\n if (message.data === \"pong\") return;\n let event: DesktopEvent;\n try { event = JSON.parse(message.data as string); } catch { return; }\n if (\"seq\" in event && event.t !== \"hello\") {\n if (event.seq <= this.lastSeq) return;\n this.lastSeq = event.seq;\n }\n if (event.t === \"closed\") this.closed = true;\n this.onEvent(event);\n });\n ws.addEventListener(\"close\", (event) => {\n clearInterval(this.pinger);\n if (this.closed || event.code === 4401) return;\n setTimeout(() => this.connect(), Math.min(10_000, 400 * 2 ** this.attempt++));\n });\n }\n\n send(command: DesktopCommand): void {\n if (this.ws?.readyState === WebSocket.OPEN) this.ws.send(JSON.stringify(command));\n }\n\n /** Streams a finished file from the relay. Reports bytes received; retries a dropped stream. */\n async download(meta: FileMeta, onProgress: (received: number) => void): Promise<File> {\n for (let attempt = 0; ; attempt++) {\n try {\n const response = await post(`${this.relay}/v1/sessions/${this.info.sid}/files/${meta.id}/download`, { token: this.info.desktopToken });\n const reader = response.body!.getReader();\n const chunks: Uint8Array[] = [];\n let received = 0;\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n received += value.byteLength;\n onProgress(received);\n }\n if (received !== meta.size) throw new PickError(\"network\", \"Incomplete download.\", 0);\n return new File(chunks as BlobPart[], meta.name, { type: meta.type || meta.sniffed || \"\", lastModified: meta.lastModified });\n } catch (error) {\n if (!(error instanceof PickError && error.code === \"network\") || attempt >= 2) throw error;\n await new Promise((resolve) => setTimeout(resolve, 600 * (attempt + 1)));\n }\n }\n }\n\n /** A file that came over the direct link: delivered (counted, phone told), or refused and why. */\n directResult(id: string, ok: boolean, code?: string): Promise<unknown> {\n return post(`${this.relay}/v1/sessions/${this.info.sid}/files/${id}/direct`, { token: this.info.desktopToken, ok, ...(code ? { code } : {}) }).catch(() => undefined);\n }\n\n ack(id: string): Promise<unknown> {\n return post(`${this.relay}/v1/sessions/${this.info.sid}/files/${id}/ack`, { token: this.info.desktopToken }).catch(() => undefined);\n }\n\n /** Forget the connected phone and get a new QR and code. */\n async rekey(): Promise<{ claimUrl: string; code: string }> {\n const response = await post(`${this.relay}/v1/sessions/${this.info.sid}/rekey`, { token: this.info.desktopToken });\n const fresh = (await response.json()) as { claimUrl: string; code: string };\n Object.assign(this.info, fresh);\n return fresh;\n }\n\n /** Ends the session: the relay deletes anything left. Uses a beacon while the page is unloading. */\n close(unloading = false): void {\n if (this.closed) return;\n this.closed = true;\n clearInterval(this.pinger);\n const url = `${this.relay}/v1/sessions/${this.info.sid}/close`;\n const body = JSON.stringify({ token: this.info.desktopToken });\n if (unloading && typeof navigator !== \"undefined\" && navigator.sendBeacon) navigator.sendBeacon(url, new Blob([body], { type: \"text/plain\" }));\n else post(url, { token: this.info.desktopToken }).catch(() => undefined);\n try { this.ws?.close(1000, \"closed\"); } catch {}\n }\n\n get isClosed(): boolean {\n return this.closed;\n }\n}\n","// The picker: one relay session, its events, and the files it collects. The modal (modal.ts) is one\n// way to show it; `ui: false` gives the same controller with no UI.\nimport { type CloseReason, type DesktopEvent, type FileMeta, type Locale, PickError, type PhoneInfo, type SessionOptions } from \"@tokshare/pick-protocol\";\nimport { DEFAULT_RELAY } from \"./config\";\nimport type { StringKey } from \"./i18n\";\nimport { DirectReceiver, verifyDirectFile } from \"./direct\";\nimport { mountModal } from \"./modal\";\nimport { RelaySession } from \"./session\";\n\nexport interface PickOptions extends Omit<SessionOptions, \"locale\"> {\n /** Your publishable key (pk_live_… or pk_test_…). */\n key: string;\n /** Relay URL. Defaults to the hosted relay. */\n relay?: string;\n /** \"auto\" follows the page's lang attribute, then the browser. */\n locale?: Locale | \"auto\";\n /** false: no modal; use the controller's events, claimUrl and code to build your own UI. */\n ui?: boolean;\n theme?: \"light\" | \"dark\" | \"auto\";\n /** Replace any of the modal's strings. */\n strings?: Partial<Record<StringKey, string>>;\n /** A small, dismissible line about TokShare for desktop in the modal and the field. Default true. */\n announce?: boolean;\n signal?: AbortSignal;\n}\n\nexport interface ProgressInfo {\n id: string;\n name: string;\n sent: number;\n total: number;\n /** \"upload\": phone → relay (or straight to this page over Wi-Fi). \"download\": relay → this page. */\n phase: \"upload\" | \"download\";\n}\n\nexport interface PickEvents {\n ready: { claimUrl: string; code: string };\n phone: { phone: PhoneInfo; needsApproval: boolean; match?: string };\n phone_left: undefined;\n /** The phone is on the same network and files come straight to this page (true), or not any more. */\n direct: { connected: boolean };\n file_started: FileMeta;\n progress: ProgressInfo;\n file: File;\n /** The same file, with the relay id its progress events used. */\n received: { id: string; file: File };\n file_failed: { id: string; code: string };\n error: PickError;\n close: CloseReason | \"canceled\" | \"finished\";\n}\n\nexport interface PickController {\n /** Resolves with the received files when the person finishes; [] if canceled before any arrived. */\n readonly done: Promise<File[]>;\n /** Files received so far. */\n readonly files: readonly File[];\n readonly claimUrl: string | null;\n readonly code: string | null;\n on<E extends keyof PickEvents>(event: E, handler: (detail: PickEvents[E]) => void): () => void;\n /** Use the files received so far. */\n finish(): void;\n /** Close without files. */\n cancel(): void;\n approve(): void;\n reject(): void;\n /** Forget the connected phone and show a new code. */\n disconnect(): Promise<void>;\n /** Start over with a new session (after an expiry or error). */\n restart(): void;\n}\n\nexport function open(options: PickOptions): PickController {\n if (!options || typeof options.key !== \"string\") throw new PickError(\"key_invalid\", \"Pass your publishable key: open({ key: 'pk_live_…' }).\");\n const relay = (options.relay || DEFAULT_RELAY).replace(/\\/+$/, \"\");\n const handlers = new Map<keyof PickEvents, Set<(detail: any) => void>>();\n const emit = <E extends keyof PickEvents>(event: E, detail: PickEvents[E]) => {\n for (const handler of handlers.get(event) ?? []) { try { handler(detail); } catch (error) { console.error(error); } }\n };\n const files: File[] = [];\n const handled = new Set<string>();\n const metas = new Map<string, FileMeta>();\n const pending = new Set<Promise<unknown>>();\n /** Files that came over the direct link (a late cloud copy of one is just cleaned up). */\n const directDone = new Set<string>();\n const metaWaiters = new Map<string, (meta: FileMeta) => void>();\n let session: RelaySession | null = null;\n let receiver: DirectReceiver | null = null;\n let settled = false;\n let resolveDone!: (files: File[]) => void;\n const done = new Promise<File[]>((resolve) => { resolveDone = resolve; });\n const multiple = options.multiple !== false;\n const sessionOptions: SessionOptions = {\n ...(options.accept !== undefined ? { accept: options.accept } : {}),\n multiple,\n ...(options.maxFiles !== undefined ? { maxFiles: options.maxFiles } : {}),\n ...(options.maxFileBytes !== undefined ? { maxFileBytes: options.maxFileBytes } : {}),\n ...(options.resizeImages ? { resizeImages: options.resizeImages } : {}),\n ...(options.confirmPhone ? { confirmPhone: true } : {}),\n ...(options.siteName ? { siteName: options.siteName } : {}),\n ...(options.locale === \"ar\" || options.locale === \"en\" ? { locale: options.locale } : {}),\n ...(options.direct === false ? { direct: false } : {}),\n };\n let maxFiles = multiple ? options.maxFiles ?? 20 : 1;\n\n const settle = (reason: PickEvents[\"close\"], result: File[]) => {\n if (settled) return;\n settled = true;\n removeEventListener(\"pagehide\", onPageHide);\n receiver?.close();\n session?.close();\n emit(\"close\", reason);\n resolveDone(result);\n };\n const onPageHide = () => session?.close(true);\n\n const receive = (meta: FileMeta) => {\n // Already here over Wi-Fi, but the phone also sent it through the cloud (it gave up waiting for\n // our answer): just let the relay delete the copy.\n if (directDone.has(meta.id)) { session?.ack(meta.id); return; }\n if (handled.has(meta.id) || !session) return;\n handled.add(meta.id);\n const current = session;\n const task = current.download(meta, (received) => emit(\"progress\", { id: meta.id, name: meta.name, sent: received, total: meta.size, phase: \"download\" }))\n .then(async (file) => {\n await current.ack(meta.id);\n if (settled) return;\n files.push(file);\n emit(\"received\", { id: meta.id, file });\n emit(\"file\", file);\n if (files.length >= maxFiles) controller.finish();\n })\n .catch((error) => emit(\"file_failed\", { id: meta.id, code: error instanceof PickError ? error.code : \"network\" }))\n .finally(() => pending.delete(task));\n pending.add(task);\n };\n\n const knownMeta = (id: string): Promise<FileMeta | null> => {\n const meta = metas.get(id);\n if (meta) return Promise.resolve(meta);\n // The bytes can beat the relay's file_started event: wait for it a little.\n return new Promise((resolve) => {\n const timer = setTimeout(() => { metaWaiters.delete(id); resolve(null); }, 10_000);\n metaWaiters.set(id, (value) => { clearTimeout(timer); metaWaiters.delete(id); resolve(value); });\n });\n };\n\n /** A file that came over the direct link: same checks as the relay, then keep it and tell the relay. */\n const completeDirect = async (id: string, chunks: Uint8Array[], size: number): Promise<{ ok: true } | { ok: false; code: string }> => {\n const current = session;\n const meta = await knownMeta(id);\n if (!current || !meta || settled || handled.has(id)) return { ok: false, code: \"failed\" };\n const result = verifyDirectFile(meta, chunks, size, current.info.options.accept, current.info.options.maxFileBytes);\n if (!result.ok) {\n current.directResult(id, false, result.code);\n return result;\n }\n handled.add(id);\n directDone.add(id);\n current.directResult(id, true);\n files.push(result.file);\n emit(\"received\", { id, file: result.file });\n emit(\"file\", result.file);\n if (files.length >= maxFiles) controller.finish();\n return { ok: true };\n };\n\n const directReceiver = (current: RelaySession): DirectReceiver | null => {\n if (options.direct === false || !DirectReceiver.supported()) return null;\n if (!receiver) {\n receiver = new DirectReceiver((d) => current.send({ t: \"rtc\", d }), {\n progress: (id, received, total) => emit(\"progress\", { id, name: metas.get(id)?.name ?? \"\", sent: received, total, phase: \"upload\" }),\n complete: completeDirect,\n state: (connected) => emit(\"direct\", { connected }),\n });\n }\n return receiver;\n };\n\n const onEvent = (event: DesktopEvent) => {\n switch (event.t) {\n case \"rtc\": if (session) directReceiver(session)?.onSignal(event.d); break;\n case \"hello\":\n // Files that finished while this page was disconnected: announce, then fetch them.\n for (const meta of event.files) {\n if (!handled.has(meta.id)) { metas.set(meta.id, meta); emit(\"file_started\", meta); }\n receive(meta);\n }\n break;\n case \"phone\": emit(\"phone\", { phone: event.phone, needsApproval: event.needsApproval, ...(event.match ? { match: event.match } : {}) }); break;\n case \"phone_left\": receiver?.close(); emit(\"phone_left\", undefined); break;\n case \"file_started\":\n metas.set(event.file.id, event.file);\n metaWaiters.get(event.file.id)?.(event.file);\n emit(\"file_started\", event.file);\n break;\n case \"progress\": emit(\"progress\", { id: event.id, name: metas.get(event.id)?.name ?? \"\", sent: event.sent, total: event.total, phase: \"upload\" }); break;\n case \"file_ready\": receive(event.file); break;\n case \"file_failed\": emit(\"file_failed\", { id: event.id, code: event.code }); break;\n case \"phone_done\": if (files.length || pending.size) controller.finish(); break;\n case \"closed\":\n // The relay ended it (expiry, rejection): keep what arrived, otherwise let the UI offer a new code.\n if (files.length) settle(event.reason, [...files]);\n else emit(\"close\", event.reason);\n break;\n }\n };\n\n const start = () => {\n RelaySession.create(relay, options.key, sessionOptions, onEvent).then((created) => {\n if (settled) { created.close(); return; }\n session = created;\n maxFiles = created.info.options.maxFiles;\n emit(\"ready\", { claimUrl: created.info.claimUrl, code: created.info.code });\n }, (error: PickError) => emit(\"error\", error));\n };\n\n const controller: PickController = {\n done,\n get files() { return files; },\n get claimUrl() { return session?.info.claimUrl ?? null; },\n get code() { return session?.info.code ?? null; },\n on(event, handler) {\n if (!handlers.has(event)) handlers.set(event, new Set());\n handlers.get(event)!.add(handler);\n return () => handlers.get(event)?.delete(handler);\n },\n finish() {\n if (settled) return;\n // Let downloads that are already under way land first.\n Promise.allSettled([...pending]).then(() => settle(\"finished\", [...files]));\n },\n cancel() { settle(\"canceled\", []); },\n approve() { session?.send({ t: \"approve\" }); },\n reject() { session?.send({ t: \"reject\" }); },\n async disconnect() {\n if (!session) return;\n receiver?.close();\n const fresh = await session.rekey();\n emit(\"ready\", fresh);\n },\n restart() {\n if (settled) return;\n receiver?.close();\n receiver = null;\n session?.close();\n session = null;\n start();\n },\n };\n\n addEventListener(\"pagehide\", onPageHide);\n options.signal?.addEventListener(\"abort\", () => controller.cancel(), { once: true });\n if (options.ui !== false) mountModal(controller, options);\n start();\n return controller;\n}\n\n/** Opens the picker and resolves with the files the person sent ([] if they canceled). */\nexport function pick(options: PickOptions): Promise<File[]> {\n return open(options).done;\n}\n\nexport interface AttachOptions extends Omit<PickOptions, \"accept\" | \"multiple\"> {\n /** \"replace\" (default) sets the input's files; \"append\" adds to what it already has. */\n mode?: \"replace\" | \"append\";\n}\n\n/** Fills an existing <input type=\"file\"> with files from the phone, firing input and change events,\n * so forms and frameworks that listen to the input keep working. Returns a function that does it. */\nexport function attach(input: HTMLInputElement, options: AttachOptions): () => Promise<File[]> {\n if (!(input instanceof HTMLInputElement) || input.type !== \"file\") throw new PickError(\"bad_request\", \"attach() needs an <input type=\\\"file\\\">.\");\n return async () => {\n const received = await pick({ ...options, accept: input.accept, multiple: input.multiple });\n if (!received.length) return received;\n const transfer = new DataTransfer();\n if (options.mode === \"append\" && input.multiple) for (const file of Array.from(input.files ?? [])) transfer.items.add(file);\n for (const file of input.multiple ? received : received.slice(0, 1)) transfer.items.add(file);\n input.files = transfer.files;\n input.dispatchEvent(new Event(\"input\", { bubbles: true }));\n input.dispatchEvent(new Event(\"change\", { bubbles: true }));\n return received;\n };\n}\n","// The upload field's styles, in TokShare's colors: lime buttons with ink text, violet highlights. Override\n// from the page with CSS variables on the field, e.g.\n// [data-tokshare-pick-field] { --tsp-accent: #0b6bcb; --tsp-accent-text: #fff; --tsp-radius: 14px; }\n// --tsp-accent fills buttons and progress; --tsp-accent-ink (borders, links, focus rings) follows it unless set.\nexport const FIELD_STYLES = `\n:host { display: block; }\n* { box-sizing: border-box; }\n[hidden] { display: none !important; }\n.wrap {\n /* Light. Lime is unreadable as text or a thin line on white, so those use a deeper violet. */\n --accent: var(--tsp-accent, #c8ff4d);\n --accent-text: var(--tsp-accent-text, #0b0d12);\n --accent-ink: var(--tsp-accent-ink, var(--tsp-accent, #6b4fe0));\n --accent-2: var(--tsp-accent-2, var(--tsp-accent, #8a6cf5));\n --button-edge: rgba(11, 13, 18, .1);\n --bg: var(--tsp-bg, #ffffff);\n --surface: var(--tsp-surface, #f6f7f9);\n --text: var(--tsp-text, #0b0d12);\n --muted: var(--tsp-muted, #5d6270);\n --line: var(--tsp-line, rgba(11, 13, 18, .12));\n --ok: #1a8a4c;\n --error: #c42f3d;\n --radius: var(--tsp-radius, 18px);\n container-type: inline-size;\n font: 14px/1.5 var(--tsp-font, Inter, system-ui, -apple-system, \"Segoe UI\", Roboto, \"Noto Sans Arabic\", sans-serif);\n color: var(--text);\n}\n@media (prefers-color-scheme: dark) {\n .wrap[data-theme=\"auto\"] { --accent-ink: var(--tsp-accent-ink, var(--tsp-accent, #c8ff4d)); --accent-2: var(--tsp-accent-2, var(--tsp-accent, #9a7cff)); --button-edge: transparent; --bg: var(--tsp-bg, #171a22); --surface: var(--tsp-surface, #12151c); --text: var(--tsp-text, #f4f4f5); --muted: var(--tsp-muted, #9297a4); --line: var(--tsp-line, rgba(255,255,255,.09)); --ok: #c8ff4d; --error: #ff8a94; }\n}\n.wrap[data-theme=\"dark\"] { --accent-ink: var(--tsp-accent-ink, var(--tsp-accent, #c8ff4d)); --accent-2: var(--tsp-accent-2, var(--tsp-accent, #9a7cff)); --button-edge: transparent; --bg: var(--tsp-bg, #171a22); --surface: var(--tsp-surface, #12151c); --text: var(--tsp-text, #f4f4f5); --muted: var(--tsp-muted, #9297a4); --line: var(--tsp-line, rgba(255,255,255,.09)); --ok: #c8ff4d; --error: #ff8a94; }\n\n/* ---- drop zone ---- */\n.zone {\n position: relative;\n border: 1.5px dashed color-mix(in srgb, var(--accent-ink) 42%, transparent);\n border-radius: var(--radius);\n background:\n radial-gradient(120% 90% at 50% 0%, color-mix(in srgb, var(--accent-2) 12%, transparent), transparent 70%),\n var(--surface);\n padding: 30px 22px;\n min-height: 232px;\n display: grid;\n align-items: center;\n transition: border-color .18s, background-color .18s, box-shadow .18s;\n}\n.zone[data-state=\"idle\"]:hover { border-color: color-mix(in srgb, var(--accent-ink) 70%, transparent); }\n.zone[data-drag] {\n border-style: solid;\n border-color: var(--accent-ink);\n background-color: color-mix(in srgb, var(--accent-ink) 8%, var(--surface));\n box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent-ink) 16%, transparent);\n}\n.zone[data-drag] .tile { transform: translateY(-3px) scale(1.06); }\n.idle { display: grid; justify-items: center; text-align: center; gap: 6px; }\n.tile {\n width: 56px; height: 56px; margin-bottom: 8px;\n display: grid; place-items: center;\n border-radius: 16px;\n background: linear-gradient(145deg, color-mix(in srgb, var(--accent) 80%, #fff), var(--accent));\n color: var(--accent-text);\n box-shadow: inset 0 1px 0 rgba(255,255,255,.45), inset 0 0 0 1px var(--button-edge), 0 12px 26px -6px color-mix(in srgb, var(--accent) 45%, transparent);\n transition: transform .2s;\n}\nsvg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; flex: none; }\n.tile svg { width: 26px; height: 26px; stroke-width: 2; }\n.title { margin: 0; font-size: 16px; font-weight: 650; letter-spacing: -.01em; }\n.hint { margin: 0; color: var(--muted); font-size: 13px; }\n.actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px; margin-top: 12px; }\n.or { color: var(--muted); font-size: 12.5px; }\n\nbutton { font: inherit; cursor: pointer; }\n.primary, .ghost {\n display: inline-flex; align-items: center; gap: 8px;\n min-height: 40px; padding: 8px 16px;\n border-radius: 11px; font-weight: 600; font-size: 14px;\n border: 1px solid transparent;\n transition: transform .12s, box-shadow .15s, background-color .15s, border-color .15s;\n}\n.primary { background: var(--accent); color: var(--accent-text); border-color: var(--button-edge); box-shadow: inset 0 1px 0 rgba(255,255,255,.45), 0 8px 22px -8px color-mix(in srgb, var(--accent) 60%, transparent); }\n.primary:hover { background: color-mix(in srgb, var(--accent) 85%, #fff); box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 12px 28px -8px color-mix(in srgb, var(--accent) 70%, transparent); }\n.ghost { background: var(--bg); color: var(--text); border-color: var(--line); }\n.ghost:hover { border-color: color-mix(in srgb, var(--accent-ink) 55%, transparent); color: var(--accent-ink); }\n.primary:active, .ghost:active { transform: translateY(1px); }\n.primary.small { min-height: 34px; padding: 6px 14px; font-size: 13px; }\n.link { all: unset; cursor: pointer; display: inline-flex; align-items: center; gap: 4px; color: var(--muted); font-weight: 600; font-size: 13px; }\n.link:hover { color: var(--text); }\nbutton:focus-visible, .link:focus-visible { outline: 3px solid color-mix(in srgb, var(--accent-ink) 60%, transparent); outline-offset: 2px; border-radius: 10px; }\n[dir=\"rtl\"] .flip { transform: scaleX(-1); }\n\n/* ---- phone, inside the field ---- */\n.phone-view { display: grid; grid-template-columns: auto 1fr; gap: 24px; align-items: center; }\n.qr-box { position: relative; width: 184px; height: 184px; padding: 8px; border-radius: 16px; background: #fff; border: 1px solid var(--line); box-shadow: 0 10px 30px rgba(15, 18, 30, .1); }\n.qr { width: 100%; height: 100%; display: block; image-rendering: pixelated; transition: opacity .25s, filter .25s; }\n.qr-box.dim .qr { opacity: .18; filter: blur(1px); }\n.qr-loading { display: none; position: absolute; inset: 8px; border-radius: 10px; background: linear-gradient(100deg, #eef0f5 30%, #f8f9fc 50%, #eef0f5 70%); background-size: 200% 100%; animation: shimmer 1.2s linear infinite; }\n.qr-box.loading .qr-loading { display: block; }\n.phone-info { display: grid; gap: 10px; min-width: 0; }\n.steps { margin: 0; padding: 0; list-style: none; counter-reset: step; display: grid; gap: 7px; }\n.steps li { counter-increment: step; display: flex; gap: 10px; align-items: baseline; color: var(--muted); font-size: 13.5px; }\n.steps li::before { content: counter(step); flex: none; width: 20px; height: 20px; display: inline-grid; place-items: center; border-radius: 50%; font-size: 11px; font-weight: 700; color: var(--accent-ink); background: color-mix(in srgb, var(--accent-ink) 14%, transparent); transform: translateY(4px); }\n.code-line { margin: 0; color: var(--muted); font-size: 12.5px; }\n.code-line b { direction: ltr; display: inline-block; font: 700 13px/1.4 ui-monospace, \"SF Mono\", Menlo, Consolas, monospace; letter-spacing: 1.2px; color: var(--text); background: var(--bg); border: 1px solid var(--line); padding: 1px 7px; border-radius: 6px; }\n.status { margin: 0; justify-self: start; display: inline-flex; align-items: center; gap: 8px; padding: 6px 12px; border-radius: 999px; background: var(--bg); border: 1px solid var(--line); font-size: 13px; font-weight: 600; }\n.status i { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); opacity: .6; }\n.status.live i { background: var(--ok); opacity: 1; box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 60%, transparent); animation: pulse 1.8s infinite; }\n.phone-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 2px; }\n.announce-slot { grid-column: 1 / -1; }\n/* ---- TokShare for desktop ---- */\n.announce { margin: 0; display: flex; align-items: center; gap: 10px; padding: 9px 8px 9px 12px; border-radius: 12px; border: 1px solid var(--line); background: color-mix(in srgb, var(--accent-2) 7%, transparent); color: var(--muted); font-size: 12.5px; line-height: 1.45; text-align: start; }\n.announce i { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--accent-2); }\n.announce span { flex: 1; min-width: 0; }\n.announce a { color: var(--accent-ink); font-weight: 650; text-decoration: underline; text-underline-offset: 2px; white-space: nowrap; }\n.announce-hide { all: unset; cursor: pointer; flex: none; width: 24px; height: 24px; display: grid; place-items: center; border-radius: 50%; font-size: 16px; color: var(--muted); }\n.announce-hide:hover { background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--text); }\n.announce-hide:focus-visible, .announce a:focus-visible { outline: 3px solid color-mix(in srgb, var(--accent-ink) 60%, transparent); outline-offset: 2px; }\n\n/* ---- messages and list ---- */\n.message { margin: 10px 2px 0; color: var(--error); font-size: 13px; }\n.list-head { display: flex; justify-content: space-between; align-items: center; margin: 14px 2px 6px; color: var(--muted); font-size: 12.5px; font-weight: 600; }\n.list { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 8px; }\n.list-head:not([hidden]) + .list { margin-top: 0; }\n.item { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 9px 10px 9px 9px; border: 1px solid var(--line); border-radius: 14px; background: var(--bg); animation: rise .2s ease-out; }\n.thumb { width: 44px; height: 44px; border-radius: 10px; overflow: hidden; display: grid; place-items: center; background: color-mix(in srgb, var(--accent-ink) 12%, transparent); color: var(--accent-ink); font-size: 10.5px; font-weight: 800; letter-spacing: .4px; }\n.thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }\n.body { display: grid; gap: 2px; min-width: 0; }\n.name { font-weight: 600; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n.meta { color: var(--muted); font-size: 12px; }\n.bar { height: 4px; border-radius: 4px; margin-top: 4px; background: color-mix(in srgb, var(--accent-ink) 12%, transparent); overflow: hidden; }\n.bar i { display: block; height: 100%; width: 0; background: linear-gradient(90deg, var(--accent-2), var(--accent)); border-radius: inherit; transition: width .2s; }\n.item.failed .meta { color: var(--error); }\n.remove { all: unset; cursor: pointer; width: 32px; height: 32px; display: grid; place-items: center; border-radius: 50%; color: var(--muted); }\n.remove:hover { background: color-mix(in srgb, var(--error) 10%, transparent); color: var(--error); }\n.remove svg { width: 16px; height: 16px; }\n\n@container (max-width: 520px) {\n .zone { padding: 24px 16px; }\n .phone-view { grid-template-columns: 1fr; justify-items: center; text-align: center; gap: 16px; }\n .steps li { text-align: start; }\n .status { justify-self: center; }\n}\n@keyframes shimmer { to { background-position: -200% 0; } }\n@keyframes pulse { 70% { box-shadow: 0 0 0 7px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }\n@keyframes rise { from { opacity: 0; transform: translateY(4px); } }\n@media (prefers-reduced-motion: reduce) { .zone, .tile, .qr, .bar i, .item { transition: none; animation: none; } .qr-loading, .status.live i { animation: none; } }\n`;\n","// A complete upload field: drop zone, Browse files, and \"Use your phone\", which opens inside the field\n// (QR, steps, live status) instead of a separate window. Files from either source land in one list\n// with thumbnails and remove buttons, and in a real <input type=\"file\" name> so forms submit them.\n//\n// mountField(\"#photos\", { key: \"pk_live_…\", name: \"photos\", accept: \"image/png,image/jpeg\", maxFileBytes: 5e6 });\n// <tokshare-pick-field key=\"pk_live_…\" name=\"photos\" accept=\"image/*\" max-size=\"5MB\" multiple></tokshare-pick-field>\nimport { announcement } from \"./announce\";\nimport { LIMITS, matchesAccept } from \"@tokshare/pick-protocol\";\nimport { FIELD_STYLES } from \"./fieldStyles\";\nimport { formatBytes, resolveLocale, translator } from \"./i18n\";\nimport { type PickController, type PickOptions, open } from \"./picker\";\nimport { drawQr, formatCode } from \"./qr\";\nimport { resolveTheme } from \"./theme\";\n\nexport interface FieldOptions extends Omit<PickOptions, \"ui\"> {\n /** Form field name: the files go into a hidden <input type=\"file\" name> inside the target. */\n name?: string;\n /** \"inline\" (default): the phone flow opens inside the field. \"modal\": in a window. false: no phone. */\n phone?: \"inline\" | \"modal\" | false;\n /** Show \"Use your phone\" even when this page itself is open on a phone. */\n phoneOnMobile?: boolean;\n /** Replaces the drop zone's title. */\n label?: string;\n}\n\nexport interface FieldController {\n readonly files: readonly File[];\n /** The hidden input the files are kept in (for forms and frameworks). */\n readonly input: HTMLInputElement;\n on(event: \"change\", handler: (files: File[]) => void): () => void;\n remove(file: File): void;\n clear(): void;\n destroy(): void;\n}\n\ntype Source = \"device\" | \"phone\";\ninterface Item { key: string; file: File | null; name: string; size: number; source: Source; percent: number; phase?: \"upload\" | \"download\"; failed?: boolean; url?: string; element?: HTMLLIElement }\n\nconst ICONS = {\n upload: '<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M12 15V4m0 0L7.5 8.5M12 4l4.5 4.5M5 14v4a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-4\"/></svg>',\n folder: '<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M3.5 7.5a2 2 0 0 1 2-2h4l2 2h7a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-13a2 2 0 0 1-2-2z\"/></svg>',\n phone: '<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><rect x=\"7\" y=\"2.5\" width=\"10\" height=\"19\" rx=\"2.5\"/><path d=\"M11 18.5h2\"/></svg>',\n close: '<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\"><path d=\"M7 7l10 10M17 7 7 17\"/></svg>',\n back: '<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" class=\"flip\"><path d=\"M14.5 6 8.5 12l6 6\"/></svg>',\n};\n\n/** \"5MB\", \"500 KB\", \"2e6\" → bytes. */\nexport function parseSize(value: string | number | null | undefined): number | undefined {\n if (value === null || value === undefined || value === \"\") return undefined;\n if (typeof value === \"number\") return value > 0 ? value : undefined;\n const match = /^\\s*([\\d.]+)\\s*(b|kb|mb|gb)?\\s*$/i.exec(value);\n if (!match) return undefined;\n const units: Record<string, number> = { b: 1, kb: 1e3, mb: 1e6, gb: 1e9 };\n const bytes = Number(match[1]) * units[(match[2] ?? \"b\").toLowerCase()]!;\n return bytes > 0 ? Math.round(bytes) : undefined;\n}\n\nfunction acceptLabel(accept: string): string {\n return accept.split(\",\").map((part) => part.trim()).filter(Boolean).map((part) => {\n if (part.endsWith(\"/*\")) return part.slice(0, -2).replace(/^./, (letter) => letter.toUpperCase()) + \"s\";\n if (part.startsWith(\".\")) return part.slice(1).toUpperCase();\n const sub = part.split(\"/\")[1] ?? part;\n return (sub === \"jpeg\" ? \"JPG\" : sub.replace(/^(x-|vnd\\.)/, \"\").split(/[.+-]/)[0]!.toUpperCase());\n }).filter((label, index, all) => all.indexOf(label) === index).join(\", \");\n}\n\nconst isPhonePage = () => typeof matchMedia === \"function\" && matchMedia(\"(pointer: coarse)\").matches && innerWidth < 820;\n\nexport function mountField(target: HTMLElement | string, options: FieldOptions): FieldController {\n const container = typeof target === \"string\" ? document.querySelector<HTMLElement>(target) : target;\n if (!container) throw new Error(`TokShare Pick: ${String(target)} not found`);\n const locale = resolveLocale(options.locale);\n const t = translator(locale, options.strings);\n const multiple = options.multiple !== false;\n const maxFiles = multiple ? Math.min(options.maxFiles ?? LIMITS.maxFiles, LIMITS.maxFiles) : 1;\n const maxBytes = Math.min(options.maxFileBytes ?? LIMITS.maxFileBytes, LIMITS.maxFileBytes);\n const accept = options.accept ?? \"\";\n const phoneMode = options.phone === false ? false : options.phone ?? \"inline\";\n const showPhone = phoneMode !== false && (options.phoneOnMobile || !isPhonePage());\n\n // The real input forms submit. Kept in the page (light DOM), hidden.\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.hidden = true;\n input.multiple = multiple;\n if (accept) input.accept = accept;\n if (options.name) input.name = options.name;\n const host = document.createElement(\"div\");\n host.setAttribute(\"data-tokshare-pick-field\", \"\");\n container.append(host, input);\n const root = host.attachShadow({ mode: \"open\" });\n if (\"adoptedStyleSheets\" in Document.prototype && \"replaceSync\" in CSSStyleSheet.prototype) {\n const sheet = new CSSStyleSheet();\n sheet.replaceSync(FIELD_STYLES);\n root.adoptedStyleSheets = [sheet];\n } else {\n const style = document.createElement(\"style\");\n style.textContent = FIELD_STYLES;\n root.append(style);\n }\n\n const hint = [\n accept ? t(\"hintTypes\", { types: acceptLabel(accept), size: formatBytes(maxBytes, locale) }) : t(\"hintAny\", { size: formatBytes(maxBytes, locale) }),\n multiple ? t(\"hintCount\", { count: maxFiles }) : \"\",\n ].filter(Boolean).join(\" · \");\n\n const wrap = document.createElement(\"div\");\n wrap.className = \"wrap\";\n wrap.dir = locale === \"ar\" ? \"rtl\" : \"ltr\";\n wrap.lang = locale;\n // Light or dark to match the page behind the field (container is already in the page).\n wrap.dataset.theme = resolveTheme(options.theme, container);\n wrap.innerHTML = `\n <div class=\"zone\" data-state=\"idle\" role=\"group\">\n <div class=\"idle\">\n <div class=\"tile\">${ICONS.upload}</div>\n <p class=\"title\"></p>\n <p class=\"hint\"></p>\n <div class=\"actions\">\n <button type=\"button\" class=\"primary browse\">${ICONS.folder}<span></span></button>\n <span class=\"or\"></span>\n <button type=\"button\" class=\"ghost phone\">${ICONS.phone}<span></span></button>\n </div>\n </div>\n <div class=\"phone-view\" hidden>\n <div class=\"qr-box\"><canvas class=\"qr\" role=\"img\"></canvas><div class=\"qr-loading\"></div></div>\n <div class=\"phone-info\">\n <p class=\"title phone-title\"></p>\n <ol class=\"steps\"><li></li><li></li><li></li></ol>\n <p class=\"code-line\"></p>\n <p class=\"status\" role=\"status\" aria-live=\"polite\"><i></i><span></span></p>\n <div class=\"phone-actions\">\n <button type=\"button\" class=\"link back\">${ICONS.back}<span></span></button>\n <button type=\"button\" class=\"primary small done\" hidden></button>\n </div>\n </div>\n <div class=\"announce-slot\"></div>\n </div>\n <input type=\"file\" class=\"native\" hidden>\n </div>\n <p class=\"message\" role=\"alert\" hidden></p>\n <div class=\"list-head\" hidden><span class=\"count\"></span><button type=\"button\" class=\"link clear\"></button></div>\n <ul class=\"list\"></ul>`;\n root.append(wrap);\n\n const $ = <T extends Element>(selector: string) => wrap.querySelector(selector) as T;\n const zone = $<HTMLDivElement>(\".zone\");\n const native = $<HTMLInputElement>(\".native\");\n native.multiple = multiple;\n if (accept) native.accept = accept;\n $<HTMLElement>(\".idle .title\").textContent = options.label ?? t(multiple ? \"dropTitle\" : \"dropTitleOne\");\n $<HTMLElement>(\".hint\").textContent = hint;\n $<HTMLElement>(\".browse span\").textContent = t(\"browse\");\n $<HTMLElement>(\".or\").textContent = t(\"or\");\n $<HTMLElement>(\".phone span\").textContent = t(\"usePhone\");\n $<HTMLElement>(\".phone-title\").textContent = t(\"phoneTitle\");\n const steps = wrap.querySelectorAll(\".steps li\");\n [\"phoneStep1\", \"phoneStep2\", \"phoneStep3\"].forEach((key, index) => { steps[index]!.textContent = t(key as \"phoneStep1\"); });\n $<HTMLElement>(\".back span\").textContent = t(\"back\");\n $<HTMLElement>(\".done\").textContent = t(\"doneWithPhone\");\n $<HTMLElement>(\".clear\").textContent = t(\"clearAll\");\n if (!showPhone) { $<HTMLElement>(\".phone\").hidden = true; $<HTMLElement>(\".or\").hidden = true; }\n const promo = announcement(options.announce, t);\n if (promo) $<HTMLElement>(\".announce-slot\").append(promo);\n else $<HTMLElement>(\".announce-slot\").remove();\n\n const items: Item[] = [];\n const handlers = new Set<(files: File[]) => void>();\n let picker: PickController | null = null;\n let messageTimer: ReturnType<typeof setTimeout> | undefined;\n\n const files = () => items.filter((item) => item.file && !item.failed).map((item) => item.file!);\n const say = (text: string) => {\n const message = $<HTMLElement>(\".message\");\n message.textContent = text;\n message.hidden = !text;\n clearTimeout(messageTimer);\n if (text) messageTimer = setTimeout(() => { message.hidden = true; }, 6000);\n };\n\n const sync = () => {\n const transfer = new DataTransfer();\n for (const file of files()) transfer.items.add(file);\n input.files = transfer.files;\n input.dispatchEvent(new Event(\"input\", { bubbles: true }));\n input.dispatchEvent(new Event(\"change\", { bubbles: true }));\n for (const handler of handlers) handler(files());\n };\n\n const renderList = () => {\n const list = $<HTMLUListElement>(\".list\");\n const shown = items.length;\n $<HTMLElement>(\".list-head\").hidden = shown < 2;\n $<HTMLElement>(\".count\").textContent = t(\"fileCount\", { count: shown });\n for (const item of items) {\n if (!item.element) {\n item.element = document.createElement(\"li\");\n list.append(item.element);\n }\n renderItem(item);\n }\n };\n\n const renderItem = (item: Item) => {\n const row = item.element!;\n const extension = (item.name.split(\".\").pop() ?? \"\").slice(0, 4).toUpperCase();\n const pending = !item.file && !item.failed;\n row.className = `item${pending ? \" pending\" : \"\"}${item.failed ? \" failed\" : \"\"}`;\n row.replaceChildren();\n const thumb = document.createElement(\"div\");\n thumb.className = \"thumb\";\n if (item.url) {\n const image = document.createElement(\"img\");\n image.alt = \"\";\n image.src = item.url;\n image.addEventListener(\"error\", () => { image.remove(); thumb.textContent = extension; });\n thumb.append(image);\n } else thumb.textContent = extension || \"FILE\";\n const body = document.createElement(\"div\");\n body.className = \"body\";\n const name = document.createElement(\"span\");\n name.className = \"name\";\n name.textContent = item.name;\n const meta = document.createElement(\"span\");\n meta.className = \"meta\";\n const state = item.failed ? t(\"failed\") : pending ? t(item.phase === \"download\" ? \"receiving\" : \"sending\", { percent: item.percent }) : \"\";\n meta.textContent = [formatBytes(item.size, locale), item.source === \"phone\" ? t(\"sourcePhone\") : t(\"sourceDevice\"), state].filter(Boolean).join(\" · \");\n body.append(name, meta);\n if (pending) {\n const bar = document.createElement(\"span\");\n bar.className = \"bar\";\n const fill = document.createElement(\"i\");\n fill.style.width = `${item.percent}%`;\n bar.append(fill);\n body.append(bar);\n }\n const remove = document.createElement(\"button\");\n remove.type = \"button\";\n remove.className = \"remove\";\n remove.innerHTML = ICONS.close;\n remove.setAttribute(\"aria-label\", t(\"remove\", { name: item.name }));\n remove.hidden = pending;\n remove.addEventListener(\"click\", () => removeItem(item));\n row.append(thumb, body, remove);\n };\n\n const removeItem = (item: Item) => {\n const index = items.indexOf(item);\n if (index < 0) return;\n items.splice(index, 1);\n if (item.url) URL.revokeObjectURL(item.url);\n item.element?.remove();\n renderList();\n sync();\n };\n\n const makeItem = (file: File, source: Source): Item => ({\n key: Math.random().toString(36).slice(2), file, name: file.name, size: file.size, source, percent: 100,\n ...(file.type.startsWith(\"image/\") ? { url: URL.createObjectURL(file) } : {}),\n });\n\n const addFiles = (incoming: File[], source: Source) => {\n const problems: string[] = [];\n if (!multiple && incoming.length) {\n for (const item of [...items]) removeItem(item);\n incoming = incoming.slice(0, 1);\n }\n for (const file of incoming) {\n if (items.filter((item) => !item.failed).length >= maxFiles) { problems.push(t(\"tooMany\", { count: maxFiles })); break; }\n if (file.size > maxBytes) { problems.push(t(\"tooLarge\", { name: file.name, size: formatBytes(maxBytes, locale) })); continue; }\n if (!matchesAccept(accept, file.name, file.type)) { problems.push(t(\"wrongType\", { name: file.name })); continue; }\n items.push(makeItem(file, source));\n }\n say(problems.join(\" \"));\n renderList();\n sync();\n };\n\n // ---- browse and drop --------------------------------------------------------------------------\n $<HTMLButtonElement>(\".browse\").addEventListener(\"click\", () => native.click());\n native.addEventListener(\"change\", () => { addFiles(Array.from(native.files ?? []), \"device\"); native.value = \"\"; });\n let depth = 0;\n zone.addEventListener(\"dragenter\", (event) => { event.preventDefault(); depth++; if (zone.dataset.state === \"idle\") zone.dataset.drag = \"true\"; });\n zone.addEventListener(\"dragover\", (event) => { event.preventDefault(); if (event.dataTransfer) event.dataTransfer.dropEffect = \"copy\"; });\n zone.addEventListener(\"dragleave\", () => { if (--depth <= 0) { depth = 0; delete zone.dataset.drag; } });\n zone.addEventListener(\"drop\", (event) => {\n event.preventDefault();\n depth = 0;\n delete zone.dataset.drag;\n if (zone.dataset.state === \"idle\") addFiles(Array.from(event.dataTransfer?.files ?? []), \"device\");\n });\n $<HTMLElement>(\".clear\").addEventListener(\"click\", () => { for (const item of [...items]) removeItem(item); });\n\n // ---- the phone ----------------------------------------------------------------------------------\n const setStatus = (text: string, live = false) => {\n $<HTMLElement>(\".status span\").textContent = text;\n $<HTMLElement>(\".status\").classList.toggle(\"live\", live);\n };\n const showIdle = () => {\n zone.dataset.state = \"idle\";\n $<HTMLElement>(\".idle\").hidden = false;\n $<HTMLElement>(\".phone-view\").hidden = true;\n $<HTMLButtonElement>(\".phone\").focus();\n };\n const pendingByRelay = new Map<string, Item>();\n\n const openInline = () => {\n zone.dataset.state = \"phone\";\n $<HTMLElement>(\".idle\").hidden = true;\n $<HTMLElement>(\".phone-view\").hidden = false;\n $<HTMLElement>(\".qr-box\").classList.add(\"loading\");\n $<HTMLElement>(\".done\").hidden = true;\n $<HTMLElement>(\".code-line\").textContent = \"\";\n setStatus(t(\"loading\"));\n const room = Math.max(1, maxFiles - files().length);\n const current = open({ ...options, ui: false, multiple, maxFiles: multiple ? room : 1, maxFileBytes: maxBytes, accept });\n picker = current;\n current.on(\"ready\", ({ claimUrl, code }) => {\n drawQr($<HTMLCanvasElement>(\".qr\"), claimUrl, 168);\n $<HTMLCanvasElement>(\".qr\").setAttribute(\"aria-label\", t(\"phoneTitle\"));\n $<HTMLElement>(\".qr-box\").classList.remove(\"loading\", \"dim\");\n const line = $<HTMLElement>(\".code-line\");\n const strong = document.createElement(\"b\");\n strong.textContent = formatCode(code);\n line.replaceChildren(document.createTextNode(`${t(\"phoneCode\", { host: new URL(claimUrl).host })} `), strong);\n setStatus(t(\"waiting\"));\n });\n let phoneLabel = \"\";\n current.on(\"phone\", ({ phone, needsApproval }) => {\n phoneLabel = phone.label;\n $<HTMLElement>(\".qr-box\").classList.add(\"dim\");\n setStatus(t(\"connected\", { label: phone.label }), true);\n if (needsApproval) current.approve();\n });\n current.on(\"direct\", ({ connected }) => {\n if (phoneLabel) setStatus(t(connected ? \"connectedDirect\" : \"connected\", { label: phoneLabel }), true);\n });\n current.on(\"phone_left\", () => setStatus(t(\"phoneLeft\")));\n current.on(\"file_started\", (meta) => {\n const item: Item = { key: meta.id, file: null, name: meta.name, size: meta.size, source: \"phone\", percent: 0 };\n pendingByRelay.set(meta.id, item);\n items.push(item);\n renderList();\n });\n current.on(\"progress\", ({ id, sent, total, phase }) => {\n const item = pendingByRelay.get(id);\n if (!item) return;\n // The phone's upload fills the bar to 90%; the download into this page fills the rest.\n const share = total ? sent / total : 0;\n item.phase = phase;\n item.percent = Math.min(99, Math.floor(phase === \"upload\" ? share * 90 : 90 + share * 10));\n renderItem(item);\n });\n current.on(\"received\", ({ id, file }) => {\n const pending = pendingByRelay.get(id);\n pendingByRelay.delete(id);\n const ready = makeItem(file, \"phone\");\n if (pending) {\n Object.assign(pending, { file, name: file.name, size: file.size, percent: 100, ...(ready.url ? { url: ready.url } : {}) });\n if (!multiple) for (const other of items.filter((item) => item !== pending)) removeItem(other);\n renderItem(pending);\n } else items.push(ready);\n renderList();\n sync();\n $<HTMLElement>(\".done\").hidden = false;\n });\n current.on(\"file_failed\", ({ id }) => {\n const item = pendingByRelay.get(id);\n if (item) { item.failed = true; renderItem(item); }\n });\n current.on(\"error\", (error) => setStatus(t(\"error\", { message: error.message })));\n current.on(\"close\", (reason) => {\n for (const item of pendingByRelay.values()) { item.failed = true; renderItem(item); }\n pendingByRelay.clear();\n if (picker === current) picker = null;\n if (reason === \"finished\" || reason === \"canceled\") showIdle();\n else { $<HTMLElement>(\".qr-box\").classList.add(\"dim\"); setStatus(t(\"expired\")); }\n });\n };\n\n const closeInline = () => {\n if (picker) picker.finish();\n else showIdle();\n };\n\n $<HTMLButtonElement>(\".phone\").addEventListener(\"click\", () => {\n if (phoneMode === \"modal\") {\n const room = Math.max(1, maxFiles - files().length);\n open({ ...options, ui: true, multiple, maxFiles: multiple ? room : 1, maxFileBytes: maxBytes, accept }).done.then((received) => addFiles(received, \"phone\"));\n } else openInline();\n });\n $<HTMLButtonElement>(\".back\").addEventListener(\"click\", closeInline);\n $<HTMLButtonElement>(\".done\").addEventListener(\"click\", closeInline);\n wrap.addEventListener(\"keydown\", (event) => { if (event.key === \"Escape\" && zone.dataset.state === \"phone\") closeInline(); });\n\n return {\n get files() { return files(); },\n input,\n on(_event, handler) { handlers.add(handler); return () => handlers.delete(handler); },\n remove(file) { const item = items.find((candidate) => candidate.file === file); if (item) removeItem(item); },\n clear() { for (const item of [...items]) removeItem(item); },\n destroy() {\n picker?.cancel();\n for (const item of items) if (item.url) URL.revokeObjectURL(item.url);\n host.remove();\n input.remove();\n },\n };\n}\n\n/** <tokshare-pick-field key name accept multiple max-files max-size phone locale theme relay label direct announce>.\n * direct=\"off\" sends everything through the cloud; announce=\"off\" hides the TokShare for desktop line. */\nexport function defineFieldElement(defaults: Partial<FieldOptions> = {}, tag = \"tokshare-pick-field\"): void {\n if (typeof customElements === \"undefined\" || customElements.get(tag)) return;\n customElements.define(tag, class extends HTMLElement {\n private controller: FieldController | null = null;\n connectedCallback() {\n if (this.controller) return;\n const attribute = (name: string) => this.getAttribute(name) ?? undefined;\n const phone = attribute(\"phone\");\n const maxFiles = Number(attribute(\"max-files\"));\n const resize = Number(attribute(\"resize\"));\n const maxFileBytes = parseSize(attribute(\"max-size\"));\n this.controller = mountField(this, {\n ...defaults,\n key: attribute(\"key\") ?? defaults.key ?? \"\",\n ...(attribute(\"relay\") ?? defaults.relay ? { relay: attribute(\"relay\") ?? defaults.relay } : {}),\n ...(attribute(\"name\") ? { name: attribute(\"name\") } : {}),\n ...(attribute(\"accept\") ? { accept: attribute(\"accept\") } : {}),\n multiple: this.hasAttribute(\"multiple\"),\n ...(maxFiles > 0 ? { maxFiles } : {}),\n ...(maxFileBytes ? { maxFileBytes } : {}),\n ...(resize > 0 ? { resizeImages: { maxDimension: resize } } : {}),\n ...(phone === \"off\" ? { phone: false as const } : phone === \"modal\" ? { phone: \"modal\" as const } : {}),\n ...(attribute(\"locale\") ? { locale: attribute(\"locale\") as \"en\" | \"ar\" | \"auto\" } : {}),\n ...(attribute(\"theme\") ? { theme: attribute(\"theme\") as \"light\" | \"dark\" | \"auto\" } : {}),\n ...(attribute(\"label\") ? { label: attribute(\"label\") } : {}),\n ...(attribute(\"direct\") === \"off\" ? { direct: false } : {}),\n ...(attribute(\"announce\") === \"off\" ? { announce: false } : {}),\n });\n this.controller.on(\"change\", (files) => this.dispatchEvent(new CustomEvent(\"files\", { detail: files, bubbles: true })));\n }\n disconnectedCallback() { this.controller?.destroy(); this.controller = null; }\n get files() { return this.controller?.files ?? []; }\n clear() { this.controller?.clear(); }\n });\n}\n"],"mappings":"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","names":["host"]}
|