@12-apps/payments-frontend 3.39.0 → 3.41.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@12-apps/payments-frontend",
3
- "version": "3.39.0",
3
+ "version": "3.41.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "Browser half of the vendor-agnostic payments platform: plug-and-play MUI components for the per-provider settings page (credential form from each provider's schema, masked hints, verify/enable) and the checkout page (PIX QR + polling, card tokenization, hosted-checkout redirect), plus the headless hooks and fetch clients they build on. Talks only to the host's payments HTTP surface — never to a provider directly. Microfrontend-ready: no app coupling, host injects theme and auth.",
@@ -23,7 +23,7 @@
23
23
  "storybook:build": "storybook build"
24
24
  },
25
25
  "dependencies": {
26
- "@12-apps/payments-backend": "^4.30.0",
26
+ "@12-apps/payments-backend": "^4.31.0",
27
27
  "react-qr-code": "^2.2.0"
28
28
  },
29
29
  "peerDependencies": {
@@ -53,7 +53,10 @@ import { clearReturnedSettlement, takeReturnedSettlement } from './returned-sett
53
53
  * things that clear it are settlement and an explicit "give up".
54
54
  */
55
55
 
56
- /** How often to ask the provider whether the payment landed. */
56
+ /**
57
+ * How often to ask the provider whether the payment landed — the recorded
58
+ * third-party-wait exception, see {@link usePollTimer}.
59
+ */
57
60
  const DEFAULT_POLL_MS = 4000;
58
61
 
59
62
  /** Give up asking after this long, rather than polling a tab forever. */
@@ -126,6 +129,24 @@ interface ActivationCallbacks {
126
129
  /**
127
130
  * Ask the provider every few seconds, and stop asking eventually.
128
131
  *
132
+ * ## A deliberate poll: the recorded exception to "hear, do not poll" (FUT-2433)
133
+ *
134
+ * Every other wait in this package hears the host's channel and keeps no timer
135
+ * while it is live. This one cannot, and it is the one exception class the
136
+ * origin host records: a timer-driven read of a THIRD PARTY's state that no
137
+ * webhook or publisher of the host's reaches yet, bounded in time, and named.
138
+ * Each tick is not a read of the host's own rows — `verify-charge` asks the
139
+ * PROVIDER whether the activation charge was paid, and while nobody has asked,
140
+ * nothing server-side has moved that a hint could carry. The activation webhook
141
+ * that would settle it is not guaranteed to arrive (a tunnel, a preview box), so
142
+ * the wait is the confirmation. It runs only while the owner is paying on the
143
+ * provider's page and gives up at `pollTimeoutMs` (ten minutes by default).
144
+ *
145
+ * Where it is recorded: the origin host's realtime doc ("Allowed exceptions")
146
+ * and the decision record that superseded its 0071 with it. If activation
147
+ * ever becomes webhook-only, this relaxes to the channel exactly as the
148
+ * checkout's waits did (FUT-649) and the exception goes away.
149
+ *
129
150
  * The give-up is a `failed` state carrying the host's own sentence, because the
130
151
  * wording is load-bearing: the charge is STILL valid, and an owner who has
131
152
  * genuinely paid must not be told they did not pay in time.
@@ -21,6 +21,7 @@ import {
21
21
  type ProviderChangeHandler,
22
22
  } from './settings-state';
23
23
  import { openSection, SetupGuideSection } from './SetupGuideSection';
24
+ import { useSettingsLive, type PaymentsSettingsLiveSignal } from './settings-live';
24
25
  import type { PaymentsSettingsCopy } from './settings-copy';
25
26
  import { PaymentsSettingsCopyProvider } from './settings-copy-context';
26
27
 
@@ -102,6 +103,16 @@ export interface PaymentProviderSettingsProps {
102
103
  * its history ({@link ProviderChangeHandler}).
103
104
  */
104
105
  onProviderChange?: ProviderChangeHandler;
106
+ /**
107
+ * The host's realtime channel for this store's payment settings (FUT-648).
108
+ *
109
+ * A hint re-reads the view, and so does every (re)connect: an OAuth grant
110
+ * completed in another tab, a colleague's save, a webhook settling the
111
+ * activation charge all reach this screen without a reload. Omit it and the
112
+ * screen reads on mount and after its own actions, exactly as before — it
113
+ * keeps no timer either way. See {@link PaymentsSettingsLiveSignal}.
114
+ */
115
+ live?: PaymentsSettingsLiveSignal;
105
116
  /**
106
117
  * The activation step, rendered under the connection card.
107
118
  *
@@ -299,8 +310,10 @@ export function PaymentProviderSettings({
299
310
  selectedProvider,
300
311
  onProviderChange,
301
312
  renderVerification,
313
+ live,
302
314
  }: PaymentProviderSettingsProps) {
303
315
  const { view, error, reload } = useSettingsState(client);
316
+ useSettingsLive(live, () => void reload());
304
317
  const { selected, setSelected } = useSelectedProvider(
305
318
  initialProvider,
306
319
  selectedProvider,
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Opening the buyer's bank app from the Pix face (FUT-3612).
3
+ *
4
+ * There is no standard Pix link that pays a copia-e-cola code, so this only
5
+ * OPENS the app; the buyer pastes the code the button already copied. Android
6
+ * opens an app through an `intent:` URL naming its package; iOS only through a
7
+ * URL scheme the bank's app registers. Neither tells the page whether it
8
+ * worked, so {@link openBankApp} watches the page: an app that opened takes
9
+ * the screen within a moment, and a page still visible after
10
+ * {@link OPEN_WAIT_MS} is a bank that did not open — not installed, or a link
11
+ * this phone does not know.
12
+ */
13
+ import type { PixBankId } from "./types";
14
+
15
+ /** How long a page may stay visible before the bank counts as not opened. */
16
+ const OPEN_WAIT_MS = 1500;
17
+
18
+ interface BankApp {
19
+ /** The Play Store package of the bank's personal app — each one checked on its Play listing (2026-10-16). */
20
+ android: string;
21
+ /**
22
+ * The URL scheme its app answers on iOS (without "://"). Only Nubank's
23
+ * (`nuapp`) is documented — in Nubank's own deep links. The other five
24
+ * publish no scheme we could find: theirs are the likeliest name, and a
25
+ * phone that does not know one is a bank that "did not open", which the face
26
+ * says (owner, 2026-10-16: Android and iOS, and say so when it does not open).
27
+ */
28
+ ios: string;
29
+ /** A scheme Android opens the app with, when one is known; else the app's launcher, by package. */
30
+ scheme?: string;
31
+ }
32
+
33
+ /** The six, in the prototype's order. */
34
+ export const PIX_BANKS: readonly PixBankId[] = ["nubank", "itau", "bradesco", "bb", "caixa", "santander"];
35
+
36
+ const APPS: Record<PixBankId, BankApp> = {
37
+ nubank: { android: "com.nu.production", ios: "nuapp", scheme: "nuapp" },
38
+ itau: { android: "com.itau", ios: "itau" },
39
+ bradesco: { android: "com.bradesco", ios: "bradesco" },
40
+ bb: { android: "br.com.bb.android", ios: "bbapp" },
41
+ caixa: { android: "br.gov.caixa.CAIXA", ios: "caixa" },
42
+ santander: { android: "com.santander.app", ios: "santanderpf" },
43
+ };
44
+
45
+ export type PhoneOs = "android" | "ios";
46
+
47
+ /** The phone this page runs on, or `null` for a computer (or no browser at all). */
48
+ export function phoneOs(nav: Pick<Navigator, "userAgent" | "maxTouchPoints"> | undefined = typeof navigator === "undefined" ? undefined : navigator): PhoneOs | null {
49
+ if (!nav) return null;
50
+ const ua = nav.userAgent;
51
+ if (/Android/i.test(ua)) return "android";
52
+ if (/iPhone|iPad|iPod/i.test(ua)) return "ios";
53
+ // iPadOS asks for the desktop site: a "Macintosh" with a touch screen.
54
+ if (/Macintosh/i.test(ua) && nav.maxTouchPoints > 1) return "ios";
55
+ return null;
56
+ }
57
+
58
+ /**
59
+ * The phone the host's bank flow runs on: its own word when it gave one
60
+ * (`phone`), else the browser's. `null` ⇒ a computer: no banks.
61
+ */
62
+ export function bankFlowOs(phone: boolean | undefined): PhoneOs | null {
63
+ if (phone === false) return null;
64
+ if (phone === true) return phoneOs() ?? "android";
65
+ return phoneOs();
66
+ }
67
+
68
+ /**
69
+ * The URL that opens `bank`'s app on `os`. Android: an `intent:` URL naming the
70
+ * package — through the app's scheme when one is known, else its launcher; a
71
+ * phone without the app gets the bank's Play Store page from the browser.
72
+ */
73
+ export function bankAppUrl(bank: PixBankId, os: PhoneOs): string {
74
+ const app = APPS[bank];
75
+ if (os === "ios") return `${app.ios}://`;
76
+ if (app.scheme) return `intent://#Intent;scheme=${app.scheme};package=${app.android};end`;
77
+ return `intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;package=${app.android};end`;
78
+ }
79
+
80
+ /**
81
+ * Open `bank`'s app, and say whether it opened: `true` when the page lost the
82
+ * screen (hidden, or left) within {@link OPEN_WAIT_MS}.
83
+ */
84
+ export function openBankApp(
85
+ bank: PixBankId,
86
+ os: PhoneOs,
87
+ env: { win: Window; doc: Document; waitMs?: number } = { win: window, doc: document },
88
+ ): Promise<boolean> {
89
+ const { win, doc } = env;
90
+ return new Promise((resolve) => {
91
+ let left = false;
92
+ const onVisibility = (): void => {
93
+ if (doc.visibilityState === "hidden") left = true;
94
+ };
95
+ const onLeave = (): void => {
96
+ left = true;
97
+ };
98
+ doc.addEventListener("visibilitychange", onVisibility);
99
+ win.addEventListener("pagehide", onLeave);
100
+ win.addEventListener("blur", onLeave);
101
+ win.setTimeout(() => {
102
+ doc.removeEventListener("visibilitychange", onVisibility);
103
+ win.removeEventListener("pagehide", onLeave);
104
+ win.removeEventListener("blur", onLeave);
105
+ resolve(left);
106
+ }, env.waitMs ?? OPEN_WAIT_MS);
107
+ try {
108
+ win.location.href = bankAppUrl(bank, os);
109
+ } catch {
110
+ // A scheme the browser refuses outright is a bank that did not open.
111
+ }
112
+ });
113
+ }
@@ -0,0 +1,26 @@
1
+ import type { PixBankCopy } from "./types";
2
+
3
+ /** The Pix-to-bank flow's words, en-US (FUT-3612). */
4
+ export const EN_US_PIX_BANK_COPY: PixBankCopy = {
5
+ names: {
6
+ nubank: { name: "Nubank", the: "" },
7
+ itau: { name: "Itaú", the: "" },
8
+ bradesco: { name: "Bradesco", the: "" },
9
+ bb: { name: "Banco do Brasil", the: "" },
10
+ caixa: { name: "Caixa", the: "" },
11
+ santander: { name: "Santander", the: "" },
12
+ },
13
+ generateAndCopy: "Create and copy the Pix",
14
+ generateCopyAndOpen: (bank) => `Create, copy and open ${bank.name}`,
15
+ copyAndOpen: (bank) => `Copy and open ${bank.name}`,
16
+ openOther: "Open another bank",
17
+ listTitle: "Open your bank and paste in Pix copia e cola",
18
+ open: (bank) => `Open ${bank.name}`,
19
+ opening: (bank) => `Opening **${bank.name}**…`,
20
+ other: "Another bank",
21
+ notOpened: (bank) => `We couldn't open ${bank.name}. Is the app installed on this phone?`,
22
+ retry: "Try again",
23
+ copied: "Pix code copied",
24
+ copiedPick: "Pix code copied. Choose your bank.",
25
+ copiedOpening: (bank) => `Pix code copied. Opening ${bank.name}…`,
26
+ };
@@ -0,0 +1,35 @@
1
+ import { Box } from "@mui/material";
2
+ import type { JSX } from "react";
3
+
4
+ import type { PixBankId } from "./types";
5
+
6
+ /**
7
+ * The six banks' own marks (FUT-3612, owner 2026-10-15: "coloca as logos dos
8
+ * bancos"), drawn at 32px beside each name so a buyer finds their bank by its
9
+ * mark. Inline as data URIs — no remote asset (ADR 0074's sibling rule, §5.1
10
+ * item 5) — and only to identify the bank. Sources: Nubank and Itaú from
11
+ * Wikimedia Commons (PD-textlogo, trademarked); Bradesco, Banco do Brasil,
12
+ * Caixa and Santander from the Bancos-em-SVG collection (the banks' symbols).
13
+ * Each is the bank's trademark.
14
+ */
15
+ const LOGOS: Record<PixBankId, string> = {
16
+ nubank: "data:image/svg+xml;base64,PHN2ZyB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIiB2aWV3Qm94PSIwIDAgMjYzLjg0MjA3IDE0NS41NjczNyIgdmVyc2lvbj0iMS4xIiBpZD0ic3ZnNiIgc29kaXBvZGk6ZG9jbmFtZT0iTnViYW5rIGxvZ28gMjAyMS5zdmciIHdpZHRoPSIyNjMuODQyMDciIGhlaWdodD0iMTQ1LjU2NzM3IiBpbmtzY2FwZTpleHBvcnQtZmlsZW5hbWU9IkM6XFVzZXJzXGFsZXhcc2l0ZXNcbnViYW5rLWxvZ28tMC5wbmciIGlua3NjYXBlOmV4cG9ydC14ZHBpPSI1NjEuNzM3MTIiIGlua3NjYXBlOmV4cG9ydC15ZHBpPSI1NjEuNzM3MTIiIGlua3NjYXBlOnZlcnNpb249IjEuMC4yIChlODZjODcwODc5LCAyMDIxLTAxLTE1LCBjdXN0b20pIj4gPG1ldGFkYXRhIGlkPSJtZXRhZGF0YTEyIj4gPHJkZjpSREY+IDxjYzpXb3JrIHJkZjphYm91dD0iIj4gPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+IDxkYzp0eXBlIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+IDxkYzp0aXRsZT48L2RjOnRpdGxlPiA8L2NjOldvcms+IDwvcmRmOlJERj4gPC9tZXRhZGF0YT4gPGRlZnMgaWQ9ImRlZnMxMCIgLz4gPHNvZGlwb2RpOm5hbWVkdmlldyBwYWdlY29sb3I9IiNmZmZmZmYiIGJvcmRlcmNvbG9yPSIjNjY2NjY2IiBib3JkZXJvcGFjaXR5PSIxIiBvYmplY3R0b2xlcmFuY2U9IjEwIiBncmlkdG9sZXJhbmNlPSIxMCIgZ3VpZGV0b2xlcmFuY2U9IjEwIiBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMCIgaW5rc2NhcGU6cGFnZXNoYWRvdz0iMiIgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxMzY2IiBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSI3MDUiIGlkPSJuYW1lZHZpZXc4IiBzaG93Z3JpZD0iZmFsc2UiIGlua3NjYXBlOnpvb209IjAuMjE0NTk3NTkiIGlua3NjYXBlOmN4PSIyMDguODkzNiIgaW5rc2NhcGU6Y3k9IjEyOC41MTMxNSIgaW5rc2NhcGU6d2luZG93LXg9Ii04IiBpbmtzY2FwZTp3aW5kb3cteT0iLTgiIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9InN2ZzYiIGlua3NjYXBlOmRvY3VtZW50LXJvdGF0aW9uPSIwIiBmaXQtbWFyZ2luLXRvcD0iMCIgZml0LW1hcmdpbi1sZWZ0PSIwIiBmaXQtbWFyZ2luLXJpZ2h0PSIwIiBmaXQtbWFyZ2luLWJvdHRvbT0iMCIgLz4gPHBhdGggZD0iTSA0Ny42Mjc1OTgsMTMuODg1NjUgQyA1NS45NzA5MTgsNS4xMjAyMiA2Ny4wMzgxODgsMCA4MC4wNDAxNTgsMCBjIDI1LjMyOTMwMiwwIDQyLjEyMjg2MiwxOC40OTM2MSA0NS4zMzU4MTIsNDYuMTk4MzEgMS4wNDE3Myw4Ljk5NzAyIDEuMDMyMTcsMjEuNjgxNDYgMS4wMjE3MiwzNi4zNzMzOCAtMC4wMDIsMS41MDY2MiAtMC4wMDIsMy4wMzQ2NCAtMC4wMDIsNC41ODE3NSB2IDU1LjAzODM5IEggOTEuNTYzMDY4IHYgLTQwLjcwODEyIGMgMCwwIC0wLjA3MSwtMzQuODQwMzYgLTAuMjgzODYsLTQxLjM1MTggLTAuOTM0ODIsLTI4LjM1OTQ1IC0xNy43MjM4MywtNDYuMTc5MTEgLTQzLjY1NDk3LC00Ni4xOTgyNiAtNy44MjM2LDguMjY1NzcgLTEyLjAxNTU5LDE4LjM3MjEgLTEyLjYzMzgxLDMzLjgyNDk4IC0wLjA4NSwyLjE1NTMxIC0wLjA2MzYsOS43OTQ5MSAtMC4wMzU0LDE5Ljg2MzY3IDAuMDE0Niw1LjIxNjggMC4wMzEsMTEuMDg1OTIgMC4wMzU0LDE3LjE4MjA0IDAuMDI1OCwyNi41MzM4OCAwLDU3LjM5MzQxIDAsNTcuMzkzNDEgSCAwLjE1NzcwMTQ1IFYgNzkuNTQ4NDIgYyAwLC0yLjE0NjY4IC0wLjAzOTE1LC00LjMxMTU1IC0wLjA3ODM5LC02LjQ4NTA2IC0wLjA3ODk5OTk5NzEsLTQuMzcyMDUgLTAuMTU4NjI2LC04Ljc3Nzc1IDAuMDc4MzksLTEzLjE0MDI1IEMgMC41NTEyNTI0NSw1Mi42NTA2MiAxLjgwOTMyMjUsNDUuNTAxNCA1LjIwMjg2ODUsMzguODU5OTUgMTIuOTcwNjU4LDIzLjY0NDgxIDI4Ljg4Njg4OCwxMy44NDgzNSA0NS44NTQ4NDgsMTMuODQ4MzUgYyAwLjU5Mjc0LDAgMS4xODU5MywwLjAxMzcgMS43NzI3NSwwLjAzNjQgeiIgY2xhc3M9IlBhdGgteHJ0a3BkLTAgZXFmWWlSIiBpZD0icGF0aDIiIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIHN0eWxlPSJmaWxsOiM4MjBhZDE7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlLXdpZHRoOjQuNTQ5IiBpbmtzY2FwZTpleHBvcnQtZmlsZW5hbWU9IkM6XFVzZXJzXGFsZXhcc2l0ZXNcbnViYW5rLWxvZ28tNS5wbmciIGlua3NjYXBlOmV4cG9ydC14ZHBpPSIxMzIuNzY1MzgiIGlua3NjYXBlOmV4cG9ydC15ZHBpPSIxMzIuNzY1MzgiIC8+IDxwYXRoIGQ9Im0gMjYzLjY4NDMzLDg1LjY0NDk5IGMgMC4yMzcsLTQuMzYyNDkgMC4xNTczOSwtOC43Njg2NiAwLjA3ODcsLTEzLjE0MDI1IC0wLjAzOTYsLTIuMTczNTEgLTAuMDc4NywtNC4zMzgzOCAtMC4wNzg3LC02LjQ4NTA1IFYgMy4zNzAyMiBoIC0zNC44MzIxOCBjIDAsMCAtMC4wMjYsMzAuODU5NTMgMCw1Ny4zOTMwOSAwLjAwNCw2LjA5NjEyIDAuMDIwNSwxMS45NjQ3OSAwLjAzNSwxNy4xODE1OSAwLjAyODIsMTAuMDY5MjEgMC4wNDk2LDE3LjcwODgxIC0wLjAzNSwxOS44NjQxMyAtMC42MTgyMSwxNS40NTM0MiAtNC44MTA1NiwyNS41NTk0OCAtMTIuNjMzOTQsMzMuODI1NDggLTI1LjkzMDY5LC0wLjAxODIgLTQyLjcxOTIzLC0xNy44MzkzOCAtNDMuNjU0NTEsLTQ2LjE5ODMyIC0wLjIxMjksLTYuNTExNDQgLTAuMzAyOTcsLTIyLjY2OTk1IC0wLjMwMjk3LC00MS4zODQ1MSBWIDMuMzQzNjEgbCAtMzQuODA2NjksMC4wMzE4IHYgNTUuMDM4NTIgYyAwLDEuNTQ3MTIgLTAuMDAyLDMuMDc0NjggLTAuMDAyLDQuNTgxNzYgLTAuMDExLDE0LjY5MTkxIC0wLjAyLDI3LjM3NTkgMS4wMjE3LDM2LjM3MzM4IDMuMjA2MTUsMjcuNzA0NzkgMTkuOTk5Nyw0Ni4xOTgzIDQ1LjMyOSw0Ni4xOTgzIDEzLjAwMjQyLDAgMjQuMDY5NjksLTUuMTIwMzUgMzIuNDEzMDEsLTEzLjg4NTgyIDAuNTg2MzcsMC4wMjI3IDEuMTc5MTEsMC4wMzY0IDEuNzcxODQsMC4wMzY0IDE2Ljk2Nzc4LDAgMzIuODg0MjksLTkuNzk2MjggNDAuNjUyMTcsLTI1LjAxMTMzIDMuMzkzNTUsLTYuNjQyIDQuNjUxMzUsLTEzLjc5MDc2IDUuMDQ0ODQsLTIxLjA2MzI1IHoiIGNsYXNzPSJQYXRoLXhydGtwZC0wIGVxZllpUiIgaWQ9InBhdGg0IiBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiBzdHlsZT0iZmlsbDojODIwYWQxO2ZpbGwtb3BhY2l0eToxO3N0cm9rZS13aWR0aDo0LjU0OSIgaW5rc2NhcGU6ZXhwb3J0LWZpbGVuYW1lPSJDOlxVc2Vyc1xhbGV4XHNpdGVzXG51YmFuay1sb2dvLTUucG5nIiBpbmtzY2FwZTpleHBvcnQteGRwaT0iMTMyLjc2NTM4IiBpbmtzY2FwZTpleHBvcnQteWRwaT0iMTMyLjc2NTM4IiAvPiA8cGF0aCBkPSJtIDExOC41ODczMSw3OTQuNjAwOTMgYyAxNC4xNTg0NiwtMTQuOTQ0NjQgMzIuOTM5NDIsLTIzLjY3NDM1IDU1LjAwMzc4LC0yMy42NzQzNSA0Mi45ODMzMSwwIDcxLjQ4MTY1LDMxLjUzMDY1IDc2LjkzNDAxLDc4Ljc2NTY1IDEuNzY3NzcsMTUuMzM5NSAxLjc1MTYsMzYuOTY1OCAxLjczMzg5LDYyLjAxNDcgMCwyLjU2ODggMCw1LjE3MzkgMCw3LjgxMTcgdiA5My44Mzc0NyBoIC01OS4xMTA0NCB2IC02OS40MDUxNyBjIDAsMCAtMC4xMjA1NSwtNTkuNDAwOSAtMC40ODE4NiwtNzAuNTAyNiAtMS41ODYxOCwtNDguMzUxNCAtMzAuMDc2NzgsLTc4LjczMyAtNzQuMDgxNjksLTc4Ljc2NTYgLTEzLjI3NjQyLDE0LjA5MjcgLTIwLjM5MDM3MiwzMS4zMjM0IC0yMS40Mzk0MDIsNTcuNjY5OCAtMC4xNDQxMiwzLjY3NDcgLTAuMTA3OTEsMTYuNjk5OCAtMC4wNjA2LDMzLjg2NjUgMC4wMjQ4LDguODk0NCAwLjA1MzMsMTguOTAwOSAwLjA2MDYsMjkuMjk0NSAwLjA0NSw0NS4yMzg5IDAsOTcuODUyNjcgMCw5Ny44NTI2NyBIIDM4LjAzNTA2OCBWIDkwNi41NTI0MyBjIDAsLTMuNjU5OSAtMC4wNjcsLTcuMzUwOSAtMC4xMzMsLTExLjA1NjcgLTAuMTMzOTMsLTcuNDU0MSAtMC4yNjkwMywtMTQuOTY1NiAwLjEzMywtMjIuNDAzNCAwLjY2ODAzLC0xMi4zOTkyIDIuODAyOTMsLTI0LjU4ODMgOC41NjE4LC0zNS45MTE1IDEzLjE4MTYzLC0yNS45NDExIDQwLjE5MTM0LC00Mi42NDM1IDY4Ljk4NTcyMiwtNDIuNjQzNSAxLjAwNTc3LDAgMi4wMTI0NCwwLjAyMyAzLjAwODIxLDAuMDYyIHoiIGNsYXNzPSJQYXRoLXhydGtwZC0wIGVxZllpUiIgaWQ9InBhdGgyLTYiIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjcuNzM3NjgiIGlua3NjYXBlOmV4cG9ydC1maWxlbmFtZT0iQzpcVXNlcnNcYWxleFxzaXRlc1xudWJhbmstbG9nby00LnBuZyIgaW5rc2NhcGU6ZXhwb3J0LXhkcGk9IjkyLjYxODA5NSIgaW5rc2NhcGU6ZXhwb3J0LXlkcGk9IjkyLjYxODA5NSIgLz4gPHBhdGggZD0ibSA0ODUuMjMyMTcsOTE2Ljk0NjgzIGMgMC40MDIyMSwtNy40Mzc5IDAuMjY3MTQsLTE0Ljk1MDEgMC4xMzM2LC0yMi40MDM1IC0wLjA2NzIsLTMuNzA1NyAtMC4xMzM2LC03LjM5NjcgLTAuMTMzNiwtMTEuMDU2NyB2IC0xMDYuODE0IGggLTU5LjEwOTYyIGMgMCwwIC0wLjA0NDMsNTIuNjEzOSAwLDk3Ljg1MjIgMC4wMSwxMC4zOTM2IDAuMDM0NiwyMC4zOTkzIDAuMDU5MywyOS4yOTM3IDAuMDQ3OCwxNy4xNjc1IDAuMDg0MSwzMC4xOTI2IC0wLjA1OTMsMzMuODY3MyAtMS4wNDkxMSwyNi4zNDczIC04LjE2MzQzLDQzLjU3NzYgLTIxLjQzOTU5LDU3LjY3MDcgLTQ0LjAwMzk4LC0wLjAzMSAtNzIuNDkzODUsLTMwLjQxNTMgLTc0LjA4MTA1LC03OC43NjU3IC0wLjM2MTI1LC0xMS4xMDE3IC0wLjUxNDE4LC0zOC42NTExIC0wLjUxNDE4LC03MC41NTg0IHYgLTY5LjQwNTE2IGwgLTU5LjA2NjM1LDAuMDU0MSB2IDkzLjgzNzg2IGMgMCwyLjYzNzcgMCw1LjI0MjEgMCw3LjgxMTYgLTAuMDE5MiwyNS4wNDkgLTAuMDMzLDQ2LjY3NDUgMS43MzM4Nyw2Mi4wMTQ3IDUuNDQwNzEsNDcuMjM1MiAzMy45MzkwNSw3OC43NjU2NyA3Ni45MjI1NSw3OC43NjU2NyAyMi4wNjUwMSwwIDQwLjg0NTg3LC04LjcyOTkgNTUuMDA0MzYsLTIzLjY3NDU3IDAuOTk1MDgsMC4wMzkgMi4wMDA5NCwwLjA2MiAzLjAwNjc5LDAuMDYyIDI4Ljc5NDA4LDAgNTUuODA0MTIsLTE2LjcwMjEgNjguOTg2MDUsLTQyLjY0MyA1Ljc1ODg5LC0xMS4zMjQzIDcuODkzMjgsLTIzLjUxMjUgOC41NjEwNSwtMzUuOTExNyB6IiBjbGFzcz0iUGF0aC14cnRrcGQtMCBlcWZZaVIiIGlkPSJwYXRoNC01IiBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDo3LjczNzY4IiBpbmtzY2FwZTpleHBvcnQtZmlsZW5hbWU9IkM6XFVzZXJzXGFsZXhcc2l0ZXNcbnViYW5rLWxvZ28tNC5wbmciIGlua3NjYXBlOmV4cG9ydC14ZHBpPSI5Mi42MTgwOTUiIGlua3NjYXBlOmV4cG9ydC15ZHBpPSI5Mi42MTgwOTUiIC8+IDwvc3ZnPg==",
17
+ itau: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MDAiIGhlaWdodD0iNTAwIiB2aWV3Qm94PSIwIDAgNTAwIDUwMCI+PHBhdGggZD0iTTIxOC42NzYgMTAuNTc0Yy0xMy43OTcuMzI4LTIzLjkxOC44MTMtNDIuNDczIDEuOTU3LTguNTgyLjUxMi0xNy45NSAxLjI2Ni0yNC41NDcgMS45MjYtMS42NTYuMTgtNS4xMi41MTItNy42OC43NTQtMTAuNzUzIDEuMDU1LTI2LjcxOCAzLjA3LTMzLjQzMyA0LjIxNS0xLjQxOC4yNDItMy40OTYuNTc0LTQuNjY4Ljc1NC0xLjE0NS4xNTItMy4xOTUuNTExLTQuNTIuNzU0LTEuMzI0LjI0Mi0zLjU1NC42NjQtNC45NjguOTAyLTQuOTczLjg0NC0xMy40MzQgMi41NjItMTguMjIzIDMuNzA3LTEuMzI4LjMzMi0zLjcwNy45MDItNS4yNzMgMS4yNjYtMS41NjcuMzU5LTIuOTguNjkxLTMuMTYuNzIyLTguODI5IDIuMTA2LTE3LjU5NCA2LjM1Ni0yNC4zNCAxMS44NjdDMzguODI0IDQ0LjczIDMyLjk1MyA1My4zNDQgMzAgNjEuODk4Yy0uNDggMS4zMjUtLjk2NSAyLjY4LTEuMTEzIDMuMDEyLS41MTIgMS4xNDUtMi43NDIgMTAuNzgxLTQuMzQgMTguNjc2LS4yMzggMS4zMjQtLjY2IDMuMjgxLS45MDIgNC4zNjctLjI0MyAxLjA4Mi0uNTcgMi45OC0uNzgyIDQuMjE1LS4xODMgMS4yMzQtLjQyMiAyLjc0Mi0uNTc0IDMuMzEyLS40NTMgMS43Mi0yLjI4OSAxMy40NjUtMy40NjUgMjEuOTg5LTEuMTQ0IDguMjU0LTEuODk4IDE0LjI1LTIuNTU4IDIwLjMzMi0uMzMyIDIuOTgtLjY2NCA1LjkwMi0uNzIzIDYuNDc2LS4wOS41Ny0uMzYzIDMuNDkzLS42MzMgNi40NzctLjI0MiAyLjk4LS42MDEgNi42MjUtLjc4NSA4LjEzMy0uNjMzIDUuNTM5LTIuMiAyOS42NjgtMi45OCA0Ni42ODctLjYwMiAxMi42MTctLjk5MyAzOS42MzctLjc4MiA1NC4zNjcuMjExIDE4LjM3Mi42NiAzNC43OSAxLjA4MiA0MC41MTIuMTUzIDIuMzE3LjQ1MyA3LjIuNjMzIDEwLjg0NC4xOCAzLjY0NC40MjIgOC4zMTIuNTc0IDEwLjM5LjY5MiAxMC40MjIgMS4yMzUgMTcuMjU4IDEuNTA0IDE5LjQyNi4xNTMgMS4zMjguNTEyIDQuODUyLjc1NCA3LjgwMS4yNDIgMi45NTMuNjAyIDYuNDc3Ljc1NCA3LjgzMi4xOCAxLjM1Ni41MTIgNC4yNzcuNzUgNi41MDguNzU0IDcuMTM3IDEuMzI4IDExLjgwNSAxLjgwOSAxNC45MS4yNDIgMS42NTYuNjY0IDQuNDg4LjkwMiA2LjMyNC44NzUgNi42MjUgMS44OTggMTMuMDcgMy4wMTIgMTguOTc3LjI0MiAxLjMyNC42MzMgMy41NTUuOTA2IDQuOTY5LjUxMiAzLjAxMSAxLjY4NyA5LjAwNyAyLjUzMSAxMi44IDIuODkgMTMuMjg2IDQuMTU2IDE3LjI1OCA3LjU1OSAyMy43OTcuOTMzIDEuODA1IDIuMTM3IDMuOTE0IDIuNjggNC42NjguNTExLjc1NCAxLjI2NSAxLjgzNiAxLjY1NiAyLjQxIDEuNzE4IDIuNTU5IDYuNjI5IDcuNTU5IDkuMzQgOS40ODkuNDQ5LjMyOCAxLjMyNC45NiAxLjg5NCAxLjQxNC42MDYuNDggMS4xNzYuODQzIDEuMzI4Ljg0My4xMjEgMCAuNDIyLjIxMS42Ni40NTQgMS4xNzYgMS4xNDQgOS40NjEgNS4wOSAxMy4wMTIgNi4xNDQuNjY0LjIxMSAxLjQ3Ny40OCAxLjgwOS42MzMuNzg1LjM2IDUuMjEgMS40NzMgMTAuNTQzIDIuNjggMi4zMi41NDMgNC42OTkgMS4xMTMgNS4yNyAxLjI2NSAxLjM4Ni4zNiAxMC4xMiAyLjEwNiAxNi43MTggMy4zMTMgMy43OTMuNjkxIDExLjE3NiAxLjg2NyAxNS44MTIgMi41MzEgMS43NDcuMjM4IDMuOTc3LjU3IDQuOTcuNzUgMy42NDQuNjMzIDE4LjcwNiAyLjM4MyAyOC4xNjMgMy4yODUgMy40MDMuMzMyIDcuNTkuNzIzIDkuMzM2LjkwMiAyLjgzMi4zMDEgNS43MjMuNTQzIDE5LjU3OCAxLjUzNiAyLjA3OC4xNTIgNi44MDkuNDIyIDEwLjU0My42MDUgMy43MzUuMTggOC45NDYuNDUgMTEuNTk4LjYwMiAyMS40NDUgMS4yMzQgODIuNzcgMS4yMzQgMTAzLjkxNCAwIDIuNjUyLS4xOCA3Ljg2My0uNDIyIDExLjU5OC0uNjAyIDYuNDE0LS4zIDguNzY1LS40NTMgMTguODI0LTEuMjA3IDEyLjg5LS45OTIgMzEuODQtMi44MzIgMzguMjU0LTMuNzM0IDEuODM2LS4yNyA1LS42OTIgNy4wNzgtLjk2NSA3LjY4LS45OTIgMTguMjIzLTIuNTkgMjQuMjQ2LTMuNzAzIDYuNTk4LTEuMjA3IDE1LjMzMi0yLjk1MyAxNi43MTktMy4zMTMuNTctLjE1MiAyLjk0OS0uNzIyIDUuMjctMS4yNjUgNS4yMS0xLjE3NiA5LjczLTIuMzIgMTAuNTQyLTIuNjhhMTc0LjggMTc0LjggMCAwIDEgMy4wMTItMS4wNTVjMi40NjktLjgxMiAxMC42NjQtNC42OTkgMTEuMzU1LTUuMzYzLjIxMS0uMjExLjgxMy0uNjYgMS4zMjUtLjk2NSAyLjM1MS0xLjQ3MyAzLjQzMy0yLjMxNiA1LjU3NC00LjI0NiAyLjQxLTIuMiA1Ljc1NC01LjgxMiA2LjU2Ni03LjA0Ny4yNy0uNDIyLjk5My0xLjQ0NSAxLjU5NC0yLjI1OC42MzMtLjg0MyAxLjE0NS0xLjU5NyAxLjE0NS0xLjcxOCAwLS4xMjIuNDg0LS45NjUgMS4wNTQtMS44NjguNTc1LS45MDIgMS4yNjYtMi4yMyAxLjU0LTIuOTUzLjMtLjY5MS42LTEuNDQ1LjcyMi0xLjU5My41Ny0uNzU0IDIuNjgtNi43NSAzLjU4Mi0xMC4xNTMgMS40MTgtNS4yNyA0LjA2Ni0xNy43MSA1LjAzMS0yMy41ODYuMjQyLTEuNTA0LjUxMi0yLjkxOC42MDItMy4xNi4yNzMtLjY2NCAxLjkzLTEwLjk5NiAzLjQzMy0yMS41MzUuMzMyLTIuMzIuNjY0LTQuNjQuNzU0LTUuMTIxLjI0My0xLjM4NyAxLjMyNS0xMC42MzMgMS44MDktMTUuNTEyLjIzOC0yLjQxLjU3LTUuMTgzLjc1LTYuMTc2LjE4NC0uOTk2LjUxMi00LjI0Ni43NTQtNy4yMy4yNDItMi45OC41NzQtNi42NTYuNzIzLTguMTMzLjE4LTEuNTA0LjQ1My00LjkzNy42MzItNy42OC4xOC0yLjc0Mi40NTMtNi4xMTMuNjAyLTcuNTMuMTgzLTEuNDE1LjUxMi02LjYyNi43NTQtMTEuNTk1LjI3My00Ljk3Mi41NzQtMTEuMDg2Ljc1NC0xMy41NTQgMS4zNTUtMjEuODk5IDEuMzU1LTc5LjM2OCAwLTEwMS45NTctLjE1My0yLjU2My0uNDIyLTcuNTktLjYwMi0xMS4xNDUtLjE4My0zLjU1NS0uNDUzLTguMjU0LS42MDUtMTAuMzk0LS4xOC0yLjE2OC0uNTctNy41LS45MDMtMTEuODk1LS4zMzItNC4zOTgtLjY2NC04LjUyNy0uNzU0LTkuMTg3LS4wOS0uNjY1LS4zNTktMy41ODYtLjYwMS02LjQ3Ny0uMjQyLTIuODktLjUxMi01LjYwMi0uNjAyLTYuMDIzLS4wOS0uNDIyLS40MjItMy4xOTYtLjc1NC02LjE3Ni0uNzgtNy4yLTEuNzQ2LTE1LjE0OS0xLjk1Ny0xNi4wODItLjA5LS40MjItLjQyMi0yLjgzMi0uNzU0LTUuMzA1LTEuNDc2LTExLjI2Mi00LjIxNC0yNi45NTctNi41NjYtMzcuNjQ4LS4zMzItMS41MDgtLjg3MS0zLjk0Ni0xLjIwMy01LjQyMi0uODQ0LTMuODU2LTEuODQtNy43NDItMi4xNjgtOC40MzQtLjE1Mi0uMzMyLS40MjItMS4xNDQtLjYzMy0xLjgwOC0uNjY0LTIuMjI3LTQuMDA4LTkuNjY4LTQuODUxLTEwLjg0NC0uMTIyLS4xOC0xLjA4Mi0xLjU5NC0yLjExLTMuMTYtMi4xMzctMy4yMjMtNy42MTctOC45NDYtMTAuOTAyLTExLjM1Ni02LjUwNC00Ljc4OS0xMy43MzUtOC4wNDMtMjMuMDctMTAuMzMyYTQ0MC45MzIgNDQwLjkzMiAwIDAgMS00LjgyLTEuMjA3Yy0xLjExNC0uMzI4LTMuMzQ1LS44MTItOC4xMzQtMS44MDVhMzk2LjMxNyAzOTYuMzE3IDAgMCAxLTQuMDY2LS44NzVjLTUuODEzLTEuNDE0LTI0LjczLTQuNDg4LTM3LjA0Ny02LjA1NC0yLjQ3My0uMzAxLTQuOTEtLjYzMy01LjQyMi0uNzUtLjkwNi0uMTg0LTUuMjczLS42MzMtMTQuMTU2LTEuNTA4LTIuNDczLS4yNDItNS44NzUtLjYwMi03LjUzMS0uNzU0LTEuNjU2LS4xOC00LjY0LS40NS02LjYyNS0uNjMzLTEuOTg5LS4xNDgtNS4yNDItLjQyMi03LjIzLS41Ny02Ljc0Ny0uNTc0LTI1LjQ4MS0xLjY1Ni0zNS44NDQtMi4xMS0yMC4wMzItLjg3NC01Ny4wMi0xLjE0NC03OS45Ny0uNTdaTTg1Ljk2NSAyMTQuMDk4Yy4xOC4xNDggMS4wNTUuNDIyIDEuOTI2LjYzMiAxLjYyOS4zOTEgMy45MTggMS40NDYgNS42MzIgMi41OSAxLjM1Ni45MDMgNC41NTEgNC4zMzYgNS4xOCA1LjU0My4zMDUuNjAyLjYzMyAxLjE0NS43MjMgMS4yMzUuMDk0LjA5LjM2My42OTEuNjA1IDEuMzU1LjIxMS42Ni40OCAxLjM1Ni42MzMgMS41MDQuMzkuNTc0Ljg0NCA0LjE1Ni44NDQgNi44MDkgMCAyLjU5LS4zOTUgNS42MzItLjkwNiA2Ljc0Ni0xLjYyNSAzLjczNC0yLjQxIDQuOTY4LTQuNDU3IDcuMTQtMS44OTkgMS45NTctMi42OCAyLjU1OS01LjI3IDMuODI1LTIuMTEgMS4wNTQtMy42MTcgMS41OTctNC44MiAxLjcxNC0uOTY1LjEyMS0xLjgwOS4zMzItMS44OTkuNDU0LS4yMS4zNjMtNi43NDYuMzYzLTYuNzQ2IDAgMC0uMTIyLS43NTQtLjMzMy0xLjcxOS0uNDU0LS45MzMtLjExNy0yLjEwNS0uMzktMi42MTctLjYwMWEzMC45OTggMzAuOTk4IDAgMCAwLTEuOTg4LS44MTNjLS41NzQtLjIxLTEuMTE3LS40NTMtMS4yMDctLjU0My0uMDktLjEyLS41NDMtLjM5LTEuMDU1LS42MzItMS43NDYtLjg3Mi01LjM2LTQuODgtNi40MTQtNy4wNzktLjU3NC0xLjE3NS0xLjExMy0yLjMyLTEuMjY1LTIuNTU4LTEuMDI0LTIuMDUtMS4yMDQtMTEuMzg3LS4yNDMtMTMuNTU1LjI3NC0uNTc0LjY2NC0xLjUzNS44NzUtMi4xMS4yMTEtLjU3LjQ1My0xLjExMy41NDMtMS4yMDIuMDktLjA5LjQ1LS42OTYuNzgyLTEuMzU2LjU3NC0xLjExNyA0LjE1Ni00Ljk3MiA0LjY2OC00Ljk3Mi4xMiAwIC4zOTQtLjIxMS42MDUtLjQ4LjU3LS42MzQgMy40OTItMi4wNDggNS4yNy0yLjUuODQzLS4yMTIgMS43NzctLjUxMyAyLjEwOS0uNjY1LjMzMi0uMTQ4IDEuMTQ0LS4zIDEuODA1LS4zOSAxLjc3Ny0uMTggOC4wMTUuMDkgOC40MDYuMzYzWm0zMjguMTkxIDIwLjk5MnYxNS4yMWgtNTguNDMzdi0yMC4zNTlsMy4yNTQtLjUxNWM3LjE5OS0xLjExMyAxMS42ODctMS44NjcgMTEuOTU3LTIuMDQ3LjE4LS4xMjEgMS42NTYtLjM2IDMuMzEyLS41NyAxLjY1Ni0uMjExIDMuMTY0LS40ODUgMy4zMTMtLjYwNi4xODMtLjExNyAxLjU5Ny0uMzkgMy4xNjQtLjYwMSAxLjU2Ni0uMTggMy42MTMtLjU0MyA0LjUyLS43ODIuOTAyLS4yMSAyLjgtLjU0MyA0LjIxNC0uNzIyIDEuNDE4LS4xODQgMi44MzItLjQ1MyAzLjE2NC0uNTc1LjMzMi0uMTQ4IDEuODM2LS40MjEgMy4zMTMtLjYzMiAxLjUwNy0uMTggMy4xOTEtLjQ1IDMuNzY1LS42MzMuNTctLjE0OSAyLjc0Mi0uNTcgNC44Mi0uOTAzIDIuMDc5LS4zMzIgNC43OS0uNzggNi4wMjQtLjk5MiAxLjIzNC0uMjQyIDIuNTU5LS40MjIgMi45NS0uNDUzbC42NjMtLjAzMVptLTI0OS4zOTggMTMuNDMzdjE4LjA0M2gzMC4xMnYyNi44MDlIMTY0LjczbC4xMTggMjcuOTIyYy4wOTMgMzAuMDkuMDMgMjguNjEzIDEuNjYgMzIuMzE2IDEuMjM0IDIuODY0IDQuNzI2IDUuNzg1IDcuNzM4IDYuNTA4LjUxMi4xMjEgMS4wODYuMzYgMS4zMjguNTQzLjU3LjQ1IDEyLjc3LjQ1IDEzLjMxMy0uMDMxLjIzOC0uMTggMS4zMjQtLjQyMiAyLjQ2OC0uNTQzbDIuMDItLjIxMXYyNi40MThsLS44MTYuMzZjLS43NS4zMzEtNC4yMTUuODc0LTguOTczIDEuNDQ1LTYuNzc3Ljc4NS0xOS4xMjkuODc1LTE5Ljg1Mi4xMi0uMTgtLjE0OC0uNjYtLjI2OS0xLjExMy0uMjY5LTEuMTc2IDAtNi4wNTUtLjkwNi02LjQxOC0xLjE3Ni0uMTgtLjEyLS45OTItLjQyMi0xLjgzNi0uNjAxLS44MTItLjIxMS0xLjYyNS0uNDg1LTEuODA4LS42MDItLjE0OS0uMTUyLS44NC0uNDIyLTEuNTA0LS42MzMtLjY2NC0uMjEtMS4yNjYtLjQ4NC0xLjM1Ni0uNTc0LS4wOS0uMDktLjYzMy0uNDIyLTEuMjA3LS43NTQtMi41LTEuMzI0LTMuMjUtMS44MDQtNC41NzgtMi45MjItLjc4MS0uNjMyLTEuNTA0LTEuMTcxLTEuNjU2LTEuMTcxLS4zMDEtLjAzMi0yLjU5LTIuNTMyLTQuMzk1LTQuODItMS4zODYtMS43NzgtMy40MzctNS4xOC00LjEyOS02LjkzLS4yNDItLjU3LS41MTEtMS4xMTQtLjYwMS0xLjIwNC0uMTIxLS4wOS0uNDIyLTEuMDIzLS43MjMtMi4xMDktLjI3My0xLjA4Mi0uNjMzLTIuMjI3LS43ODUtMi41NTktLjE0OC0uMzMyLS41MTItMS42ODctLjc1LTMuMDExYTE0NC4yODYgMTQ0LjI4NiAwIDAgMC0uODE2LTMuNzY2Yy0uMjExLS45MDItLjM2LTExLjUwOC0uNDUtMzEuNTY2bC0uMTItMzAuMThoLTE3LjQ0MnYtMjYuODA5aDE3LjQ3M3YtMzAuMzYzbDIuMDQ2LS4yMWMxLjExNC0uMTE4IDIuMTY4LS4zMjkgMi4zMi0uNDUuMTgtLjEyMSAxLjY1Ny0uMzkgMy4zMTMtLjYwMiAxLjY1Ni0uMjEgMy4xNjQtLjUxNSAzLjMxMy0uNjMyLjE4LS4xMjEgMi4wNzgtLjQ1NCA0LjIxOC0uNzIzIDIuMTY4LS4zMDUgNC4wNjctLjYzMyA0LjIxNS0uNzU0LjE4LS4xMjEgMS4xNzYtLjMzMiAyLjI1OC0uNDIyYTQ5LjcxOSA0OS43MTkgMCAwIDAgNC4yMTktLjY5MWMzLjIyMy0uNjY0IDguODU1LTEuNTQgOS4xMjUtMS4zODcuMTIxLjA1OS4yMSA4LjI1NC4yMSAxOC4xOTFabTk5Ljg1MSAxNS4xOGM0LjIxNS4yNDIgOC45NzcuNzg1IDkuMzM2IDEuMDU1LjE4LjEyLjkwMy4zMzIgMS42NTcuNDIyIDEuNzE4LjI3MyA1LjkwNiAxLjUwNyA4LjQzMyAyLjUzIDIuMTEuODQ1IDYuODA5IDMuMTkyIDcuNTMxIDMuNzk4LjI0My4xOC43ODIuNTM5IDEuMjA0LjcyMi40MjEuMjExIDEuNzUgMS4yNjIgMi45MjEgMi4yOSAxLjE3NiAxLjA1NCAyLjI2MiAxLjk1NyAyLjQxIDIuMDE1LjQ1NC4yMTEgNS44MTMgNi43MTkgNS44MTMgNy4wNzggMCAuMDkuMjc0LjU3NS42MDYgMS4wMjQuNjMyLjkwNiAzLjMxMiA2LjExNyAzLjMxMiA2LjQ0OSAwIC4xMTcuMjQyLjc4MS41NyAxLjQ3My4zMDEuNjk1LjY2NCAxLjc1Ljc4NiAyLjMyLjEyLjU3NC4zMzIgMS4xNzYuNDQ5IDEuMzU1LjEyLjE1My4zOTQgMS4xMTQuNjA1IDIuMTEuMTguOTkyLjQyMiAyLjAyLjUxMiAyLjI1OC4xMjEuMjQyLjM5IDEuNTM1LjYzMyAyLjg2My4zNiAxLjk4OC40NDkgOS40ODguNTcgNDIuNjhsLjEyMSA0MC4zaC0zMi44NmwtLjAzLTMuNTU0Yy0uMDMyLTEuOTI2LS4xMjItNC43MjctLjI0My02LjIwNGwtLjE4LTIuNzEtLjg3NCAxLjIwM2MtMS4zODMgMS44NC01LjkzNCA2LjE3NS03LjczOSA3LjM3OS0zLjk0OSAyLjU5My01IDMuMjIyLTYuMDg2IDMuNTg2LS42NjQuMTgtMS41MzUuNTQzLTEuOTU3Ljc4LS40NTMuMjEyLTEuNTY2LjU3NS0yLjQ3Mi43NTUtLjkwMy4yMS0xLjgwNS40ODQtMS45NTcuNjAxLTEuNTM1IDEuMTQ1LTIwLjUxMiAxLjExNy0yMS45ODktLjAyNy0uMTQ4LS4xMjEtMS4yMzQtLjM5LTIuNDEtLjYwMi0xLjE0NC0uMjEtMi41LS41NDMtMy4wMTEtLjc4NS0uNDgtLjIxLTEuNzc4LS43NTQtMi44MjktMS4xNzZhNDIuNDIgNDIuNDIgMCAwIDEtMy41NTQtMS43NDYgNDkuODY2IDQ5Ljg2NiAwIDAgMC0yLjQ0Mi0xLjQxNGMtMS4yNjUtLjY5NS0xLjY4Ny0xLjA4Ni01LjEyLTQuNTItMy41MjQtMy41MjMtMy45NzctNC4wMDMtMy45NzctNC4zMzUgMC0uMTIxLS4zOTEtLjc4NS0uODQtMS40NzctLjQ4NS0uNjkxLTEuMTc2LTEuOTU3LTEuNTQtMi43NzMtLjM1OS0uODQtLjg0My0xLjgzNi0xLjA1NC0yLjI1OC0uMjM4LS40MjItLjU3LTEuNTA0LS43ODEtMi40MS0uMjExLS45MDMtLjQ4LTEuODA1LS42MDItMS45NTctLjMzMi0uNDIyLS45MDYtNC43LS45MDYtNi41NjcgMC0uODctLjE0OC0xLjc0Ni0uMzI4LTEuOTI1LS4zNjMtLjM2NC0uMjc0LTEuNTY3LjY2LTguODI5LjE4LTEuNDE0LjQ1My0yLjcxLjU3NC0yLjg1OS4xMjEtLjE4LjM5LS45NjUuNTctMS43NzcuMzkxLTEuNTY3IDEuMjA4LTMuNjE0IDIuMDUxLTUuMTUzLjI3LS41MTEuNjMtMS4yMDMuODEzLTEuNTY2LjE4LS4zOS40MjItLjY5MS41Ny0uNjkxLjEyMSAwIC4yMTEtLjE4LjIxMS0uMzkxIDAtLjMzMiAzLjMxMy00LjY0IDMuODg3LTUuMDMxLjEyLS4wOS4zMzItLjM5LjQyMi0uNjkyLjEyLS4zMzIuNDgtLjYzMi44MTItLjcyMi4zMzItLjA5LjYwMi0uMjc0LjYwMi0uMzk1IDAtLjMgNS4wNjItNC4yNzcgNi43NzctNS4yNyAxLjIzNC0uNzUzIDQuMDA4LTIuMTY3IDguMDQzLTQuMDk3LjU3NC0uMyA2LjIwMy0yLjEwNiA4LjY3Ni0yLjguOTAyLS4yNyAyLjY4LS42MzQgMy45MTQtLjgxMyAxLjIzNC0uMjExIDIuNDEtLjQ1MyAyLjU2Mi0uNTcuMTgtLjEyMiAxLjk4NS0uMzk1IDQuMDY3LS41NzUgMi4wNzgtLjE4IDQuNjM3LS40OCA1LjcyMi0uNjMzIDQuMjc4LS42MzIgMTkuMzA1LS41MTEgMjAuOTAzLjE1My41NDMuMjM4LjU3LjEyLjM2LTIuNDQyLS4xMTgtMS40NzYtLjMyOS0yLjc0Mi0uNDUtMi44MzItLjE1Mi0uMDktLjMzMi0uNjYtLjQ1My0xLjI2NS0uMjExLTEuMTE0LTEuMzU2LTMuNTUxLTIuNDM4LTUuMjExLS42OTUtMS4wNTEtMy42MTctNC4wNjctMy45NDktNC4wNjctLjExNyAwLS42MjktLjMtMS4xNDQtLjY5MS0xLjMyNS0uOTY1LTMuNDYxLTEuOTI2LTQuNzU4LTIuMTY4LS42MzMtLjEyMS0xLjE0NS0uMzMyLTEuMTQ1LS40NTMgMC0xLjMyNC0xOS40NTctMS41MzUtMjUuMy0uMjM5LS43NTQuMTQ5LTIuNS40OC0zLjkxNS43MjMtMS40MTguMjM4LTIuODMyLjU3LTMuMTY0LjcyMy0uMzMyLjE0OC0xLjQxNC40MjItMi40MS42MDEtLjk5Mi4xOC0yLjA3OC40NTMtMi40MS42MDItLjMzMi4xNTItMS41MzUuNDg0LTIuNjguNzU0LTEuMTQ0LjI3LTIuMjMuNTctMi40MS43MjItLjE4LjEyMi0uOTkyLjQyMi0xLjgzNi42MzMtLjgxMi4yMTEtMS42NTYuNTEyLTEuODA4LjYzMy0uMTguMTIxLS45OTMuMzktMS44MDkuNjAyLS44NC4xOC0yLjAxNi42MDEtMi42MTcuOTAyLS42MzMuMzMyLTEuMjA3LjU3NC0xLjI5Ny41NzQtLjA5IDAtLjE1Mi02LjI5Ny0uMTUyLTEzLjk3NiAwLTEwLjg3NS4wOTMtMTQuMDM2LjM5NC0xNC4yNzguMjExLS4xOCAxLjA1NS0uNDggMS44NjctLjY5MS44NDQtLjE4IDEuNjU3LS40NTMgMS44MDUtLjU3NC4xODQtLjEyMSAxLjE3Ni0uNDggMi4yNjItLjc1NCAxLjA4Mi0uMzAxIDIuMTA1LS42MyAyLjI1OC0uNzUuMTgtLjE1MyAxLjExMy0uMzk1IDIuMDc4LS42MDIuOTk2LS4yMSAyLjAyLS40ODQgMi4yNTgtLjYzMy4yNzMtLjEyIDEuNTA3LS40NTMgMi43NDItLjcyMmE1OC45NSA1OC45NSAwIDAgMCAyLjg2My0uNjMzYy4zMjgtLjA5NCAyLjAxNi0uMzYzIDMuNzYyLS42MDYgMS43NS0uMjM4IDMuNTg2LS41NyA0LjA2Ni0uNzIyIDEuNzUtLjU0IDE3LjUzMS0xLjUzNSAyMS4wODYtMS4zMjQuOTkyLjA1OCAzLjE2NC4xOCA0LjgyLjI3Wk05OC40OTIgMzI2LjUwOHY1OS45MzdINjMuMjU0VjI2Ni41NjZoMzUuMjM4Wm0yNjYuMjY2LTIyLjU5NGMwIDM1LjY2NC4xNTIgNDIuNTYzLjg3NSA0My41MjcuMTQ4LjE0OS4zMzIuNzUuNDUzIDEuMzI1LjQyMiAyLjI1NyAyLjM3OSA1LjU0MyA0LjYwNSA3Ljc3IDEuMTc2IDEuMjA2IDIuNSAyLjI2IDIuOTIyIDIuMzc4LjQ1My4wOTQuNzg1LjI3NC43ODUuMzk1IDAgLjExNyAxLjA1NS41MzkgMi4zNDguOTYgMS45My42MDYgMi45NTMuNzIzIDUuOTY1LjcyMyAyLjExIDAgMy45NDUtLjE0OCA0LjM2Ny0uMzI4LjM5LS4yMSAxLjMyNC0uNTEyIDIuMDc4LS43MjMuNzU0LS4yMSAyLjExLS44NDMgMy4wMTItMS40NDkgMS42ODctMS4wODIgNC44Mi0zLjk3MiA0LjgyLTQuNDU3IDAtLjE0OC40MjItLjgxMi45MDMtMS40NDUuNTExLS42NjQuOTA2LTEuMzI0LjkwNi0xLjUwNCAwLS4xODQuMjctLjgxNi41Ny0xLjQxOC4zMzItLjYwMi42OTItMS42MjUuODEzLTIuMjU4LjA5LS42NjQuMy0xLjMyNC40NTMtMS40NzYuNzU0LS45NjUuODc1LTcuMDQ3Ljg3NS00Mi4zOHYtMzYuOTg4aDM1LjIzOHYxMTkuODhINDIwLjA2Yy0xMy4wNCAwLTE2Ljc3OC0uMDktMTYuOTU3LS4zOTEtLjEyMi0uMTgtLjI3LTMuMDQzLS4zMzItNi4zMjUtLjA2LTMuMjUzLS4yMTEtNS45MzMtLjMyOS01LjkzMy0uMTIgMC0uNDg0LjM2LS44NDMuODEyLTEuNjg4IDIuMjktNC4zNCA0Ljg4LTguNDk2IDguMzEzLS42MDIuNDgtMS44MzYgMS4xNDQtNC41NDcgMi40NjktMS4yMzUuNjAxLTIuNTkgMS4yOTYtMy4wMTIgMS41MDctLjQyMi4yMTEtMS41NjYuNTQzLTIuNTYzLjc1NC0uOTkyLjIxMS0xLjg2Ny40OC0xLjk1Ny42MDItLjMuNDUtNS42MzIuOTAyLTEwLjkwMi45MDItNS4xOCAwLTkuMzk4LS4zNi0xMC42MzMtLjg3NS0uMzMyLS4xNDgtMS40NzYtLjUxMS0yLjU2Mi0uNzgxLTEuMDgyLS4yNy0yLjA3OC0uNjMzLTIuMjU4LS43NTQtLjE0OC0uMTIxLS44NzEtLjQyMi0xLjU2Ni0uNjMzLS43MjMtLjE4LTEuMjkzLS40NDktMS4yOTMtLjU3IDAtLjEyMS0uNTQzLS4zOS0xLjIwNy0uNjAyLS42Ni0uMjEtMS4yMDQtLjQ4NC0xLjIwNC0uNjA1IDAtLjExNy0uMzMyLS4zNi0uNzIyLS41NC0yLjU5LTEuMTc1LTguNDY1LTYuNjg3LTEwLjkzNC0xMC4yNDEtMS41MDgtMi4xNjgtMy44MjgtNi41MDgtNC4zMDgtOC4xMDItLjE4LS42MzMtLjU0My0xLjU2Ni0uNzU0LTIuMDUtLjIxMS0uNTEyLS41Ny0xLjU5NC0uNzU0LTIuNDEtLjE4LS44NC0uNDUtMS43MTYtLjYwMi0yLjAxNi0uMTQ4LS4yNzQtLjQyMi0xLjY4OC0uNjAxLTMuMTY0LS4xOC0xLjQ0Ni0uNTEyLTIuOTIyLS42OTItMy4yNTQtLjI3My0uNDUtLjM5NC0xMS4yMDQtLjQ1My00My4zMTNsLS4wOS00Mi42OGgzNS4yN1ptMCAwIiBzdHlsZT0ic3Ryb2tlOm5vbmU7ZmlsbC1ydWxlOm5vbnplcm87ZmlsbDojRkY2MjAwO2ZpbGwtb3BhY2l0eToxIi8+PHBhdGggZD0iTTI2MC42OTEgMzMzLjE2NGMtMS40NzIuMTQ5LTIuOTguMzktMy4zMTIuNTQtLjMzMi4xODMtMS40MTQuNDUyLTIuNDEuNjYzLS45NjEuMTgtMi4yNTguNTQzLTIuODYuODEzLTQuNTIgMS45NTctNi43MTggMy4yNTQtOC4yMjIgNC44Mi0xLjQ0NiAxLjUwOC0yLjg5NSA0LjMwOS0zLjEzMyA2LjA1NS0uMDYzLjYwMS0uMjc0IDEuMzg2LS40NTMgMS43MTUtLjMzMi42OTUtLjIxMSAyLjgzMi4zMzIgNS42MzIuNjAxIDMuMDQzIDMuMDEyIDYuNzUgNS4xNDggNy44NjQgMy43OTcgMS45NTcgNC41MiAyLjI1NyA2LjYzIDIuNTkgMy43OTIuNTcgMTEuMDIzLjI0MiAxMi41ODktLjYwMi4yNy0uMTUyIDEuMzg3LS42NjQgMi40NjktMS4xNDUgMS4wODYtLjUxMSAyLjUtMS4zMjggMy4xNjQtMS44NC42NjQtLjUxMSAxLjQxNC0xLjExMyAxLjY4Ny0xLjMyNCAxLjcxNS0xLjI5MyA0Ljg4LTYuNTM1IDUuMzAxLTguNzAzLjA5LS41NDMuMzMyLTEuMTc2LjUxMi0xLjQxOC4yMS0uMjcuMzYtMy4wNDMuNDIyLTguMDEybC4xMi03LjU5LTEuNjI4LS4xNzljLTIuMi0uMjczLTEzLjA0LS4xOC0xNi4zNTYuMTIxWm0wIDAiIHN0eWxlPSJzdHJva2U6bm9uZTtmaWxsLXJ1bGU6bm9uemVybztmaWxsOiNGRjYyMDA7ZmlsbC1vcGFjaXR5OjEiLz48L3N2Zz4=",
18
+ bradesco: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjUwMCIgaGVpZ2h0PSIyNTAwIiB2aWV3Qm94PSIwIDAgMzc4Ljc2MjM0IDM3OC44MDYiIHZlcnNpb249IjEuMSIgaWQ9InN2ZzEwIiBzb2RpcG9kaTpkb2NuYW1lPSJicmFkZXNjby5zdmciIGlua3NjYXBlOnZlcnNpb249IjEuMi4yICg3MzJhMDFkYTYzLCAyMDIyLTEyLTA5KSIgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiIHhtbG5zOnNvZGlwb2RpPSJodHRwOi8vc29kaXBvZGkuc291cmNlZm9yZ2UubmV0L0RURC9zb2RpcG9kaS0wLmR0ZCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4gPGRlZnMgaWQ9ImRlZnMxNCIgLz4gPHNvZGlwb2RpOm5hbWVkdmlldyBpZD0ibmFtZWR2aWV3MTIiIHBhZ2Vjb2xvcj0iIzUwNTA1MCIgYm9yZGVyY29sb3I9IiNlZWVlZWUiIGJvcmRlcm9wYWNpdHk9IjEiIGlua3NjYXBlOnNob3dwYWdlc2hhZG93PSIwIiBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMCIgaW5rc2NhcGU6cGFnZWNoZWNrZXJib2FyZD0iMCIgaW5rc2NhcGU6ZGVza2NvbG9yPSIjNTA1MDUwIiBzaG93Z3JpZD0iZmFsc2UiIGlua3NjYXBlOnpvb209IjAuMTUzMzAwNzUiIGlua3NjYXBlOmN4PSIxODE5Ljk1MiIgaW5rc2NhcGU6Y3k9IjE1MjYuNDExMyIgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxOTIwIiBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSIxMDA5IiBpbmtzY2FwZTp3aW5kb3cteD0iLTgiIGlua3NjYXBlOndpbmRvdy15PSItOCIgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0iZzgiIC8+IDxnIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBpZD0iZzgiPiA8cGF0aCBkPSJNIC0wLjAxMTkyODE0LDAuMjA0NzA0MDggSCAzNzguNzE5NTUgViAzNzguOTEwNDQgSCAyMjIuMDc3NTQgViAyMjIuMDE5MjYgSCAxODcuNzQyNjggViAzNzguOTEwNDQgSCAxNjkuNTAzMDMgViAyNzEuNzk0MjkgSCAxNTIuMzM4NyBWIDM3OC45MTA0NCBIIC0wLjAxMTkyODE0IFogTSAxMi44NTk3NzUsMTMyLjIxMjEgQyAzMi44ODM3OTksMTIzLjE5OTM3IDUyLjkxMDI5OCwxMTQuMTgxNjQgNzIuOTQyOTg0LDEwNS4xNjE0MyAxNTMuMzYzMjksLTcuODgzNDU5NiAyNTcuODM1NDMsMzQuOTE0OSAyOTUuMDMyNDUsODguOTMxNTIyIDIwOC40ODE5NCwzMy4wMjk2MTQgMTQ0LjQ2MzcxLDYxLjUyNDQ3MiAxMTIuNjQwODQsOTkuNzUyMjkgMzU1LjgzODMxLDc0LjMxNTI1OSA0MTYuNjM1NTIsMjIzLjYzNDE0IDI4NS4zNzU1OCwyNzguMjgzNzYgNDAxLjYwMjAzLDE4NC4xNDc4MSAyNTMuOTAwNDEsMTA3LjMyNDU4IDk5Ljc2NzksMTE0Ljg5ODEzIDYyLjc0MTY0NSwxODMuNzgyNzIgNzQuODk1NjQyLDIzNC42MzgwOCAxMDkuNDIxMDUsMjgwLjQ0NjkyIDcyLjE5NDM0MSwyNTEuNzA3ODQgNDcuNTA1MjIyLDIwOS43MDMyMiA2Ny41Nzg3NDMsMTIwLjMwODUxIDQ5LjMzNzg0OSwxMjQuMjc5NyAzMS4wOTY5NTYsMTI4LjI0NTkgMTIuODU5Nzc1LDEzMi4yMTIxIFoiIGZpbGw9IiNjYzIyMjkiIGlkPSJwYXRoMiIgc3R5bGU9InN0cm9rZS13aWR0aDoxLjI0MTc0IiAvPiA8L2c+IDwvc3ZnPg==",
19
+ bb: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjUwMCIgaGVpZ2h0PSIyNTAwIiB2aWV3Qm94PSIwIDAgMTkyLjc1NiAxOTIuNzU2IiB2ZXJzaW9uPSIxLjEiIGlkPSJzdmcxMCIgc29kaXBvZGk6ZG9jbmFtZT0iYmFuY28tZG8tYnJhc2lsLXNlbS1mdW5kby5zdmciIGlua3NjYXBlOnZlcnNpb249IjEuMi4yICg3MzJhMDFkYTYzLCAyMDIyLTEyLTA5KSIgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiIHhtbG5zOnNvZGlwb2RpPSJodHRwOi8vc29kaXBvZGkuc291cmNlZm9yZ2UubmV0L0RURC9zb2RpcG9kaS0wLmR0ZCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4gPGRlZnMgaWQ9ImRlZnMxNCIgLz4gPHNvZGlwb2RpOm5hbWVkdmlldyBpZD0ibmFtZWR2aWV3MTIiIHBhZ2Vjb2xvcj0iIzUwNTA1MCIgYm9yZGVyY29sb3I9IiNlZWVlZWUiIGJvcmRlcm9wYWNpdHk9IjEiIGlua3NjYXBlOnNob3dwYWdlc2hhZG93PSIwIiBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMCIgaW5rc2NhcGU6cGFnZWNoZWNrZXJib2FyZD0iMCIgaW5rc2NhcGU6ZGVza2NvbG9yPSIjNTA1MDUwIiBzaG93Z3JpZD0iZmFsc2UiIGlua3NjYXBlOnpvb209IjAuMjE2OCIgaW5rc2NhcGU6Y3g9IjEyNTAiIGlua3NjYXBlOmN5PSIxMjUwIiBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjE5MjAiIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEwMDkiIGlua3NjYXBlOndpbmRvdy14PSItOCIgaW5rc2NhcGU6d2luZG93LXk9Ii04IiBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIiBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJzdmcxMCIgLz4gPGcgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGlkPSJnOCI+IDxwYXRoIGZpbGw9IiMzMzM0OGUiIGQ9Ik05Ni4zOTYgMTYuOTI1bC03OC44NSA1Mi44NSAzMi44MTkgMjEuMzExTDg5LjU3NyA2NC42NiA3NC4wMjMgNTQuNDQzbDIxLjMwNS0xNC4yNzQgNDYuMjMxIDMwLjY3OS03NS44NDUgNTAuOTE4IDE2LjQwNSAxMC44NjUgOTQuMzc5LTYyLjg0OC0uMjEzLS4yMTMtNzkuODg5LTUyLjY0NXpNMTc1LjAyNyAxNi45NDdsLTMyLjgwOCAyMS43MzEgMTYuNDA0IDExLjA3OCAxNi40MDQtMTEuMDc4VjE2Ljk0N3pNMTcuMDA1IDE3NS44MzJsMzIuODA5LTIxLjczLTE2LjQwNC0xMS4wNzktMTYuNDA1IDExLjA3OXYyMS43M3oiIGlkPSJwYXRoNCIgLz4gPHBhdGggZmlsbD0iIzMzMzQ4ZSIgZD0iTTk2LjM2IDE3NS43ODdsNzguODQ5LTUyLjg1MS0zMi44MTgtMjEuMzExLTM5LjIxMSAyNi40MjYgMTUuNTUyIDEwLjIxNy0yMS4zMDQgMTQuMjc1LTQ2LjIzMS0zMC42OCA3NS44NDQtNTAuOTE3LTE2LjQwNC0xMC44NjYtOTQuMzggNjIuODQ4LjIxMy4yMTUgNzkuODkgNTIuNjQ0eiIgaWQ9InBhdGg2IiAvPiA8L2c+IDwvc3ZnPg==",
20
+ caixa: "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjUwMCIgaGVpZ2h0PSIyNTAwIiB2aWV3Qm94PSIwIDAgMTkyLjc1NiAxOTIuNzU2IiB2ZXJzaW9uPSIxLjEiIGlkPSJzdmc3NDI5IiBzb2RpcG9kaTpkb2NuYW1lPSJjYWl4YS1lY29ub21pY2EtZmVkZXJhbC1YLnN2ZyIgaW5rc2NhcGU6dmVyc2lvbj0iMS4yLjIgKDczMmEwMWRhNjMsIDIwMjItMTItMDkpIiB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPiA8ZGVmcyBpZD0iZGVmczc0MzMiIC8+IDxzb2RpcG9kaTpuYW1lZHZpZXcgaWQ9Im5hbWVkdmlldzc0MzEiIHBhZ2Vjb2xvcj0iIzUwNTA1MCIgYm9yZGVyY29sb3I9IiNlZWVlZWUiIGJvcmRlcm9wYWNpdHk9IjEiIGlua3NjYXBlOnNob3dwYWdlc2hhZG93PSIwIiBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMCIgaW5rc2NhcGU6cGFnZWNoZWNrZXJib2FyZD0iMCIgaW5rc2NhcGU6ZGVza2NvbG9yPSIjNTA1MDUwIiBzaG93Z3JpZD0iZmFsc2UiIGlua3NjYXBlOnpvb209IjAuMTUzMzAwNzUiIGlua3NjYXBlOmN4PSIyOTMuNTQwNjQiIGlua3NjYXBlOmN5PSIxNDgwLjc0OTQiIGlua3NjYXBlOndpbmRvdy13aWR0aD0iMTkyMCIgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iMTAwOSIgaW5rc2NhcGU6d2luZG93LXg9Ii04IiBpbmtzY2FwZTp3aW5kb3cteT0iLTgiIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9InN2Zzc0MjkiIC8+IDxnIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBpZD0iZzc0MjciIHRyYW5zZm9ybT0ibWF0cml4KDQuNDMzNTkwOCwwLDAsNC40MzM1OTA4LC00NDguMTk1NzEsLTMyNi4wNzg1OCkiPiA8cGF0aCBkPSJtIDExNC43MjUsOTcuNjU2IGggMTQuNjM2IGwgMTAuMDMsMTYuNjEyIGggLTE0LjYzOSB6IiBmaWxsPSIjMGQ2ZmFiIiBpZD0icGF0aDc0MjEiIHNvZGlwb2RpOm5vZGV0eXBlcz0iY2NjY2MiIC8+IDxwYXRoIGZpbGw9IiNkYjgxMzUiIGQ9Im0gMTE2LjI0Niw5NS4xMDQgaCAxNS4xMjkgbCAxMy4xMzksLTE2LjU0IGggLTE1LjEyOSB6IG0gLTE1LjEyOSwxOS4yNjUgaCAxNS4xMjkgbCAxMy4xMzksLTE2Ljc0NCBoIC0xNS4xMjkgeiIgaWQ9InBhdGg3NDIzIiAvPiA8cGF0aCBmaWxsPSIjMGQ2ZmFiIiBkPSJtIDEwNi41NzIsNzguMzYyIGggMTQuMTIxIGwgOS42NzQsMTYuNzQyIGggLTE0LjEyMSB6IiBpZD0icGF0aDc0MjUiIHNvZGlwb2RpOm5vZGV0eXBlcz0iY2NjY2MiIC8+IDwvZz4gPC9zdmc+",
21
+ santander: "data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjI1MDAiIHZpZXdCb3g9IjAgMC40IDIzOC4yIDI0MC43MTkyNiIgd2lkdGg9IjI1MDAiIHZlcnNpb249IjEuMSIgaWQ9InN2ZzQiIHNvZGlwb2RpOmRvY25hbWU9ImJhbmNvLXNhbnRhbmRlci1sb2dvLnN2ZyIgaW5rc2NhcGU6dmVyc2lvbj0iMS4yLjIgKDczMmEwMWRhNjMsIDIwMjItMTItMDkpIiB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPiA8ZGVmcyBpZD0iZGVmczgiIC8+IDxzb2RpcG9kaTpuYW1lZHZpZXcgaWQ9Im5hbWVkdmlldzYiIHBhZ2Vjb2xvcj0iIzUwNTA1MCIgYm9yZGVyY29sb3I9IiNlZWVlZWUiIGJvcmRlcm9wYWNpdHk9IjEiIGlua3NjYXBlOnNob3dwYWdlc2hhZG93PSIwIiBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMCIgaW5rc2NhcGU6cGFnZWNoZWNrZXJib2FyZD0iMCIgaW5rc2NhcGU6ZGVza2NvbG9yPSIjNTA1MDUwIiBzaG93Z3JpZD0iZmFsc2UiIGlua3NjYXBlOnpvb209IjAuMTczMzgyNTgiIGlua3NjYXBlOmN4PSItNDAuMzczMTQ0IiBpbmtzY2FwZTpjeT0iMTEwMS42MTAxIiBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjE5MjAiIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjEwMDkiIGlua3NjYXBlOndpbmRvdy14PSItOCIgaW5rc2NhcGU6d2luZG93LXk9Ii04IiBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIiBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJzdmc0IiAvPiA8cGF0aCBkPSJtIDE3MS43MzY1LDExMS43MjI0NyBjIC0wLjU0Nzk4LC04LjY2Mjc2IC0yLjczOTg2LC0xNy4zMjU1MTkgLTcuMTIzNjUsLTI0LjgzMzI0OCBMIDEyNy4zNTA2OSwxOC4xNjQ2NDEgYyAtMi43Mzk4NSwtNS4xOTc2NTYgLTQuOTMxNzUsLTEwLjk3MjgzMDMgLTYuMDI3NywtMTYuNzQ4MDA2IGwgLTEuNjQzOTIsMi44ODc1ODc1IGMgLTkuMzE1NTMsMTYuNzQ4MDA4NSAtOS4zMTU1MywzOC4xMTYxNTQ1IDAsNTQuODY0MTYxNSBsIDMwLjEzODUsNTQuODY0MTU2IGMgOS4zMTU1NSwxNi43NDggOS4zMTU1NSwzOC4xMTYxNiAwLDU0Ljg2NDE2IGwgLTEuNjQzOSwyLjg4NzU4IGMgLTEuMDk1OTQsLTUuNzc1MTcgLTMuMjg3ODQsLTExLjU1MDM1IC02LjAyNzcxLC0xNi43NDgwMSBMIDExNC43NDczMiwxMDQuNzkyMjYgOTcuMjEyMTg2LDcyLjQ1MTI4NSBDIDk0LjQ3MjMyMSw2Ny4yNTM2MjggOTIuMjgwNDI4LDYxLjQ3ODQ1NCA5MS4xODQ0ODMsNTUuNzAzMjc5IGwgLTEuNjQzOTE5LDIuODg3NTg4IGMgLTkuMzE1NTQxLDE2Ljc0ODAwNiAtOS4zMTU1NDEsMzcuNTM4NjM2IDAsNTQuODY0MTczIGwgMzAuMTM4NTA2LDU0Ljg2NDE0IGMgOS4zMTU1NCwxNi43NDggOS4zMTU1NCwzOC4xMTYxNSAwLDU0Ljg2NDE2IGwgLTEuNjQzOTEsMi44ODc1OSBjIC0xLjA5NTk0LC01Ljc3NTE4IC0zLjI4Nzg0LC0xMS41NTAzNiAtNi4wMjc3MSwtMTYuNzQ4MDEgTCA3NC4xOTczMTksMTQwLjU5ODMzIGMgLTQuOTMxNzU0LC05LjI0MDI3IC03LjEyMzY0NywtMTkuNjM1NTcgLTcuMTIzNjQ3LC0zMC4wMzA4OSAtNDAuMDAyMDMsMTAuOTcyODMgLTY3Ljk0ODY1MDk1LDM0LjY1MTAzIC02Ny45NDg2NTA5NSw2MS43OTQzNSAwLDM4LjExNjE2IDUzLjcwMTM1MTk1LDY4LjcyNDU5IDEyMC4wMDYwNzg5NSw2OC43MjQ1OSA2Ni4zMDQ3MywwIDEyMC4wMDYwOSwtMzAuNjA4NDMgMTIwLjAwNjA5LC02OC43MjQ1OSAwLjU0Nzk2LC0yNS45ODgyOCAtMjYuODUwNjgsLTQ5LjY2NjQ5IC02Ny40MDA2OSwtNjAuNjM5MzIgeiIgZmlsbD0iI2VhMWQyNSIgaWQ9InBhdGgyIiBzb2RpcG9kaTpub2RldHlwZXM9ImNjY2NjY2NjY2NjY2NjY2NjY2NjY3NzY2MiIHN0eWxlPSJzdHJva2Utd2lkdGg6NS42MjU1MSIgLz4gPC9zdmc+",
22
+ };
23
+
24
+ export function BankLogo({ bank }: { bank: PixBankId }): JSX.Element {
25
+ return (
26
+ <Box
27
+ component="img"
28
+ src={LOGOS[bank]}
29
+ alt=""
30
+ aria-hidden="true"
31
+ data-bank={bank}
32
+ sx={{ width: 32, height: 32, flex: "none", objectFit: "contain", borderRadius: 1 }}
33
+ />
34
+ );
35
+ }
@@ -0,0 +1,26 @@
1
+ import type { PixBankCopy } from "./types";
2
+
3
+ /** The Pix-to-bank flow's words, pt-BR (FUT-3612). */
4
+ export const PT_BR_PIX_BANK_COPY: PixBankCopy = {
5
+ names: {
6
+ nubank: { name: "Nubank", the: "o " },
7
+ itau: { name: "Itaú", the: "o " },
8
+ bradesco: { name: "Bradesco", the: "o " },
9
+ bb: { name: "Banco do Brasil", the: "o " },
10
+ caixa: { name: "Caixa", the: "a " },
11
+ santander: { name: "Santander", the: "o " },
12
+ },
13
+ generateAndCopy: "Gerar e copiar o Pix",
14
+ generateCopyAndOpen: (bank) => `Gerar, copiar e abrir ${bank.the}${bank.name}`,
15
+ copyAndOpen: (bank) => `Copiar e abrir ${bank.the}${bank.name}`,
16
+ openOther: "Abrir outro banco",
17
+ listTitle: "Abra seu banco e cole em Pix copia e cola",
18
+ open: (bank) => `Abrir ${bank.name}`,
19
+ opening: (bank) => `Abrindo ${bank.the}**${bank.name}**…`,
20
+ other: "Outro banco",
21
+ notOpened: (bank) => `Não conseguimos abrir ${bank.the}${bank.name}. O app está instalado neste celular?`,
22
+ retry: "Tentar de novo",
23
+ copied: "Código Pix copiado",
24
+ copiedPick: "Código Pix copiado. Escolha o banco.",
25
+ copiedOpening: (bank) => `Código Pix copiado. Abrindo ${bank.the}${bank.name}…`,
26
+ };
@@ -84,9 +84,11 @@ export function lastUsedCard(saved: readonly SavedCard[]): SavedCard | undefined
84
84
  /**
85
85
  * What is chosen before the buyer touches anything (M7, owner 2026-10-15): a
86
86
  * saved card makes "Cartão de crédito" the choice with that card selected —
87
- * the one used last ({@link lastUsedCard}). Nothing else is ever
88
- * preselected: never Pix, never a door tender (FUT-1478), and not a store's
89
- * only method either (that pick used to raise an order with no tap at all).
87
+ * the one used last ({@link lastUsedCard}). The buyer's LAST online method
88
+ * (`lastMethod`, FUT-3611) wins when the store offers it: Pix as Pix, since
89
+ * choosing creates nothing any more. Never a door tender (FUT-1478), and not
90
+ * a store's only method by itself either (that pick used to raise an order
91
+ * with no tap at all).
90
92
  *
91
93
  * A buyer back here because a card was REFUSED (`fresh`) keeps the card
92
94
  * chosen, with no saved card selected for them — the one this would pick is
@@ -96,7 +98,10 @@ export function preselection(
96
98
  rows: readonly OnlineRow[],
97
99
  saved: readonly SavedCard[],
98
100
  fresh: boolean,
101
+ lastMethod: "PIX" | "CARD" | null = null,
99
102
  ): { choice: CheckoutListChoice; selection: string | null } | null {
103
+ const pixOffered = rows.some((row) => row.method === "PIX" && !row.disabled);
104
+ if (lastMethod === "PIX" && pixOffered && !fresh) return { choice: { kind: "online", method: "PIX" }, selection: null };
100
105
  const card = rows.find((row) => row.method === "CARD" && !row.disabled);
101
106
  if (!card) return null;
102
107
  if (fresh) return { choice: { kind: "online", method: "CARD" }, selection: saved.length > 0 ? null : NEW_CARD };
@@ -1,6 +1,19 @@
1
- import { createContext, useContext, useMemo, useState, type JSX, type ReactNode } from "react";
1
+ import { createContext, useContext, useMemo, useRef, useState, type JSX, type MutableRefObject, type ReactNode } from "react";
2
2
 
3
- import type { CheckoutPaymentList } from "./types";
3
+ import type { DeferredCopy } from "../pix-parts";
4
+
5
+ import type { CheckoutPaymentList, PixBankId } from "./types";
6
+
7
+ /**
8
+ * What the bar's Pix press asked of the code it is raising (FUT-3612): copy it
9
+ * the moment it arrives (the clipboard was opened inside the tap), then open
10
+ * `bank` — or show the six banks when `pick`. Consumed once by the Pix face.
11
+ */
12
+ export interface PixIntent {
13
+ copy: DeferredCopy;
14
+ bank: PixBankId | null;
15
+ pick: boolean;
16
+ }
4
17
 
5
18
  /**
6
19
  * What the one list shares with the panes it mounts (FUT-3591/3592): its
@@ -23,6 +36,15 @@ export interface PaymentListMode {
23
36
  * default — because the list skips that step.
24
37
  */
25
38
  consent: ListConsent;
39
+ /** The Pix press's intent, waiting for its code — see {@link PixIntent}. */
40
+ pixIntent: MutableRefObject<PixIntent | null>;
41
+ /**
42
+ * The armed charge (`armedCharge`) for this step: when it was armed and
43
+ * whether it was spent. Held HERE, above the faces, so a list face that
44
+ * remounts (after a Pix, "Prefere pagar com cartão?") can never fire it
45
+ * again — the 1-tap tap consented to ONE charge, right away.
46
+ */
47
+ armed: MutableRefObject<{ since: number; spent: boolean }>;
26
48
  }
27
49
 
28
50
  export interface ListConsent {
@@ -45,7 +67,9 @@ export function PaymentListProvider({
45
67
  children: ReactNode;
46
68
  }): JSX.Element {
47
69
  const [qrOpen, setQrOpen] = useState(false);
48
- const value = useMemo(() => ({ list, qrOpen, setQrOpen, onLeavePix, consent }), [list, qrOpen, onLeavePix, consent]);
70
+ const pixIntent = useRef<PixIntent | null>(null);
71
+ const armed = useRef({ since: Date.now(), spent: false });
72
+ const value = useMemo(() => ({ list, qrOpen, setQrOpen, onLeavePix, consent, pixIntent, armed }), [list, qrOpen, onLeavePix, consent]);
49
73
  return <PaymentListContext.Provider value={value}>{children}</PaymentListContext.Provider>;
50
74
  }
51
75
 
@@ -10,7 +10,11 @@ import type { BuyerContact, CheckoutProviderConfig } from "../types";
10
10
  import type { useCheckoutController } from "../use-checkout-controller";
11
11
  import { useCheckoutComponents } from "../ui";
12
12
 
13
+
13
14
  import { actionLabel, blockedReason, cardName } from "./choice";
15
+ import { usePaymentListMode, type PaymentListMode } from "./context";
16
+ import { armPixCopy, armedReady, otherBankShown, pixBankLabel, useArmedCharge, useDropRefusedCopy } from "./list-memory";
17
+ import { OtherBankLink } from "./list-pix";
14
18
  import { ChoiceList } from "./choice-list";
15
19
  import { CardRun, WalletRun, type ListChargeFailure } from "./charge-runners";
16
20
  import { ActionButton, ChargeBar, GooglePayAction, ListBar } from "./list-bar";
@@ -75,9 +79,10 @@ function onlineTotal(props: ListFaceProps): string {
75
79
  }
76
80
 
77
81
  /** An online choice's press: the card goes through the bar, Pix and the hand-off raise at once. */
78
- function actOnline(props: ListFaceProps, method: CheckoutOnlineChoice): void {
82
+ function actOnline(props: ListFaceProps, method: CheckoutOnlineChoice, mode: PaymentListMode | null, pick = false): void {
79
83
  const { c, charge, cap } = props;
80
84
  saveAsked(props);
85
+ if (method === "PIX" && mode) armPixCopy(props.list, mode, pick);
81
86
  if (method === "CARD") return charge.start("CARD", onlineTotal(props));
82
87
  const raised = method === "PIX" ? "PIX" : handOffMethod(cap.offered);
83
88
  if (method === "HAND_OFF") props.onHandOff();
@@ -90,13 +95,14 @@ function actOnline(props: ListFaceProps, method: CheckoutOnlineChoice): void {
90
95
  * or a charge. A door option hands the press to the host; the card counts five
91
96
  * seconds first; everything else raises at once.
92
97
  */
93
- function useAct(props: ListFaceProps, clearFailure: () => void): () => void {
94
- return () => {
98
+ function useAct(props: ListFaceProps, clearFailure: () => void): (pick?: boolean) => void {
99
+ const mode = usePaymentListMode();
100
+ return (pick = false) => {
95
101
  const { choice } = props.state;
96
102
  if (!choice || inFlight(props)) return;
97
103
  if (choice.kind === "door") return chosenDoor(props)?.onSend();
98
104
  clearFailure();
99
- actOnline(props, choice.method);
105
+ actOnline(props, choice.method, mode, pick);
100
106
  };
101
107
  }
102
108
 
@@ -176,7 +182,7 @@ function buttonFacts(props: ListFaceProps): { label: string; total: string; busy
176
182
  const door = chosenDoor(props);
177
183
  const online = state.choice?.kind === "online";
178
184
  return {
179
- label: list.hold ? list.hold.action : actionLabel(list.copy, state.choice, door, props.provider),
185
+ label: list.hold ? list.hold.action : pixBankLabel(list, state) ?? actionLabel(list.copy, state.choice, door, props.provider),
180
186
  total: door ? (door.totalLabel ?? props.total) : online ? onlineTotal(props) : props.total,
181
187
  busy: inFlight(props),
182
188
  };
@@ -198,27 +204,58 @@ function googlePayLive(props: ListFaceProps, reason: string | null, busy: boolea
198
204
  return choice?.kind === "online" && choice.method === "GOOGLE_PAY" && props.cap.googlePay !== null && reason === null && !busy;
199
205
  }
200
206
 
207
+ /** The 5-second bar (or the charge going out), and the host's footer while it counts. */
208
+ function ChargingBar({ props, onCancel }: { props: ListFaceProps; onCancel: () => void }): JSX.Element {
209
+ const { charge, list } = props;
210
+ const counting = charge.phase === "counting";
211
+ const footer = counting ? list.chargeFooter?.(charge.cancel) : null;
212
+ return (
213
+ <>
214
+ <ChargeBar text={chargingText(props)} full={!counting} cancelLabel={list.copy.cancel} onCancel={onCancel} />
215
+ {footer ? <Box data-testid="list-charge-footer">{footer}</Box> : null}
216
+ </>
217
+ );
218
+ }
219
+
220
+ /** The button, and "Abrir outro banco" under it when a remembered bank would open. */
221
+ function PressButton({ props, act, reason, returnFocus }: {
222
+ props: ListFaceProps;
223
+ act: (pick?: boolean) => void;
224
+ reason: string | null;
225
+ returnFocus: boolean;
226
+ }): JSX.Element {
227
+ const { list, state } = props;
228
+ const { label, total, busy } = buttonFacts(props);
229
+ const other = list.pixBank && otherBankShown(list, state, reason === null && !busy) ? list.pixBank.copy.openOther : null;
230
+ return (
231
+ <>
232
+ <ActionButton label={label} total={total} disabled={reason !== null || busy} loading={busy} onClick={() => act()} focusOnMount={returnFocus} />
233
+ {other ? <OtherBankLink label={other} onClick={() => act(true)} /> : null}
234
+ </>
235
+ );
236
+ }
237
+
201
238
  /** The button, the 5-second bar, Google's own button, or nothing for a charge nobody can confirm yet. */
202
239
  function BarAction({ props, failure, act, onGooglePay, onCancel, reason, returnFocus }: {
203
240
  props: ListFaceProps;
204
241
  failure: ListChargeFailure | null;
205
- act: () => void;
242
+ act: (pick?: boolean) => void;
206
243
  onGooglePay: () => void;
207
244
  onCancel: () => void;
208
245
  reason: string | null;
209
246
  returnFocus: boolean;
210
247
  }): JSX.Element | null {
211
- const { charge, list, cap } = props;
212
- if (cardCharging(charge)) {
213
- return <ChargeBar text={chargingText(props)} full={charge.phase !== "counting"} cancelLabel={list.copy.cancel} onCancel={onCancel} />;
214
- }
248
+ const { charge, cap } = props;
249
+ if (cardCharging(charge)) return <ChargingBar props={props} onCancel={onCancel} />;
215
250
  // An UNRESOLVED charge may be holding the buyer's money: no pay control at
216
251
  // all under "não pague de novo" (FUT-563), as the card pane does today.
217
252
  if (failure?.code === UNRESOLVED_CODE) return null;
218
- const { label, total, busy } = buttonFacts(props);
219
- if (googlePayUnpriced(props)) return <ActionButton label={label} total={total} disabled loading={false} onClick={act} />;
220
- if (googlePayLive(props, reason, busy) && cap.googlePay) return <GooglePayAction client={cap.googlePay.client} onPress={onGooglePay} />;
221
- return <ActionButton label={label} total={total} disabled={reason !== null || busy} loading={busy} onClick={act} focusOnMount={returnFocus} />;
253
+ if (googlePayUnpriced(props)) {
254
+ const { label, total } = buttonFacts(props);
255
+ return <ActionButton label={label} total={total} disabled loading={false} onClick={() => act()} />;
256
+ }
257
+ if (googlePayLive(props, reason, inFlight(props)) && cap.googlePay) return <GooglePayAction client={cap.googlePay.client} onPress={onGooglePay} />;
258
+ return <PressButton props={props} act={act} reason={reason} returnFocus={returnFocus} />;
222
259
  }
223
260
 
224
261
  /** The charge under way, once there is an order to run it against. */
@@ -318,6 +355,9 @@ export function ListFace(props: ListFaceProps): JSX.Element {
318
355
  const door = chosenDoor(props);
319
356
  const reason = reasonOf(props, door);
320
357
  useChargeGuard(props, reason);
358
+ const free = reason === null && props.charge.phase === "idle" && !c.creating;
359
+ useArmedCharge(armedReady(list, state, free), act);
360
+ useDropRefusedCopy(c.createError);
321
361
  const { returnFocus, onCancel } = useCancelWithFocus(charge);
322
362
  const shown = charge.phase !== "waiting";
323
363
  const facts = barFacts(props, door, reason);
@@ -327,7 +367,7 @@ export function ListFace(props: ListFaceProps): JSX.Element {
327
367
  <ChoiceList copy={list.copy} state={state} door={list.door ?? []} buyer={c.buyer} onBuyerChange={c.setBuyer} provider={props.provider} failure={failure} locked={facts.locked} covered={coveredByHost(list)} />
328
368
  ) : null}
329
369
  <Runners props={props} sheet={sheet.current} onFailed={onFailed} />
330
- <RaiseError c={c} onRetry={act} />
370
+ <RaiseError c={c} onRetry={() => act()} />
331
371
  {shown ? (
332
372
  <ListBar summary={list.summary} extras={facts.extras} payer={facts.charging ? null : <PayerLine props={props} />} reason={facts.underButton} live={facts.live}>
333
373
  <BarAction props={props} failure={failure} act={act} onGooglePay={onGooglePay} onCancel={onCancel} reason={reason} returnFocus={returnFocus} />