@asteby/storefront-react 0.23.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/fiscal/server-extract.ts","../src/fiscal/server.ts"],"names":[],"mappings":"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","file":"fiscal-server.js","sourcesContent":["/**\n * Reads a tax document uploaded without JavaScript, on the server, with the same engine the browser uses. In memory\n * only: the bytes are never written to disk, never logged and are dropped when this returns.\n */\nimport type { IdentityDocumentSpec, Region } from '@asteby/storefront'\nimport { IdentityDocumentError, buildDocumentEvidence, catalogsFromRegion, extractIdentityDocument, readPdfText } from '@asteby/storefront/fiscal-document'\nimport { summarizeExtraction } from './extraction.js'\nimport type { FiscalExtractionSummary } from './types.js'\n\nexport type UploadLimits = { maxBytes: number; maxPages: number; timeoutMs: number }\n\n/** 5 MiB, 6 pages, 3 s: the same as the browser reader. */\nexport const UPLOAD_LIMITS: Readonly<UploadLimits> = Object.freeze({ maxBytes: 5 * 1024 * 1024, maxPages: 6, timeoutMs: 3000 })\n\nconst PDF_MAGIC = [0x25, 0x50, 0x44, 0x46, 0x2d] // %PDF-\n\nexport async function extractUploadedDocument(\n file: Blob,\n spec: IdentityDocumentSpec,\n region: Pick<Region, 'fiscal_id'>,\n options: { limits?: Partial<UploadLimits>; now?: Date } = {},\n): Promise<FiscalExtractionSummary> {\n const lim = { ...UPLOAD_LIMITS, ...options.limits }\n // The region can only lower the limits.\n const maxBytes = Math.min(lim.maxBytes, spec.max_bytes || lim.maxBytes)\n const maxPages = Math.min(lim.maxPages, spec.max_pages || lim.maxPages)\n if (file.size > maxBytes) throw new IdentityDocumentError('too_large', 'file over the size limit', { reason: 'bytes' })\n const bytes = new Uint8Array(await file.arrayBuffer())\n if (!PDF_MAGIC.every((b, i) => bytes[i] === b)) throw new IdentityDocumentError('not_pdf', 'not a PDF')\n // The engine is the only reader. QR cross-check needs a canvas, which a server does not have: `qr_match` stays null.\n const { text, sha256 } = await readPdfText(bytes, { maxBytes, maxPages, timeoutMs: lim.timeoutMs })\n const x = extractIdentityDocument(text, spec, {\n catalogs: region.fiscal_id ? catalogsFromRegion(region.fiscal_id) : {},\n ...(options.now ? { now: options.now } : {}),\n })\n return summarizeExtraction(x, buildDocumentEvidence(x, { sha256, source: 'pdf_server' }), region.fiscal_id?.regimes.map((r) => r.code))\n}\n","/**\n * Server side of the fiscal components (`@asteby/storefront-react/fiscal/server`): `loadFiscalContext` for the loader and\n * `createInvoiceAction` for the action. No React, no router: Web `Request`/`Response` only, so any framework mounts it.\n *\n * The browser never talks to OPS. The action uses the store's `sk_` client and the buyer's session token (read from the\n * store's cookie). A tax document uploaded WITHOUT JavaScript is read in memory here with the same engine the browser\n * uses, and discarded: no disk, no logs, no copy.\n */\nimport {\n isStorefrontError,\n repairPath,\n type FiscalDocumentEvidence,\n type FiscalIdentityInput,\n type InvoiceRequest,\n type InvoicingCapabilities,\n type Region,\n type StorefrontClient,\n} from '@asteby/storefront'\nimport { normalizeTaxId } from './format.js'\nimport { extractUploadedDocument, UPLOAD_LIMITS, type UploadLimits } from './server-extract.js'\nimport type { FiscalActionData, FiscalErrorCode, FiscalIntent } from './types.js'\n\nexport type { FiscalActionData, FiscalErrorCode, FiscalIntent } from './types.js'\nexport { UPLOAD_LIMITS, extractUploadedDocument } from './server-extract.js'\nexport type { UploadLimits } from './server-extract.js'\n\n// ---- context ---------------------------------------------------------------------------------------------------------\n\nexport type FiscalContext = {\n /** The store can invoice: it has a region with a fiscal catalog and `capabilities.invoicing.available`. */\n available: boolean\n region: Region | null\n invoicing: InvoicingCapabilities | null\n}\n\n/** What is assumed when the store cannot be asked: no invoicing, nothing breaks. */\nexport const NO_FISCAL_CONTEXT: Readonly<FiscalContext> = Object.freeze({ available: false, region: null, invoicing: null })\n\nconst FAILURE_TTL_MS = 5_000\nconst cache = new WeakMap<object, { at: number; ok: boolean; value: FiscalContext }>()\n\nexport type LoadFiscalContextOptions = {\n /** How long a good answer is reused per client (default 60 s). `0` disables the cache. */\n ttlMs?: number\n signal?: AbortSignal\n now?: () => number\n}\n\n/**\n * Asks the store for its region and what invoicing it offers, with a short cache per client. It NEVER throws: when OPS\n * does not answer (older server, outage, token without scope) it returns `NO_FISCAL_CONTEXT` and retries after a few\n * seconds, so a checkout without invoicing keeps working. Use it as the loader: `loader = () => loadFiscalContext(sf)`.\n */\nexport async function loadFiscalContext(sf: StorefrontClient, options: LoadFiscalContextOptions = {}): Promise<FiscalContext> {\n const now = options.now ?? Date.now\n const ttl = options.ttlMs ?? 60_000\n const hit = cache.get(sf)\n if (hit && now() - hit.at < (hit.ok ? ttl : FAILURE_TTL_MS)) return hit.value\n const opt = options.signal ? { signal: options.signal } : undefined\n const [region, caps] = await Promise.allSettled([sf.region(opt), sf.customer.capabilities(opt)])\n const reg = region.status === 'fulfilled' ? region.value : null\n const invoicing = caps.status === 'fulfilled' ? (caps.value?.invoicing ?? null) : null\n const ok = region.status === 'fulfilled' && caps.status === 'fulfilled'\n const value: FiscalContext = {\n available: !!reg?.fiscal_id && !!invoicing?.available,\n region: reg,\n invoicing: invoicing?.available ? invoicing : null,\n }\n cache.set(sf, { at: now(), ok, value: ok ? value : value.available ? value : NO_FISCAL_CONTEXT })\n return ok || value.available ? value : NO_FISCAL_CONTEXT\n}\n\n// ---- action ----------------------------------------------------------------------------------------------------------\n\n/** What the action needs of a cookie to read the buyer's session. React Router's `createCookie(...)` fits as it is. */\nexport type SessionCookie = { parse(header: string | null): unknown }\n\nexport type CreateInvoiceActionOptions = {\n storefront: StorefrontClient\n /** The store's cookie for the buyer session token (`createCookie('sf_customer', ...)`), to know who is asking. */\n customerCookie?: SessionCookie\n /** Alternative to `customerCookie`: returns the buyer's session token, or `null` for a guest. */\n readCustomerToken?: (request: Request) => string | null | undefined | Promise<string | null | undefined>\n /** Shopper IP for the per-shopper rate limit (see `clientIp` of the client). */\n clientIp?: (request: Request) => string | null | undefined\n /** Region + capabilities source, for tests or a shared cache (default `loadFiscalContext`). */\n context?: (sf: StorefrontClient) => Promise<FiscalContext>\n /** Limits of the no-JS upload (defaults: 5 MiB, 6 pages, 3 s). The region's own limits can only lower them. */\n limits?: Partial<UploadLimits>\n /** Clock, for the freshness check. */\n now?: () => Date\n /** Rejects cross-site posts (default `true`): `Origin` and `Sec-Fetch-Site` must match the site. */\n sameSiteOnly?: boolean\n /** Prefix of the form fields (default `invoice`). */\n namePrefix?: string\n}\n\nconst EVIDENCE_SOURCES = new Set(['pdf_client', 'pdf_server', 'qr', 'manual'])\n\n/** Reads the evidence the reader put in the form, keeping only the known keys (a form is untrusted input). */\nexport function parseEvidence(raw: unknown): FiscalDocumentEvidence | undefined {\n if (typeof raw !== 'string' || !raw || raw.length > 4096) return undefined\n let o: unknown\n try {\n o = JSON.parse(raw)\n } catch {\n return undefined\n }\n if (typeof o !== 'object' || o === null) return undefined\n const e = o as Record<string, unknown>\n if (typeof e.kind !== 'string' || !e.kind || typeof e.source !== 'string' || !EVIDENCE_SOURCES.has(e.source)) return undefined\n const str = (v: unknown, max: number) => (typeof v === 'string' && v.length <= max ? v : null)\n return {\n kind: e.kind.slice(0, 64),\n document_id: str(e.document_id, 64),\n issued_on: str(e.issued_on, 32),\n sha256: typeof e.sha256 === 'string' && /^[0-9a-f]{64}$/.test(e.sha256) ? e.sha256 : null,\n ...(typeof e.extractor === 'string' ? { extractor: e.extractor.slice(0, 64) } : {}),\n source: e.source as FiscalDocumentEvidence['source'],\n qr_match: typeof e.qr_match === 'boolean' ? e.qr_match : null,\n }\n}\n\n/** Reads the `invoice.*` fields of a form into the API's `InvoiceRequest`. */\nexport function invoiceFromForm(form: FormData, prefix = 'invoice'): InvoiceRequest {\n const text = (k: string) => {\n const v = form.get(`${prefix}.${k}`)\n return typeof v === 'string' ? v.trim() : ''\n }\n const evidence = parseEvidence(form.get(`${prefix}.document`))\n const out: InvoiceRequest = {\n requested: true,\n tax_id: normalizeTaxId(text('tax_id')),\n legal_name: text('legal_name'),\n tax_regime: text('tax_regime'),\n use: text('use'),\n postal_code: text('postal_code'),\n }\n if (evidence) out.document = evidence\n if (form.get(`${prefix}.save`)) out.save = true\n return out\n}\n\nconst fail = (intent: FiscalIntent | undefined, code: FiscalErrorCode, extra: Partial<FiscalActionData> = {}): FiscalActionData => ({\n ok: false,\n ...(intent ? { intent } : {}),\n ...extra,\n error: { code, ...(extra.error?.field ? { field: extra.error.field } : {}), ...(extra.error?.blocked ? { blocked: extra.error.blocked } : {}) },\n})\n\nconst LOG_EVERY_MS = 60_000\nlet lastLogAt = -Infinity\nfunction logMisconfigured(scopes: readonly string[]): void {\n const t = Date.now()\n if (t - lastLogAt < LOG_EVERY_MS) return\n lastLogAt = t\n console.error(\n `[@asteby/storefront-react] La credencial de la tienda no tiene permisos${scopes.length ? ` (${scopes.join(', ')})` : ''}; ` +\n `la facturación no funciona hasta repararlo en ${repairPath()}.`,\n )\n}\n\n/** `fiscal.tax_regime` (profile) and `invoice.tax_regime` (cart, order) both name the same form control. */\nconst formField = (field: string | undefined, prefix: string) => (field ? field.replace(/^(fiscal|invoice)\\./, `${prefix}.`) : undefined)\n\nfunction toFailure(err: unknown, intent: FiscalIntent, prefix: string, values?: Partial<FiscalActionData['values']>): FiscalActionData {\n const carry: Partial<FiscalActionData> = values ? { values } : {}\n if (!isStorefrontError(err)) return fail(intent, 'unavailable', carry)\n if (err.code === 'insufficient_scope') {\n logMisconfigured(err.requiredScopes)\n return fail(intent, 'store_misconfigured', carry)\n }\n const details = (err.details ?? {}) as { reason?: unknown; blocked_reason?: unknown }\n switch (err.status) {\n case 401:\n return fail(intent, 'unauthorized', carry)\n case 404:\n return fail(intent, 'not_found', carry)\n case 409: {\n const why = typeof details.reason === 'string' ? details.reason : typeof details.blocked_reason === 'string' ? details.blocked_reason : ''\n return fail(intent, why === 'already_checked_out' ? 'not_found' : 'blocked', { ...carry, ...(why ? { error: { code: 'blocked', blocked: why } } : {}) })\n }\n case 422:\n case 400: {\n const field = formField(err.field, prefix)\n return fail(intent, 'validation', {\n ...carry,\n ...(field ? { fieldErrors: { [field]: err.message || 'invalid' }, error: { code: 'validation', field } } : {}),\n })\n }\n case 429:\n return fail(intent, 'rate_limited', carry)\n case 403:\n return fail(intent, 'unsupported', carry)\n default:\n return fail(intent, 'unavailable', carry)\n }\n}\n\nfunction sameSite(request: Request): boolean {\n const site = request.headers.get('sec-fetch-site')\n if (site && site !== 'same-origin' && site !== 'same-site' && site !== 'none') return false\n const origin = request.headers.get('origin')\n if (!origin) return true\n try {\n const host = request.headers.get('x-forwarded-host') ?? request.headers.get('host') ?? new URL(request.url).host\n return new URL(origin).host === host.split(',')[0]!.trim()\n } catch {\n return false\n }\n}\n\n/**\n * The invoicing action: one `POST` form with an `intent` field.\n *\n * | intent | fields | does |\n * | ------------------ | --------------------------------------------------- | ---------------------------------------------------------- |\n * | `set-invoice` | cart_id, invoice.* (`invoice.want` unset withdraws) | `carts.setInvoice`: validates against the region BEFORE paying |\n * | `save-profile` | invoice.*, consent | `customer.update({ fiscal })`, needs a session and consent |\n * | `request-invoice` | order_id, invoice.* | `customer.requestInvoice` (invoice after the purchase) |\n * | `clear-profile` | - | `customer.update({ fiscal: null })` (the buyer's right to delete) |\n * | `extract-document` | document (file), document_kind? | reads the file in memory, discards it, `step: 'review'` |\n *\n * It never redirects: it returns a `FiscalActionData` for the page to render (`<InvoiceToggle data={...}>`), with 422s\n * mapped to the field (`fieldErrors['invoice.tax_regime']`). The tax id of the buyer is never logged.\n */\nexport function createInvoiceAction(options: CreateInvoiceActionOptions) {\n const { storefront: sf } = options\n const prefix = options.namePrefix ?? 'invoice'\n const loadContext = options.context ?? ((c: StorefrontClient) => loadFiscalContext(c))\n const limits: UploadLimits = { ...UPLOAD_LIMITS, ...options.limits }\n\n async function sessionToken(request: Request): Promise<string | null> {\n if (options.readCustomerToken) return (await options.readCustomerToken(request)) || null\n if (!options.customerCookie) return null\n const v = await options.customerCookie.parse(request.headers.get('cookie'))\n return typeof v === 'string' && v ? v : null\n }\n\n return async function invoiceAction({ request }: { request: Request }): Promise<FiscalActionData> {\n if (options.sameSiteOnly !== false && !sameSite(request)) return fail(undefined, 'unsupported')\n // A file bigger than the limit is refused before it is buffered.\n const declared = Number(request.headers.get('content-length') ?? 0)\n if (declared > limits.maxBytes + 256 * 1024) return fail('extract-document', 'too_large')\n const form = await request.formData().catch(() => null)\n if (!form) return fail(undefined, 'validation')\n const intent = form.get('intent') as FiscalIntent\n const ip = options.clientIp?.(request)\n const token = await sessionToken(request)\n const w = { ...(ip ? { clientIp: ip } : {}), ...(token ? { customerToken: token } : {}) }\n const invoice = invoiceFromForm(form, prefix)\n const echo = { tax_id: invoice.tax_id ?? '', legal_name: invoice.legal_name ?? '', postal_code: invoice.postal_code ?? '', tax_regime: invoice.tax_regime ?? '', use: invoice.use ?? '' }\n const text = (name: string) => {\n const v = form.get(name)\n return typeof v === 'string' ? v.trim() : ''\n }\n\n try {\n switch (intent) {\n case 'set-invoice': {\n const cartId = text('cart_id')\n if (!cartId) return fail(intent, 'validation')\n if (!form.get(`${prefix}.want`) && !form.get(`${prefix}.requested`)) {\n await sf.carts.setInvoice(cartId, null, w)\n return { ok: true, intent, step: 'cleared' }\n }\n await sf.carts.setInvoice(cartId, invoice, w)\n return { ok: true, intent, step: 'saved', values: echo }\n }\n case 'save-profile': {\n if (!token) return fail(intent, 'unauthorized', { values: echo })\n if (!form.get('consent')) return fail(intent, 'consent_required', { values: echo })\n const fiscal: FiscalIdentityInput = {\n tax_id: invoice.tax_id ?? '',\n legal_name: invoice.legal_name ?? '',\n tax_regime: invoice.tax_regime ?? '',\n postal_code: invoice.postal_code ?? '',\n invoice_use: invoice.use ?? '',\n ...(invoice.document ? { document: invoice.document } : {}),\n }\n await sf.customer.update({ fiscal }, w)\n return { ok: true, intent, step: 'saved', values: echo }\n }\n case 'clear-profile': {\n if (!token) return fail(intent, 'unauthorized')\n await sf.customer.update({ fiscal: null }, w)\n return { ok: true, intent, step: 'cleared' }\n }\n case 'request-invoice': {\n if (!token) return fail(intent, 'unauthorized', { values: echo })\n const orderId = text('order_id')\n if (!orderId) return fail(intent, 'validation')\n const result = await sf.customer.requestInvoice(orderId, invoice, w)\n return { ok: true, intent, step: result.status === 'issued' ? 'issued' : 'pending', result, ...(result.invoice ? { invoice: result.invoice } : {}) }\n }\n case 'extract-document': {\n const ctx = await loadContext(sf)\n const region = ctx.region\n const kind = text('document_kind')\n const specs = region?.fiscal_id?.documents ?? []\n const spec = (kind ? specs.find((d) => d.kind === kind) : specs[0]) ?? undefined\n if (!ctx.available || !region || !spec) return fail(intent, 'unsupported')\n const file = form.get('document')\n if (!file || typeof file === 'string' || file.size === 0) return fail(intent, 'not_pdf')\n try {\n const extraction = await extractUploadedDocument(file, spec, region, { limits, ...(options.now ? { now: options.now() } : {}) })\n return { ok: true, intent, step: 'review', extraction }\n } catch (err) {\n const code = (err as { code?: string } | null)?.code\n const known: FiscalErrorCode[] = ['not_pdf', 'too_large', 'no_text', 'password', 'unreadable']\n // Never log the error: it can carry text from the document.\n return fail(intent, known.includes(code as FiscalErrorCode) ? (code as FiscalErrorCode) : 'unreadable')\n }\n }\n default:\n return fail(undefined, 'validation')\n }\n } catch (err) {\n return toFailure(err, intent, prefix, intent === 'clear-profile' ? undefined : echo)\n }\n }\n}\n\nexport type InvoiceAction = ReturnType<typeof createInvoiceAction>\n"]}
1
+ {"version":3,"sources":["../src/fiscal/server-extract.ts","../src/fiscal/server.ts"],"names":[],"mappings":";;;;AAYO,IAAM,aAAA,GAAwC,MAAA,CAAO,MAAA,CAAO,EAAE,QAAA,EAAU,CAAA,GAAI,IAAA,GAAO,IAAA,EAAM,QAAA,EAAU,CAAA,EAAG,SAAA,EAAW,GAAA,EAAM;AAE9H,IAAM,YAAY,CAAC,EAAA,EAAM,EAAA,EAAM,EAAA,EAAM,IAAM,EAAI,CAAA;AAE/C,eAAsB,wBACpB,IAAA,EACA,IAAA,EACA,MAAA,EACA,OAAA,GAA0D,EAAC,EACzB;AAClC,EAAA,MAAM,MAAM,EAAE,GAAG,aAAA,EAAe,GAAG,QAAQ,MAAA,EAAO;AAElD,EAAA,MAAM,QAAA,GAAW,KAAK,GAAA,CAAI,GAAA,CAAI,UAAU,IAAA,CAAK,SAAA,IAAa,IAAI,QAAQ,CAAA;AACtE,EAAA,MAAM,QAAA,GAAW,KAAK,GAAA,CAAI,GAAA,CAAI,UAAU,IAAA,CAAK,SAAA,IAAa,IAAI,QAAQ,CAAA;AACtE,EAAA,IAAI,IAAA,CAAK,IAAA,GAAO,QAAA,EAAU,MAAM,IAAI,qBAAA,CAAsB,WAAA,EAAa,0BAAA,EAA4B,EAAE,MAAA,EAAQ,OAAA,EAAS,CAAA;AACtH,EAAA,MAAM,QAAQ,IAAI,UAAA,CAAW,MAAM,IAAA,CAAK,aAAa,CAAA;AACrD,EAAA,IAAI,CAAC,SAAA,CAAU,KAAA,CAAM,CAAC,GAAG,CAAA,KAAM,KAAA,CAAM,CAAC,CAAA,KAAM,CAAC,CAAA,EAAG,MAAM,IAAI,qBAAA,CAAsB,WAAW,WAAW,CAAA;AAEtG,EAAA,MAAM,EAAE,IAAA,EAAM,MAAA,EAAO,GAAI,MAAM,WAAA,CAAY,KAAA,EAAO,EAAE,QAAA,EAAU,QAAA,EAAU,SAAA,EAAW,GAAA,CAAI,WAAW,CAAA;AAClG,EAAA,MAAM,CAAA,GAAI,uBAAA,CAAwB,IAAA,EAAM,IAAA,EAAM;AAAA,IAC5C,UAAU,MAAA,CAAO,SAAA,GAAY,mBAAmB,MAAA,CAAO,SAAS,IAAI,EAAC;AAAA,IACrE,GAAI,QAAQ,GAAA,GAAM,EAAE,KAAK,OAAA,CAAQ,GAAA,KAAQ;AAAC,GAC3C,CAAA;AACD,EAAA,OAAO,oBAAoB,CAAA,EAAG,qBAAA,CAAsB,GAAG,EAAE,MAAA,EAAQ,QAAQ,YAAA,EAAc,CAAA,EAAG,MAAA,CAAO,WAAW,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAC,CAAA;AACxI;;;ACEO,IAAM,iBAAA,GAA6C,MAAA,CAAO,MAAA,CAAO,EAAE,SAAA,EAAW,KAAA,EAAO,MAAA,EAAQ,aAAA,EAAwB,MAAA,EAAQ,IAAA,EAAM,SAAA,EAAW,IAAA,EAAM;AAE3J,IAAM,cAAA,GAAiB,GAAA;AACvB,IAAM,KAAA,uBAAY,OAAA,EAAmE;AAerF,eAAsB,iBAAA,CAAkB,EAAA,EAAsB,OAAA,GAAoC,EAAC,EAA2B;AAC5H,EAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,IAAO,IAAA,CAAK,GAAA;AAChC,EAAA,MAAM,GAAA,GAAM,QAAQ,KAAA,IAAS,GAAA;AAC7B,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,GAAA,CAAI,EAAE,CAAA;AACxB,EAAA,IAAI,GAAA,IAAO,GAAA,EAAI,GAAI,GAAA,CAAI,EAAA,IAAM,IAAI,EAAA,GAAK,GAAA,GAAM,cAAA,CAAA,EAAiB,OAAO,GAAA,CAAI,KAAA;AACxE,EAAA,MAAM,MAAM,OAAA,CAAQ,MAAA,GAAS,EAAE,MAAA,EAAQ,OAAA,CAAQ,QAAO,GAAI,MAAA;AAC1D,EAAA,MAAM,CAAC,MAAA,EAAQ,IAAI,CAAA,GAAI,MAAM,QAAQ,UAAA,CAAW,CAAC,EAAA,CAAG,MAAA,CAAO,GAAG,CAAA,EAAG,EAAA,CAAG,SAAS,YAAA,CAAa,GAAG,CAAC,CAAC,CAAA;AAC/F,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,MAAA,KAAW,WAAA,GAAc,OAAO,KAAA,GAAQ,IAAA;AAC3D,EAAA,MAAM,QAAA,GAAW,MAAA,CAAO,MAAA,KAAW,UAAA,IAAc,iBAAA,CAAkB,OAAO,MAAM,CAAA,IAAK,MAAA,CAAO,MAAA,CAAO,MAAA,KAAW,GAAA;AAC9G,EAAA,MAAM,YAAY,IAAA,CAAK,MAAA,KAAW,cAAe,IAAA,CAAK,KAAA,EAAO,aAAa,IAAA,GAAQ,IAAA;AAClF,EAAA,MAAM,MAAM,MAAA,CAAO,MAAA,KAAW,WAAA,IAAe,QAAA,KAAa,KAAK,MAAA,KAAW,WAAA;AAC1E,EAAA,MAAM,YAAY,CAAC,CAAC,KAAK,SAAA,IAAa,CAAC,CAAC,SAAA,EAAW,SAAA;AACnD,EAAA,MAAM,SAAuB,SAAA,GACzB,WAAA,GACA,CAAC,EAAA,GACC,aAAA,GACA,YAAY,CAAC,GAAA,EAAK,SAAA,GAChB,SAAA,IAAa,CAAC,SAAA,CAAU,SAAA,GACtB,QACA,WAAA,GACF,CAAC,YACC,SAAA,GACA,KAAA;AACV,EAAA,MAAM,KAAA,GAAuB,EAAE,SAAA,EAAW,MAAA,EAAQ,MAAA,EAAQ,KAAK,SAAA,EAAW,SAAA,EAAW,SAAA,GAAY,SAAA,GAAY,IAAA,EAAK;AAClH,EAAA,KAAA,CAAM,GAAA,CAAI,EAAA,EAAI,EAAE,EAAA,EAAI,GAAA,EAAI,EAAG,EAAA,EAAI,KAAA,EAAO,EAAA,IAAM,SAAA,GAAY,KAAA,GAAQ,iBAAA,EAAmB,CAAA;AACnF,EAAA,OAAO,EAAA,IAAM,YAAY,KAAA,GAAQ,iBAAA;AACnC;AA2BA,IAAM,gBAAA,uBAAuB,GAAA,CAAI,CAAC,cAAc,YAAA,EAAc,IAAA,EAAM,QAAQ,CAAC,CAAA;AAGtE,SAAS,cAAc,GAAA,EAAkD;AAC9E,EAAA,IAAI,OAAO,QAAQ,QAAA,IAAY,CAAC,OAAO,GAAA,CAAI,MAAA,GAAS,MAAM,OAAO,MAAA;AACjE,EAAA,IAAI,CAAA;AACJ,EAAA,IAAI;AACF,IAAA,CAAA,GAAI,IAAA,CAAK,MAAM,GAAG,CAAA;AAAA,EACpB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,KAAM,MAAM,OAAO,MAAA;AAChD,EAAA,MAAM,CAAA,GAAI,CAAA;AACV,EAAA,IAAI,OAAO,CAAA,CAAE,IAAA,KAAS,QAAA,IAAY,CAAC,EAAE,IAAA,IAAQ,OAAO,CAAA,CAAE,MAAA,KAAW,YAAY,CAAC,gBAAA,CAAiB,IAAI,CAAA,CAAE,MAAM,GAAG,OAAO,MAAA;AACrH,EAAA,MAAM,GAAA,GAAM,CAAC,CAAA,EAAY,GAAA,KAAiB,OAAO,MAAM,QAAA,IAAY,CAAA,CAAE,MAAA,IAAU,GAAA,GAAM,CAAA,GAAI,IAAA;AACzF,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,CAAA,CAAE,IAAA,CAAK,KAAA,CAAM,GAAG,EAAE,CAAA;AAAA,IACxB,WAAA,EAAa,GAAA,CAAI,CAAA,CAAE,WAAA,EAAa,EAAE,CAAA;AAAA,IAClC,SAAA,EAAW,GAAA,CAAI,CAAA,CAAE,SAAA,EAAW,EAAE,CAAA;AAAA,IAC9B,MAAA,EAAQ,OAAO,CAAA,CAAE,MAAA,KAAW,QAAA,IAAY,gBAAA,CAAiB,IAAA,CAAK,CAAA,CAAE,MAAM,CAAA,GAAI,CAAA,CAAE,MAAA,GAAS,IAAA;AAAA,IACrF,GAAI,OAAO,CAAA,CAAE,SAAA,KAAc,WAAW,EAAE,SAAA,EAAW,CAAA,CAAE,SAAA,CAAU,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,KAAM,EAAC;AAAA,IACjF,QAAQ,CAAA,CAAE,MAAA;AAAA,IACV,UAAU,OAAO,CAAA,CAAE,QAAA,KAAa,SAAA,GAAY,EAAE,QAAA,GAAW;AAAA,GAC3D;AACF;AAGO,SAAS,eAAA,CAAgB,IAAA,EAAgB,MAAA,GAAS,SAAA,EAA2B;AAClF,EAAA,MAAM,IAAA,GAAO,CAAC,CAAA,KAAc;AAC1B,IAAA,MAAM,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,MAAM,CAAA,CAAA,EAAI,CAAC,CAAA,CAAE,CAAA;AACnC,IAAA,OAAO,OAAO,CAAA,KAAM,QAAA,GAAW,CAAA,CAAE,MAAK,GAAI,EAAA;AAAA,EAC5C,CAAA;AACA,EAAA,MAAM,WAAW,aAAA,CAAc,IAAA,CAAK,IAAI,CAAA,EAAG,MAAM,WAAW,CAAC,CAAA;AAC7D,EAAA,MAAM,GAAA,GAAsB;AAAA,IAC1B,SAAA,EAAW,IAAA;AAAA,IACX,MAAA,EAAQ,cAAA,CAAe,IAAA,CAAK,QAAQ,CAAC,CAAA;AAAA,IACrC,UAAA,EAAY,KAAK,YAAY,CAAA;AAAA,IAC7B,UAAA,EAAY,KAAK,YAAY,CAAA;AAAA,IAC7B,GAAA,EAAK,KAAK,KAAK,CAAA;AAAA,IACf,WAAA,EAAa,KAAK,aAAa;AAAA,GACjC;AACA,EAAA,IAAI,QAAA,MAAc,QAAA,GAAW,QAAA;AAC7B,EAAA,IAAI,KAAK,GAAA,CAAI,CAAA,EAAG,MAAM,CAAA,KAAA,CAAO,CAAA,MAAO,IAAA,GAAO,IAAA;AAC3C,EAAA,OAAO,GAAA;AACT;AAEA,IAAM,OAAO,CAAC,MAAA,EAAkC,IAAA,EAAuB,KAAA,GAAmC,EAAC,MAAyB;AAAA,EAClI,EAAA,EAAI,KAAA;AAAA,EACJ,GAAI,MAAA,GAAS,EAAE,MAAA,KAAW,EAAC;AAAA,EAC3B,GAAG,KAAA;AAAA,EACH,KAAA,EAAO,EAAE,IAAA,EAAM,GAAI,KAAA,CAAM,KAAA,EAAO,KAAA,GAAQ,EAAE,KAAA,EAAO,KAAA,CAAM,KAAA,CAAM,KAAA,EAAM,GAAI,EAAC,EAAI,GAAI,KAAA,CAAM,KAAA,EAAO,OAAA,GAAU,EAAE,OAAA,EAAS,KAAA,CAAM,KAAA,CAAM,OAAA,EAAQ,GAAI,EAAC;AAC7I,CAAA,CAAA;AAEA,IAAM,YAAA,GAAe,GAAA;AACrB,IAAI,SAAA,GAAY,CAAA,QAAA;AAChB,SAAS,iBAAiB,MAAA,EAAiC;AACzD,EAAA,MAAM,CAAA,GAAI,KAAK,GAAA,EAAI;AACnB,EAAA,IAAI,CAAA,GAAI,YAAY,YAAA,EAAc;AAClC,EAAA,SAAA,GAAY,CAAA;AACZ,EAAA,OAAA,CAAQ,KAAA;AAAA,IACN,CAAA,uEAAA,EAA0E,MAAA,CAAO,MAAA,GAAS,CAAA,EAAA,EAAK,MAAA,CAAO,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAA,GAAM,EAAE,CAAA,mDAAA,EACrE,UAAA,EAAY,CAAA,CAAA;AAAA,GACjE;AACF;AAGA,IAAM,SAAA,GAAY,CAAC,KAAA,EAA2B,MAAA,KAAoB,KAAA,GAAQ,KAAA,CAAM,OAAA,CAAQ,qBAAA,EAAuB,CAAA,EAAG,MAAM,CAAA,CAAA,CAAG,CAAA,GAAI,MAAA;AAE/H,SAAS,SAAA,CAAU,GAAA,EAAc,MAAA,EAAsB,MAAA,EAAgB,MAAA,EAAgE;AACrI,EAAA,MAAM,KAAA,GAAmC,MAAA,GAAS,EAAE,MAAA,KAAW,EAAC;AAChE,EAAA,IAAI,CAAC,kBAAkB,GAAG,CAAA,SAAU,IAAA,CAAK,MAAA,EAAQ,eAAe,KAAK,CAAA;AACrE,EAAA,IAAI,GAAA,CAAI,SAAS,oBAAA,EAAsB;AACrC,IAAA,gBAAA,CAAiB,IAAI,cAAc,CAAA;AACnC,IAAA,OAAO,IAAA,CAAK,MAAA,EAAQ,qBAAA,EAAuB,KAAK,CAAA;AAAA,EAClD;AACA,EAAA,MAAM,OAAA,GAAW,GAAA,CAAI,OAAA,IAAW,EAAC;AACjC,EAAA,QAAQ,IAAI,MAAA;AAAQ,IAClB,KAAK,GAAA;AACH,MAAA,OAAO,IAAA,CAAK,MAAA,EAAQ,cAAA,EAAgB,KAAK,CAAA;AAAA,IAC3C,KAAK,GAAA;AACH,MAAA,OAAO,IAAA,CAAK,MAAA,EAAQ,WAAA,EAAa,KAAK,CAAA;AAAA,IACxC,KAAK,GAAA,EAAK;AACR,MAAA,MAAM,GAAA,GAAM,OAAO,OAAA,CAAQ,MAAA,KAAW,QAAA,GAAW,OAAA,CAAQ,MAAA,GAAS,OAAO,OAAA,CAAQ,cAAA,KAAmB,QAAA,GAAW,OAAA,CAAQ,cAAA,GAAiB,EAAA;AACxI,MAAA,OAAO,IAAA,CAAK,QAAQ,GAAA,KAAQ,qBAAA,GAAwB,cAAc,SAAA,EAAW,EAAE,GAAG,KAAA,EAAO,GAAI,GAAA,GAAM,EAAE,KAAA,EAAO,EAAE,MAAM,SAAA,EAAW,OAAA,EAAS,KAAI,EAAE,GAAI,EAAC,EAAI,CAAA;AAAA,IACzJ;AAAA,IACA,KAAK,GAAA;AAAA,IACL,KAAK,GAAA,EAAK;AACR,MAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,GAAA,CAAI,KAAA,EAAO,MAAM,CAAA;AACzC,MAAA,OAAO,IAAA,CAAK,QAAQ,YAAA,EAAc;AAAA,QAChC,GAAG,KAAA;AAAA,QACH,GAAI,KAAA,GAAQ,EAAE,aAAa,EAAE,CAAC,KAAK,GAAG,GAAA,CAAI,WAAW,SAAA,EAAU,EAAG,OAAO,EAAE,IAAA,EAAM,cAAc,KAAA,EAAM,KAAM;AAAC,OAC7G,CAAA;AAAA,IACH;AAAA,IACA,KAAK,GAAA;AACH,MAAA,OAAO,IAAA,CAAK,MAAA,EAAQ,cAAA,EAAgB,KAAK,CAAA;AAAA,IAC3C,KAAK,GAAA;AACH,MAAA,OAAO,IAAA,CAAK,MAAA,EAAQ,aAAA,EAAe,KAAK,CAAA;AAAA,IAC1C;AACE,MAAA,OAAO,IAAA,CAAK,MAAA,EAAQ,aAAA,EAAe,KAAK,CAAA;AAAA;AAE9C;AAEA,SAAS,SAAS,OAAA,EAA2B;AAC3C,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,gBAAgB,CAAA;AACjD,EAAA,IAAI,QAAQ,IAAA,KAAS,aAAA,IAAiB,SAAS,WAAA,IAAe,IAAA,KAAS,QAAQ,OAAO,KAAA;AACtF,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA;AAC3C,EAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AACpB,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,kBAAkB,CAAA,IAAK,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAA,IAAK,IAAI,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA,CAAE,IAAA;AAC5G,IAAA,OAAO,IAAI,GAAA,CAAI,MAAM,CAAA,CAAE,IAAA,KAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,CAAG,IAAA,EAAK;AAAA,EAC3D,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAgBO,SAAS,oBAAoB,OAAA,EAAqC;AACvE,EAAA,MAAM,EAAE,UAAA,EAAY,EAAA,EAAG,GAAI,OAAA;AAC3B,EAAA,MAAM,MAAA,GAAS,QAAQ,UAAA,IAAc,SAAA;AACrC,EAAA,MAAM,cAAc,OAAA,CAAQ,OAAA,KAAY,CAAC,CAAA,KAAwB,kBAAkB,CAAC,CAAA,CAAA;AACpF,EAAA,MAAM,SAAuB,EAAE,GAAG,aAAA,EAAe,GAAG,QAAQ,MAAA,EAAO;AAEnE,EAAA,eAAe,aAAa,OAAA,EAA0C;AACpE,IAAA,IAAI,QAAQ,iBAAA,EAAmB,OAAQ,MAAM,OAAA,CAAQ,iBAAA,CAAkB,OAAO,CAAA,IAAM,IAAA;AACpF,IAAA,IAAI,CAAC,OAAA,CAAQ,cAAA,EAAgB,OAAO,IAAA;AACpC,IAAA,MAAM,CAAA,GAAI,MAAM,OAAA,CAAQ,cAAA,CAAe,MAAM,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAC,CAAA;AAC1E,IAAA,OAAO,OAAO,CAAA,KAAM,QAAA,IAAY,CAAA,GAAI,CAAA,GAAI,IAAA;AAAA,EAC1C;AAEA,EAAA,OAAO,eAAe,aAAA,CAAc,EAAE,OAAA,EAAQ,EAAoD;AAChG,IAAA,IAAI,OAAA,CAAQ,YAAA,KAAiB,KAAA,IAAS,CAAC,QAAA,CAAS,OAAO,CAAA,EAAG,OAAO,IAAA,CAAK,MAAA,EAAW,aAAa,CAAA;AAE9F,IAAA,MAAM,WAAW,MAAA,CAAO,OAAA,CAAQ,QAAQ,GAAA,CAAI,gBAAgB,KAAK,CAAC,CAAA;AAClE,IAAA,IAAI,QAAA,GAAW,OAAO,QAAA,GAAW,GAAA,GAAM,MAAM,OAAO,IAAA,CAAK,oBAAoB,WAAW,CAAA;AACxF,IAAA,MAAM,OAAO,MAAM,OAAA,CAAQ,UAAS,CAAE,KAAA,CAAM,MAAM,IAAI,CAAA;AACtD,IAAA,IAAI,CAAC,IAAA,EAAM,OAAO,IAAA,CAAK,QAAW,YAAY,CAAA;AAC9C,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,GAAA,CAAI,QAAQ,CAAA;AAChC,IAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,QAAA,GAAW,OAAO,CAAA;AACrC,IAAA,MAAM,KAAA,GAAQ,MAAM,YAAA,CAAa,OAAO,CAAA;AACxC,IAAA,MAAM,IAAI,EAAE,GAAI,EAAA,GAAK,EAAE,UAAU,EAAA,EAAG,GAAI,EAAC,EAAI,GAAI,KAAA,GAAQ,EAAE,eAAe,KAAA,EAAM,GAAI,EAAC,EAAG;AACxF,IAAA,MAAM,OAAA,GAAU,eAAA,CAAgB,IAAA,EAAM,MAAM,CAAA;AAC5C,IAAA,MAAM,IAAA,GAAO,EAAE,MAAA,EAAQ,OAAA,CAAQ,UAAU,EAAA,EAAI,UAAA,EAAY,QAAQ,UAAA,IAAc,EAAA,EAAI,aAAa,OAAA,CAAQ,WAAA,IAAe,IAAI,UAAA,EAAY,OAAA,CAAQ,cAAc,EAAA,EAAI,GAAA,EAAK,OAAA,CAAQ,GAAA,IAAO,EAAA,EAAG;AACxL,IAAA,MAAM,IAAA,GAAO,CAAC,IAAA,KAAiB;AAC7B,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA;AACvB,MAAA,OAAO,OAAO,CAAA,KAAM,QAAA,GAAW,CAAA,CAAE,MAAK,GAAI,EAAA;AAAA,IAC5C,CAAA;AAEA,IAAA,IAAI;AACF,MAAA,QAAQ,MAAA;AAAQ,QACd,KAAK,aAAA,EAAe;AAClB,UAAA,MAAM,MAAA,GAAS,KAAK,SAAS,CAAA;AAC7B,UAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,IAAA,CAAK,QAAQ,YAAY,CAAA;AAC7C,UAAA,IAAI,CAAC,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAM,CAAA,KAAA,CAAO,CAAA,IAAK,CAAC,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,MAAM,YAAY,CAAA,EAAG;AACnE,YAAA,MAAM,EAAA,CAAG,KAAA,CAAM,UAAA,CAAW,MAAA,EAAQ,MAAM,CAAC,CAAA;AACzC,YAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,MAAA,EAAQ,MAAM,SAAA,EAAU;AAAA,UAC7C;AACA,UAAA,MAAM,EAAA,CAAG,KAAA,CAAM,UAAA,CAAW,MAAA,EAAQ,SAAS,CAAC,CAAA;AAC5C,UAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,QAAQ,IAAA,EAAM,OAAA,EAAS,QAAQ,IAAA,EAAK;AAAA,QACzD;AAAA,QACA,KAAK,cAAA,EAAgB;AACnB,UAAA,IAAI,CAAC,OAAO,OAAO,IAAA,CAAK,QAAQ,cAAA,EAAgB,EAAE,MAAA,EAAQ,IAAA,EAAM,CAAA;AAChE,UAAA,IAAI,CAAC,IAAA,CAAK,GAAA,CAAI,SAAS,CAAA,EAAG,OAAO,IAAA,CAAK,MAAA,EAAQ,kBAAA,EAAoB,EAAE,MAAA,EAAQ,IAAA,EAAM,CAAA;AAClF,UAAA,MAAM,MAAA,GAA8B;AAAA,YAClC,MAAA,EAAQ,QAAQ,MAAA,IAAU,EAAA;AAAA,YAC1B,UAAA,EAAY,QAAQ,UAAA,IAAc,EAAA;AAAA,YAClC,UAAA,EAAY,QAAQ,UAAA,IAAc,EAAA;AAAA,YAClC,WAAA,EAAa,QAAQ,WAAA,IAAe,EAAA;AAAA,YACpC,WAAA,EAAa,QAAQ,GAAA,IAAO,EAAA;AAAA,YAC5B,GAAI,QAAQ,QAAA,GAAW,EAAE,UAAU,OAAA,CAAQ,QAAA,KAAa;AAAC,WAC3D;AACA,UAAA,MAAM,GAAG,QAAA,CAAS,MAAA,CAAO,EAAE,MAAA,IAAU,CAAC,CAAA;AACtC,UAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,QAAQ,IAAA,EAAM,OAAA,EAAS,QAAQ,IAAA,EAAK;AAAA,QACzD;AAAA,QACA,KAAK,eAAA,EAAiB;AACpB,UAAA,IAAI,CAAC,KAAA,EAAO,OAAO,IAAA,CAAK,QAAQ,cAAc,CAAA;AAC9C,UAAA,MAAM,GAAG,QAAA,CAAS,MAAA,CAAO,EAAE,MAAA,EAAQ,IAAA,IAAQ,CAAC,CAAA;AAC5C,UAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,MAAA,EAAQ,MAAM,SAAA,EAAU;AAAA,QAC7C;AAAA,QACA,KAAK,iBAAA,EAAmB;AACtB,UAAA,IAAI,CAAC,OAAO,OAAO,IAAA,CAAK,QAAQ,cAAA,EAAgB,EAAE,MAAA,EAAQ,IAAA,EAAM,CAAA;AAChE,UAAA,MAAM,OAAA,GAAU,KAAK,UAAU,CAAA;AAC/B,UAAA,IAAI,CAAC,OAAA,EAAS,OAAO,IAAA,CAAK,QAAQ,YAAY,CAAA;AAC9C,UAAA,MAAM,SAAS,MAAM,EAAA,CAAG,SAAS,cAAA,CAAe,OAAA,EAAS,SAAS,CAAC,CAAA;AACnE,UAAA,OAAO,EAAE,IAAI,IAAA,EAAM,MAAA,EAAQ,MAAM,MAAA,CAAO,MAAA,KAAW,WAAW,QAAA,GAAW,SAAA,EAAW,QAAQ,GAAI,MAAA,CAAO,UAAU,EAAE,OAAA,EAAS,OAAO,OAAA,EAAQ,GAAI,EAAC,EAAG;AAAA,QACrJ;AAAA,QACA,KAAK,kBAAA,EAAoB;AACvB,UAAA,MAAM,GAAA,GAAM,MAAM,WAAA,CAAY,EAAE,CAAA;AAChC,UAAA,MAAM,SAAS,GAAA,CAAI,MAAA;AACnB,UAAA,MAAM,IAAA,GAAO,KAAK,eAAe,CAAA;AACjC,UAAA,MAAM,KAAA,GAAQ,MAAA,EAAQ,SAAA,EAAW,SAAA,IAAa,EAAC;AAC/C,UAAA,MAAM,IAAA,GAAA,CAAQ,IAAA,GAAO,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,IAAI,CAAA,GAAI,KAAA,CAAM,CAAC,CAAA,KAAM,KAAA,CAAA;AACvE,UAAA,IAAI,CAAC,GAAA,CAAI,SAAA,IAAa,CAAC,MAAA,IAAU,CAAC,IAAA,EAAM,OAAO,IAAA,CAAK,MAAA,EAAQ,aAAa,CAAA;AACzE,UAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,UAAU,CAAA;AAChC,UAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,CAAK,IAAA,KAAS,CAAA,EAAG,OAAO,IAAA,CAAK,MAAA,EAAQ,SAAS,CAAA;AACvF,UAAA,IAAI;AACF,YAAA,MAAM,aAAa,MAAM,uBAAA,CAAwB,MAAM,IAAA,EAAM,MAAA,EAAQ,EAAE,MAAA,EAAQ,GAAI,QAAQ,GAAA,GAAM,EAAE,KAAK,OAAA,CAAQ,GAAA,IAAM,GAAI,IAAK,CAAA;AAC/H,YAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,UAAU,UAAA,EAAW;AAAA,UACxD,SAAS,GAAA,EAAK;AACZ,YAAA,MAAM,OAAQ,GAAA,EAAkC,IAAA;AAChD,YAAA,MAAM,QAA2B,CAAC,SAAA,EAAW,WAAA,EAAa,SAAA,EAAW,YAAY,YAAY,CAAA;AAE7F,YAAA,OAAO,KAAK,MAAA,EAAQ,KAAA,CAAM,SAAS,IAAuB,CAAA,GAAK,OAA2B,YAAY,CAAA;AAAA,UACxG;AAAA,QACF;AAAA,QACA;AACE,UAAA,OAAO,IAAA,CAAK,QAAW,YAAY,CAAA;AAAA;AACvC,IACF,SAAS,GAAA,EAAK;AACZ,MAAA,OAAO,UAAU,GAAA,EAAK,MAAA,EAAQ,QAAQ,MAAA,KAAW,eAAA,GAAkB,SAAY,IAAI,CAAA;AAAA,IACrF;AAAA,EACF,CAAA;AACF","file":"fiscal-server.js","sourcesContent":["/**\n * Reads a tax document uploaded without JavaScript, on the server, with the same engine the browser uses. In memory\n * only: the bytes are never written to disk, never logged and are dropped when this returns.\n */\nimport type { IdentityDocumentSpec, Region } from '@asteby/storefront'\nimport { IdentityDocumentError, buildDocumentEvidence, catalogsFromRegion, extractIdentityDocument, readPdfText } from '@asteby/storefront/fiscal-document'\nimport { summarizeExtraction } from './extraction.js'\nimport type { FiscalExtractionSummary } from './types.js'\n\nexport type UploadLimits = { maxBytes: number; maxPages: number; timeoutMs: number }\n\n/** 5 MiB, 6 pages, 3 s: the same as the browser reader. */\nexport const UPLOAD_LIMITS: Readonly<UploadLimits> = Object.freeze({ maxBytes: 5 * 1024 * 1024, maxPages: 6, timeoutMs: 3000 })\n\nconst PDF_MAGIC = [0x25, 0x50, 0x44, 0x46, 0x2d] // %PDF-\n\nexport async function extractUploadedDocument(\n file: Blob,\n spec: IdentityDocumentSpec,\n region: Pick<Region, 'fiscal_id'>,\n options: { limits?: Partial<UploadLimits>; now?: Date } = {},\n): Promise<FiscalExtractionSummary> {\n const lim = { ...UPLOAD_LIMITS, ...options.limits }\n // The region can only lower the limits.\n const maxBytes = Math.min(lim.maxBytes, spec.max_bytes || lim.maxBytes)\n const maxPages = Math.min(lim.maxPages, spec.max_pages || lim.maxPages)\n if (file.size > maxBytes) throw new IdentityDocumentError('too_large', 'file over the size limit', { reason: 'bytes' })\n const bytes = new Uint8Array(await file.arrayBuffer())\n if (!PDF_MAGIC.every((b, i) => bytes[i] === b)) throw new IdentityDocumentError('not_pdf', 'not a PDF')\n // The engine is the only reader. QR cross-check needs a canvas, which a server does not have: `qr_match` stays null.\n const { text, sha256 } = await readPdfText(bytes, { maxBytes, maxPages, timeoutMs: lim.timeoutMs })\n const x = extractIdentityDocument(text, spec, {\n catalogs: region.fiscal_id ? catalogsFromRegion(region.fiscal_id) : {},\n ...(options.now ? { now: options.now } : {}),\n })\n return summarizeExtraction(x, buildDocumentEvidence(x, { sha256, source: 'pdf_server' }), region.fiscal_id?.regimes.map((r) => r.code))\n}\n","/**\n * Server side of the fiscal components (`@asteby/storefront-react/fiscal/server`): `loadFiscalContext` for the loader and\n * `createInvoiceAction` for the action. No React, no router: Web `Request`/`Response` only, so any framework mounts it.\n *\n * The browser never talks to OPS. The action uses the store's `sk_` client and the buyer's session token (read from the\n * store's cookie). A tax document uploaded WITHOUT JavaScript is read in memory here with the same engine the browser\n * uses, and discarded: no disk, no logs, no copy.\n */\nimport {\n isStorefrontError,\n repairPath,\n type FiscalDocumentEvidence,\n type FiscalIdentityInput,\n type InvoiceRequest,\n type InvoicingCapabilities,\n type Region,\n type StorefrontClient,\n} from '@asteby/storefront'\nimport { normalizeTaxId } from './format.js'\nimport { extractUploadedDocument, UPLOAD_LIMITS, type UploadLimits } from './server-extract.js'\nimport type { FiscalActionData, FiscalErrorCode, FiscalIntent, FiscalReason } from './types.js'\n\nexport type { FiscalActionData, FiscalErrorCode, FiscalIntent, FiscalReason } from './types.js'\nexport { UPLOAD_LIMITS, extractUploadedDocument } from './server-extract.js'\nexport type { UploadLimits } from './server-extract.js'\n\n// ---- context ---------------------------------------------------------------------------------------------------------\n\nexport type FiscalContext = {\n /** The store can invoice: it has a region with a fiscal catalog and `capabilities.invoicing.available`. */\n available: boolean\n /** Why `available` is what it is. Absent on contexts built by older code: read it as `unknown`. */\n reason?: FiscalReason\n region: Region | null\n invoicing: InvoicingCapabilities | null\n}\n\n/** What is assumed when the store cannot be asked: nothing is known (`unreachable`), nothing breaks. */\nexport const NO_FISCAL_CONTEXT: Readonly<FiscalContext> = Object.freeze({ available: false, reason: 'unreachable' as const, region: null, invoicing: null })\n\nconst FAILURE_TTL_MS = 5_000\nconst cache = new WeakMap<object, { at: number; ok: boolean; value: FiscalContext }>()\n\nexport type LoadFiscalContextOptions = {\n /** How long a good answer is reused per client (default 60 s). `0` disables the cache. */\n ttlMs?: number\n signal?: AbortSignal\n now?: () => number\n}\n\n/**\n * Asks the store for its region and what invoicing it offers, with a short cache per client. It NEVER throws: when OPS\n * does not answer (older server, outage, token without scope) it returns `NO_FISCAL_CONTEXT` and retries after a few\n * seconds, so a checkout without invoicing keeps working. `reason` says which of the cases it is. Use it as the loader:\n * `loader = () => loadFiscalContext(sf)`.\n */\nexport async function loadFiscalContext(sf: StorefrontClient, options: LoadFiscalContextOptions = {}): Promise<FiscalContext> {\n const now = options.now ?? Date.now\n const ttl = options.ttlMs ?? 60_000\n const hit = cache.get(sf)\n if (hit && now() - hit.at < (hit.ok ? ttl : FAILURE_TTL_MS)) return hit.value\n const opt = options.signal ? { signal: options.signal } : undefined\n const [region, caps] = await Promise.allSettled([sf.region(opt), sf.customer.capabilities(opt)])\n const reg = region.status === 'fulfilled' ? region.value : null\n const noRegion = region.status === 'rejected' && isStorefrontError(region.reason) && region.reason.status === 404\n const invoicing = caps.status === 'fulfilled' ? (caps.value?.invoicing ?? null) : null\n const ok = (region.status === 'fulfilled' || noRegion) && caps.status === 'fulfilled'\n const available = !!reg?.fiscal_id && !!invoicing?.available\n const reason: FiscalReason = available\n ? 'available'\n : !ok\n ? 'unreachable'\n : noRegion || !reg?.fiscal_id\n ? invoicing && !invoicing.available\n ? 'off'\n : 'no_region'\n : !invoicing\n ? 'unknown'\n : 'off'\n const value: FiscalContext = { available, reason, region: reg, invoicing: invoicing?.available ? invoicing : null }\n cache.set(sf, { at: now(), ok, value: ok || available ? value : NO_FISCAL_CONTEXT })\n return ok || available ? value : NO_FISCAL_CONTEXT\n}\n\n// ---- action ----------------------------------------------------------------------------------------------------------\n\n/** What the action needs of a cookie to read the buyer's session. React Router's `createCookie(...)` fits as it is. */\nexport type SessionCookie = { parse(header: string | null): unknown }\n\nexport type CreateInvoiceActionOptions = {\n storefront: StorefrontClient\n /** The store's cookie for the buyer session token (`createCookie('sf_customer', ...)`), to know who is asking. */\n customerCookie?: SessionCookie\n /** Alternative to `customerCookie`: returns the buyer's session token, or `null` for a guest. */\n readCustomerToken?: (request: Request) => string | null | undefined | Promise<string | null | undefined>\n /** Shopper IP for the per-shopper rate limit (see `clientIp` of the client). */\n clientIp?: (request: Request) => string | null | undefined\n /** Region + capabilities source, for tests or a shared cache (default `loadFiscalContext`). */\n context?: (sf: StorefrontClient) => Promise<FiscalContext>\n /** Limits of the no-JS upload (defaults: 5 MiB, 6 pages, 3 s). The region's own limits can only lower them. */\n limits?: Partial<UploadLimits>\n /** Clock, for the freshness check. */\n now?: () => Date\n /** Rejects cross-site posts (default `true`): `Origin` and `Sec-Fetch-Site` must match the site. */\n sameSiteOnly?: boolean\n /** Prefix of the form fields (default `invoice`). */\n namePrefix?: string\n}\n\nconst EVIDENCE_SOURCES = new Set(['pdf_client', 'pdf_server', 'qr', 'manual'])\n\n/** Reads the evidence the reader put in the form, keeping only the known keys (a form is untrusted input). */\nexport function parseEvidence(raw: unknown): FiscalDocumentEvidence | undefined {\n if (typeof raw !== 'string' || !raw || raw.length > 4096) return undefined\n let o: unknown\n try {\n o = JSON.parse(raw)\n } catch {\n return undefined\n }\n if (typeof o !== 'object' || o === null) return undefined\n const e = o as Record<string, unknown>\n if (typeof e.kind !== 'string' || !e.kind || typeof e.source !== 'string' || !EVIDENCE_SOURCES.has(e.source)) return undefined\n const str = (v: unknown, max: number) => (typeof v === 'string' && v.length <= max ? v : null)\n return {\n kind: e.kind.slice(0, 64),\n document_id: str(e.document_id, 64),\n issued_on: str(e.issued_on, 32),\n sha256: typeof e.sha256 === 'string' && /^[0-9a-f]{64}$/.test(e.sha256) ? e.sha256 : null,\n ...(typeof e.extractor === 'string' ? { extractor: e.extractor.slice(0, 64) } : {}),\n source: e.source as FiscalDocumentEvidence['source'],\n qr_match: typeof e.qr_match === 'boolean' ? e.qr_match : null,\n }\n}\n\n/** Reads the `invoice.*` fields of a form into the API's `InvoiceRequest`. */\nexport function invoiceFromForm(form: FormData, prefix = 'invoice'): InvoiceRequest {\n const text = (k: string) => {\n const v = form.get(`${prefix}.${k}`)\n return typeof v === 'string' ? v.trim() : ''\n }\n const evidence = parseEvidence(form.get(`${prefix}.document`))\n const out: InvoiceRequest = {\n requested: true,\n tax_id: normalizeTaxId(text('tax_id')),\n legal_name: text('legal_name'),\n tax_regime: text('tax_regime'),\n use: text('use'),\n postal_code: text('postal_code'),\n }\n if (evidence) out.document = evidence\n if (form.get(`${prefix}.save`)) out.save = true\n return out\n}\n\nconst fail = (intent: FiscalIntent | undefined, code: FiscalErrorCode, extra: Partial<FiscalActionData> = {}): FiscalActionData => ({\n ok: false,\n ...(intent ? { intent } : {}),\n ...extra,\n error: { code, ...(extra.error?.field ? { field: extra.error.field } : {}), ...(extra.error?.blocked ? { blocked: extra.error.blocked } : {}) },\n})\n\nconst LOG_EVERY_MS = 60_000\nlet lastLogAt = -Infinity\nfunction logMisconfigured(scopes: readonly string[]): void {\n const t = Date.now()\n if (t - lastLogAt < LOG_EVERY_MS) return\n lastLogAt = t\n console.error(\n `[@asteby/storefront-react] La credencial de la tienda no tiene permisos${scopes.length ? ` (${scopes.join(', ')})` : ''}; ` +\n `la facturación no funciona hasta repararlo en ${repairPath()}.`,\n )\n}\n\n/** `fiscal.tax_regime` (profile) and `invoice.tax_regime` (cart, order) both name the same form control. */\nconst formField = (field: string | undefined, prefix: string) => (field ? field.replace(/^(fiscal|invoice)\\./, `${prefix}.`) : undefined)\n\nfunction toFailure(err: unknown, intent: FiscalIntent, prefix: string, values?: Partial<FiscalActionData['values']>): FiscalActionData {\n const carry: Partial<FiscalActionData> = values ? { values } : {}\n if (!isStorefrontError(err)) return fail(intent, 'unavailable', carry)\n if (err.code === 'insufficient_scope') {\n logMisconfigured(err.requiredScopes)\n return fail(intent, 'store_misconfigured', carry)\n }\n const details = (err.details ?? {}) as { reason?: unknown; blocked_reason?: unknown }\n switch (err.status) {\n case 401:\n return fail(intent, 'unauthorized', carry)\n case 404:\n return fail(intent, 'not_found', carry)\n case 409: {\n const why = typeof details.reason === 'string' ? details.reason : typeof details.blocked_reason === 'string' ? details.blocked_reason : ''\n return fail(intent, why === 'already_checked_out' ? 'not_found' : 'blocked', { ...carry, ...(why ? { error: { code: 'blocked', blocked: why } } : {}) })\n }\n case 422:\n case 400: {\n const field = formField(err.field, prefix)\n return fail(intent, 'validation', {\n ...carry,\n ...(field ? { fieldErrors: { [field]: err.message || 'invalid' }, error: { code: 'validation', field } } : {}),\n })\n }\n case 429:\n return fail(intent, 'rate_limited', carry)\n case 403:\n return fail(intent, 'unsupported', carry)\n default:\n return fail(intent, 'unavailable', carry)\n }\n}\n\nfunction sameSite(request: Request): boolean {\n const site = request.headers.get('sec-fetch-site')\n if (site && site !== 'same-origin' && site !== 'same-site' && site !== 'none') return false\n const origin = request.headers.get('origin')\n if (!origin) return true\n try {\n const host = request.headers.get('x-forwarded-host') ?? request.headers.get('host') ?? new URL(request.url).host\n return new URL(origin).host === host.split(',')[0]!.trim()\n } catch {\n return false\n }\n}\n\n/**\n * The invoicing action: one `POST` form with an `intent` field.\n *\n * | intent | fields | does |\n * | ------------------ | --------------------------------------------------- | ---------------------------------------------------------- |\n * | `set-invoice` | cart_id, invoice.* (`invoice.want` unset withdraws) | `carts.setInvoice`: validates against the region BEFORE paying |\n * | `save-profile` | invoice.*, consent | `customer.update({ fiscal })`, needs a session and consent |\n * | `request-invoice` | order_id, invoice.* | `customer.requestInvoice` (invoice after the purchase) |\n * | `clear-profile` | - | `customer.update({ fiscal: null })` (the buyer's right to delete) |\n * | `extract-document` | document (file), document_kind? | reads the file in memory, discards it, `step: 'review'` |\n *\n * It never redirects: it returns a `FiscalActionData` for the page to render (`<InvoiceToggle data={...}>`), with 422s\n * mapped to the field (`fieldErrors['invoice.tax_regime']`). The tax id of the buyer is never logged.\n */\nexport function createInvoiceAction(options: CreateInvoiceActionOptions) {\n const { storefront: sf } = options\n const prefix = options.namePrefix ?? 'invoice'\n const loadContext = options.context ?? ((c: StorefrontClient) => loadFiscalContext(c))\n const limits: UploadLimits = { ...UPLOAD_LIMITS, ...options.limits }\n\n async function sessionToken(request: Request): Promise<string | null> {\n if (options.readCustomerToken) return (await options.readCustomerToken(request)) || null\n if (!options.customerCookie) return null\n const v = await options.customerCookie.parse(request.headers.get('cookie'))\n return typeof v === 'string' && v ? v : null\n }\n\n return async function invoiceAction({ request }: { request: Request }): Promise<FiscalActionData> {\n if (options.sameSiteOnly !== false && !sameSite(request)) return fail(undefined, 'unsupported')\n // A file bigger than the limit is refused before it is buffered.\n const declared = Number(request.headers.get('content-length') ?? 0)\n if (declared > limits.maxBytes + 256 * 1024) return fail('extract-document', 'too_large')\n const form = await request.formData().catch(() => null)\n if (!form) return fail(undefined, 'validation')\n const intent = form.get('intent') as FiscalIntent\n const ip = options.clientIp?.(request)\n const token = await sessionToken(request)\n const w = { ...(ip ? { clientIp: ip } : {}), ...(token ? { customerToken: token } : {}) }\n const invoice = invoiceFromForm(form, prefix)\n const echo = { tax_id: invoice.tax_id ?? '', legal_name: invoice.legal_name ?? '', postal_code: invoice.postal_code ?? '', tax_regime: invoice.tax_regime ?? '', use: invoice.use ?? '' }\n const text = (name: string) => {\n const v = form.get(name)\n return typeof v === 'string' ? v.trim() : ''\n }\n\n try {\n switch (intent) {\n case 'set-invoice': {\n const cartId = text('cart_id')\n if (!cartId) return fail(intent, 'validation')\n if (!form.get(`${prefix}.want`) && !form.get(`${prefix}.requested`)) {\n await sf.carts.setInvoice(cartId, null, w)\n return { ok: true, intent, step: 'cleared' }\n }\n await sf.carts.setInvoice(cartId, invoice, w)\n return { ok: true, intent, step: 'saved', values: echo }\n }\n case 'save-profile': {\n if (!token) return fail(intent, 'unauthorized', { values: echo })\n if (!form.get('consent')) return fail(intent, 'consent_required', { values: echo })\n const fiscal: FiscalIdentityInput = {\n tax_id: invoice.tax_id ?? '',\n legal_name: invoice.legal_name ?? '',\n tax_regime: invoice.tax_regime ?? '',\n postal_code: invoice.postal_code ?? '',\n invoice_use: invoice.use ?? '',\n ...(invoice.document ? { document: invoice.document } : {}),\n }\n await sf.customer.update({ fiscal }, w)\n return { ok: true, intent, step: 'saved', values: echo }\n }\n case 'clear-profile': {\n if (!token) return fail(intent, 'unauthorized')\n await sf.customer.update({ fiscal: null }, w)\n return { ok: true, intent, step: 'cleared' }\n }\n case 'request-invoice': {\n if (!token) return fail(intent, 'unauthorized', { values: echo })\n const orderId = text('order_id')\n if (!orderId) return fail(intent, 'validation')\n const result = await sf.customer.requestInvoice(orderId, invoice, w)\n return { ok: true, intent, step: result.status === 'issued' ? 'issued' : 'pending', result, ...(result.invoice ? { invoice: result.invoice } : {}) }\n }\n case 'extract-document': {\n const ctx = await loadContext(sf)\n const region = ctx.region\n const kind = text('document_kind')\n const specs = region?.fiscal_id?.documents ?? []\n const spec = (kind ? specs.find((d) => d.kind === kind) : specs[0]) ?? undefined\n if (!ctx.available || !region || !spec) return fail(intent, 'unsupported')\n const file = form.get('document')\n if (!file || typeof file === 'string' || file.size === 0) return fail(intent, 'not_pdf')\n try {\n const extraction = await extractUploadedDocument(file, spec, region, { limits, ...(options.now ? { now: options.now() } : {}) })\n return { ok: true, intent, step: 'review', extraction }\n } catch (err) {\n const code = (err as { code?: string } | null)?.code\n const known: FiscalErrorCode[] = ['not_pdf', 'too_large', 'no_text', 'password', 'unreadable']\n // Never log the error: it can carry text from the document.\n return fail(intent, known.includes(code as FiscalErrorCode) ? (code as FiscalErrorCode) : 'unreadable')\n }\n }\n default:\n return fail(undefined, 'validation')\n }\n } catch (err) {\n return toFailure(err, intent, prefix, intent === 'clear-profile' ? undefined : echo)\n }\n }\n}\n\nexport type InvoiceAction = ReturnType<typeof createInvoiceAction>\n"]}
package/dist/fiscal.cjs CHANGED
@@ -339,7 +339,14 @@ var ES2 = {
339
339
  windowTitle: "Ya pas\xF3 el plazo para facturar",
340
340
  windowBody: "Este pedido est\xE1 fuera del plazo para pedir factura. Si necesitas ayuda, contacta a la tienda.",
341
341
  unavailableTitle: "Factura no disponible",
342
- unavailableBody: "Esta tienda no emite factura de este pedido. Si la necesitas, cont\xE1ctala.",
342
+ unavailableBody: "Este pedido no se puede facturar por ahora. Si la necesitas, contacta a la tienda.",
343
+ notEnabledTitle: "Facturaci\xF3n a\xFAn no activa",
344
+ notEnabledBody: "La tienda todav\xEDa no tiene la facturaci\xF3n en l\xEDnea activa. Si necesitas factura, cont\xE1ctala.",
345
+ unknownTitle: "Factura",
346
+ unknownBody: "Por ahora no podemos mostrar el estado de la facturaci\xF3n de este pedido. Si necesitas factura, contacta a la tienda.",
347
+ unreachableBody: "No pudimos verificar la facturaci\xF3n en este momento. Int\xE9ntalo de nuevo en unos minutos o contacta a la tienda.",
348
+ sandbox: "Facturaci\xF3n en pruebas (sandbox): las facturas no tienen validez fiscal.",
349
+ windowNote: "Puedes pedirla hasta {days} d\xEDas despu\xE9s de la compra.",
343
350
  cancelledTitle: "Factura cancelada",
344
351
  cancelledBody: "Esta factura fue cancelada. Si necesitas una nueva, contacta a la tienda.",
345
352
  reasons: {
@@ -479,7 +486,14 @@ var EN2 = {
479
486
  windowTitle: "The invoicing period has ended",
480
487
  windowBody: "This order is outside the period to request an invoice. If you need help, contact the store.",
481
488
  unavailableTitle: "Invoice not available",
482
- unavailableBody: "This store does not issue an invoice for this order. If you need one, contact them.",
489
+ unavailableBody: "This order cannot be invoiced right now. If you need one, contact the store.",
490
+ notEnabledTitle: "Invoicing not active yet",
491
+ notEnabledBody: "The store has not turned on online invoicing yet. If you need an invoice, contact them.",
492
+ unknownTitle: "Invoice",
493
+ unknownBody: "We cannot show the invoicing status of this order right now. If you need an invoice, contact the store.",
494
+ unreachableBody: "We could not check invoicing right now. Try again in a few minutes or contact the store.",
495
+ sandbox: "Invoicing in test mode (sandbox): invoices have no fiscal validity.",
496
+ windowNote: "You can request it up to {days} days after the purchase.",
483
497
  cancelledTitle: "Invoice cancelled",
484
498
  cancelledBody: "This invoice was cancelled. If you need a new one, contact the store.",
485
499
  reasons: {
@@ -1582,8 +1596,7 @@ function labelOf(list, code, locale) {
1582
1596
  const e = list?.find((x) => x.code === code);
1583
1597
  return e ? `${e.code} \xB7 ${entryLabel(e, locale)}` : code;
1584
1598
  }
1585
- function invoiceCardState(invoice, available = true) {
1586
- if (!available) return "unavailable";
1599
+ function orderState(invoice) {
1587
1600
  if (!invoice) return "not_requested";
1588
1601
  const stage = invoice.stage ?? "";
1589
1602
  const blocked = invoice.blocked_reason ?? "";
@@ -1598,11 +1611,18 @@ function invoiceCardState(invoice, available = true) {
1598
1611
  if (invoice.can_request === false && blocked) return "unavailable";
1599
1612
  return "not_requested";
1600
1613
  }
1614
+ function invoiceCardState(invoice, available = true, reason) {
1615
+ if (available) return orderState(invoice);
1616
+ if (reason === "off" || reason === "no_region") return "not_enabled";
1617
+ const own = orderState(invoice);
1618
+ if (invoice && (own !== "not_requested" || invoice.can_request === true || invoice.action === "request")) return own;
1619
+ return reason === "unreachable" ? "unreachable" : "unknown";
1620
+ }
1601
1621
  function InvoiceStatusCard(props) {
1602
- const { invoice, available = true, onRequest, requestHref, onCorrect, correctHref, onRefresh, refreshMs = 1e4, refreshForMs = 6e4, contact, messages, classNames: cx = {}, headingLevel = 3 } = props;
1622
+ const { invoice, available = true, availability, testMode, windowDays, onRequest, requestHref, onCorrect, correctHref, onRefresh, refreshMs = 1e4, refreshForMs = 6e4, contact, messages, classNames: cx = {}, headingLevel = 3 } = props;
1603
1623
  const locale = useResolvedLocale(props.locale);
1604
1624
  const m = fiscalMessages(locale, messages).status;
1605
- const state = invoiceCardState(invoice, available);
1625
+ const state = invoiceCardState(invoice, available, availability);
1606
1626
  const titleId = `sf-invoice-card-${react.useId().replace(/:/g, "")}`;
1607
1627
  const [tired, setTired] = react.useState(false);
1608
1628
  const refresh = react.useRef(onRefresh);
@@ -1635,7 +1655,10 @@ function InvoiceStatusCard(props) {
1635
1655
  switch (state) {
1636
1656
  case "not_requested": {
1637
1657
  title = m.title;
1638
- body = /* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.body, children: m.requestHelp });
1658
+ body = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1659
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.body, children: m.requestHelp }),
1660
+ windowDays && windowDays > 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.meta, "data-sf-invoice-window": true, children: fill(m.windowNote, { days: windowDays }) }) : null
1661
+ ] });
1639
1662
  const can = invoice?.can_request !== false;
1640
1663
  if (can && (onRequest || requestHref)) {
1641
1664
  actions = onRequest ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: cx.primary, onClick: onRequest, "data-sf-invoice-request": true, children: m.request }) : /* @__PURE__ */ jsxRuntime.jsx("a", { href: requestHref, className: cx.primary, "data-sf-invoice-request": true, children: m.request });
@@ -1693,6 +1716,18 @@ function InvoiceStatusCard(props) {
1693
1716
  title = m.cancelledTitle;
1694
1717
  body = /* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.body, children: m.cancelledBody });
1695
1718
  break;
1719
+ case "not_enabled":
1720
+ case "unknown":
1721
+ case "unreachable": {
1722
+ title = state === "not_enabled" ? m.notEnabledTitle : m.unknownTitle;
1723
+ body = /* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.body, children: state === "not_enabled" ? m.notEnabledBody : state === "unreachable" ? m.unreachableBody : m.unknownBody });
1724
+ const mail = contact?.url ?? (contact?.email ? `mailto:${contact.email}` : null);
1725
+ actions = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1726
+ state === "unreachable" && onRefresh ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: cx.secondary, onClick: manualRefresh, "data-sf-invoice-refresh": true, children: m.refresh }) : null,
1727
+ mail ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: mail, className: cx.secondary, "data-sf-invoice-contact": true, children: m.contact }) : null
1728
+ ] });
1729
+ break;
1730
+ }
1696
1731
  default:
1697
1732
  title = m.unavailableTitle;
1698
1733
  body = /* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.body, children: m.unavailableBody });
@@ -1704,6 +1739,7 @@ function InvoiceStatusCard(props) {
1704
1739
  title
1705
1740
  ] }),
1706
1741
  /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-live": live || state === "issued" ? "polite" : void 0, "data-sf-invoice-live": true, children: body }),
1742
+ testMode ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.meta, "data-sf-invoice-sandbox": true, children: m.sandbox }) : null,
1707
1743
  actions ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx.actions, "data-sf-invoice-actions": true, children: actions }) : null
1708
1744
  ] });
1709
1745
  }
@@ -1716,6 +1752,9 @@ var ICON = {
1716
1752
  needs_review: "\u25D0",
1717
1753
  window_closed: "\u2013",
1718
1754
  unavailable: "\u2013",
1755
+ not_enabled: "\u2013",
1756
+ unknown: "?",
1757
+ unreachable: "?",
1719
1758
  cancelled: "\xD7"
1720
1759
  };
1721
1760