{"version":3,"file":"pix.cjs","names":[],"sources":["../../src/br/pix.ts"],"sourcesContent":["/**\n * @tempest-limits file-lines — EMV®QRCPS-MPM for Pix: the TLV writer, the\n * CRC16-CCITT, the field catalogue with its nesting, key-type detection and the\n * parser that has to accept what other banks emit. Reader and writer live together\n * because each one is the other's test — a payload this file builds is a payload it\n * must parse back.\n */\nimport { validateCNPJ, validateCPF } from \"@/forms/br-validators\";\n\n/**\n * A Pix payload could not be built or read.\n *\n * Its own class so a caller can tell \"the operator typed a bad key\" apart from a\n * bug, and so an `ErrorBoundary` can render a form error instead of a crash.\n */\nexport class PixError extends Error {\n    constructor(message: string) {\n        super(message);\n        this.name = \"PixError\";\n    }\n}\n\n/** The five key formats DICT accepts. */\nexport type PixKeyType = \"cpf\" | \"cnpj\" | \"email\" | \"phone\" | \"evp\";\n\n/** A key after normalisation, ready to go into the payload. */\nexport interface NormalizedPixKey {\n    type: PixKeyType;\n    /** The exact string written into the BR Code. */\n    value: string;\n}\n\n/** One TLV as it appeared in a payload, unknown tags included. */\nexport interface PixField {\n    /** Two-character tag, e.g. `\"59\"`. */\n    id: string;\n    /** Raw value, still encoded when the tag is itself a template. */\n    value: string;\n}\n\n/** A BR Code that carries the key — the one you print on a poster. */\nexport interface PixStaticInput {\n    kind?: \"static\";\n    /** CPF, CNPJ, e-mail, phone or EVP. Validated and normalised. */\n    key: string;\n    /** Payee name. Truncated by the spec at 25 characters — longer throws. */\n    merchantName: string;\n    /** Payee city. Truncated by the spec at 15 characters — longer throws. */\n    merchantCity: string;\n    /** Amount in BRL. Omit for a payer-chooses-the-value QR. */\n    amount?: number;\n    /** Reference the PSP echoes back, `[A-Za-z0-9]{1,25}`. Defaults to `\"***\"`. */\n    txid?: string;\n    /** Free text shown by some wallets. Goes into tag 26, sub-tag 02. */\n    description?: string;\n    /** CEP, digits only. Optional tag 61. */\n    postalCode?: string;\n    /** Single-use QR: sets tag 01 to `\"12\"` instead of `\"11\"`. */\n    oneTime?: boolean;\n}\n\n/** A BR Code that carries a URL the wallet fetches to learn the amount. */\nexport interface PixDynamicInput {\n    kind: \"dynamic\";\n    /**\n     * `payloadLocation` — the https URL the wallet GETs, **without** the scheme,\n     * exactly as BACEN specifies (`pix.example.com/qr/v2/abc`).\n     */\n    url: string;\n    merchantName: string;\n    merchantCity: string;\n    postalCode?: string;\n    /** Single-use QR. Defaults to `true`, which is what a dynamic QR normally is. */\n    oneTime?: boolean;\n}\n\n/** Everything `pixPayload` accepts. */\nexport type PixInput = PixStaticInput | PixDynamicInput;\n\n/** A payload taken apart again. */\nexport interface PixData {\n    /** `\"dynamic\"` when tag 26 carried a URL instead of a key. */\n    kind: \"static\" | \"dynamic\";\n    /** Present on a static payload. */\n    key?: string;\n    keyType?: PixKeyType;\n    /** Present on a dynamic payload. */\n    url?: string;\n    merchantName: string;\n    merchantCity: string;\n    /** Reais. `undefined` when the payer chooses the amount. */\n    amount?: number;\n    /** ISO 4217 numeric. `\"986\"` for BRL. */\n    currency: string;\n    countryCode: string;\n    merchantCategoryCode: string;\n    /** `\"***\"` on a reusable static QR that identifies no single transaction. */\n    txid?: string;\n    description?: string;\n    postalCode?: string;\n    /** Tag 01 read as `\"12\"`. */\n    oneTime: boolean;\n    /** The four hex characters that closed the payload. */\n    crc: string;\n    /** Whether those four characters match a recomputed CRC. */\n    crcValid: boolean;\n    /** Every top-level TLV, in payload order, unknown tags included. */\n    fields: PixField[];\n}\n\n/** Options for {@link parsePixPayload}. */\nexport interface ParsePixOptions {\n    /**\n     * Throw when the checksum does not match. Default `true`.\n     *\n     * Turn it off only to inspect a payload you already know is broken: a BR Code\n     * whose CRC fails has been corrupted in transit, and the account it now points\n     * at is not the account the payee published.\n     */\n    requireCrc?: boolean;\n}\n\n/**\n * Generator polynomial of CRC-16/CCITT-FALSE, `x^16 + x^12 + x^5 + 1`.\n *\n * Taken from the CRC catalogue entry `CRC-16/IBM-3740` (alias CCITT-FALSE):\n * `width=16 poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000\n * check=0x29b1`. The BACEN \"Manual de Padrões para Iniciação do Pix\" names this\n * exact variant for tag 63.\n */\nconst CRC16_POLYNOMIAL = 0x1021;\n\n/** Register preset of CRC-16/CCITT-FALSE. Not zero — that is a different variant. */\nconst CRC16_INITIAL = 0xffff;\n\n/** Keeps the shift register 16 bits wide. */\nconst CRC16_MASK = 0xffff;\n\nconst TAG_PAYLOAD_FORMAT = \"00\";\nconst TAG_POINT_OF_INITIATION = \"01\";\nconst TAG_MERCHANT_ACCOUNT_INFO = \"26\";\nconst TAG_MERCHANT_CATEGORY_CODE = \"52\";\nconst TAG_TRANSACTION_CURRENCY = \"53\";\nconst TAG_TRANSACTION_AMOUNT = \"54\";\nconst TAG_COUNTRY_CODE = \"58\";\nconst TAG_MERCHANT_NAME = \"59\";\nconst TAG_MERCHANT_CITY = \"60\";\nconst TAG_POSTAL_CODE = \"61\";\nconst TAG_ADDITIONAL_DATA = \"62\";\nconst TAG_CRC = \"63\";\n\nconst MAI_TAG_GUI = \"00\";\nconst MAI_TAG_KEY = \"01\";\nconst MAI_TAG_DESCRIPTION = \"02\";\nconst MAI_TAG_URL = \"25\";\nconst ADDITIONAL_TAG_TXID = \"05\";\n\n/** Globally Unique Identifier that marks tag 26 as a Pix account. */\nconst PIX_GUI = \"br.gov.bcb.pix\";\n\nconst PAYLOAD_FORMAT_VERSION = \"01\";\nconst POINT_OF_INITIATION_REUSABLE = \"11\";\nconst POINT_OF_INITIATION_SINGLE_USE = \"12\";\nconst DEFAULT_MERCHANT_CATEGORY_CODE = \"0000\";\nconst CURRENCY_BRL = \"986\";\nconst COUNTRY_BR = \"BR\";\nconst TXID_UNSPECIFIED = \"***\";\n\nconst MAX_MERCHANT_NAME = 25;\nconst MAX_MERCHANT_CITY = 15;\nconst MAX_TXID = 25;\nconst MAX_TLV_VALUE = 99;\nconst MAX_EMAIL_KEY = 77;\n\n/**\n * CRC-16/CCITT-FALSE of a string, as four upper-case hex characters.\n *\n * Bitwise rather than table-driven: 200-odd characters at 8 shifts each is\n * nothing, and a 256-entry table is 2 KB of payload every consumer of the `/br`\n * entry would carry.\n *\n * The input is taken as UTF-8 bytes. A Pix payload is ASCII by construction —\n * {@link pixPayload} rejects anything else — but the function is exported and a\n * caller may hand it arbitrary text, and hashing UTF-16 code units would then\n * disagree with every other implementation.\n *\n * @param input - Bytes to run through the register.\n * @returns Four upper-case hex characters, zero-padded.\n *\n * @example\n * pixCrc16(\"123456789\"); // \"29B1\" — the catalogue check value\n */\nexport function pixCrc16(input: string): string {\n    const bytes = new TextEncoder().encode(input);\n    let crc = CRC16_INITIAL;\n    for (const byte of bytes) {\n        crc ^= byte << 8;\n        for (let bit = 0; bit < 8; bit += 1) {\n            crc =\n                (crc & 0x8000) !== 0\n                    ? ((crc << 1) ^ CRC16_POLYNOMIAL) & CRC16_MASK\n                    : (crc << 1) & CRC16_MASK;\n        }\n    }\n    return crc.toString(16).toUpperCase().padStart(4, \"0\");\n}\n\n/** Digits of a possibly masked value. */\nfunction digits(value: string): string {\n    return value.replace(/\\D/g, \"\");\n}\n\n/**\n * Drop diacritics and reject whatever is left outside printable ASCII.\n *\n * The BR Code character set has no room for accents, and a wallet that meets one\n * either fails to parse the QR or shows mojibake. Stripping them is lossy but\n * legible (\"São Paulo\" → \"Sao Paulo\"), which beats both alternatives; anything\n * that is not a diacritic — an emoji, a CJK character — is a mistake the caller\n * has to see, so it throws.\n */\nfunction toPayloadText(value: string, field: string): string {\n    const stripped = value.normalize(\"NFD\").replace(/\\p{Diacritic}/gu, \"\");\n    if (/[^\\x20-\\x7E]/.test(stripped)) {\n        throw new PixError(\n            `${field} has characters the BR Code cannot carry: ${JSON.stringify(value)}. ` +\n                \"Use unaccented ASCII.\",\n        );\n    }\n    return stripped;\n}\n\n/** One `ID + 2-digit length + value` triple. */\nfunction tlv(id: string, value: string): string {\n    if (value.length > MAX_TLV_VALUE) {\n        throw new PixError(\n            `Tag ${id} is ${value.length} characters; the EMV length field holds at most ${MAX_TLV_VALUE}.`,\n        );\n    }\n    return `${id}${String(value.length).padStart(2, \"0\")}${value}`;\n}\n\n/**\n * Classify a Pix key, or `null` when it matches no accepted format.\n *\n * !!! warning \"CPF and a national phone number are both eleven digits\"\n *     `\"11987654321\"` is a valid mobile number and could be a CPF. The check\n *     digits break the tie: an 11-digit string is a CPF when its DV validates and\n *     a phone otherwise. Pass phone keys as `+5511987654321` to remove the guess\n *     entirely.\n *\n * @param key - Raw key, masked or not.\n * @returns The key type, or `null`.\n */\nexport function pixKeyType(key: string): PixKeyType | null {\n    const trimmed = key.trim();\n    if (trimmed === \"\") return null;\n\n    if (trimmed.includes(\"@\")) {\n        return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]{2,}$/.test(trimmed) && trimmed.length <= MAX_EMAIL_KEY\n            ? \"email\"\n            : null;\n    }\n    if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(trimmed)) {\n        return \"evp\";\n    }\n\n    const numbers = digits(trimmed);\n    if (numbers.length === 14) return validateCNPJ(numbers) ? \"cnpj\" : null;\n    if (numbers.length === 11 && validateCPF(numbers)) return \"cpf\";\n    if (trimmed.startsWith(\"+\")) {\n        return /^\\+55\\d{10,11}$/.test(`+${numbers}`) ? \"phone\" : null;\n    }\n    if (numbers.length === 10 || numbers.length === 11) return \"phone\";\n    if (numbers.length === 12 || numbers.length === 13) {\n        return numbers.startsWith(\"55\") ? \"phone\" : null;\n    }\n    return null;\n}\n\n/**\n * Validate a Pix key and return the exact string to write into the payload.\n *\n * Normalisation per type: CPF and CNPJ lose their mask, a phone becomes E.164\n * with the `+55` country code, an EVP is lower-cased, and an e-mail is\n * lower-cased because DICT stores it that way — a key that differs only in case\n * would otherwise fail to resolve.\n *\n * All validation lives in {@link pixKeyType}; past that gate the normalisation is\n * total, which is why the phone branch strips a country code purely on length\n * rather than re-checking the shape.\n *\n * @param key - Raw key, masked or not.\n * @returns The type and the normalised value.\n * @throws {PixError} When the key matches no accepted format, or when a document\n * key fails its check digits.\n *\n * @example\n * normalizePixKey(\"123.456.789-09\"); // { type: \"cpf\", value: \"12345678909\" }\n * normalizePixKey(\"(11) 98765-4321\"); // { type: \"phone\", value: \"+5511987654321\" }\n */\nexport function normalizePixKey(key: string): NormalizedPixKey {\n    const trimmed = key.trim();\n    const type = pixKeyType(trimmed);\n    if (type === null) {\n        throw new PixError(\n            `Not a Pix key: ${JSON.stringify(key)}. Expected a CPF, CNPJ, e-mail, ` +\n                \"phone (+5511987654321) or EVP (UUID).\",\n        );\n    }\n\n    if (type === \"email\") return { type, value: trimmed.toLowerCase() };\n    if (type === \"evp\") return { type, value: trimmed.toLowerCase() };\n    if (type === \"phone\") {\n        const numbers = digits(trimmed);\n        return { type, value: `+55${numbers.length > 11 ? numbers.slice(2) : numbers}` };\n    }\n    return { type, value: digits(trimmed) };\n}\n\n/** Format an amount the way tag 54 wants it: dot separator, two decimals. */\nfunction toAmountField(amount: number): string {\n    if (!Number.isFinite(amount)) {\n        throw new PixError(`Amount must be a finite number, got ${amount}.`);\n    }\n    if (amount <= 0) {\n        throw new PixError(\n            `Amount must be positive, got ${amount}. Omit \\`amount\\` for a QR whose value the payer types.`,\n        );\n    }\n    const field = amount.toFixed(2);\n    if (field.length > 13) {\n        throw new PixError(`Amount ${field} does not fit tag 54, which holds 13 characters.`);\n    }\n    return field;\n}\n\n/** Bound the two free-text identity fields the spec caps hard. */\nfunction toBoundedText(value: string, max: number, field: string): string {\n    const text = toPayloadText(value.trim(), field);\n    if (text === \"\") throw new PixError(`${field} is required.`);\n    if (text.length > max) {\n        throw new PixError(\n            `${field} is ${text.length} characters; the BR Code allows ${max}. Shorten it — ` +\n                \"truncating here would silently change what the payer sees.\",\n        );\n    }\n    return text;\n}\n\n/** Tag 62, which exists only to carry the txid. */\nfunction additionalDataField(txid: string | undefined): string {\n    const value = txid?.trim() ?? \"\";\n    if (value === \"\" || value === TXID_UNSPECIFIED) {\n        return tlv(TAG_ADDITIONAL_DATA, tlv(ADDITIONAL_TAG_TXID, TXID_UNSPECIFIED));\n    }\n    if (!new RegExp(`^[A-Za-z0-9]{1,${MAX_TXID}}$`).test(value)) {\n        throw new PixError(\n            `txid must be 1 to ${MAX_TXID} letters or digits, got ${JSON.stringify(txid)}.`,\n        );\n    }\n    return tlv(TAG_ADDITIONAL_DATA, tlv(ADDITIONAL_TAG_TXID, value));\n}\n\n/** Tag 26 for a static payload: GUI, key and the optional description. */\nfunction staticMerchantAccount(input: PixStaticInput): string {\n    const { value } = normalizePixKey(input.key);\n    let inner = tlv(MAI_TAG_GUI, PIX_GUI) + tlv(MAI_TAG_KEY, value);\n    const description = input.description?.trim();\n    if (description !== undefined && description !== \"\") {\n        inner += tlv(MAI_TAG_DESCRIPTION, toPayloadText(description, \"description\"));\n    }\n    if (inner.length > MAX_TLV_VALUE) {\n        throw new PixError(\n            `Tag 26 is ${inner.length} characters, over the ${MAX_TLV_VALUE} the length field allows. ` +\n                \"Shorten `description`.\",\n        );\n    }\n    return tlv(TAG_MERCHANT_ACCOUNT_INFO, inner);\n}\n\n/** Tag 26 for a dynamic payload: GUI plus the URL, and no key. */\nfunction dynamicMerchantAccount(input: PixDynamicInput): string {\n    const url = toPayloadText(input.url.trim(), \"url\").replace(/^https?:\\/\\//i, \"\");\n    if (url === \"\") throw new PixError(\"url is required for a dynamic BR Code.\");\n    const inner = tlv(MAI_TAG_GUI, PIX_GUI) + tlv(MAI_TAG_URL, url);\n    if (inner.length > MAX_TLV_VALUE) {\n        throw new PixError(\n            `Tag 26 is ${inner.length} characters, over the ${MAX_TLV_VALUE} the length field allows. ` +\n                \"Shorten the payload URL.\",\n        );\n    }\n    return tlv(TAG_MERCHANT_ACCOUNT_INFO, inner);\n}\n\n/**\n * Build a Pix \"Copia e Cola\" payload — the string behind a Pix QR code.\n *\n * The format is EMVCo MPM: a flat list of `ID + 2-digit length + value` triples,\n * closed by tag 63 holding a CRC-16/CCITT-FALSE over **everything before it,\n * including the literal `6304` header of tag 63 itself**. That last detail is the\n * one implementations get wrong; see {@link pixCrc16}.\n *\n * Two shapes come out of here:\n *\n * - **static** — tag 26 carries the key, so the QR is self-contained and can be\n *   printed. Amount optional; a txid of `\"***\"` means \"identifies no single\n *   transaction\", which is what a reusable poster QR wants.\n * - **dynamic** — tag 26 carries a URL instead, and the wallet fetches the amount\n *   and payee from the PSP. Use it when the value is per-order. Defaults to\n *   single-use (tag 01 = `12`).\n *\n * The distinction matters and is not cosmetic: a static QR settles against\n * whatever the payer typed, a dynamic one against what the PSP served, so a\n * charge that must reconcile to a cent needs the dynamic form.\n *\n * @param input - Static or dynamic payload description.\n * @returns The full payload, CRC included, ready to render as a QR or to copy.\n * @throws {PixError} On an unrecognised key, a field over its length cap, a\n * non-positive amount, or text that is not representable in the BR Code.\n *\n * @example\n * pixPayload({\n *   key: \"12345678909\",\n *   merchantName: \"Loja Tempest\",\n *   merchantCity: \"São Paulo\",\n *   amount: 25.5,\n *   txid: \"PEDIDO123\",\n * });\n */\nexport function pixPayload(input: PixInput): string {\n    const dynamic = input.kind === \"dynamic\";\n    const oneTime = input.oneTime ?? dynamic;\n\n    let payload = tlv(TAG_PAYLOAD_FORMAT, PAYLOAD_FORMAT_VERSION);\n    payload += tlv(\n        TAG_POINT_OF_INITIATION,\n        oneTime ? POINT_OF_INITIATION_SINGLE_USE : POINT_OF_INITIATION_REUSABLE,\n    );\n    payload += dynamic ? dynamicMerchantAccount(input) : staticMerchantAccount(input);\n    payload += tlv(TAG_MERCHANT_CATEGORY_CODE, DEFAULT_MERCHANT_CATEGORY_CODE);\n    payload += tlv(TAG_TRANSACTION_CURRENCY, CURRENCY_BRL);\n    if (!dynamic && input.amount !== undefined) {\n        payload += tlv(TAG_TRANSACTION_AMOUNT, toAmountField(input.amount));\n    }\n    payload += tlv(TAG_COUNTRY_CODE, COUNTRY_BR);\n    payload += tlv(\n        TAG_MERCHANT_NAME,\n        toBoundedText(input.merchantName, MAX_MERCHANT_NAME, \"merchantName\"),\n    );\n    payload += tlv(\n        TAG_MERCHANT_CITY,\n        toBoundedText(input.merchantCity, MAX_MERCHANT_CITY, \"merchantCity\"),\n    );\n    const postalCode = input.postalCode === undefined ? \"\" : digits(input.postalCode);\n    if (postalCode !== \"\") payload += tlv(TAG_POSTAL_CODE, postalCode);\n    payload += additionalDataField(dynamic ? TXID_UNSPECIFIED : input.txid);\n\n    const withCrcHeader = `${payload}${TAG_CRC}04`;\n    return `${withCrcHeader}${pixCrc16(withCrcHeader)}`;\n}\n\n/**\n * Split a flat run of TLVs. Stops cleanly at the first malformed triple.\n *\n * @throws {PixError} When a length prefix is not two digits or runs past the end.\n */\nfunction parseTlv(input: string, where: string): PixField[] {\n    const fields: PixField[] = [];\n    let cursor = 0;\n    while (cursor < input.length) {\n        const id = input.slice(cursor, cursor + 2);\n        const rawLength = input.slice(cursor + 2, cursor + 4);\n        if (!/^\\d{2}$/.test(id) || !/^\\d{2}$/.test(rawLength)) {\n            throw new PixError(\n                `Malformed TLV in ${where} at offset ${cursor}: expected a 2-digit tag and length.`,\n            );\n        }\n        const length = Number(rawLength);\n        const start = cursor + 4;\n        if (start + length > input.length) {\n            throw new PixError(\n                `Tag ${id} in ${where} declares ${length} characters but only ${input.length - start} remain.`,\n            );\n        }\n        fields.push({ id, value: input.slice(start, start + length) });\n        cursor = start + length;\n    }\n    return fields;\n}\n\n/** First value for a tag, or `undefined`. */\nfunction pick(fields: readonly PixField[], id: string): string | undefined {\n    return fields.find((field) => field.id === id)?.value;\n}\n\n/**\n * Read a Pix \"Copia e Cola\" payload back into its parts.\n *\n * Tolerant by design: tags the SDK does not know about are kept verbatim in\n * {@link PixData.fields} instead of raising, because PSPs do add their own\n * templates and a reader that rejects them is useless in production. What is\n * *not* tolerated is a broken frame — a length prefix that runs off the end, a\n * missing tag 63 — or a checksum mismatch, which means the string was corrupted\n * and no longer names the account the payee published.\n *\n * @param payload - The copia-e-cola string. Surrounding whitespace is ignored.\n * @param options - See {@link ParsePixOptions}.\n * @returns The decoded payload.\n * @throws {PixError} On a malformed frame, a missing CRC tag, a tag 26 that is\n * not a Pix account, or — unless `requireCrc` is `false` — a CRC mismatch.\n *\n * @example\n * const data = parsePixPayload(copied);\n * console.log(data.key, data.amount, data.txid);\n */\nexport function parsePixPayload(payload: string, options: ParsePixOptions = {}): PixData {\n    const { requireCrc = true } = options;\n    const text = payload.trim();\n    if (text.length < 8) throw new PixError(\"Payload is too short to be a BR Code.\");\n\n    const crcHeaderAt = text.length - 8;\n    if (text.slice(crcHeaderAt, crcHeaderAt + 4) !== `${TAG_CRC}04`) {\n        throw new PixError(\"Payload does not end in a `6304` CRC tag.\");\n    }\n    const crc = text.slice(-4).toUpperCase();\n    const expected = pixCrc16(text.slice(0, -4));\n    const crcValid = crc === expected;\n    if (!crcValid && requireCrc) {\n        throw new PixError(`CRC mismatch: payload says ${crc}, recomputed ${expected}.`);\n    }\n\n    const fields = parseTlv(text.slice(0, crcHeaderAt), \"payload\");\n    const merchantAccount = pick(fields, TAG_MERCHANT_ACCOUNT_INFO);\n    if (merchantAccount === undefined) {\n        throw new PixError(\"Payload has no tag 26 (merchant account information).\");\n    }\n    const account = parseTlv(merchantAccount, \"tag 26\");\n    const gui = pick(account, MAI_TAG_GUI);\n    if (gui?.toLowerCase() !== PIX_GUI) {\n        throw new PixError(\n            `Tag 26 is not a Pix account: expected GUI ${PIX_GUI}, got ${JSON.stringify(gui)}.`,\n        );\n    }\n\n    const url = pick(account, MAI_TAG_URL);\n    const key = pick(account, MAI_TAG_KEY);\n    const amountField = pick(fields, TAG_TRANSACTION_AMOUNT);\n    const txid = pick(\n        parseTlv(pick(fields, TAG_ADDITIONAL_DATA) ?? \"\", \"tag 62\"),\n        ADDITIONAL_TAG_TXID,\n    );\n\n    return {\n        kind: url !== undefined && key === undefined ? \"dynamic\" : \"static\",\n        ...(key === undefined ? {} : { key, keyType: pixKeyType(key) ?? undefined }),\n        ...(url === undefined ? {} : { url }),\n        merchantName: pick(fields, TAG_MERCHANT_NAME) ?? \"\",\n        merchantCity: pick(fields, TAG_MERCHANT_CITY) ?? \"\",\n        ...(amountField === undefined ? {} : { amount: Number(amountField) }),\n        currency: pick(fields, TAG_TRANSACTION_CURRENCY) ?? \"\",\n        countryCode: pick(fields, TAG_COUNTRY_CODE) ?? \"\",\n        merchantCategoryCode: pick(fields, TAG_MERCHANT_CATEGORY_CODE) ?? \"\",\n        ...(txid === undefined ? {} : { txid }),\n        ...(pick(account, MAI_TAG_DESCRIPTION) === undefined\n            ? {}\n            : { description: pick(account, MAI_TAG_DESCRIPTION) }),\n        ...(pick(fields, TAG_POSTAL_CODE) === undefined\n            ? {}\n            : { postalCode: pick(fields, TAG_POSTAL_CODE) }),\n        oneTime: pick(fields, TAG_POINT_OF_INITIATION) === POINT_OF_INITIATION_SINGLE_USE,\n        crc,\n        crcValid,\n        fields,\n    };\n}\n"],"mappings":"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"}