diff options
Diffstat (limited to 'packages/taler-wallet-webextension')
37 files changed, 4151 insertions, 7253 deletions
diff --git a/packages/taler-wallet-webextension/src/background.dev.ts b/packages/taler-wallet-webextension/src/background.dev.ts index d27d83bab..9938ed7e8 100644 --- a/packages/taler-wallet-webextension/src/background.dev.ts +++ b/packages/taler-wallet-webextension/src/background.dev.ts @@ -27,17 +27,17 @@ import { platform, setupPlatform } from "./platform/api.js"; import devAPI from "./platform/dev.js"; import { wxMain } from "./wxBackend.js"; -console.log("Wallet setup for Dev API") -setupPlatform(devAPI) +console.log("Wallet setup for Dev API"); +setupPlatform(devAPI); try { platform.registerOnInstalled(() => { - platform.openWalletPage("/welcome") - }) + platform.openWalletPage("/welcome"); + }); } catch (e) { console.error(e); } platform.notifyWhenAppIsReady(() => { wxMain(); -}) +}); diff --git a/packages/taler-wallet-webextension/src/background.ts b/packages/taler-wallet-webextension/src/background.ts index 134bec190..6221ab080 100644 --- a/packages/taler-wallet-webextension/src/background.ts +++ b/packages/taler-wallet-webextension/src/background.ts @@ -28,22 +28,24 @@ import chromeAPI from "./platform/chrome.js"; import firefoxAPI from "./platform/firefox.js"; import { wxMain } from "./wxBackend.js"; -const isFirefox = typeof (window as any) !== 'undefined' && typeof (window as any)['InstallTrigger'] !== 'undefined' +const isFirefox = + typeof (window as any) !== "undefined" && + typeof (window as any)["InstallTrigger"] !== "undefined"; -// FIXME: create different entry point for any platform instead of +// FIXME: create different entry point for any platform instead of // switching in runtime if (isFirefox) { - console.log("Wallet setup for Firefox API") - setupPlatform(firefoxAPI) + console.log("Wallet setup for Firefox API"); + setupPlatform(firefoxAPI); } else { - console.log("Wallet setup for Chrome API") - setupPlatform(chromeAPI) + console.log("Wallet setup for Chrome API"); + setupPlatform(chromeAPI); } try { platform.registerOnInstalled(() => { - platform.openWalletPage("/welcome") - }) + platform.openWalletPage("/welcome"); + }); } catch (e) { console.error(e); } @@ -51,4 +53,4 @@ try { // setGlobalLogLevelFromString("trace") platform.notifyWhenAppIsReady(() => { wxMain(); -}) +}); diff --git a/packages/taler-wallet-webextension/src/browserHttpLib.ts b/packages/taler-wallet-webextension/src/browserHttpLib.ts index 93d4939c5..2fca0ea34 100644 --- a/packages/taler-wallet-webextension/src/browserHttpLib.ts +++ b/packages/taler-wallet-webextension/src/browserHttpLib.ts @@ -178,7 +178,7 @@ export class BrowserHttpLib implements HttpRequestLibrary { ): Promise<HttpResponse> { return this.fetch(url, { method: "POST", - headers: {"Content-Type": "application/json"}, + headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), ...opt, }); diff --git a/packages/taler-wallet-webextension/src/context/devContext.ts b/packages/taler-wallet-webextension/src/context/devContext.ts index ec79f22d8..fb4781ba0 100644 --- a/packages/taler-wallet-webextension/src/context/devContext.ts +++ b/packages/taler-wallet-webextension/src/context/devContext.ts @@ -29,7 +29,9 @@ interface Type { } const Context = createContext<Type>({ devMode: false, - toggleDevMode: async () => { return; }, + toggleDevMode: async () => { + return; + }, }); export const useDevContext = (): Type => useContext(Context); @@ -55,7 +57,8 @@ export const DevContextProviderForTesting = ({ export const DevContextProvider = ({ children }: { children: any }): VNode => { const [value, setter] = useLocalStorage("devMode"); const devMode = value === "true"; - const toggleDevMode = async (): Promise<void> => setter((v) => (!v ? "true" : undefined)); + const toggleDevMode = async (): Promise<void> => + setter((v) => (!v ? "true" : undefined)); children = children.length === 1 && typeof children === "function" ? children({ devMode }) diff --git a/packages/taler-wallet-webextension/src/context/iocContext.ts b/packages/taler-wallet-webextension/src/context/iocContext.ts index aaf1f8b67..d875d9c76 100644 --- a/packages/taler-wallet-webextension/src/context/iocContext.ts +++ b/packages/taler-wallet-webextension/src/context/iocContext.ts @@ -32,18 +32,31 @@ const Context = createContext<Type>({ /** * Inversion of control Context - * - * This context act as a proxy between API that need to be replaced in + * + * This context act as a proxy between API that need to be replaced in * different environments - * - * @returns + * + * @returns */ export const useIocContext = (): Type => useContext(Context); -export const IoCProviderForTesting = ({ value, children }: { value: Type, children: any }): VNode => { +export const IoCProviderForTesting = ({ + value, + children, +}: { + value: Type; + children: any; +}): VNode => { return h(Context.Provider, { value, children }); }; -export const IoCProviderForRuntime = ({ children }: { children: any }): VNode => { - return h(Context.Provider, { value: { findTalerUriInActiveTab: platform.findTalerUriInActiveTab }, children }); +export const IoCProviderForRuntime = ({ + children, +}: { + children: any; +}): VNode => { + return h(Context.Provider, { + value: { findTalerUriInActiveTab: platform.findTalerUriInActiveTab }, + children, + }); }; diff --git a/packages/taler-wallet-webextension/src/context/translation.ts b/packages/taler-wallet-webextension/src/context/translation.ts index 9d55c918b..edc1f9ca3 100644 --- a/packages/taler-wallet-webextension/src/context/translation.ts +++ b/packages/taler-wallet-webextension/src/context/translation.ts @@ -27,7 +27,7 @@ import { strings } from "../i18n/strings.js"; interface Type { lang: string; - supportedLang: { [id in keyof typeof supportedLang]: string } + supportedLang: { [id in keyof typeof supportedLang]: string }; changeLanguage: (l: string) => void; i18n: typeof i18n; isSaved: boolean; @@ -47,7 +47,6 @@ const supportedLang = { navigator: "Defined by navigator", }; - const initial = { lang: "en", supportedLang, @@ -84,7 +83,10 @@ export const TranslationProvider = ({ } else { setupI18n(lang, strings); } - return h(Context.Provider, { value: { lang, changeLanguage, supportedLang, i18n, isSaved }, children }); + return h(Context.Provider, { + value: { lang, changeLanguage, supportedLang, i18n, isSaved }, + children, + }); }; export const useTranslationContext = (): Type => useContext(Context); diff --git a/packages/taler-wallet-webextension/src/cta/Deposit.test.ts b/packages/taler-wallet-webextension/src/cta/Deposit.test.ts index 16e7961cc..e4c909f9b 100644 --- a/packages/taler-wallet-webextension/src/cta/Deposit.test.ts +++ b/packages/taler-wallet-webextension/src/cta/Deposit.test.ts @@ -26,58 +26,61 @@ import { useComponentState } from "./Deposit.jsx"; describe("Deposit CTA states", () => { it("should tell the user that the URI is missing", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState(undefined, undefined, { - prepareRefund: async () => ({}), - applyRefund: async () => ({}), - onUpdateNotification: async () => ({}) - } as any), - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState(undefined, undefined, { + prepareRefund: async () => ({}), + applyRefund: async () => ({}), + onUpdateNotification: async () => ({}), + } as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } - await waitNextUpdate() + await waitNextUpdate(); { - const { status, hook } = getLastResultOrThrow() + const { status, hook } = getLastResultOrThrow(); - expect(status).equals('loading') + expect(status).equals("loading"); if (!hook) expect.fail(); if (!hook.hasError) expect.fail(); if (hook.operational) expect.fail(); expect(hook.message).eq("ERROR_NO-URI-FOR-DEPOSIT"); } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should be ready after loading", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState("payto://refund/asdasdas", "EUR:1", { - prepareDeposit: async () => ({ - effectiveDepositAmount: Amounts.parseOrThrow("EUR:1"), - totalDepositCost: Amounts.parseOrThrow("EUR:1.2") - } as PrepareDepositResponse as any), - createDepositGroup: async () => ({}), - } as any), - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState("payto://refund/asdasdas", "EUR:1", { + prepareDeposit: async () => + ({ + effectiveDepositAmount: Amounts.parseOrThrow("EUR:1"), + totalDepositCost: Amounts.parseOrThrow("EUR:1.2"), + } as PrepareDepositResponse as any), + createDepositGroup: async () => ({}), + } as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } - await waitNextUpdate() + await waitNextUpdate(); { - const state = getLastResultOrThrow() + const state = getLastResultOrThrow(); - if (state.status !== 'ready') expect.fail(); + if (state.status !== "ready") expect.fail(); if (state.hook) expect.fail(); expect(state.confirm.onClick).not.undefined; expect(state.cost).deep.eq(Amounts.parseOrThrow("EUR:1.2")); @@ -85,8 +88,6 @@ describe("Deposit CTA states", () => { expect(state.effective).deep.eq(Amounts.parseOrThrow("EUR:1")); } - await assertNoPendingUpdate() - + await assertNoPendingUpdate(); }); - -});
\ No newline at end of file +}); diff --git a/packages/taler-wallet-webextension/src/cta/Pay.test.ts b/packages/taler-wallet-webextension/src/cta/Pay.test.ts index 7e9d5338f..a45ebd3a2 100644 --- a/packages/taler-wallet-webextension/src/cta/Pay.test.ts +++ b/packages/taler-wallet-webextension/src/cta/Pay.test.ts @@ -19,7 +19,16 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { AmountJson, Amounts, BalancesResponse, ConfirmPayResult, ConfirmPayResultType, NotificationType, PreparePayResult, PreparePayResultType } from "@gnu-taler/taler-util"; +import { + AmountJson, + Amounts, + BalancesResponse, + ConfirmPayResult, + ConfirmPayResultType, + NotificationType, + PreparePayResult, + PreparePayResultType, +} from "@gnu-taler/taler-util"; import { expect } from "chai"; import { mountHook } from "../test-utils.js"; import * as wxApi from "../wxApi.js"; @@ -29,8 +38,8 @@ const nullFunction: any = () => null; type VoidFunction = () => void; type Subs = { - [key in NotificationType]?: VoidFunction -} + [key in NotificationType]?: VoidFunction; +}; export class SubsHandler { private subs: Subs = {}; @@ -39,311 +48,340 @@ export class SubsHandler { this.saveSubscription = this.saveSubscription.bind(this); } - saveSubscription(messageTypes: NotificationType[], callback: VoidFunction): VoidFunction { - messageTypes.forEach(m => { + saveSubscription( + messageTypes: NotificationType[], + callback: VoidFunction, + ): VoidFunction { + messageTypes.forEach((m) => { this.subs[m] = callback; - }) + }); return nullFunction; } notifyEvent(event: NotificationType): void { const cb = this.subs[event]; - if (cb === undefined) expect.fail(`Expected to have a subscription for ${event}`); - cb() + if (cb === undefined) + expect.fail(`Expected to have a subscription for ${event}`); + cb(); } } - describe("Pay CTA states", () => { it("should tell the user that the URI is missing", async () => { - - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState(undefined, { - onUpdateNotification: nullFunction, - } as Partial<typeof wxApi> as any) - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState(undefined, { + onUpdateNotification: nullFunction, + } as Partial<typeof wxApi> as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } - await waitNextUpdate() + await waitNextUpdate(); { - const { status, hook } = getLastResultOrThrow() + const { status, hook } = getLastResultOrThrow(); - expect(status).equals('loading') - if (hook === undefined) expect.fail() + expect(status).equals("loading"); + if (hook === undefined) expect.fail(); expect(hook.hasError).true; expect(hook.operational).false; } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should response with no balance", async () => { - - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState('taller://pay', { - onUpdateNotification: nullFunction, - preparePay: async () => ({ - amountRaw: 'USD:10', - status: PreparePayResultType.InsufficientBalance, - } as Partial<PreparePayResult>), - getBalance: async () => ({ - balances: [] - } as Partial<BalancesResponse>), - } as Partial<typeof wxApi> as any) - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState("taller://pay", { + onUpdateNotification: nullFunction, + preparePay: async () => + ({ + amountRaw: "USD:10", + status: PreparePayResultType.InsufficientBalance, + } as Partial<PreparePayResult>), + getBalance: async () => + ({ + balances: [], + } as Partial<BalancesResponse>), + } as Partial<typeof wxApi> as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } await waitNextUpdate(); { - const r = getLastResultOrThrow() - if (r.status !== 'ready') expect.fail() + const r = getLastResultOrThrow(); + if (r.status !== "ready") expect.fail(); expect(r.balance).undefined; - expect(r.amount).deep.equal(Amounts.parseOrThrow('USD:10')) + expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:10")); expect(r.payHandler.onClick).undefined; } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should not be able to pay if there is no enough balance", async () => { - - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState('taller://pay', { - onUpdateNotification: nullFunction, - preparePay: async () => ({ - amountRaw: 'USD:10', - status: PreparePayResultType.InsufficientBalance, - } as Partial<PreparePayResult>), - getBalance: async () => ({ - balances: [{ - available: 'USD:5' - }] - } as Partial<BalancesResponse>), - } as Partial<typeof wxApi> as any) - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState("taller://pay", { + onUpdateNotification: nullFunction, + preparePay: async () => + ({ + amountRaw: "USD:10", + status: PreparePayResultType.InsufficientBalance, + } as Partial<PreparePayResult>), + getBalance: async () => + ({ + balances: [ + { + available: "USD:5", + }, + ], + } as Partial<BalancesResponse>), + } as Partial<typeof wxApi> as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } await waitNextUpdate(); { - const r = getLastResultOrThrow() - if (r.status !== 'ready') expect.fail() - expect(r.balance).deep.equal(Amounts.parseOrThrow('USD:5')); - expect(r.amount).deep.equal(Amounts.parseOrThrow('USD:10')) + const r = getLastResultOrThrow(); + if (r.status !== "ready") expect.fail(); + expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:5")); + expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:10")); expect(r.payHandler.onClick).undefined; } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should be able to pay (without fee)", async () => { - - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState('taller://pay', { - onUpdateNotification: nullFunction, - preparePay: async () => ({ - amountRaw: 'USD:10', - amountEffective: 'USD:10', - status: PreparePayResultType.PaymentPossible, - } as Partial<PreparePayResult>), - getBalance: async () => ({ - balances: [{ - available: 'USD:15' - }] - } as Partial<BalancesResponse>), - } as Partial<typeof wxApi> as any) - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState("taller://pay", { + onUpdateNotification: nullFunction, + preparePay: async () => + ({ + amountRaw: "USD:10", + amountEffective: "USD:10", + status: PreparePayResultType.PaymentPossible, + } as Partial<PreparePayResult>), + getBalance: async () => + ({ + balances: [ + { + available: "USD:15", + }, + ], + } as Partial<BalancesResponse>), + } as Partial<typeof wxApi> as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } await waitNextUpdate(); { - const r = getLastResultOrThrow() - if (r.status !== 'ready') expect.fail() - expect(r.balance).deep.equal(Amounts.parseOrThrow('USD:15')); - expect(r.amount).deep.equal(Amounts.parseOrThrow('USD:10')) - expect(r.totalFees).deep.equal(Amounts.parseOrThrow('USD:0')) + const r = getLastResultOrThrow(); + if (r.status !== "ready") expect.fail(); + expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:15")); + expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:10")); + expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:0")); expect(r.payHandler.onClick).not.undefined; } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should be able to pay (with fee)", async () => { - - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState('taller://pay', { - onUpdateNotification: nullFunction, - preparePay: async () => ({ - amountRaw: 'USD:9', - amountEffective: 'USD:10', - status: PreparePayResultType.PaymentPossible, - } as Partial<PreparePayResult>), - getBalance: async () => ({ - balances: [{ - available: 'USD:15' - }] - } as Partial<BalancesResponse>), - } as Partial<typeof wxApi> as any) - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState("taller://pay", { + onUpdateNotification: nullFunction, + preparePay: async () => + ({ + amountRaw: "USD:9", + amountEffective: "USD:10", + status: PreparePayResultType.PaymentPossible, + } as Partial<PreparePayResult>), + getBalance: async () => + ({ + balances: [ + { + available: "USD:15", + }, + ], + } as Partial<BalancesResponse>), + } as Partial<typeof wxApi> as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } await waitNextUpdate(); { - const r = getLastResultOrThrow() - if (r.status !== 'ready') expect.fail() - expect(r.balance).deep.equal(Amounts.parseOrThrow('USD:15')); - expect(r.amount).deep.equal(Amounts.parseOrThrow('USD:9')) - expect(r.totalFees).deep.equal(Amounts.parseOrThrow('USD:1')) + const r = getLastResultOrThrow(); + if (r.status !== "ready") expect.fail(); + expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:15")); + expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:9")); + expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); expect(r.payHandler.onClick).not.undefined; } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should get confirmation done after pay successfully", async () => { - - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState('taller://pay', { - onUpdateNotification: nullFunction, - preparePay: async () => ({ - amountRaw: 'USD:9', - amountEffective: 'USD:10', - status: PreparePayResultType.PaymentPossible, - } as Partial<PreparePayResult>), - getBalance: async () => ({ - balances: [{ - available: 'USD:15' - }] - } as Partial<BalancesResponse>), - confirmPay: async () => ({ - type: ConfirmPayResultType.Done, - contractTerms: {} - } as Partial<ConfirmPayResult>), - } as Partial<typeof wxApi> as any) - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState("taller://pay", { + onUpdateNotification: nullFunction, + preparePay: async () => + ({ + amountRaw: "USD:9", + amountEffective: "USD:10", + status: PreparePayResultType.PaymentPossible, + } as Partial<PreparePayResult>), + getBalance: async () => + ({ + balances: [ + { + available: "USD:15", + }, + ], + } as Partial<BalancesResponse>), + confirmPay: async () => + ({ + type: ConfirmPayResultType.Done, + contractTerms: {}, + } as Partial<ConfirmPayResult>), + } as Partial<typeof wxApi> as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } await waitNextUpdate(); { - const r = getLastResultOrThrow() - if (r.status !== 'ready') expect.fail() - expect(r.balance).deep.equal(Amounts.parseOrThrow('USD:15')); - expect(r.amount).deep.equal(Amounts.parseOrThrow('USD:9')) - expect(r.totalFees).deep.equal(Amounts.parseOrThrow('USD:1')) + const r = getLastResultOrThrow(); + if (r.status !== "ready") expect.fail(); + expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:15")); + expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:9")); + expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); if (r.payHandler.onClick === undefined) expect.fail(); - r.payHandler.onClick() + r.payHandler.onClick(); } await waitNextUpdate(); { - const r = getLastResultOrThrow() - if (r.status !== 'confirmed') expect.fail() - expect(r.balance).deep.equal(Amounts.parseOrThrow('USD:15')); - expect(r.amount).deep.equal(Amounts.parseOrThrow('USD:9')) - expect(r.totalFees).deep.equal(Amounts.parseOrThrow('USD:1')) + const r = getLastResultOrThrow(); + if (r.status !== "confirmed") expect.fail(); + expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:15")); + expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:9")); + expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); if (r.payResult.type !== ConfirmPayResultType.Done) expect.fail(); expect(r.payResult.contractTerms).not.undefined; expect(r.payHandler.onClick).undefined; } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should not stay in ready state after pay with error", async () => { - - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState('taller://pay', { - onUpdateNotification: nullFunction, - preparePay: async () => ({ - amountRaw: 'USD:9', - amountEffective: 'USD:10', - status: PreparePayResultType.PaymentPossible, - } as Partial<PreparePayResult>), - getBalance: async () => ({ - balances: [{ - available: 'USD:15' - }] - } as Partial<BalancesResponse>), - confirmPay: async () => ({ - type: ConfirmPayResultType.Pending, - lastError: { code: 1 }, - } as Partial<ConfirmPayResult>), - } as Partial<typeof wxApi> as any) - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState("taller://pay", { + onUpdateNotification: nullFunction, + preparePay: async () => + ({ + amountRaw: "USD:9", + amountEffective: "USD:10", + status: PreparePayResultType.PaymentPossible, + } as Partial<PreparePayResult>), + getBalance: async () => + ({ + balances: [ + { + available: "USD:15", + }, + ], + } as Partial<BalancesResponse>), + confirmPay: async () => + ({ + type: ConfirmPayResultType.Pending, + lastError: { code: 1 }, + } as Partial<ConfirmPayResult>), + } as Partial<typeof wxApi> as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } await waitNextUpdate(); { - const r = getLastResultOrThrow() - if (r.status !== 'ready') expect.fail() - expect(r.balance).deep.equal(Amounts.parseOrThrow('USD:15')); - expect(r.amount).deep.equal(Amounts.parseOrThrow('USD:9')) - expect(r.totalFees).deep.equal(Amounts.parseOrThrow('USD:1')) + const r = getLastResultOrThrow(); + if (r.status !== "ready") expect.fail(); + expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:15")); + expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:9")); + expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); if (r.payHandler.onClick === undefined) expect.fail(); - r.payHandler.onClick() + r.payHandler.onClick(); } await waitNextUpdate(); { - const r = getLastResultOrThrow() - if (r.status !== 'ready') expect.fail() - expect(r.balance).deep.equal(Amounts.parseOrThrow('USD:15')); - expect(r.amount).deep.equal(Amounts.parseOrThrow('USD:9')) - expect(r.totalFees).deep.equal(Amounts.parseOrThrow('USD:1')) + const r = getLastResultOrThrow(); + if (r.status !== "ready") expect.fail(); + expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:15")); + expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:9")); + expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); expect(r.payHandler.onClick).undefined; if (r.payHandler.error === undefined) expect.fail(); //FIXME: error message here is bad - expect(r.payHandler.error.errorDetail.hint).eq("could not confirm payment") + expect(r.payHandler.error.errorDetail.hint).eq( + "could not confirm payment", + ); expect(r.payHandler.error.errorDetail.payResult).deep.equal({ type: ConfirmPayResultType.Pending, - lastError: { code: 1 } - }) + lastError: { code: 1 }, + }); } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should update balance if a coins is withdraw", async () => { @@ -351,40 +389,45 @@ describe("Pay CTA states", () => { let availableBalance = Amounts.parseOrThrow("USD:10"); function notifyCoinWithdrawn(newAmount: AmountJson): void { - availableBalance = Amounts.add(availableBalance, newAmount).amount - subscriptions.notifyEvent(NotificationType.CoinWithdrawn) + availableBalance = Amounts.add(availableBalance, newAmount).amount; + subscriptions.notifyEvent(NotificationType.CoinWithdrawn); } - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState('taller://pay', { - onUpdateNotification: subscriptions.saveSubscription, - preparePay: async () => ({ - amountRaw: 'USD:9', - amountEffective: 'USD:10', - status: PreparePayResultType.PaymentPossible, - } as Partial<PreparePayResult>), - getBalance: async () => ({ - balances: [{ - available: Amounts.stringify(availableBalance) - }] - } as Partial<BalancesResponse>), - } as Partial<typeof wxApi> as any) - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState("taller://pay", { + onUpdateNotification: subscriptions.saveSubscription, + preparePay: async () => + ({ + amountRaw: "USD:9", + amountEffective: "USD:10", + status: PreparePayResultType.PaymentPossible, + } as Partial<PreparePayResult>), + getBalance: async () => + ({ + balances: [ + { + available: Amounts.stringify(availableBalance), + }, + ], + } as Partial<BalancesResponse>), + } as Partial<typeof wxApi> as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } await waitNextUpdate(); { - const r = getLastResultOrThrow() - if (r.status !== 'ready') expect.fail() - expect(r.balance).deep.equal(Amounts.parseOrThrow('USD:10')); - expect(r.amount).deep.equal(Amounts.parseOrThrow('USD:9')) - expect(r.totalFees).deep.equal(Amounts.parseOrThrow('USD:1')) + const r = getLastResultOrThrow(); + if (r.status !== "ready") expect.fail(); + expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:10")); + expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:9")); + expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); expect(r.payHandler.onClick).not.undefined; notifyCoinWithdrawn(Amounts.parseOrThrow("USD:5")); @@ -393,16 +436,14 @@ describe("Pay CTA states", () => { await waitNextUpdate(); { - const r = getLastResultOrThrow() - if (r.status !== 'ready') expect.fail() - expect(r.balance).deep.equal(Amounts.parseOrThrow('USD:15')); - expect(r.amount).deep.equal(Amounts.parseOrThrow('USD:9')) - expect(r.totalFees).deep.equal(Amounts.parseOrThrow('USD:1')) + const r = getLastResultOrThrow(); + if (r.status !== "ready") expect.fail(); + expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:15")); + expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:9")); + expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); expect(r.payHandler.onClick).not.undefined; } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); - - -});
\ No newline at end of file +}); diff --git a/packages/taler-wallet-webextension/src/cta/Refund.test.ts b/packages/taler-wallet-webextension/src/cta/Refund.test.ts index 864b4f12c..80ef15c84 100644 --- a/packages/taler-wallet-webextension/src/cta/Refund.test.ts +++ b/packages/taler-wallet-webextension/src/cta/Refund.test.ts @@ -19,7 +19,12 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { AmountJson, Amounts, NotificationType, PrepareRefundResult } from "@gnu-taler/taler-util"; +import { + AmountJson, + Amounts, + NotificationType, + PrepareRefundResult, +} from "@gnu-taler/taler-util"; import { expect } from "chai"; import { mountHook } from "../test-utils.js"; import { SubsHandler } from "./Pay.test.js"; @@ -29,146 +34,151 @@ import { useComponentState } from "./Refund.jsx"; describe("Refund CTA states", () => { it("should tell the user that the URI is missing", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState(undefined, { - prepareRefund: async () => ({}), - applyRefund: async () => ({}), - onUpdateNotification: async () => ({}) - } as any), - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState(undefined, { + prepareRefund: async () => ({}), + applyRefund: async () => ({}), + onUpdateNotification: async () => ({}), + } as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } - await waitNextUpdate() + await waitNextUpdate(); { - const { status, hook } = getLastResultOrThrow() + const { status, hook } = getLastResultOrThrow(); - expect(status).equals('loading') + expect(status).equals("loading"); if (!hook) expect.fail(); if (!hook.hasError) expect.fail(); if (hook.operational) expect.fail(); expect(hook.message).eq("ERROR_NO-URI-FOR-REFUND"); } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should be ready after loading", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState("taler://refund/asdasdas", { - prepareRefund: async () => ({ - effectivePaid: 'EUR:2', - awaiting: 'EUR:2', - gone: 'EUR:0', - granted: 'EUR:0', - pending: false, - proposalId: '1', - info: { - contractTermsHash: '123', - merchant: { - name: 'the merchant name' - }, - orderId: 'orderId1', - summary: 'the sumary' - } - } as PrepareRefundResult as any), - applyRefund: async () => ({}), - onUpdateNotification: async () => ({}) - } as any), - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState("taler://refund/asdasdas", { + prepareRefund: async () => + ({ + effectivePaid: "EUR:2", + awaiting: "EUR:2", + gone: "EUR:0", + granted: "EUR:0", + pending: false, + proposalId: "1", + info: { + contractTermsHash: "123", + merchant: { + name: "the merchant name", + }, + orderId: "orderId1", + summary: "the sumary", + }, + } as PrepareRefundResult as any), + applyRefund: async () => ({}), + onUpdateNotification: async () => ({}), + } as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } - await waitNextUpdate() + await waitNextUpdate(); { - const state = getLastResultOrThrow() + const state = getLastResultOrThrow(); - if (state.status !== 'ready') expect.fail(); + if (state.status !== "ready") expect.fail(); if (state.hook) expect.fail(); expect(state.accept.onClick).not.undefined; expect(state.ignore.onClick).not.undefined; - expect(state.merchantName).eq('the merchant name'); - expect(state.orderId).eq('orderId1'); + expect(state.merchantName).eq("the merchant name"); + expect(state.orderId).eq("orderId1"); expect(state.products).undefined; } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should be ignored after clicking the ignore button", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState("taler://refund/asdasdas", { - prepareRefund: async () => ({ - effectivePaid: 'EUR:2', - awaiting: 'EUR:2', - gone: 'EUR:0', - granted: 'EUR:0', - pending: false, - proposalId: '1', - info: { - contractTermsHash: '123', - merchant: { - name: 'the merchant name' - }, - orderId: 'orderId1', - summary: 'the sumary' - } - } as PrepareRefundResult as any), - applyRefund: async () => ({}), - onUpdateNotification: async () => ({}) - } as any), - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState("taler://refund/asdasdas", { + prepareRefund: async () => + ({ + effectivePaid: "EUR:2", + awaiting: "EUR:2", + gone: "EUR:0", + granted: "EUR:0", + pending: false, + proposalId: "1", + info: { + contractTermsHash: "123", + merchant: { + name: "the merchant name", + }, + orderId: "orderId1", + summary: "the sumary", + }, + } as PrepareRefundResult as any), + applyRefund: async () => ({}), + onUpdateNotification: async () => ({}), + } as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } - await waitNextUpdate() + await waitNextUpdate(); { - const state = getLastResultOrThrow() + const state = getLastResultOrThrow(); - if (state.status !== 'ready') expect.fail(); + if (state.status !== "ready") expect.fail(); if (state.hook) expect.fail(); expect(state.accept.onClick).not.undefined; - expect(state.merchantName).eq('the merchant name'); - expect(state.orderId).eq('orderId1'); + expect(state.merchantName).eq("the merchant name"); + expect(state.orderId).eq("orderId1"); expect(state.products).undefined; if (state.ignore.onClick === undefined) expect.fail(); - state.ignore.onClick() + state.ignore.onClick(); } - await waitNextUpdate() + await waitNextUpdate(); { - const state = getLastResultOrThrow() + const state = getLastResultOrThrow(); - if (state.status !== 'ignored') expect.fail(); + if (state.status !== "ignored") expect.fail(); if (state.hook) expect.fail(); - expect(state.merchantName).eq('the merchant name'); + expect(state.merchantName).eq("the merchant name"); } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should be in progress when doing refresh", async () => { - let granted = Amounts.getZero('EUR') - const unit: AmountJson = { currency: 'EUR', value: 1, fraction: 0 } - const refunded: AmountJson = { currency: 'EUR', value: 2, fraction: 0 } - let awaiting: AmountJson = refunded + let granted = Amounts.getZero("EUR"); + const unit: AmountJson = { currency: "EUR", value: 1, fraction: 0 }; + const refunded: AmountJson = { currency: "EUR", value: 2, fraction: 0 }; + let awaiting: AmountJson = refunded; let pending = true; const subscriptions = new SubsHandler(); @@ -177,80 +187,82 @@ describe("Refund CTA states", () => { granted = Amounts.add(granted, unit).amount; pending = granted.value < refunded.value; awaiting = Amounts.sub(refunded, granted).amount; - subscriptions.notifyEvent(NotificationType.RefreshMelted) + subscriptions.notifyEvent(NotificationType.RefreshMelted); } - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState("taler://refund/asdasdas", { - prepareRefund: async () => ({ - awaiting: Amounts.stringify(awaiting), - effectivePaid: 'EUR:2', - gone: 'EUR:0', - granted: Amounts.stringify(granted), - pending, - proposalId: '1', - info: { - contractTermsHash: '123', - merchant: { - name: 'the merchant name' - }, - orderId: 'orderId1', - summary: 'the sumary' - } - } as PrepareRefundResult as any), - applyRefund: async () => ({}), - onUpdateNotification: subscriptions.saveSubscription, - } as any), - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState("taler://refund/asdasdas", { + prepareRefund: async () => + ({ + awaiting: Amounts.stringify(awaiting), + effectivePaid: "EUR:2", + gone: "EUR:0", + granted: Amounts.stringify(granted), + pending, + proposalId: "1", + info: { + contractTermsHash: "123", + merchant: { + name: "the merchant name", + }, + orderId: "orderId1", + summary: "the sumary", + }, + } as PrepareRefundResult as any), + applyRefund: async () => ({}), + onUpdateNotification: subscriptions.saveSubscription, + } as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } - await waitNextUpdate() + await waitNextUpdate(); { - const state = getLastResultOrThrow() + const state = getLastResultOrThrow(); - if (state.status !== 'in-progress') expect.fail('1'); + if (state.status !== "in-progress") expect.fail("1"); if (state.hook) expect.fail(); - expect(state.merchantName).eq('the merchant name'); + expect(state.merchantName).eq("the merchant name"); expect(state.products).undefined; - expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2")) + expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2")); // expect(state.progress).closeTo(1 / 3, 0.01) - notifyMelt() + notifyMelt(); } - await waitNextUpdate() + await waitNextUpdate(); { - const state = getLastResultOrThrow() + const state = getLastResultOrThrow(); - if (state.status !== 'in-progress') expect.fail('2'); + if (state.status !== "in-progress") expect.fail("2"); if (state.hook) expect.fail(); - expect(state.merchantName).eq('the merchant name'); + expect(state.merchantName).eq("the merchant name"); expect(state.products).undefined; - expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2")) + expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2")); // expect(state.progress).closeTo(2 / 3, 0.01) - notifyMelt() + notifyMelt(); } - await waitNextUpdate() + await waitNextUpdate(); { - const state = getLastResultOrThrow() + const state = getLastResultOrThrow(); - if (state.status !== 'completed') expect.fail('3'); + if (state.status !== "completed") expect.fail("3"); if (state.hook) expect.fail(); - expect(state.merchantName).eq('the merchant name'); + expect(state.merchantName).eq("the merchant name"); expect(state.products).undefined; - expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2")) + expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:2")); } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); -});
\ No newline at end of file +}); diff --git a/packages/taler-wallet-webextension/src/cta/Tip.test.ts b/packages/taler-wallet-webextension/src/cta/Tip.test.ts index 0eda9b5be..192173463 100644 --- a/packages/taler-wallet-webextension/src/cta/Tip.test.ts +++ b/packages/taler-wallet-webextension/src/cta/Tip.test.ts @@ -26,64 +26,67 @@ import { useComponentState } from "./Tip.jsx"; describe("Tip CTA states", () => { it("should tell the user that the URI is missing", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState(undefined, { - prepareTip: async () => ({}), - acceptTip: async () => ({}) - } as any), - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState(undefined, { + prepareTip: async () => ({}), + acceptTip: async () => ({}), + } as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } - await waitNextUpdate() + await waitNextUpdate(); { - const { status, hook } = getLastResultOrThrow() + const { status, hook } = getLastResultOrThrow(); - expect(status).equals('loading') + expect(status).equals("loading"); if (!hook) expect.fail(); if (!hook.hasError) expect.fail(); if (hook.operational) expect.fail(); expect(hook.message).eq("ERROR_NO-URI-FOR-TIP"); } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should be ready for accepting the tip", async () => { let tipAccepted = false; - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState("taler://tip/asd", { - prepareTip: async () => ({ - accepted: tipAccepted, - exchangeBaseUrl: "exchange url", - merchantBaseUrl: "merchant url", - tipAmountEffective: "EUR:1", - walletTipId: "tip_id", - } as PrepareTipResult as any), - acceptTip: async () => { - tipAccepted = true - } - } as any), - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState("taler://tip/asd", { + prepareTip: async () => + ({ + accepted: tipAccepted, + exchangeBaseUrl: "exchange url", + merchantBaseUrl: "merchant url", + tipAmountEffective: "EUR:1", + walletTipId: "tip_id", + } as PrepareTipResult as any), + acceptTip: async () => { + tipAccepted = true; + }, + } as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } - await waitNextUpdate() + await waitNextUpdate(); { - const state = getLastResultOrThrow() + const state = getLastResultOrThrow(); - if (state.status !== "ready") expect.fail() + if (state.status !== "ready") expect.fail(); if (state.hook) expect.fail(); expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1")); expect(state.merchantBaseUrl).eq("merchant url"); @@ -93,45 +96,46 @@ describe("Tip CTA states", () => { state.accept.onClick(); } - await waitNextUpdate() + await waitNextUpdate(); { - const state = getLastResultOrThrow() + const state = getLastResultOrThrow(); - if (state.status !== "accepted") expect.fail() + if (state.status !== "accepted") expect.fail(); if (state.hook) expect.fail(); expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1")); expect(state.merchantBaseUrl).eq("merchant url"); expect(state.exchangeBaseUrl).eq("exchange url"); - } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should be ignored after clicking the ignore button", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState("taler://tip/asd", { - prepareTip: async () => ({ - exchangeBaseUrl: "exchange url", - merchantBaseUrl: "merchant url", - tipAmountEffective: "EUR:1", - walletTipId: "tip_id", - } as PrepareTipResult as any), - acceptTip: async () => ({}) - } as any), - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState("taler://tip/asd", { + prepareTip: async () => + ({ + exchangeBaseUrl: "exchange url", + merchantBaseUrl: "merchant url", + tipAmountEffective: "EUR:1", + walletTipId: "tip_id", + } as PrepareTipResult as any), + acceptTip: async () => ({}), + } as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } - await waitNextUpdate() + await waitNextUpdate(); { - const state = getLastResultOrThrow() + const state = getLastResultOrThrow(); - if (state.status !== "ready") expect.fail() + if (state.status !== "ready") expect.fail(); if (state.hook) expect.fail(); expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1")); expect(state.merchantBaseUrl).eq("merchant url"); @@ -141,52 +145,49 @@ describe("Tip CTA states", () => { state.ignore.onClick(); } - await waitNextUpdate() + await waitNextUpdate(); { - const state = getLastResultOrThrow() + const state = getLastResultOrThrow(); - if (state.status !== "ignored") expect.fail() + if (state.status !== "ignored") expect.fail(); if (state.hook) expect.fail(); - } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should render accepted if the tip has been used previously", async () => { - - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState("taler://tip/asd", { - prepareTip: async () => ({ - accepted: true, - exchangeBaseUrl: "exchange url", - merchantBaseUrl: "merchant url", - tipAmountEffective: "EUR:1", - walletTipId: "tip_id", - } as PrepareTipResult as any), - acceptTip: async () => ({}) - } as any), - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState("taler://tip/asd", { + prepareTip: async () => + ({ + accepted: true, + exchangeBaseUrl: "exchange url", + merchantBaseUrl: "merchant url", + tipAmountEffective: "EUR:1", + walletTipId: "tip_id", + } as PrepareTipResult as any), + acceptTip: async () => ({}), + } as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading"); expect(hook).undefined; } - await waitNextUpdate() + await waitNextUpdate(); { - const state = getLastResultOrThrow() + const state = getLastResultOrThrow(); - if (state.status !== "accepted") expect.fail() + if (state.status !== "accepted") expect.fail(); if (state.hook) expect.fail(); expect(state.amount).deep.eq(Amounts.parseOrThrow("EUR:1")); expect(state.merchantBaseUrl).eq("merchant url"); expect(state.exchangeBaseUrl).eq("exchange url"); - } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); - - -});
\ No newline at end of file +}); diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw.test.ts b/packages/taler-wallet-webextension/src/cta/Withdraw.test.ts index 7f05870c1..6fa8933c3 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw.test.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw.test.ts @@ -19,234 +19,249 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { Amounts, ExchangeListItem, GetExchangeTosResult } from "@gnu-taler/taler-util"; +import { + Amounts, + ExchangeListItem, + GetExchangeTosResult, +} from "@gnu-taler/taler-util"; import { ExchangeWithdrawDetails } from "@gnu-taler/taler-wallet-core"; import { expect } from "chai"; import { mountHook } from "../test-utils.js"; import { useComponentState } from "./Withdraw.js"; -const exchanges: ExchangeListItem[] = [{ - currency: 'ARS', - exchangeBaseUrl: 'http://exchange.demo.taler.net', - paytoUris: [], - tos: { - acceptedVersion: '', - } -}] +const exchanges: ExchangeListItem[] = [ + { + currency: "ARS", + exchangeBaseUrl: "http://exchange.demo.taler.net", + paytoUris: [], + tos: { + acceptedVersion: "", + }, + }, +]; describe("Withdraw CTA states", () => { it("should tell the user that the URI is missing", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState(undefined, { - listExchanges: async () => ({ exchanges }), - getWithdrawalDetailsForUri: async ({ talerWithdrawUri }: any) => ({ - amount: 'ARS:2', - possibleExchanges: exchanges, - }) - } as any), - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState(undefined, { + listExchanges: async () => ({ exchanges }), + getWithdrawalDetailsForUri: async ({ talerWithdrawUri }: any) => ({ + amount: "ARS:2", + possibleExchanges: exchanges, + }), + } as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading-uri') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading-uri"); expect(hook).undefined; } - await waitNextUpdate() + await waitNextUpdate(); { - const { status, hook } = getLastResultOrThrow() + const { status, hook } = getLastResultOrThrow(); - expect(status).equals('loading-uri') + expect(status).equals("loading-uri"); if (!hook) expect.fail(); if (!hook.hasError) expect.fail(); if (hook.operational) expect.fail(); expect(hook.message).eq("ERROR_NO-URI-FOR-WITHDRAWAL"); } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should tell the user that there is not known exchange", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState('taler-withdraw://', { - listExchanges: async () => ({ exchanges }), - getWithdrawalDetailsForUri: async ({ talerWithdrawUri }: any) => ({ - amount: 'EUR:2', - possibleExchanges: [], - }) - } as any), - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState("taler-withdraw://", { + listExchanges: async () => ({ exchanges }), + getWithdrawalDetailsForUri: async ({ talerWithdrawUri }: any) => ({ + amount: "EUR:2", + possibleExchanges: [], + }), + } as any), + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading-uri') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading-uri"); expect(hook).undefined; } - await waitNextUpdate() + await waitNextUpdate(); { - const { status, hook } = getLastResultOrThrow() + const { status, hook } = getLastResultOrThrow(); - expect(status).equals('loading-exchange') + expect(status).equals("loading-exchange"); - expect(hook).deep.equals({ "hasError": true, "operational": false, "message": "ERROR_NO-DEFAULT-EXCHANGE" }); + expect(hook).deep.equals({ + hasError: true, + operational: false, + message: "ERROR_NO-DEFAULT-EXCHANGE", + }); } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should be able to withdraw if tos are ok", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState('taler-withdraw://', { - listExchanges: async () => ({ exchanges }), - getWithdrawalDetailsForUri: async ({ talerWithdrawUri }: any) => ({ - amount: 'ARS:2', - possibleExchanges: exchanges, - }), - getExchangeWithdrawalInfo: async (): Promise<ExchangeWithdrawDetails> => ({ - withdrawalAmountRaw: 'ARS:5', - withdrawalAmountEffective: 'ARS:5', + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState("taler-withdraw://", { + listExchanges: async () => ({ exchanges }), + getWithdrawalDetailsForUri: async ({ talerWithdrawUri }: any) => ({ + amount: "ARS:2", + possibleExchanges: exchanges, + }), + getExchangeWithdrawalInfo: + async (): Promise<ExchangeWithdrawDetails> => + ({ + withdrawalAmountRaw: "ARS:5", + withdrawalAmountEffective: "ARS:5", + } as any), + getExchangeTos: async (): Promise<GetExchangeTosResult> => ({ + contentType: "text", + content: "just accept", + acceptedEtag: "v1", + currentEtag: "v1", + }), } as any), - getExchangeTos: async (): Promise<GetExchangeTosResult> => ({ - contentType: 'text', - content: 'just accept', - acceptedEtag: 'v1', - currentEtag: 'v1' - }) - } as any), - ); + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading-uri') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading-uri"); expect(hook).undefined; } - await waitNextUpdate() + await waitNextUpdate(); { - const { status, hook } = getLastResultOrThrow() + const { status, hook } = getLastResultOrThrow(); - expect(status).equals('loading-info') + expect(status).equals("loading-info"); expect(hook).undefined; } - await waitNextUpdate() + await waitNextUpdate(); { - const state = getLastResultOrThrow() - expect(state.status).equals("success") + const state = getLastResultOrThrow(); + expect(state.status).equals("success"); if (state.status !== "success") return; - expect(state.exchange.isDirty).false - expect(state.exchange.value).equal("http://exchange.demo.taler.net") + expect(state.exchange.isDirty).false; + expect(state.exchange.value).equal("http://exchange.demo.taler.net"); expect(state.exchange.list).deep.equal({ - "http://exchange.demo.taler.net": "http://exchange.demo.taler.net" - }) - expect(state.showExchangeSelection).false - - expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2")) - expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0")) - expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2")) + "http://exchange.demo.taler.net": "http://exchange.demo.taler.net", + }); + expect(state.showExchangeSelection).false; - expect(state.doWithdrawal.onClick).not.undefined - expect(state.mustAcceptFirst).false + expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2")); + expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0")); + expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2")); + expect(state.doWithdrawal.onClick).not.undefined; + expect(state.mustAcceptFirst).false; } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should be accept the tos before withdraw", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState('taler-withdraw://', { - listExchanges: async () => ({ exchanges }), - getWithdrawalDetailsForUri: async ({ talerWithdrawUri }: any) => ({ - amount: 'ARS:2', - possibleExchanges: exchanges, - }), - getExchangeWithdrawalInfo: async (): Promise<ExchangeWithdrawDetails> => ({ - withdrawalAmountRaw: 'ARS:5', - withdrawalAmountEffective: 'ARS:5', + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState("taler-withdraw://", { + listExchanges: async () => ({ exchanges }), + getWithdrawalDetailsForUri: async ({ talerWithdrawUri }: any) => ({ + amount: "ARS:2", + possibleExchanges: exchanges, + }), + getExchangeWithdrawalInfo: + async (): Promise<ExchangeWithdrawDetails> => + ({ + withdrawalAmountRaw: "ARS:5", + withdrawalAmountEffective: "ARS:5", + } as any), + getExchangeTos: async (): Promise<GetExchangeTosResult> => ({ + contentType: "text", + content: "just accept", + acceptedEtag: "v1", + currentEtag: "v2", + }), + setExchangeTosAccepted: async () => ({}), } as any), - getExchangeTos: async (): Promise<GetExchangeTosResult> => ({ - contentType: 'text', - content: 'just accept', - acceptedEtag: 'v1', - currentEtag: 'v2' - }), - setExchangeTosAccepted: async () => ({}) - } as any), - ); + ); { - const { status, hook } = getLastResultOrThrow() - expect(status).equals('loading-uri') + const { status, hook } = getLastResultOrThrow(); + expect(status).equals("loading-uri"); expect(hook).undefined; } - await waitNextUpdate() + await waitNextUpdate(); { - const { status, hook } = getLastResultOrThrow() + const { status, hook } = getLastResultOrThrow(); - expect(status).equals('loading-info') + expect(status).equals("loading-info"); expect(hook).undefined; } - await waitNextUpdate() + await waitNextUpdate(); { - const state = getLastResultOrThrow() - expect(state.status).equals("success") + const state = getLastResultOrThrow(); + expect(state.status).equals("success"); if (state.status !== "success") return; - expect(state.exchange.isDirty).false - expect(state.exchange.value).equal("http://exchange.demo.taler.net") + expect(state.exchange.isDirty).false; + expect(state.exchange.value).equal("http://exchange.demo.taler.net"); expect(state.exchange.list).deep.equal({ - "http://exchange.demo.taler.net": "http://exchange.demo.taler.net" - }) - expect(state.showExchangeSelection).false + "http://exchange.demo.taler.net": "http://exchange.demo.taler.net", + }); + expect(state.showExchangeSelection).false; - expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2")) - expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0")) - expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2")) + expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2")); + expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0")); + expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2")); - expect(state.doWithdrawal.onClick).undefined - expect(state.mustAcceptFirst).true + expect(state.doWithdrawal.onClick).undefined; + expect(state.mustAcceptFirst).true; // accept TOS - state.tosProps?.onAccept(true) + state.tosProps?.onAccept(true); } - await waitNextUpdate() + await waitNextUpdate(); { - const state = getLastResultOrThrow() - expect(state.status).equals("success") + const state = getLastResultOrThrow(); + expect(state.status).equals("success"); if (state.status !== "success") return; - expect(state.exchange.isDirty).false - expect(state.exchange.value).equal("http://exchange.demo.taler.net") + expect(state.exchange.isDirty).false; + expect(state.exchange.value).equal("http://exchange.demo.taler.net"); expect(state.exchange.list).deep.equal({ - "http://exchange.demo.taler.net": "http://exchange.demo.taler.net" - }) - expect(state.showExchangeSelection).false + "http://exchange.demo.taler.net": "http://exchange.demo.taler.net", + }); + expect(state.showExchangeSelection).false; - expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2")) - expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0")) - expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2")) - - expect(state.doWithdrawal.onClick).not.undefined - expect(state.mustAcceptFirst).true + expect(state.toBeReceived).deep.equal(Amounts.parseOrThrow("ARS:2")); + expect(state.withdrawalFee).deep.equal(Amounts.parseOrThrow("ARS:0")); + expect(state.chosenAmount).deep.equal(Amounts.parseOrThrow("ARS:2")); + expect(state.doWithdrawal.onClick).not.undefined; + expect(state.mustAcceptFirst).true; } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); - -});
\ No newline at end of file +}); diff --git a/packages/taler-wallet-webextension/src/cta/termsExample.ts b/packages/taler-wallet-webextension/src/cta/termsExample.ts index 986874c18..4210e7a7e 100644 --- a/packages/taler-wallet-webextension/src/cta/termsExample.ts +++ b/packages/taler-wallet-webextension/src/cta/termsExample.ts @@ -779,4 +779,3 @@ trailer << /Root 3 0 R >> %%EOF `; - diff --git a/packages/taler-wallet-webextension/src/custom.d.ts b/packages/taler-wallet-webextension/src/custom.d.ts index 711112ad8..c09f34e2b 100644 --- a/packages/taler-wallet-webextension/src/custom.d.ts +++ b/packages/taler-wallet-webextension/src/custom.d.ts @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ - declare module "*.jpeg" { +declare module "*.jpeg" { const content: any; export default content; } diff --git a/packages/taler-wallet-webextension/src/hooks/useAsyncAsHook.ts b/packages/taler-wallet-webextension/src/hooks/useAsyncAsHook.ts index 04a6dbb18..d13a68383 100644 --- a/packages/taler-wallet-webextension/src/hooks/useAsyncAsHook.ts +++ b/packages/taler-wallet-webextension/src/hooks/useAsyncAsHook.ts @@ -13,9 +13,7 @@ You should have received a copy of the GNU General Public License along with TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { - NotificationType, TalerErrorDetail -} from "@gnu-taler/taler-util"; +import { NotificationType, TalerErrorDetail } from "@gnu-taler/taler-util"; import { TalerError } from "@gnu-taler/taler-wallet-core"; import { useEffect, useMemo, useState } from "preact/hooks"; import * as wxApi from "../wxApi.js"; @@ -44,19 +42,23 @@ interface WithRetry { } export type HookResponse<T> = HookOk<T> | HookError | undefined; -export type HookResponseWithRetry<T> = ((HookOk<T> | HookError) & WithRetry) | undefined; +export type HookResponseWithRetry<T> = + | ((HookOk<T> | HookError) & WithRetry) + | undefined; export function useAsyncAsHook<T>( fn: () => Promise<T | false>, deps?: any[], ): HookResponseWithRetry<T> { - const [result, setHookResponse] = useState<HookResponse<T>>(undefined); - const args = useMemo(() => ({ - fn - // eslint-disable-next-line react-hooks/exhaustive-deps - }), deps || []) + const args = useMemo( + () => ({ + fn, + // eslint-disable-next-line react-hooks/exhaustive-deps + }), + deps || [], + ); async function doAsync(): Promise<void> { try { diff --git a/packages/taler-wallet-webextension/src/hooks/useExtendedPermissions.ts b/packages/taler-wallet-webextension/src/hooks/useExtendedPermissions.ts index e3ea56d1b..08bb39668 100644 --- a/packages/taler-wallet-webextension/src/hooks/useExtendedPermissions.ts +++ b/packages/taler-wallet-webextension/src/hooks/useExtendedPermissions.ts @@ -24,9 +24,9 @@ export function useExtendedPermissions(): ToggleHandler { const [enabled, setEnabled] = useState(false); const [error, setError] = useState<TalerError | undefined>(); const toggle = async (): Promise<void> => { - return handleExtendedPerm(enabled, setEnabled).catch(e => { - setError(TalerError.fromException(e)) - }) + return handleExtendedPerm(enabled, setEnabled).catch((e) => { + setError(TalerError.fromException(e)); + }); }; useEffect(() => { @@ -40,12 +40,15 @@ export function useExtendedPermissions(): ToggleHandler { value: enabled, button: { onClick: toggle, - error - } + error, + }, }; } -async function handleExtendedPerm(isEnabled: boolean, onChange: (value: boolean) => void): Promise<void> { +async function handleExtendedPerm( + isEnabled: boolean, + onChange: (value: boolean) => void, +): Promise<void> { if (!isEnabled) { // We set permissions here, since apparently FF wants this to be done // as the result of an input event ... @@ -60,11 +63,10 @@ async function handleExtendedPerm(isEnabled: boolean, onChange: (value: boolean) onChange(res.newValue); } else { try { - await wxApi.toggleHeaderListener(false).then(r => onChange(r.newValue)); + await wxApi.toggleHeaderListener(false).then((r) => onChange(r.newValue)); } catch (e) { - console.log(e) + console.log(e); } - } - return + return; } diff --git a/packages/taler-wallet-webextension/src/hooks/useLang.ts b/packages/taler-wallet-webextension/src/hooks/useLang.ts index 0436f25df..46f3e1188 100644 --- a/packages/taler-wallet-webextension/src/hooks/useLang.ts +++ b/packages/taler-wallet-webextension/src/hooks/useLang.ts @@ -17,12 +17,14 @@ import { useNotNullLocalStorage } from "./useLocalStorage.js"; function getBrowserLang(): string | undefined { - if (window.navigator.languages) return window.navigator.languages[0] - if (window.navigator.language) return window.navigator.language + if (window.navigator.languages) return window.navigator.languages[0]; + if (window.navigator.language) return window.navigator.language; return undefined; } -export function useLang(initial?: string): [string, (s: string) => void, boolean] { +export function useLang( + initial?: string, +): [string, (s: string) => void, boolean] { const defaultLang = (getBrowserLang() || initial || "en").substring(0, 2); return useNotNullLocalStorage("lang-preference", defaultLang); } diff --git a/packages/taler-wallet-webextension/src/hooks/useLocalStorage.ts b/packages/taler-wallet-webextension/src/hooks/useLocalStorage.ts index 31d54e451..ed0f1d2bb 100644 --- a/packages/taler-wallet-webextension/src/hooks/useLocalStorage.ts +++ b/packages/taler-wallet-webextension/src/hooks/useLocalStorage.ts @@ -25,13 +25,13 @@ export function useLocalStorage( key: string, initialValue?: string, ): [string | undefined, StateUpdater<string | undefined>] { - const [storedValue, setStoredValue] = useState<string | undefined>((): - | string - | undefined => { - return typeof window !== "undefined" - ? window.localStorage.getItem(key) || initialValue - : initialValue; - }); + const [storedValue, setStoredValue] = useState<string | undefined>( + (): string | undefined => { + return typeof window !== "undefined" + ? window.localStorage.getItem(key) || initialValue + : initialValue; + }, + ); const setValue = ( value?: string | ((val?: string) => string | undefined), diff --git a/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.test.ts b/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.test.ts index 4893d43ff..7cf97265e 100644 --- a/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.test.ts +++ b/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.test.ts @@ -14,48 +14,47 @@ You should have received a copy of the GNU General Public License along with GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { useTalerActionURL } from "./useTalerActionURL.js" +import { useTalerActionURL } from "./useTalerActionURL.js"; import { mountHook } from "../test-utils.js"; import { IoCProviderForTesting } from "../context/iocContext.js"; import { h, VNode } from "preact"; import { expect } from "chai"; -describe('useTalerActionURL hook', () => { - - it('should be set url to undefined when dismiss', async () => { - +describe("useTalerActionURL hook", () => { + it("should be set url to undefined when dismiss", async () => { const ctx = ({ children }: { children: any }): VNode => { return h(IoCProviderForTesting, { value: { findTalerUriInActiveTab: async () => "asd", - }, children - }) - } + }, + children, + }); + }; - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(useTalerActionURL, ctx) + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(useTalerActionURL, ctx); { - const [url] = getLastResultOrThrow() + const [url] = getLastResultOrThrow(); expect(url).undefined; } - - await waitNextUpdate("waiting for useEffect") + await waitNextUpdate("waiting for useEffect"); { - const [url, setDismissed] = getLastResultOrThrow() + const [url, setDismissed] = getLastResultOrThrow(); expect(url).equals("asd"); - setDismissed(true) + setDismissed(true); } - await waitNextUpdate("after dismiss") + await waitNextUpdate("after dismiss"); { - const [url] = getLastResultOrThrow() - if (url !== undefined) throw Error('invalid') + const [url] = getLastResultOrThrow(); + if (url !== undefined) throw Error("invalid"); expect(url).undefined; } - await assertNoPendingUpdate() - }) -})
\ No newline at end of file + await assertNoPendingUpdate(); + }); +}); diff --git a/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts b/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts index b2dd739e2..0a2ad4aa1 100644 --- a/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts +++ b/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts @@ -25,7 +25,7 @@ export function useTalerActionURL(): [ undefined, ); const [dismissed, setDismissed] = useState(false); - const { findTalerUriInActiveTab } = useIocContext() + const { findTalerUriInActiveTab } = useIocContext(); useEffect(() => { async function check(): Promise<void> { diff --git a/packages/taler-wallet-webextension/src/i18n/strings.ts b/packages/taler-wallet-webextension/src/i18n/strings.ts index 890c783d7..6aad13f45 100644 --- a/packages/taler-wallet-webextension/src/i18n/strings.ts +++ b/packages/taler-wallet-webextension/src/i18n/strings.ts @@ -1,5595 +1,2205 @@ export const strings: any = {}; -strings['de'] = { - "domain": "messages", - "locale_data": { - "messages": { +strings["de"] = { + domain: "messages", + locale_data: { + messages: { "": { - "domain": "messages", - "plural_forms": "nplurals=2; plural=n != 1;", - "lang": "de" + domain: "messages", + plural_forms: "nplurals=2; plural=n != 1;", + lang: "de", }, - "Balance": [ - "Guthaben" - ], - "Backup": [ - "Backup" - ], - "Settings": [ - "Einstellungen" - ], - "Dev": [ - "Dev" - ], - "Loading": [ - "Lädt Daten" - ], - "Open reserve page": [ - "Seite der Reserve aufrufen" - ], - "Open pay page": [ - "Seite für Zahlungen aufrufen" - ], - "Open refund page": [ - "Seite für Rückerstattungen aufrufen" - ], - "Open tip page": [ - "Seite der Aufwandsentschädigungen aufrufen" - ], - "Open withdraw page": [ - "Abhebeseite öffnen" - ], - "Back": [ - "Zurück" - ], - "You have no balance to show.": [ - "Es gibt kein Guthaben anzuzeigen." - ], - "To withdraw money you can start from your bank site or click the \"withdraw\" button to use a known exchange.": [ - "Zum Abheben von digitalem Geld bitte von der Bank-Seite aus starten oder \"Abheben\" drücken, um einen schon bekannten Exchange zu verwenden." - ], - "Withdraw": [ - "Abheben" - ], - "Could not load balance page": [ - "Konnte die Umsatzanzeige nicht laden" - ], - "Deposit %1$s": [ - "%1$s zahlen" - ], - "Enter URI": [ - "URI eingeben" - ], + Balance: ["Guthaben"], + Backup: ["Backup"], + Settings: ["Einstellungen"], + Dev: ["Dev"], + Loading: ["Lädt Daten"], + "Open reserve page": ["Seite der Reserve aufrufen"], + "Open pay page": ["Seite für Zahlungen aufrufen"], + "Open refund page": ["Seite für Rückerstattungen aufrufen"], + "Open tip page": ["Seite der Aufwandsentschädigungen aufrufen"], + "Open withdraw page": ["Abhebeseite öffnen"], + Back: ["Zurück"], + "You have no balance to show.": ["Es gibt kein Guthaben anzuzeigen."], + 'To withdraw money you can start from your bank site or click the "withdraw" button to use a known exchange.': + [ + 'Zum Abheben von digitalem Geld bitte von der Bank-Seite aus starten oder "Abheben" drücken, um einen schon bekannten Exchange zu verwenden.', + ], + Withdraw: ["Abheben"], + "Could not load balance page": ["Konnte die Umsatzanzeige nicht laden"], + "Deposit %1$s": ["%1$s zahlen"], + "Enter URI": ["URI eingeben"], "Diagnostics timed out. Could not talk to the wallet backend.": [ - "Die Diagnostik ist abgeschlossen. Es war keine Kommunikation mit dem Wallet-Backend möglich." - ], - "Problems detected:": [ - "Ein Problem wurde festgestellt:" - ], - "Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": [ - "Bitte prüfen Sie ihre %1$s Einstellungen, für die Sie IndexedDB verwenden (preference name %2$s prüfen)." - ], - "Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": [ - "Die Datenbank des Wallets ist veraltet. Aktuell wird jedoch keine Migration auf eine neue Version unterstützt. Bitte wählen Sie %1$s zum Zurücksetzen der Wallet-Datenbank." - ], - "Running diagnostics": [ - "Diagnostik wird durchgeführt" - ], - "Debug tools": [ - "Debugging-Tools" - ], - "reset": [ - "zurücksetzen" - ], - "import database": [ - "" - ], - "export database": [ - "" - ], - "Database exported at %1$s %2$s to download": [ - "" - ], - "Coins": [ - "" - ], - "Pending operations": [ - "" - ], - "usable coins": [ - "" - ], - "id": [ - "" - ], - "denom": [ - "" - ], - "value": [ - "" - ], - "status": [ - "" - ], - "from refresh?": [ - "" - ], - "spent coins": [ - "" - ], - "click to show": [ - "" - ], - "Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": [ - "" - ], - "Taler Action": [ - "" - ], - "This page has pay action.": [ - "" - ], - "This page has a withdrawal action.": [ - "" - ], - "This page has a tip action.": [ - "" - ], - "This page has a notify reserve action.": [ - "" - ], - "Notify": [ - "" - ], - "This page has a refund action.": [ - "" - ], - "This page has a malformed taler uri.": [ - "" - ], - "Dismiss": [ - "" - ], - "Could not load backup providers": [ - "" - ], - "No backup providers configured": [ - "" - ], - "Add provider": [ - "" - ], - "Sync all backups": [ - "" - ], - "Sync now": [ - "" - ], - "Last synced": [ - "" - ], - "Not synced": [ - "" - ], - "Expires in": [ - "" - ], - "Exchange doesn't have terms of service": [ - "" - ], - "Review exchange terms of service": [ - "" - ], - "Review new version of terms of service": [ - "" - ], - "Show terms of service": [ - "" - ], - "I accept the exchange terms of service": [ - "" - ], - "The exchange reply with a empty terms of service": [ - "" - ], - "Download Terms of Service": [ - "" - ], - "Hide terms of service": [ - "" - ], - "Review terms of service": [ - "" - ], - "Exchange URL": [ - "" - ], - "Cancel": [ - "Abbrechen" - ], - "Loading terms..": [ - "" - ], - "Add exchange": [ - "" - ], - "Add exchange anyway": [ - "" - ], - "Add new exchange": [ - "" - ], - "Add exchange for %1$s": [ - "" - ], - "Enter the URL of an exchange you trust.": [ - "" - ], - "An exchange has been found! Review the information and click next": [ - "" - ], - "This exchange doesn't match the expected currency %1$s": [ - "" - ], - "Unable to verify this exchange": [ - "" - ], - "Unable to add this exchange": [ - "" - ], - "loading": [ - "" - ], - "Version": [ - "" - ], - "Currency": [ - "" - ], - "Next": [ - "" - ], - "Add backup provider": [ - "" - ], - "Could not get provider information": [ - "" - ], - "Backup providers may charge for their service": [ - "" - ], - "URL": [ - "" - ], - "Name": [ - "" - ], - "Provider URL": [ - "" - ], - "Please review and accept this provider's terms of service": [ - "" - ], - "Pricing": [ - "" - ], - "free of charge": [ - "" - ], - "%1$s per year of service": [ - "" - ], - "Storage": [ - "" - ], - "%1$s megabytes of storage per year of service": [ - "" - ], - "Accept terms of service": [ - "" - ], - "There was an error loading the provider detail for \"%1$s\"": [ - "" - ], - "There is not known provider with url \"%1$s\".": [ - "" - ], - "Last backup": [ - "" - ], - "Back up": [ - "" - ], - "Provider fee": [ - "" - ], - "per year": [ - "" - ], - "Extend": [ - "" - ], - "terms has changed, extending the service will imply accepting the new terms of service": [ - "" - ], - "old": [ - "" - ], - "new": [ - "" - ], - "fee": [ - "" - ], - "storage": [ - "" - ], - "back": [ - "" - ], - "Remove provider": [ - "" - ], - "This provider has reported an error": [ - "" - ], - "There is conflict with another backup from %1$s": [ - "" - ], - "Backup is not readable": [ - "" - ], - "Unknown backup problem: %1$s": [ - "" - ], - "service paid": [ - "" - ], - "Backup valid until": [ - "" - ], - "this popup is being closed and you are being redirected to %1$s": [ - "" - ], - "Select one option": [ - "" - ], - "Manual Withdrawal": [ - "Manuelles Abheben" - ], - "Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": [ - "" - ], - "No exchange configured": [ - "" - ], - "Can't create the reserve": [ - "" - ], - "Exchange": [ - "Exchange" - ], - "Add Exchange": [ - "" - ], - "Amount": [ - "Betrag" - ], - "Start withdrawal": [ - "Abhebung beginnen" - ], - "no balance": [ - "Kein Guthaben" - ], - "There is no known bank account to send money to": [ - "" - ], - "Send %1$s to your account": [ - "" - ], - "Bank account IBAN number": [ - "" - ], - "Deposit fee": [ - "" - ], - "Total deposit": [ - "" - ], - "Deposit": [ - "" - ], - "Deposit %1$s %2$s": [ - "Einlösen %1$s %2$s" - ], - "Waiting for confirmation": [ - "" - ], - "PENDING": [ - "" - ], - "Could not load the list of transactions": [ - "" - ], - "There is no history for this currency": [ - "" - ], - "Account": [ - "" - ], - "Bank host": [ - "" - ], - "Bank account": [ - "" - ], - "IBAN": [ - "" - ], - "Chosen amount": [ - "" - ], - "Subject": [ - "Verwendungszweck" - ], - "could not parse payto uri from exchange %1$s": [ - "" - ], - "Exchange is ready for withdrawal": [ - "" - ], - "To complete the process you need to wire %1$s to the exchange bank account": [ - "" - ], - "Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": [ - "" - ], - "Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": [ - "" - ], - "Cancel withdrawal": [ - "" - ], - "Display": [ - "" - ], - "Current Language": [ - "" - ], - "Navigator": [ - "" - ], - "Automatically open wallet based on page content": [ - "" - ], - "Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": [ - "" - ], - "Trust": [ - "" - ], - "No exchange yet": [ - "" - ], - "Term of Service": [ - "" - ], - "ok": [ - "" - ], - "changed": [ - "" - ], - "not accepted": [ - "" - ], - "Add an exchange": [ - "" - ], - "Developer mode": [ - "" - ], - "(More options and information useful for debugging)": [ - "" - ], - "Could not load the transaction information": [ - "" - ], - "There was an error trying to complete the transaction": [ - "" - ], - "This transaction is not completed": [ - "" - ], - "Retry": [ - "Erneut versuchen" - ], - "Forget": [ - "" - ], - "Caution!": [ - "" - ], - "If you have already wired money to the exchange you will loose the chance to get the coins form it.": [ - "" - ], - "Confirm": [ - "Bestätigen" - ], - "Withdrawal": [ - "Abheben" - ], - "Total withdrawn": [ - "Insgesamt abgehoben" - ], - "Exchange fee": [ - "" - ], - "The bank is waiting for confirmation. Go to the %1$s": [ - "" - ], - "Waiting for the coins to arrive": [ - "" - ], - "Payment": [ - "Zahlung" - ], - "Total paid": [ - "" - ], - "Purchase amount": [ - "" - ], - "Fee": [ - "" - ], - "Merchant": [ - "" - ], - "Purchase": [ - "" - ], - "Receipt": [ - "" - ], - "Total send": [ - "" - ], - "Deposit amount": [ - "" - ], - "Refresh": [ - "" - ], - "Total refresh": [ - "" - ], - "Refresh amount": [ - "" - ], - "Tip": [ - "" - ], - "Total tip": [ - "" - ], - "Received amount": [ - "" - ], - "Refund": [ - "" - ], - "Total refund": [ - "" - ], - "Refund amount": [ - "" - ], - "Browser Extension Installed!": [ - "" - ], - "Thank you for installing the wallet.": [ - "" - ], - "Permissions": [ - "" - ], - "(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": [ - "" - ], - "Next Steps": [ - "" - ], - "Try the demo": [ - "" - ], - "Learn how to top up your wallet balance": [ - "" - ], - "Could not load pay status": [ - "" - ], - "Could not load contract terms from merchant or wallet backend.": [ - "" - ], - "Pay with a mobile phone": [ - "" - ], - "Hide QR": [ - "" - ], - "Scan the QR code or %1$s": [ - "" - ], - "Processing": [ - "" - ], - "Pay %1$s": [ - "" - ], - "Your balance of %1$s is not enough to pay for this purchase": [ - "" - ], - "Your balance is not enough to pay for this purchase.": [ - "" - ], - "Withdraw digital cash": [ - "Digitales Bargeld abheben" - ], - "Merchant message": [ - "" - ], - "Digital cash payment": [ - "" - ], - "Already paid, you are going to be redirected to %1$s": [ - "" - ], - "Already paid": [ - "" - ], - "Already claimed": [ - "" - ], - "Payment complete": [ - "" - ], - "You are going to be redirected to $ %1$s": [ - "" - ], - "You can close this page.": [ - "" - ], - "Total to pay": [ - "" - ], - "List of products": [ - "" - ], - "Total": [ - "" - ], - "free": [ - "" - ], - "Refund Status": [ - "" - ], - "The product %1$s has received a total effective refund of": [ - "" - ], - "Refund processing is still in progress.": [ - "" - ], - "The refund amount of %1$s could not be applied.": [ - "" - ], - "missing taler refund uri": [ - "" - ], - "Error: %1$s": [ - "" - ], - "Updating refund status": [ - "" - ], - "Tip from %1$s accepted. Check your transactions list for more details.": [ - "" - ], + "Die Diagnostik ist abgeschlossen. Es war keine Kommunikation mit dem Wallet-Backend möglich.", + ], + "Problems detected:": ["Ein Problem wurde festgestellt:"], + "Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": + [ + "Bitte prüfen Sie ihre %1$s Einstellungen, für die Sie IndexedDB verwenden (preference name %2$s prüfen).", + ], + "Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": + [ + "Die Datenbank des Wallets ist veraltet. Aktuell wird jedoch keine Migration auf eine neue Version unterstützt. Bitte wählen Sie %1$s zum Zurücksetzen der Wallet-Datenbank.", + ], + "Running diagnostics": ["Diagnostik wird durchgeführt"], + "Debug tools": ["Debugging-Tools"], + reset: ["zurücksetzen"], + "import database": [""], + "export database": [""], + "Database exported at %1$s %2$s to download": [""], + Coins: [""], + "Pending operations": [""], + "usable coins": [""], + id: [""], + denom: [""], + value: [""], + status: [""], + "from refresh?": [""], + "spent coins": [""], + "click to show": [""], + "Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": + [""], + "Taler Action": [""], + "This page has pay action.": [""], + "This page has a withdrawal action.": [""], + "This page has a tip action.": [""], + "This page has a notify reserve action.": [""], + Notify: [""], + "This page has a refund action.": [""], + "This page has a malformed taler uri.": [""], + Dismiss: [""], + "Could not load backup providers": [""], + "No backup providers configured": [""], + "Add provider": [""], + "Sync all backups": [""], + "Sync now": [""], + "Last synced": [""], + "Not synced": [""], + "Expires in": [""], + "Exchange doesn't have terms of service": [""], + "Review exchange terms of service": [""], + "Review new version of terms of service": [""], + "Show terms of service": [""], + "I accept the exchange terms of service": [""], + "The exchange reply with a empty terms of service": [""], + "Download Terms of Service": [""], + "Hide terms of service": [""], + "Review terms of service": [""], + "Exchange URL": [""], + Cancel: ["Abbrechen"], + "Loading terms..": [""], + "Add exchange": [""], + "Add exchange anyway": [""], + "Add new exchange": [""], + "Add exchange for %1$s": [""], + "Enter the URL of an exchange you trust.": [""], + "An exchange has been found! Review the information and click next": [""], + "This exchange doesn't match the expected currency %1$s": [""], + "Unable to verify this exchange": [""], + "Unable to add this exchange": [""], + loading: [""], + Version: [""], + Currency: [""], + Next: [""], + "Add backup provider": [""], + "Could not get provider information": [""], + "Backup providers may charge for their service": [""], + URL: [""], + Name: [""], + "Provider URL": [""], + "Please review and accept this provider's terms of service": [""], + Pricing: [""], + "free of charge": [""], + "%1$s per year of service": [""], + Storage: [""], + "%1$s megabytes of storage per year of service": [""], + "Accept terms of service": [""], + 'There was an error loading the provider detail for "%1$s"': [""], + 'There is not known provider with url "%1$s".': [""], + "Last backup": [""], + "Back up": [""], + "Provider fee": [""], + "per year": [""], + Extend: [""], + "terms has changed, extending the service will imply accepting the new terms of service": + [""], + old: [""], + new: [""], + fee: [""], + storage: [""], + back: [""], + "Remove provider": [""], + "This provider has reported an error": [""], + "There is conflict with another backup from %1$s": [""], + "Backup is not readable": [""], + "Unknown backup problem: %1$s": [""], + "service paid": [""], + "Backup valid until": [""], + "this popup is being closed and you are being redirected to %1$s": [""], + "Select one option": [""], + "Manual Withdrawal": ["Manuelles Abheben"], + "Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": + [""], + "No exchange configured": [""], + "Can't create the reserve": [""], + Exchange: ["Exchange"], + "Add Exchange": [""], + Amount: ["Betrag"], + "Start withdrawal": ["Abhebung beginnen"], + "no balance": ["Kein Guthaben"], + "There is no known bank account to send money to": [""], + "Send %1$s to your account": [""], + "Bank account IBAN number": [""], + "Deposit fee": [""], + "Total deposit": [""], + Deposit: [""], + "Deposit %1$s %2$s": ["Einlösen %1$s %2$s"], + "Waiting for confirmation": [""], + PENDING: [""], + "Could not load the list of transactions": [""], + "There is no history for this currency": [""], + Account: [""], + "Bank host": [""], + "Bank account": [""], + IBAN: [""], + "Chosen amount": [""], + Subject: ["Verwendungszweck"], + "could not parse payto uri from exchange %1$s": [""], + "Exchange is ready for withdrawal": [""], + "To complete the process you need to wire %1$s to the exchange bank account": + [""], + "Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": + [""], + "Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": + [""], + "Cancel withdrawal": [""], + Display: [""], + "Current Language": [""], + Navigator: [""], + "Automatically open wallet based on page content": [""], + "Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": + [""], + Trust: [""], + "No exchange yet": [""], + "Term of Service": [""], + ok: [""], + changed: [""], + "not accepted": [""], + "Add an exchange": [""], + "Developer mode": [""], + "(More options and information useful for debugging)": [""], + "Could not load the transaction information": [""], + "There was an error trying to complete the transaction": [""], + "This transaction is not completed": [""], + Retry: ["Erneut versuchen"], + Forget: [""], + "Caution!": [""], + "If you have already wired money to the exchange you will loose the chance to get the coins form it.": + [""], + Confirm: ["Bestätigen"], + Withdrawal: ["Abheben"], + "Total withdrawn": ["Insgesamt abgehoben"], + "Exchange fee": [""], + "The bank is waiting for confirmation. Go to the %1$s": [""], + "Waiting for the coins to arrive": [""], + Payment: ["Zahlung"], + "Total paid": [""], + "Purchase amount": [""], + Fee: [""], + Merchant: [""], + Purchase: [""], + Receipt: [""], + "Total send": [""], + "Deposit amount": [""], + Refresh: [""], + "Total refresh": [""], + "Refresh amount": [""], + Tip: [""], + "Total tip": [""], + "Received amount": [""], + Refund: [""], + "Total refund": [""], + "Refund amount": [""], + "Browser Extension Installed!": [""], + "Thank you for installing the wallet.": [""], + Permissions: [""], + "(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": + [""], + "Next Steps": [""], + "Try the demo": [""], + "Learn how to top up your wallet balance": [""], + "Could not load pay status": [""], + "Could not load contract terms from merchant or wallet backend.": [""], + "Pay with a mobile phone": [""], + "Hide QR": [""], + "Scan the QR code or %1$s": [""], + Processing: [""], + "Pay %1$s": [""], + "Your balance of %1$s is not enough to pay for this purchase": [""], + "Your balance is not enough to pay for this purchase.": [""], + "Withdraw digital cash": ["Digitales Bargeld abheben"], + "Merchant message": [""], + "Digital cash payment": [""], + "Already paid, you are going to be redirected to %1$s": [""], + "Already paid": [""], + "Already claimed": [""], + "Payment complete": [""], + "You are going to be redirected to $ %1$s": [""], + "You can close this page.": [""], + "Total to pay": [""], + "List of products": [""], + Total: [""], + free: [""], + "Refund Status": [""], + "The product %1$s has received a total effective refund of": [""], + "Refund processing is still in progress.": [""], + "The refund amount of %1$s could not be applied.": [""], + "missing taler refund uri": [""], + "Error: %1$s": [""], + "Updating refund status": [""], + "Tip from %1$s accepted. Check your transactions list for more details.": + [""], "The merchant %1$s is offering you a tip of %2$s via the exchange %3$s": [ - "Der Händler %1$s bietet Ihnen eine Aufwandsentschädigung von %2$s durch den Exchange %3$s" - ], - "Accept tip": [ - "" - ], - "Ignore": [ - "" - ], - "missing tip uri": [ - "" - ], - "You've ignored the tip.": [ - "" - ], - "Digital cash withdrawal": [ - "" - ], - "Could not finish the withdrawal operation": [ - "" - ], - "Total to withdraw": [ - "" - ], - "Known exchanges": [ - "" - ], - "Cancel exchange selection": [ - "" - ], - "Confirm exchange selection": [ - "" - ], - "Switch exchange": [ - "" - ], - "Confirm withdrawal": [ - "" - ], - "Withdraw anyway": [ - "Trotzdem abheben" - ], - "Could not load the withdrawal details": [ - "" - ], - "missing withdraw uri": [ - "" - ], - "Could not get the info from the URI": [ - "" - ], - "Could not load the list of known exchanges": [ - "" - ], - "All done, your transaction is in progress": [ - "" - ], - "Edit": [ - "" - ], - "missing pay uri": [ - "" - ], - "Could not get the payment information for this order": [ - "" - ], - "Loading payment information": [ - "" - ], - "Digital cash deposit": [ - "" - ], - "You will now be sent back to the merchant you came from.": [ - "" - ], - "Manual Reset Required": [ - "" - ], - "The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": [ - "" - ], - "Once the database format has stabilized, we will provide automatic upgrades.": [ - "" - ], - "I understand that I will lose all my data": [ - "" - ], - "Reset": [ - "" - ], - "Everything is fine!": [ - "" - ], - "A reset is not required anymore, you can close this page.": [ - "" - ], - "Not implemented yet.": [ - "" - ] - } - } + "Der Händler %1$s bietet Ihnen eine Aufwandsentschädigung von %2$s durch den Exchange %3$s", + ], + "Accept tip": [""], + Ignore: [""], + "missing tip uri": [""], + "You've ignored the tip.": [""], + "Digital cash withdrawal": [""], + "Could not finish the withdrawal operation": [""], + "Total to withdraw": [""], + "Known exchanges": [""], + "Cancel exchange selection": [""], + "Confirm exchange selection": [""], + "Switch exchange": [""], + "Confirm withdrawal": [""], + "Withdraw anyway": ["Trotzdem abheben"], + "Could not load the withdrawal details": [""], + "missing withdraw uri": [""], + "Could not get the info from the URI": [""], + "Could not load the list of known exchanges": [""], + "All done, your transaction is in progress": [""], + Edit: [""], + "missing pay uri": [""], + "Could not get the payment information for this order": [""], + "Loading payment information": [""], + "Digital cash deposit": [""], + "You will now be sent back to the merchant you came from.": [""], + "Manual Reset Required": [""], + "The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": + [""], + "Once the database format has stabilized, we will provide automatic upgrades.": + [""], + "I understand that I will lose all my data": [""], + Reset: [""], + "Everything is fine!": [""], + "A reset is not required anymore, you can close this page.": [""], + "Not implemented yet.": [""], + }, + }, }; -strings['es'] = { - "domain": "messages", - "locale_data": { - "messages": { +strings["es"] = { + domain: "messages", + locale_data: { + messages: { "": { - "domain": "messages", - "plural_forms": "nplurals=2; plural=n != 1;", - "lang": "es" + domain: "messages", + plural_forms: "nplurals=2; plural=n != 1;", + lang: "es", }, - "Balance": [ - "Balance" - ], - "Backup": [ - "Copia de seguridad" - ], - "Settings": [ - "Configuración" - ], - "Dev": [ - "Dev" - ], - "Loading": [ - "Cargando" - ], - "Open reserve page": [ - "Abrir página de reserva" - ], - "Open pay page": [ - "Abrir página de pago" - ], - "Open refund page": [ - "Abrir página de devolución" - ], - "Open tip page": [ - "Abrir página de propina" - ], - "Open withdraw page": [ - "Abrir página de retirada" - ], - "Back": [ - "Atrás" - ], - "You have no balance to show.": [ - "No tienes balance para mostrar." - ], - "To withdraw money you can start from your bank site or click the \"withdraw\" button to use a known exchange.": [ - "Para retirar dinero puedes empezar desde el sitio de tu banco o cliquear en el botón \"retirar\" para usar un exchange conocido." - ], - "Withdraw": [ - "Retirar" - ], - "Could not load balance page": [ - "No se pudo cargar la página" - ], - "Deposit %1$s": [ - "Depositar %1$s" - ], - "Enter URI": [ - "Ingresar URI" - ], + Balance: ["Balance"], + Backup: ["Copia de seguridad"], + Settings: ["Configuración"], + Dev: ["Dev"], + Loading: ["Cargando"], + "Open reserve page": ["Abrir página de reserva"], + "Open pay page": ["Abrir página de pago"], + "Open refund page": ["Abrir página de devolución"], + "Open tip page": ["Abrir página de propina"], + "Open withdraw page": ["Abrir página de retirada"], + Back: ["Atrás"], + "You have no balance to show.": ["No tienes balance para mostrar."], + 'To withdraw money you can start from your bank site or click the "withdraw" button to use a known exchange.': + [ + 'Para retirar dinero puedes empezar desde el sitio de tu banco o cliquear en el botón "retirar" para usar un exchange conocido.', + ], + Withdraw: ["Retirar"], + "Could not load balance page": ["No se pudo cargar la página"], + "Deposit %1$s": ["Depositar %1$s"], + "Enter URI": ["Ingresar URI"], "Diagnostics timed out. Could not talk to the wallet backend.": [ - "El diagnóstico caducó. No nos pudimos comunicar con la billetera." - ], - "Problems detected:": [ - "Problemas detectados:" - ], - "Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": [ - "Por favor revisa en tu configuración %1$s que tienes IndexedDB habilitado (el nombre de la preferencia %2$s)." - ], - "Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": [ - "La base de datos de la billetera expiró. Por ahora la migración automática no está soportada. Por favor dirijasé a %1$s para reiniciar la base de datos de la billetera." - ], - "Running diagnostics": [ - "Ejecutando diagnósticos" - ], - "Debug tools": [ - "Herramientas de desarrollo" - ], - "reset": [ - "Reiniciar" - ], - "import database": [ - "importar base de datos" - ], - "export database": [ - "exportar base de datos" - ], + "El diagnóstico caducó. No nos pudimos comunicar con la billetera.", + ], + "Problems detected:": ["Problemas detectados:"], + "Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": + [ + "Por favor revisa en tu configuración %1$s que tienes IndexedDB habilitado (el nombre de la preferencia %2$s).", + ], + "Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": + [ + "La base de datos de la billetera expiró. Por ahora la migración automática no está soportada. Por favor dirijasé a %1$s para reiniciar la base de datos de la billetera.", + ], + "Running diagnostics": ["Ejecutando diagnósticos"], + "Debug tools": ["Herramientas de desarrollo"], + reset: ["Reiniciar"], + "import database": ["importar base de datos"], + "export database": ["exportar base de datos"], "Database exported at %1$s %2$s to download": [ - "Base de datos exportada a %1$s %2$s para descargar" - ], - "Coins": [ - "Monedas" - ], - "Pending operations": [ - "Operaciones pendientes" - ], - "usable coins": [ - "monedas usables" - ], - "id": [ - "id" - ], - "denom": [ - "denominación" - ], - "value": [ - "valor" - ], - "status": [ - "estado" - ], - "from refresh?": [ - "desde refresco?" - ], - "spent coins": [ - "monedas gastadas" - ], - "click to show": [ - "hacer clic para mostrar" - ], - "Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": [ - "Quieres DESTRUIR IRREVOCABLEMENTE todo dentro de tu billetera y PERDER TODAS TUS MONEDAS?" - ], - "Taler Action": [ - "Acción Taler" - ], - "This page has pay action.": [ - "Esta página tiene una acción de pago." - ], + "Base de datos exportada a %1$s %2$s para descargar", + ], + Coins: ["Monedas"], + "Pending operations": ["Operaciones pendientes"], + "usable coins": ["monedas usables"], + id: ["id"], + denom: ["denominación"], + value: ["valor"], + status: ["estado"], + "from refresh?": ["desde refresco?"], + "spent coins": ["monedas gastadas"], + "click to show": ["hacer clic para mostrar"], + "Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": + [ + "Quieres DESTRUIR IRREVOCABLEMENTE todo dentro de tu billetera y PERDER TODAS TUS MONEDAS?", + ], + "Taler Action": ["Acción Taler"], + "This page has pay action.": ["Esta página tiene una acción de pago."], "This page has a withdrawal action.": [ - "Esta página tiene una acción de retirada." + "Esta página tiene una acción de retirada.", ], "This page has a tip action.": [ - "Esta página tiene una acción de propina." + "Esta página tiene una acción de propina.", ], "This page has a notify reserve action.": [ - "Esta página tiene una acción de notificación de reserva." - ], - "Notify": [ - "Notificar" + "Esta página tiene una acción de notificación de reserva.", ], + Notify: ["Notificar"], "This page has a refund action.": [ - "Esta página tiene una acción de devolución." + "Esta página tiene una acción de devolución.", ], "This page has a malformed taler uri.": [ - "Esta página tiene una URI de Taler malformada." - ], - "Dismiss": [ - "Descartar" + "Esta página tiene una URI de Taler malformada.", ], + Dismiss: ["Descartar"], "Could not load backup providers": [ - "No se pudo cargar los proveedores de copias de seguridad" + "No se pudo cargar los proveedores de copias de seguridad", ], "No backup providers configured": [ - "No hay proveedores de copias de seguridad configurados" - ], - "Add provider": [ - "Agregar proveedor" - ], - "Sync all backups": [ - "Sincronizar todas las copias de seguridad" - ], - "Sync now": [ - "Sincronizar ahora" - ], - "Last synced": [ - "Ultima vez sincronizado" - ], - "Not synced": [ - "No sincronizado" - ], - "Expires in": [ - "Expira en" - ], + "No hay proveedores de copias de seguridad configurados", + ], + "Add provider": ["Agregar proveedor"], + "Sync all backups": ["Sincronizar todas las copias de seguridad"], + "Sync now": ["Sincronizar ahora"], + "Last synced": ["Ultima vez sincronizado"], + "Not synced": ["No sincronizado"], + "Expires in": ["Expira en"], "Exchange doesn't have terms of service": [ - "El exchange no tiene los términos de servicio" - ], - "Review exchange terms of service": [ - "Revisar los términos de servicio" + "El exchange no tiene los términos de servicio", ], + "Review exchange terms of service": ["Revisar los términos de servicio"], "Review new version of terms of service": [ - "Revisar los nuevos términos de servicio" - ], - "Show terms of service": [ - "Mostrar términos de servicio" + "Revisar los nuevos términos de servicio", ], + "Show terms of service": ["Mostrar términos de servicio"], "I accept the exchange terms of service": [ - "Yo acepto los términos de servicio del exchange" + "Yo acepto los términos de servicio del exchange", ], "The exchange reply with a empty terms of service": [ - "El exchange respondió con unos términos de servicio vacíos" - ], - "Download Terms of Service": [ - "Descargar los términos de servicio" - ], - "Hide terms of service": [ - "Esconder los términos de servicio" - ], - "Review terms of service": [ - "Revisar los términos de servicio" - ], - "Exchange URL": [ - "Exchange URL" - ], - "Cancel": [ - "Cancelar" - ], - "Loading terms..": [ - "Cargando términos..." - ], - "Add exchange": [ - "Agregar exchange" - ], - "Add exchange anyway": [ - "Agregar exchange de todas maneras" - ], - "Add new exchange": [ - "Agregar nuevo exchange" - ], - "Add exchange for %1$s": [ - "Agregar exchange para %1$s" - ], + "El exchange respondió con unos términos de servicio vacíos", + ], + "Download Terms of Service": ["Descargar los términos de servicio"], + "Hide terms of service": ["Esconder los términos de servicio"], + "Review terms of service": ["Revisar los términos de servicio"], + "Exchange URL": ["Exchange URL"], + Cancel: ["Cancelar"], + "Loading terms..": ["Cargando términos..."], + "Add exchange": ["Agregar exchange"], + "Add exchange anyway": ["Agregar exchange de todas maneras"], + "Add new exchange": ["Agregar nuevo exchange"], + "Add exchange for %1$s": ["Agregar exchange para %1$s"], "Enter the URL of an exchange you trust.": [ - "Ingresar la URL de un exchange en el que confíes." + "Ingresar la URL de un exchange en el que confíes.", ], "An exchange has been found! Review the information and click next": [ - "Un exchange ha sido encontrado! Revisa la información y haz clic en siguiente" + "Un exchange ha sido encontrado! Revisa la información y haz clic en siguiente", ], "This exchange doesn't match the expected currency %1$s": [ - "Este exchange no coincide con la divisa %1$s esperada" + "Este exchange no coincide con la divisa %1$s esperada", ], "Unable to verify this exchange": [ - "No fue posible verificar este exchange" - ], - "Unable to add this exchange": [ - "No fue posible agregar este exchange" - ], - "loading": [ - "cargando" - ], - "Version": [ - "Versión" - ], - "Currency": [ - "Divisa" - ], - "Next": [ - "Siguiente" - ], - "Add backup provider": [ - "Agregar proveedor de copias de seguridad" - ], + "No fue posible verificar este exchange", + ], + "Unable to add this exchange": ["No fue posible agregar este exchange"], + loading: ["cargando"], + Version: ["Versión"], + Currency: ["Divisa"], + Next: ["Siguiente"], + "Add backup provider": ["Agregar proveedor de copias de seguridad"], "Could not get provider information": [ - "No se pudo conseguir la información del proveedor" + "No se pudo conseguir la información del proveedor", ], "Backup providers may charge for their service": [ - "Los proveedores de copias de seguridad pueden cobrarte por su servicio" - ], - "URL": [ - "URL" - ], - "Name": [ - "Nombre" - ], - "Provider URL": [ - "URL del proveedor" + "Los proveedores de copias de seguridad pueden cobrarte por su servicio", ], + URL: ["URL"], + Name: ["Nombre"], + "Provider URL": ["URL del proveedor"], "Please review and accept this provider's terms of service": [ - "Por favor revisa y acepta, los términos de servicio del proveedor" - ], - "Pricing": [ - "Precios" - ], - "free of charge": [ - "Gratis" - ], - "%1$s per year of service": [ - "%1$s por año de servicio" - ], - "Storage": [ - "Alamcenamiento" + "Por favor revisa y acepta, los términos de servicio del proveedor", ], + Pricing: ["Precios"], + "free of charge": ["Gratis"], + "%1$s per year of service": ["%1$s por año de servicio"], + Storage: ["Alamcenamiento"], "%1$s megabytes of storage per year of service": [ - "%1$s megabytes de almacenamiento por año de servicio" - ], - "Accept terms of service": [ - "Aceptar los términos de servicio" - ], - "There was an error loading the provider detail for \"%1$s\"": [ - "Hubo un error cargando los detalles del proveedor para \"%1$s\"" - ], - "There is not known provider with url \"%1$s\".": [ - "No hay proveedor conocido con la URL \"%1$s\"." - ], - "Last backup": [ - "Última copia de seguridad" - ], - "Back up": [ - "Copia de seguridad" - ], - "Provider fee": [ - "Tarifa del proveedor" - ], - "per year": [ - "por año" - ], - "Extend": [ - "Extender" - ], - "terms has changed, extending the service will imply accepting the new terms of service": [ - "los términos han cambiado, extender el servicio implicará aceptar los nuevos términos de servicio" - ], - "old": [ - "viejo" - ], - "new": [ - "nuevo" - ], - "fee": [ - "tarifa" - ], - "storage": [ - "almacenamiento" - ], - "back": [ - "volver" - ], - "Remove provider": [ - "Eliminar proveedor" - ], + "%1$s megabytes de almacenamiento por año de servicio", + ], + "Accept terms of service": ["Aceptar los términos de servicio"], + 'There was an error loading the provider detail for "%1$s"': [ + 'Hubo un error cargando los detalles del proveedor para "%1$s"', + ], + 'There is not known provider with url "%1$s".': [ + 'No hay proveedor conocido con la URL "%1$s".', + ], + "Last backup": ["Última copia de seguridad"], + "Back up": ["Copia de seguridad"], + "Provider fee": ["Tarifa del proveedor"], + "per year": ["por año"], + Extend: ["Extender"], + "terms has changed, extending the service will imply accepting the new terms of service": + [ + "los términos han cambiado, extender el servicio implicará aceptar los nuevos términos de servicio", + ], + old: ["viejo"], + new: ["nuevo"], + fee: ["tarifa"], + storage: ["almacenamiento"], + back: ["volver"], + "Remove provider": ["Eliminar proveedor"], "This provider has reported an error": [ - "Este proveedor ha reportado un error" + "Este proveedor ha reportado un error", ], "There is conflict with another backup from %1$s": [ - "Hay un conflicto con otra copia de seguridad de %1$s" - ], - "Backup is not readable": [ - "La copia de seguridad no es legible" + "Hay un conflicto con otra copia de seguridad de %1$s", ], + "Backup is not readable": ["La copia de seguridad no es legible"], "Unknown backup problem: %1$s": [ - "Problema de copia de seguridad desconocido: %1$s" - ], - "service paid": [ - "servicio pagado" - ], - "Backup valid until": [ - "Copia de seguridad válida hasta" + "Problema de copia de seguridad desconocido: %1$s", ], + "service paid": ["servicio pagado"], + "Backup valid until": ["Copia de seguridad válida hasta"], "this popup is being closed and you are being redirected to %1$s": [ - "Este popup está siendo cerrado y estás siendo redirigido a %1$s" - ], - "Select one option": [ - "Seleccione una opción" - ], - "Manual Withdrawal": [ - "Retirada Manual" - ], - "Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": [ - "Elija un exchange desde donde las monedas serán retiradas. El exchange enviará las monedas a esta billetera después de recibir una transferencia bancaria con el asunto correcto." - ], - "No exchange configured": [ - "Sin exchange configurado" - ], - "Can't create the reserve": [ - "No se pudo crear una reserva" - ], - "Exchange": [ - "Exchange" - ], - "Add Exchange": [ - "Agregar Exchange" - ], - "Amount": [ - "Cantidad" - ], - "Start withdrawal": [ - "Comenzar la retirada" - ], - "no balance": [ - "sin balance" - ], + "Este popup está siendo cerrado y estás siendo redirigido a %1$s", + ], + "Select one option": ["Seleccione una opción"], + "Manual Withdrawal": ["Retirada Manual"], + "Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": + [ + "Elija un exchange desde donde las monedas serán retiradas. El exchange enviará las monedas a esta billetera después de recibir una transferencia bancaria con el asunto correcto.", + ], + "No exchange configured": ["Sin exchange configurado"], + "Can't create the reserve": ["No se pudo crear una reserva"], + Exchange: ["Exchange"], + "Add Exchange": ["Agregar Exchange"], + Amount: ["Cantidad"], + "Start withdrawal": ["Comenzar la retirada"], + "no balance": ["sin balance"], "There is no known bank account to send money to": [ - "No hay una cuenta bancaria conocida, donde enviar el dinero" - ], - "Send %1$s to your account": [ - "Enviar %1$s a tu cuenta" - ], - "Bank account IBAN number": [ - "Número IBAN de cuenta bancaria" - ], - "Deposit fee": [ - "Comisión de depósito" - ], - "Total deposit": [ - "Depósito total" - ], - "Deposit": [ - "Depósito" - ], - "Deposit %1$s %2$s": [ - "Depositar %1$s %2$s" - ], - "Waiting for confirmation": [ - "Esperando confirmación" - ], - "PENDING": [ - "PENDIENTE" - ], + "No hay una cuenta bancaria conocida, donde enviar el dinero", + ], + "Send %1$s to your account": ["Enviar %1$s a tu cuenta"], + "Bank account IBAN number": ["Número IBAN de cuenta bancaria"], + "Deposit fee": ["Comisión de depósito"], + "Total deposit": ["Depósito total"], + Deposit: ["Depósito"], + "Deposit %1$s %2$s": ["Depositar %1$s %2$s"], + "Waiting for confirmation": ["Esperando confirmación"], + PENDING: ["PENDIENTE"], "Could not load the list of transactions": [ - "No se pudo cargar la lista de transacciones" + "No se pudo cargar la lista de transacciones", ], "There is no history for this currency": [ - "No hay historial para esta divisa" - ], - "Account": [ - "Cuenta" - ], - "Bank host": [ - "Banco anfitrión" - ], - "Bank account": [ - "Cuenta del banco" - ], - "IBAN": [ - "IBAN" - ], - "Chosen amount": [ - "Elegir cantidad" - ], - "Subject": [ - "Asunto" - ], + "No hay historial para esta divisa", + ], + Account: ["Cuenta"], + "Bank host": ["Banco anfitrión"], + "Bank account": ["Cuenta del banco"], + IBAN: ["IBAN"], + "Chosen amount": ["Elegir cantidad"], + Subject: ["Asunto"], "could not parse payto uri from exchange %1$s": [ - "No se pudo analizar la URI pagar-a del exchange %1$s" + "No se pudo analizar la URI pagar-a del exchange %1$s", ], "Exchange is ready for withdrawal": [ - "El exchange está listo para la retirada" - ], - "To complete the process you need to wire %1$s to the exchange bank account": [ - "Para completar el proceso necesitas transferir %1$s a la cuenta bancaria del exchange" - ], - "Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": [ - "Asegúrate de usar el asunto correcto, de lo contrario el dinero no llegará a esta billetera." - ], - "Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": [ - "Alternativamente, también puedes escanear el código QR o abrir %1$s si tienes una App bancaria instalada que soporta RFC 8905" - ], - "Cancel withdrawal": [ - "Cancelar retirada" - ], - "Display": [ - "Pantalla" - ], - "Current Language": [ - "Lenguaje actual" - ], - "Navigator": [ - "Navegador" - ], + "El exchange está listo para la retirada", + ], + "To complete the process you need to wire %1$s to the exchange bank account": + [ + "Para completar el proceso necesitas transferir %1$s a la cuenta bancaria del exchange", + ], + "Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": + [ + "Asegúrate de usar el asunto correcto, de lo contrario el dinero no llegará a esta billetera.", + ], + "Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": + [ + "Alternativamente, también puedes escanear el código QR o abrir %1$s si tienes una App bancaria instalada que soporta RFC 8905", + ], + "Cancel withdrawal": ["Cancelar retirada"], + Display: ["Pantalla"], + "Current Language": ["Lenguaje actual"], + Navigator: ["Navegador"], "Automatically open wallet based on page content": [ - "Abrir automáticamente la billetera basada en el contenido de la página" - ], - "Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": [ - "Habilitar la opción de debajo, hará que el uso de la billetera sea mas rápido, pero requiere más permisos de tu navegador." - ], - "Trust": [ - "Confianza" - ], - "No exchange yet": [ - "No hay exchanges todavía" - ], - "Term of Service": [ - "Términos de servicio" - ], - "ok": [ - "ok" - ], - "changed": [ - "modificado" - ], - "not accepted": [ - "no aceptado" - ], - "Add an exchange": [ - "Agregar un exchange" - ], - "Developer mode": [ - "Modo desarrollador" - ], + "Abrir automáticamente la billetera basada en el contenido de la página", + ], + "Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": + [ + "Habilitar la opción de debajo, hará que el uso de la billetera sea mas rápido, pero requiere más permisos de tu navegador.", + ], + Trust: ["Confianza"], + "No exchange yet": ["No hay exchanges todavía"], + "Term of Service": ["Términos de servicio"], + ok: ["ok"], + changed: ["modificado"], + "not accepted": ["no aceptado"], + "Add an exchange": ["Agregar un exchange"], + "Developer mode": ["Modo desarrollador"], "(More options and information useful for debugging)": [ - "(Más información y opciones útiles para depuración)" + "(Más información y opciones útiles para depuración)", ], "Could not load the transaction information": [ - "No se pudo cargar información de la transacción" + "No se pudo cargar información de la transacción", ], "There was an error trying to complete the transaction": [ - "Hubo un error intentando completar la transacción" + "Hubo un error intentando completar la transacción", ], "This transaction is not completed": [ - "Esta transacción no está completada" - ], - "Retry": [ - "Reintentar" - ], - "Forget": [ - "Olvidar" - ], - "Caution!": [ - "Cuidado!" - ], - "If you have already wired money to the exchange you will loose the chance to get the coins form it.": [ - "Si tú ya has transferido dinero al exchange, perderás la oportunidad de recibir las monedas desde este." - ], - "Confirm": [ - "Confirmar" - ], - "Withdrawal": [ - "Retirada" - ], - "Total withdrawn": [ - "Total extraído" - ], - "Exchange fee": [ - "Comisión del exchange" - ], + "Esta transacción no está completada", + ], + Retry: ["Reintentar"], + Forget: ["Olvidar"], + "Caution!": ["Cuidado!"], + "If you have already wired money to the exchange you will loose the chance to get the coins form it.": + [ + "Si tú ya has transferido dinero al exchange, perderás la oportunidad de recibir las monedas desde este.", + ], + Confirm: ["Confirmar"], + Withdrawal: ["Retirada"], + "Total withdrawn": ["Total extraído"], + "Exchange fee": ["Comisión del exchange"], "The bank is waiting for confirmation. Go to the %1$s": [ - "El banco espera la confirmación. Dirigete a %1$s" + "El banco espera la confirmación. Dirigete a %1$s", ], "Waiting for the coins to arrive": [ - "Esperando a que las monedas lleguen" - ], - "Payment": [ - "Pago" - ], - "Total paid": [ - "Total pagado" - ], - "Purchase amount": [ - "Importe de la compra" - ], - "Fee": [ - "Comisión" - ], - "Merchant": [ - "Comerciante" - ], - "Purchase": [ - "Compra" - ], - "Receipt": [ - "Recibo" - ], - "Total send": [ - "Total enviado" - ], - "Deposit amount": [ - "Cantidad a depositar" - ], - "Refresh": [ - "Actualizar" - ], - "Total refresh": [ - "Actualización total" - ], - "Refresh amount": [ - "Refrescar cantidad" - ], - "Tip": [ - "Propina" - ], - "Total tip": [ - "Total de propina" - ], - "Received amount": [ - "Cantidad recibida" - ], - "Refund": [ - "Devolución" - ], - "Total refund": [ - "Devolución total" - ], - "Refund amount": [ - "Importe de la devolución" - ], - "Browser Extension Installed!": [ - "Extensión del navegador instalada!" - ], + "Esperando a que las monedas lleguen", + ], + Payment: ["Pago"], + "Total paid": ["Total pagado"], + "Purchase amount": ["Importe de la compra"], + Fee: ["Comisión"], + Merchant: ["Comerciante"], + Purchase: ["Compra"], + Receipt: ["Recibo"], + "Total send": ["Total enviado"], + "Deposit amount": ["Cantidad a depositar"], + Refresh: ["Actualizar"], + "Total refresh": ["Actualización total"], + "Refresh amount": ["Refrescar cantidad"], + Tip: ["Propina"], + "Total tip": ["Total de propina"], + "Received amount": ["Cantidad recibida"], + Refund: ["Devolución"], + "Total refund": ["Devolución total"], + "Refund amount": ["Importe de la devolución"], + "Browser Extension Installed!": ["Extensión del navegador instalada!"], "Thank you for installing the wallet.": [ - "Gracias por haber instalado la billetera." - ], - "Permissions": [ - "Permisos" - ], - "(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": [ - "(Habilitar esta opción de abajo hará el uso de la billetera mas rápido, pero requiere mas permisos de tu navegador)" - ], - "Next Steps": [ - "Próximos pasos" - ], - "Try the demo": [ - "Probar la demostración" - ], + "Gracias por haber instalado la billetera.", + ], + Permissions: ["Permisos"], + "(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": + [ + "(Habilitar esta opción de abajo hará el uso de la billetera mas rápido, pero requiere mas permisos de tu navegador)", + ], + "Next Steps": ["Próximos pasos"], + "Try the demo": ["Probar la demostración"], "Learn how to top up your wallet balance": [ - "Aprender como llenar tu billetera" - ], - "Could not load pay status": [ - "No se pudo cargar el estado del pago" + "Aprender como llenar tu billetera", ], + "Could not load pay status": ["No se pudo cargar el estado del pago"], "Could not load contract terms from merchant or wallet backend.": [ - "No se pudieron cargar los términos de contrato del comerciante o de la billetera." - ], - "Pay with a mobile phone": [ - "Pagar con un teléfono móbil" - ], - "Hide QR": [ - "Esconder QR" - ], - "Scan the QR code or %1$s": [ - "Escanear el código QR o %1$s" - ], - "Processing": [ - "Procesando" - ], - "Pay %1$s": [ - "Pagar %1$s" + "No se pudieron cargar los términos de contrato del comerciante o de la billetera.", ], + "Pay with a mobile phone": ["Pagar con un teléfono móbil"], + "Hide QR": ["Esconder QR"], + "Scan the QR code or %1$s": ["Escanear el código QR o %1$s"], + Processing: ["Procesando"], + "Pay %1$s": ["Pagar %1$s"], "Your balance of %1$s is not enough to pay for this purchase": [ - "Tu balance de %1$s no es suficiente para pagar por esta compra" + "Tu balance de %1$s no es suficiente para pagar por esta compra", ], "Your balance is not enough to pay for this purchase.": [ - "Tu balance no es suficiente para pagar esta compra." - ], - "Withdraw digital cash": [ - "Retirar dinero digital" - ], - "Merchant message": [ - "Mensaje del comerciante" - ], - "Digital cash payment": [ - "Pago con dinero digital" + "Tu balance no es suficiente para pagar esta compra.", ], + "Withdraw digital cash": ["Retirar dinero digital"], + "Merchant message": ["Mensaje del comerciante"], + "Digital cash payment": ["Pago con dinero digital"], "Already paid, you are going to be redirected to %1$s": [ - "Ya pagado, estás siendo dirigido a %1$s" - ], - "Already paid": [ - "Ya pagado" - ], - "Already claimed": [ - "Ya reclamado" - ], - "Payment complete": [ - "Pago completado" + "Ya pagado, estás siendo dirigido a %1$s", ], + "Already paid": ["Ya pagado"], + "Already claimed": ["Ya reclamado"], + "Payment complete": ["Pago completado"], "You are going to be redirected to $ %1$s": [ - "Vas a ser redirigido a %1$s" - ], - "You can close this page.": [ - "Puedes cerrar esta página." - ], - "Total to pay": [ - "Total a pagar" - ], - "List of products": [ - "Lista de productos" - ], - "Total": [ - "Total" - ], - "free": [ - "Gratis" - ], - "Refund Status": [ - "Estado del reembolso" - ], + "Vas a ser redirigido a %1$s", + ], + "You can close this page.": ["Puedes cerrar esta página."], + "Total to pay": ["Total a pagar"], + "List of products": ["Lista de productos"], + Total: ["Total"], + free: ["Gratis"], + "Refund Status": ["Estado del reembolso"], "The product %1$s has received a total effective refund of": [ - "El producto %1$s ha recibido un reembolso total efectivo de" + "El producto %1$s ha recibido un reembolso total efectivo de", ], "Refund processing is still in progress.": [ - "El proceso de reembolso está todavía en progreso." + "El proceso de reembolso está todavía en progreso.", ], "The refund amount of %1$s could not be applied.": [ - "El importe del reembolso de %1$s no pudo ser aplicado." - ], - "missing taler refund uri": [ - "falta la URI Taler de reembolso" - ], - "Error: %1$s": [ - "Error: %1$s" - ], - "Updating refund status": [ - "Actualizando el estado de reembolso" - ], - "Tip from %1$s accepted. Check your transactions list for more details.": [ - "Propina de %1$s aceptada. Revisa tu lista de transacciones para más detalle." - ], + "El importe del reembolso de %1$s no pudo ser aplicado.", + ], + "missing taler refund uri": ["falta la URI Taler de reembolso"], + "Error: %1$s": ["Error: %1$s"], + "Updating refund status": ["Actualizando el estado de reembolso"], + "Tip from %1$s accepted. Check your transactions list for more details.": + [ + "Propina de %1$s aceptada. Revisa tu lista de transacciones para más detalle.", + ], "The merchant %1$s is offering you a tip of %2$s via the exchange %3$s": [ - "El comerciante %1$s te está ofreciendo una propina de %2$s a través del exchange %3$s" - ], - "Accept tip": [ - "Aceptar propina" - ], - "Ignore": [ - "Ignorar" - ], - "missing tip uri": [ - "falta la URI de la propina" - ], - "You've ignored the tip.": [ - "Has ignorado la propina." - ], - "Digital cash withdrawal": [ - "Retirada de dinero digital" + "El comerciante %1$s te está ofreciendo una propina de %2$s a través del exchange %3$s", ], + "Accept tip": ["Aceptar propina"], + Ignore: ["Ignorar"], + "missing tip uri": ["falta la URI de la propina"], + "You've ignored the tip.": ["Has ignorado la propina."], + "Digital cash withdrawal": ["Retirada de dinero digital"], "Could not finish the withdrawal operation": [ - "No se pudo completar la operación de retirada" - ], - "Total to withdraw": [ - "Total a retirar" - ], - "Known exchanges": [ - "Exchange conocidos" - ], - "Cancel exchange selection": [ - "Cancelar la selección de exchange" - ], - "Confirm exchange selection": [ - "Confirmar la selección de exchange" - ], - "Switch exchange": [ - "Cambiar exchange" - ], - "Confirm withdrawal": [ - "Confirmar retirada" - ], - "Withdraw anyway": [ - "Retirar de todas maneras" - ], + "No se pudo completar la operación de retirada", + ], + "Total to withdraw": ["Total a retirar"], + "Known exchanges": ["Exchange conocidos"], + "Cancel exchange selection": ["Cancelar la selección de exchange"], + "Confirm exchange selection": ["Confirmar la selección de exchange"], + "Switch exchange": ["Cambiar exchange"], + "Confirm withdrawal": ["Confirmar retirada"], + "Withdraw anyway": ["Retirar de todas maneras"], "Could not load the withdrawal details": [ - "No se pudieron cargar los detalles de la retirada" - ], - "missing withdraw uri": [ - "falta la URI de retirada" + "No se pudieron cargar los detalles de la retirada", ], + "missing withdraw uri": ["falta la URI de retirada"], "Could not get the info from the URI": [ - "No se pudo obtener la información desde la URI" + "No se pudo obtener la información desde la URI", ], "Could not load the list of known exchanges": [ - "No se pudo cargar la lista de exchange conocidos" + "No se pudo cargar la lista de exchange conocidos", ], "All done, your transaction is in progress": [ - "Todo completo, su transacción está en progreso" - ], - "Edit": [ - "Editar" - ], - "missing pay uri": [ - "falta la URI de pago" + "Todo completo, su transacción está en progreso", ], + Edit: ["Editar"], + "missing pay uri": ["falta la URI de pago"], "Could not get the payment information for this order": [ - "No se pudo obtener la información de pago para esta orden" - ], - "Loading payment information": [ - "Cargado la información de pago" - ], - "Digital cash deposit": [ - "Depósito de dinero digital" + "No se pudo obtener la información de pago para esta orden", ], + "Loading payment information": ["Cargado la información de pago"], + "Digital cash deposit": ["Depósito de dinero digital"], "You will now be sent back to the merchant you came from.": [ - "Ahora serás enviado de nuevo al comerciante desde donde viniste." - ], - "Manual Reset Required": [ - "Reinicio Manual Necesario" - ], - "The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": [ - "La base de datos de billetera en tu navegador es incompatible con la billetera instalada actualmente. Por favor reinicie manualmente." - ], - "Once the database format has stabilized, we will provide automatic upgrades.": [ - "Una vez que el formato de la base de datos se haya estabilizado, proveeremos de actualizaciones automáticas." - ], + "Ahora serás enviado de nuevo al comerciante desde donde viniste.", + ], + "Manual Reset Required": ["Reinicio Manual Necesario"], + "The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": + [ + "La base de datos de billetera en tu navegador es incompatible con la billetera instalada actualmente. Por favor reinicie manualmente.", + ], + "Once the database format has stabilized, we will provide automatic upgrades.": + [ + "Una vez que el formato de la base de datos se haya estabilizado, proveeremos de actualizaciones automáticas.", + ], "I understand that I will lose all my data": [ - "Entiendo que perderé toda mi información" - ], - "Reset": [ - "Reiniciar" - ], - "Everything is fine!": [ - "Todo está bien!" + "Entiendo que perderé toda mi información", ], + Reset: ["Reiniciar"], + "Everything is fine!": ["Todo está bien!"], "A reset is not required anymore, you can close this page.": [ - "Un reinicio ya no es necesario, puede cerrar esta página." + "Un reinicio ya no es necesario, puede cerrar esta página.", ], - "Not implemented yet.": [ - "Todavía no implementado." - ] - } - } + "Not implemented yet.": ["Todavía no implementado."], + }, + }, }; -strings['fr'] = { - "domain": "messages", - "locale_data": { - "messages": { +strings["fr"] = { + domain: "messages", + locale_data: { + messages: { "": { - "domain": "messages", - "plural_forms": "nplurals=2; plural=(n!=1);", - "lang": "fr" + domain: "messages", + plural_forms: "nplurals=2; plural=(n!=1);", + lang: "fr", }, - "Balance": [ - "" - ], - "Backup": [ - "" - ], - "Settings": [ - "" - ], - "Dev": [ - "" - ], - "Loading": [ - "" - ], - "Open reserve page": [ - "" - ], - "Open pay page": [ - "" - ], - "Open refund page": [ - "" - ], - "Open tip page": [ - "" - ], - "Open withdraw page": [ - "" - ], - "Back": [ - "" - ], - "You have no balance to show.": [ - "" - ], - "To withdraw money you can start from your bank site or click the \"withdraw\" button to use a known exchange.": [ - "" - ], - "Withdraw": [ - "" - ], - "Could not load balance page": [ - "" - ], - "Deposit %1$s": [ - "" - ], - "Enter URI": [ - "" - ], - "Diagnostics timed out. Could not talk to the wallet backend.": [ - "" - ], - "Problems detected:": [ - "" - ], - "Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": [ - "" - ], - "Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": [ - "" - ], - "Running diagnostics": [ - "" - ], - "Debug tools": [ - "" - ], - "reset": [ - "" - ], - "import database": [ - "" - ], - "export database": [ - "" - ], - "Database exported at %1$s %2$s to download": [ - "" - ], - "Coins": [ - "" - ], - "Pending operations": [ - "" - ], - "usable coins": [ - "" - ], - "id": [ - "" - ], - "denom": [ - "" - ], - "value": [ - "" - ], - "status": [ - "" - ], - "from refresh?": [ - "" - ], - "spent coins": [ - "" - ], - "click to show": [ - "" - ], - "Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": [ - "" - ], - "Taler Action": [ - "" - ], - "This page has pay action.": [ - "" - ], - "This page has a withdrawal action.": [ - "" - ], - "This page has a tip action.": [ - "" - ], - "This page has a notify reserve action.": [ - "" - ], - "Notify": [ - "" - ], - "This page has a refund action.": [ - "" - ], - "This page has a malformed taler uri.": [ - "" - ], - "Dismiss": [ - "" - ], - "Could not load backup providers": [ - "" - ], - "No backup providers configured": [ - "" - ], - "Add provider": [ - "" - ], - "Sync all backups": [ - "" - ], - "Sync now": [ - "" - ], - "Last synced": [ - "" - ], - "Not synced": [ - "" - ], - "Expires in": [ - "" - ], - "Exchange doesn't have terms of service": [ - "" - ], - "Review exchange terms of service": [ - "" - ], - "Review new version of terms of service": [ - "" - ], - "Show terms of service": [ - "" - ], - "I accept the exchange terms of service": [ - "" - ], - "The exchange reply with a empty terms of service": [ - "" - ], - "Download Terms of Service": [ - "" - ], - "Hide terms of service": [ - "" - ], - "Review terms of service": [ - "" - ], - "Exchange URL": [ - "" - ], - "Cancel": [ - "" - ], - "Loading terms..": [ - "" - ], - "Add exchange": [ - "" - ], - "Add exchange anyway": [ - "" - ], - "Add new exchange": [ - "" - ], - "Add exchange for %1$s": [ - "" - ], - "Enter the URL of an exchange you trust.": [ - "" - ], - "An exchange has been found! Review the information and click next": [ - "" - ], - "This exchange doesn't match the expected currency %1$s": [ - "" - ], - "Unable to verify this exchange": [ - "" - ], - "Unable to add this exchange": [ - "" - ], - "loading": [ - "" - ], - "Version": [ - "" - ], - "Currency": [ - "" - ], - "Next": [ - "" - ], - "Add backup provider": [ - "" - ], - "Could not get provider information": [ - "" - ], - "Backup providers may charge for their service": [ - "" - ], - "URL": [ - "" - ], - "Name": [ - "" - ], - "Provider URL": [ - "" - ], - "Please review and accept this provider's terms of service": [ - "" - ], - "Pricing": [ - "" - ], - "free of charge": [ - "" - ], - "%1$s per year of service": [ - "" - ], - "Storage": [ - "" - ], - "%1$s megabytes of storage per year of service": [ - "" - ], - "Accept terms of service": [ - "" - ], - "There was an error loading the provider detail for \"%1$s\"": [ - "" - ], - "There is not known provider with url \"%1$s\".": [ - "" - ], - "Last backup": [ - "" - ], - "Back up": [ - "" - ], - "Provider fee": [ - "" - ], - "per year": [ - "" - ], - "Extend": [ - "" - ], - "terms has changed, extending the service will imply accepting the new terms of service": [ - "" - ], - "old": [ - "" - ], - "new": [ - "" - ], - "fee": [ - "" - ], - "storage": [ - "" - ], - "back": [ - "" - ], - "Remove provider": [ - "" - ], - "This provider has reported an error": [ - "" - ], - "There is conflict with another backup from %1$s": [ - "" - ], - "Backup is not readable": [ - "" - ], - "Unknown backup problem: %1$s": [ - "" - ], - "service paid": [ - "" - ], - "Backup valid until": [ - "" - ], - "this popup is being closed and you are being redirected to %1$s": [ - "" - ], - "Select one option": [ - "" - ], - "Manual Withdrawal": [ - "" - ], - "Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": [ - "" - ], - "No exchange configured": [ - "" - ], - "Can't create the reserve": [ - "" - ], - "Exchange": [ - "" - ], - "Add Exchange": [ - "" - ], - "Amount": [ - "" - ], - "Start withdrawal": [ - "" - ], - "no balance": [ - "" - ], - "There is no known bank account to send money to": [ - "" - ], - "Send %1$s to your account": [ - "" - ], - "Bank account IBAN number": [ - "" - ], - "Deposit fee": [ - "" - ], - "Total deposit": [ - "" - ], - "Deposit": [ - "" - ], - "Deposit %1$s %2$s": [ - "" - ], - "Waiting for confirmation": [ - "" - ], - "PENDING": [ - "" - ], - "Could not load the list of transactions": [ - "" - ], - "There is no history for this currency": [ - "" - ], - "Account": [ - "" - ], - "Bank host": [ - "" - ], - "Bank account": [ - "" - ], - "IBAN": [ - "" - ], - "Chosen amount": [ - "" - ], - "Subject": [ - "" - ], - "could not parse payto uri from exchange %1$s": [ - "" - ], - "Exchange is ready for withdrawal": [ - "" - ], - "To complete the process you need to wire %1$s to the exchange bank account": [ - "" - ], - "Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": [ - "" - ], - "Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": [ - "" - ], - "Cancel withdrawal": [ - "" - ], - "Display": [ - "" - ], - "Current Language": [ - "" - ], - "Navigator": [ - "" - ], - "Automatically open wallet based on page content": [ - "" - ], - "Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": [ - "" - ], - "Trust": [ - "" - ], - "No exchange yet": [ - "" - ], - "Term of Service": [ - "" - ], - "ok": [ - "" - ], - "changed": [ - "" - ], - "not accepted": [ - "" - ], - "Add an exchange": [ - "" - ], - "Developer mode": [ - "" - ], - "(More options and information useful for debugging)": [ - "" - ], - "Could not load the transaction information": [ - "" - ], - "There was an error trying to complete the transaction": [ - "" - ], - "This transaction is not completed": [ - "" - ], - "Retry": [ - "" - ], - "Forget": [ - "" - ], - "Caution!": [ - "" - ], - "If you have already wired money to the exchange you will loose the chance to get the coins form it.": [ - "" - ], - "Confirm": [ - "Confirmer" - ], - "Withdrawal": [ - "" - ], - "Total withdrawn": [ - "" - ], - "Exchange fee": [ - "" - ], - "The bank is waiting for confirmation. Go to the %1$s": [ - "" - ], - "Waiting for the coins to arrive": [ - "" - ], - "Payment": [ - "" - ], - "Total paid": [ - "" - ], - "Purchase amount": [ - "" - ], - "Fee": [ - "" - ], - "Merchant": [ - "" - ], - "Purchase": [ - "" - ], - "Receipt": [ - "" - ], - "Total send": [ - "" - ], - "Deposit amount": [ - "" - ], - "Refresh": [ - "" - ], - "Total refresh": [ - "" - ], - "Refresh amount": [ - "" - ], - "Tip": [ - "" - ], - "Total tip": [ - "" - ], - "Received amount": [ - "" - ], - "Refund": [ - "" - ], - "Total refund": [ - "" - ], - "Refund amount": [ - "" - ], - "Browser Extension Installed!": [ - "" - ], - "Thank you for installing the wallet.": [ - "" - ], - "Permissions": [ - "" - ], - "(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": [ - "" - ], - "Next Steps": [ - "" - ], - "Try the demo": [ - "" - ], - "Learn how to top up your wallet balance": [ - "" - ], - "Could not load pay status": [ - "" - ], - "Could not load contract terms from merchant or wallet backend.": [ - "" - ], - "Pay with a mobile phone": [ - "" - ], - "Hide QR": [ - "" - ], - "Scan the QR code or %1$s": [ - "" - ], - "Processing": [ - "" - ], - "Pay %1$s": [ - "" - ], - "Your balance of %1$s is not enough to pay for this purchase": [ - "" - ], - "Your balance is not enough to pay for this purchase.": [ - "" - ], - "Withdraw digital cash": [ - "" - ], - "Merchant message": [ - "" - ], - "Digital cash payment": [ - "" - ], - "Already paid, you are going to be redirected to %1$s": [ - "" - ], - "Already paid": [ - "" - ], - "Already claimed": [ - "" - ], - "Payment complete": [ - "" - ], - "You are going to be redirected to $ %1$s": [ - "" - ], - "You can close this page.": [ - "" - ], - "Total to pay": [ - "" - ], - "List of products": [ - "" - ], - "Total": [ - "" - ], - "free": [ - "" - ], - "Refund Status": [ - "" - ], - "The product %1$s has received a total effective refund of": [ - "" - ], - "Refund processing is still in progress.": [ - "" - ], - "The refund amount of %1$s could not be applied.": [ - "" - ], - "missing taler refund uri": [ - "" - ], - "Error: %1$s": [ - "" - ], - "Updating refund status": [ - "" - ], - "Tip from %1$s accepted. Check your transactions list for more details.": [ - "" - ], + Balance: [""], + Backup: [""], + Settings: [""], + Dev: [""], + Loading: [""], + "Open reserve page": [""], + "Open pay page": [""], + "Open refund page": [""], + "Open tip page": [""], + "Open withdraw page": [""], + Back: [""], + "You have no balance to show.": [""], + 'To withdraw money you can start from your bank site or click the "withdraw" button to use a known exchange.': + [""], + Withdraw: [""], + "Could not load balance page": [""], + "Deposit %1$s": [""], + "Enter URI": [""], + "Diagnostics timed out. Could not talk to the wallet backend.": [""], + "Problems detected:": [""], + "Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": + [""], + "Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": + [""], + "Running diagnostics": [""], + "Debug tools": [""], + reset: [""], + "import database": [""], + "export database": [""], + "Database exported at %1$s %2$s to download": [""], + Coins: [""], + "Pending operations": [""], + "usable coins": [""], + id: [""], + denom: [""], + value: [""], + status: [""], + "from refresh?": [""], + "spent coins": [""], + "click to show": [""], + "Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": + [""], + "Taler Action": [""], + "This page has pay action.": [""], + "This page has a withdrawal action.": [""], + "This page has a tip action.": [""], + "This page has a notify reserve action.": [""], + Notify: [""], + "This page has a refund action.": [""], + "This page has a malformed taler uri.": [""], + Dismiss: [""], + "Could not load backup providers": [""], + "No backup providers configured": [""], + "Add provider": [""], + "Sync all backups": [""], + "Sync now": [""], + "Last synced": [""], + "Not synced": [""], + "Expires in": [""], + "Exchange doesn't have terms of service": [""], + "Review exchange terms of service": [""], + "Review new version of terms of service": [""], + "Show terms of service": [""], + "I accept the exchange terms of service": [""], + "The exchange reply with a empty terms of service": [""], + "Download Terms of Service": [""], + "Hide terms of service": [""], + "Review terms of service": [""], + "Exchange URL": [""], + Cancel: [""], + "Loading terms..": [""], + "Add exchange": [""], + "Add exchange anyway": [""], + "Add new exchange": [""], + "Add exchange for %1$s": [""], + "Enter the URL of an exchange you trust.": [""], + "An exchange has been found! Review the information and click next": [""], + "This exchange doesn't match the expected currency %1$s": [""], + "Unable to verify this exchange": [""], + "Unable to add this exchange": [""], + loading: [""], + Version: [""], + Currency: [""], + Next: [""], + "Add backup provider": [""], + "Could not get provider information": [""], + "Backup providers may charge for their service": [""], + URL: [""], + Name: [""], + "Provider URL": [""], + "Please review and accept this provider's terms of service": [""], + Pricing: [""], + "free of charge": [""], + "%1$s per year of service": [""], + Storage: [""], + "%1$s megabytes of storage per year of service": [""], + "Accept terms of service": [""], + 'There was an error loading the provider detail for "%1$s"': [""], + 'There is not known provider with url "%1$s".': [""], + "Last backup": [""], + "Back up": [""], + "Provider fee": [""], + "per year": [""], + Extend: [""], + "terms has changed, extending the service will imply accepting the new terms of service": + [""], + old: [""], + new: [""], + fee: [""], + storage: [""], + back: [""], + "Remove provider": [""], + "This provider has reported an error": [""], + "There is conflict with another backup from %1$s": [""], + "Backup is not readable": [""], + "Unknown backup problem: %1$s": [""], + "service paid": [""], + "Backup valid until": [""], + "this popup is being closed and you are being redirected to %1$s": [""], + "Select one option": [""], + "Manual Withdrawal": [""], + "Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": + [""], + "No exchange configured": [""], + "Can't create the reserve": [""], + Exchange: [""], + "Add Exchange": [""], + Amount: [""], + "Start withdrawal": [""], + "no balance": [""], + "There is no known bank account to send money to": [""], + "Send %1$s to your account": [""], + "Bank account IBAN number": [""], + "Deposit fee": [""], + "Total deposit": [""], + Deposit: [""], + "Deposit %1$s %2$s": [""], + "Waiting for confirmation": [""], + PENDING: [""], + "Could not load the list of transactions": [""], + "There is no history for this currency": [""], + Account: [""], + "Bank host": [""], + "Bank account": [""], + IBAN: [""], + "Chosen amount": [""], + Subject: [""], + "could not parse payto uri from exchange %1$s": [""], + "Exchange is ready for withdrawal": [""], + "To complete the process you need to wire %1$s to the exchange bank account": + [""], + "Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": + [""], + "Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": + [""], + "Cancel withdrawal": [""], + Display: [""], + "Current Language": [""], + Navigator: [""], + "Automatically open wallet based on page content": [""], + "Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": + [""], + Trust: [""], + "No exchange yet": [""], + "Term of Service": [""], + ok: [""], + changed: [""], + "not accepted": [""], + "Add an exchange": [""], + "Developer mode": [""], + "(More options and information useful for debugging)": [""], + "Could not load the transaction information": [""], + "There was an error trying to complete the transaction": [""], + "This transaction is not completed": [""], + Retry: [""], + Forget: [""], + "Caution!": [""], + "If you have already wired money to the exchange you will loose the chance to get the coins form it.": + [""], + Confirm: ["Confirmer"], + Withdrawal: [""], + "Total withdrawn": [""], + "Exchange fee": [""], + "The bank is waiting for confirmation. Go to the %1$s": [""], + "Waiting for the coins to arrive": [""], + Payment: [""], + "Total paid": [""], + "Purchase amount": [""], + Fee: [""], + Merchant: [""], + Purchase: [""], + Receipt: [""], + "Total send": [""], + "Deposit amount": [""], + Refresh: [""], + "Total refresh": [""], + "Refresh amount": [""], + Tip: [""], + "Total tip": [""], + "Received amount": [""], + Refund: [""], + "Total refund": [""], + "Refund amount": [""], + "Browser Extension Installed!": [""], + "Thank you for installing the wallet.": [""], + Permissions: [""], + "(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": + [""], + "Next Steps": [""], + "Try the demo": [""], + "Learn how to top up your wallet balance": [""], + "Could not load pay status": [""], + "Could not load contract terms from merchant or wallet backend.": [""], + "Pay with a mobile phone": [""], + "Hide QR": [""], + "Scan the QR code or %1$s": [""], + Processing: [""], + "Pay %1$s": [""], + "Your balance of %1$s is not enough to pay for this purchase": [""], + "Your balance is not enough to pay for this purchase.": [""], + "Withdraw digital cash": [""], + "Merchant message": [""], + "Digital cash payment": [""], + "Already paid, you are going to be redirected to %1$s": [""], + "Already paid": [""], + "Already claimed": [""], + "Payment complete": [""], + "You are going to be redirected to $ %1$s": [""], + "You can close this page.": [""], + "Total to pay": [""], + "List of products": [""], + Total: [""], + free: [""], + "Refund Status": [""], + "The product %1$s has received a total effective refund of": [""], + "Refund processing is still in progress.": [""], + "The refund amount of %1$s could not be applied.": [""], + "missing taler refund uri": [""], + "Error: %1$s": [""], + "Updating refund status": [""], + "Tip from %1$s accepted. Check your transactions list for more details.": + [""], "The merchant %1$s is offering you a tip of %2$s via the exchange %3$s": [ - "" - ], - "Accept tip": [ - "" - ], - "Ignore": [ - "" - ], - "missing tip uri": [ - "" - ], - "You've ignored the tip.": [ - "" - ], - "Digital cash withdrawal": [ - "" - ], - "Could not finish the withdrawal operation": [ - "" - ], - "Total to withdraw": [ - "" - ], - "Known exchanges": [ - "" - ], - "Cancel exchange selection": [ - "" - ], - "Confirm exchange selection": [ - "" - ], - "Switch exchange": [ - "" - ], - "Confirm withdrawal": [ - "" - ], - "Withdraw anyway": [ - "" - ], - "Could not load the withdrawal details": [ - "" - ], - "missing withdraw uri": [ - "" - ], - "Could not get the info from the URI": [ - "" - ], - "Could not load the list of known exchanges": [ - "" - ], - "All done, your transaction is in progress": [ - "" - ], - "Edit": [ - "" - ], - "missing pay uri": [ - "" - ], - "Could not get the payment information for this order": [ - "" - ], - "Loading payment information": [ - "" - ], - "Digital cash deposit": [ - "" - ], - "You will now be sent back to the merchant you came from.": [ - "" - ], - "Manual Reset Required": [ - "" - ], - "The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": [ - "" - ], - "Once the database format has stabilized, we will provide automatic upgrades.": [ - "" - ], - "I understand that I will lose all my data": [ - "" - ], - "Reset": [ - "" - ], - "Everything is fine!": [ - "" - ], - "A reset is not required anymore, you can close this page.": [ - "" - ], - "Not implemented yet.": [ - "" - ] - } - } + "", + ], + "Accept tip": [""], + Ignore: [""], + "missing tip uri": [""], + "You've ignored the tip.": [""], + "Digital cash withdrawal": [""], + "Could not finish the withdrawal operation": [""], + "Total to withdraw": [""], + "Known exchanges": [""], + "Cancel exchange selection": [""], + "Confirm exchange selection": [""], + "Switch exchange": [""], + "Confirm withdrawal": [""], + "Withdraw anyway": [""], + "Could not load the withdrawal details": [""], + "missing withdraw uri": [""], + "Could not get the info from the URI": [""], + "Could not load the list of known exchanges": [""], + "All done, your transaction is in progress": [""], + Edit: [""], + "missing pay uri": [""], + "Could not get the payment information for this order": [""], + "Loading payment information": [""], + "Digital cash deposit": [""], + "You will now be sent back to the merchant you came from.": [""], + "Manual Reset Required": [""], + "The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": + [""], + "Once the database format has stabilized, we will provide automatic upgrades.": + [""], + "I understand that I will lose all my data": [""], + Reset: [""], + "Everything is fine!": [""], + "A reset is not required anymore, you can close this page.": [""], + "Not implemented yet.": [""], + }, + }, }; -strings['it'] = { - "domain": "messages", - "locale_data": { - "messages": { +strings["it"] = { + domain: "messages", + locale_data: { + messages: { "": { - "domain": "messages", - "plural_forms": "nplurals=2; plural=n != 1;", - "lang": "it" + domain: "messages", + plural_forms: "nplurals=2; plural=n != 1;", + lang: "it", }, - "Balance": [ - "" - ], - "Backup": [ - "" - ], - "Settings": [ - "" - ], - "Dev": [ - "" - ], - "Loading": [ - "" - ], - "Open reserve page": [ - "" - ], - "Open pay page": [ - "" - ], - "Open refund page": [ - "" - ], - "Open tip page": [ - "" - ], - "Open withdraw page": [ - "" - ], - "Back": [ - "" - ], - "You have no balance to show.": [ - "" - ], - "To withdraw money you can start from your bank site or click the \"withdraw\" button to use a known exchange.": [ - "" - ], - "Withdraw": [ - "" - ], - "Could not load balance page": [ - "" - ], - "Deposit %1$s": [ - "" - ], - "Enter URI": [ - "" - ], - "Diagnostics timed out. Could not talk to the wallet backend.": [ - "" - ], - "Problems detected:": [ - "" - ], - "Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": [ - "" - ], - "Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": [ - "" - ], - "Running diagnostics": [ - "" - ], - "Debug tools": [ - "" - ], - "reset": [ - "" - ], - "import database": [ - "" - ], - "export database": [ - "" - ], - "Database exported at %1$s %2$s to download": [ - "" - ], - "Coins": [ - "" - ], - "Pending operations": [ - "" - ], - "usable coins": [ - "" - ], - "id": [ - "" - ], - "denom": [ - "" - ], - "value": [ - "" - ], - "status": [ - "" - ], - "from refresh?": [ - "" - ], - "spent coins": [ - "" - ], - "click to show": [ - "" - ], - "Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": [ - "" - ], - "Taler Action": [ - "" - ], - "This page has pay action.": [ - "" - ], - "This page has a withdrawal action.": [ - "" - ], - "This page has a tip action.": [ - "" - ], - "This page has a notify reserve action.": [ - "" - ], - "Notify": [ - "" - ], - "This page has a refund action.": [ - "" - ], - "This page has a malformed taler uri.": [ - "" - ], - "Dismiss": [ - "" - ], - "Could not load backup providers": [ - "" - ], - "No backup providers configured": [ - "" - ], - "Add provider": [ - "" - ], - "Sync all backups": [ - "" - ], - "Sync now": [ - "" - ], - "Last synced": [ - "" - ], - "Not synced": [ - "" - ], - "Expires in": [ - "" - ], - "Exchange doesn't have terms of service": [ - "" - ], - "Review exchange terms of service": [ - "" - ], - "Review new version of terms of service": [ - "" - ], - "Show terms of service": [ - "" - ], - "I accept the exchange terms of service": [ - "" - ], - "The exchange reply with a empty terms of service": [ - "" - ], - "Download Terms of Service": [ - "" - ], - "Hide terms of service": [ - "" - ], - "Review terms of service": [ - "" - ], - "Exchange URL": [ - "" - ], - "Cancel": [ - "" - ], - "Loading terms..": [ - "" - ], - "Add exchange": [ - "" - ], - "Add exchange anyway": [ - "" - ], - "Add new exchange": [ - "" - ], - "Add exchange for %1$s": [ - "" - ], - "Enter the URL of an exchange you trust.": [ - "" - ], - "An exchange has been found! Review the information and click next": [ - "" - ], - "This exchange doesn't match the expected currency %1$s": [ - "" - ], - "Unable to verify this exchange": [ - "" - ], - "Unable to add this exchange": [ - "" - ], - "loading": [ - "" - ], - "Version": [ - "" - ], - "Currency": [ - "" - ], - "Next": [ - "" - ], - "Add backup provider": [ - "" - ], - "Could not get provider information": [ - "" - ], - "Backup providers may charge for their service": [ - "" - ], - "URL": [ - "" - ], - "Name": [ - "" - ], - "Provider URL": [ - "" - ], - "Please review and accept this provider's terms of service": [ - "" - ], - "Pricing": [ - "" - ], - "free of charge": [ - "" - ], - "%1$s per year of service": [ - "" - ], - "Storage": [ - "" - ], - "%1$s megabytes of storage per year of service": [ - "" - ], - "Accept terms of service": [ - "" - ], - "There was an error loading the provider detail for \"%1$s\"": [ - "" - ], - "There is not known provider with url \"%1$s\".": [ - "" - ], - "Last backup": [ - "" - ], - "Back up": [ - "" - ], - "Provider fee": [ - "" - ], - "per year": [ - "" - ], - "Extend": [ - "" - ], - "terms has changed, extending the service will imply accepting the new terms of service": [ - "" - ], - "old": [ - "" - ], - "new": [ - "" - ], - "fee": [ - "" - ], - "storage": [ - "" - ], - "back": [ - "" - ], - "Remove provider": [ - "" - ], - "This provider has reported an error": [ - "" - ], - "There is conflict with another backup from %1$s": [ - "" - ], - "Backup is not readable": [ - "" - ], - "Unknown backup problem: %1$s": [ - "" - ], - "service paid": [ - "" - ], - "Backup valid until": [ - "" - ], - "this popup is being closed and you are being redirected to %1$s": [ - "" - ], - "Select one option": [ - "" - ], - "Manual Withdrawal": [ - "" - ], - "Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": [ - "" - ], - "No exchange configured": [ - "" - ], - "Can't create the reserve": [ - "" - ], - "Exchange": [ - "" - ], - "Add Exchange": [ - "" - ], - "Amount": [ - "" - ], - "Start withdrawal": [ - "" - ], - "no balance": [ - "" - ], - "There is no known bank account to send money to": [ - "" - ], - "Send %1$s to your account": [ - "" - ], - "Bank account IBAN number": [ - "" - ], - "Deposit fee": [ - "" - ], - "Total deposit": [ - "" - ], - "Deposit": [ - "" - ], - "Deposit %1$s %2$s": [ - "" - ], - "Waiting for confirmation": [ - "" - ], - "PENDING": [ - "" - ], - "Could not load the list of transactions": [ - "" - ], - "There is no history for this currency": [ - "" - ], - "Account": [ - "" - ], - "Bank host": [ - "" - ], - "Bank account": [ - "" - ], - "IBAN": [ - "" - ], - "Chosen amount": [ - "" - ], - "Subject": [ - "" - ], - "could not parse payto uri from exchange %1$s": [ - "" - ], - "Exchange is ready for withdrawal": [ - "" - ], - "To complete the process you need to wire %1$s to the exchange bank account": [ - "" - ], - "Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": [ - "" - ], - "Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": [ - "" - ], - "Cancel withdrawal": [ - "" - ], - "Display": [ - "" - ], - "Current Language": [ - "" - ], - "Navigator": [ - "" - ], - "Automatically open wallet based on page content": [ - "" - ], - "Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": [ - "" - ], - "Trust": [ - "" - ], - "No exchange yet": [ - "" - ], - "Term of Service": [ - "" - ], - "ok": [ - "" - ], - "changed": [ - "" - ], - "not accepted": [ - "" - ], - "Add an exchange": [ - "" - ], - "Developer mode": [ - "" - ], - "(More options and information useful for debugging)": [ - "" - ], - "Could not load the transaction information": [ - "" - ], - "There was an error trying to complete the transaction": [ - "" - ], - "This transaction is not completed": [ - "" - ], - "Retry": [ - "" - ], - "Forget": [ - "" - ], - "Caution!": [ - "" - ], - "If you have already wired money to the exchange you will loose the chance to get the coins form it.": [ - "" - ], - "Confirm": [ - "Confermare" - ], - "Withdrawal": [ - "" - ], - "Total withdrawn": [ - "" - ], - "Exchange fee": [ - "" - ], - "The bank is waiting for confirmation. Go to the %1$s": [ - "" - ], - "Waiting for the coins to arrive": [ - "" - ], - "Payment": [ - "" - ], - "Total paid": [ - "" - ], - "Purchase amount": [ - "" - ], - "Fee": [ - "" - ], - "Merchant": [ - "" - ], - "Purchase": [ - "" - ], - "Receipt": [ - "" - ], - "Total send": [ - "" - ], - "Deposit amount": [ - "" - ], - "Refresh": [ - "" - ], - "Total refresh": [ - "" - ], - "Refresh amount": [ - "" - ], - "Tip": [ - "" - ], - "Total tip": [ - "" - ], - "Received amount": [ - "" - ], - "Refund": [ - "" - ], - "Total refund": [ - "" - ], - "Refund amount": [ - "" - ], - "Browser Extension Installed!": [ - "" - ], - "Thank you for installing the wallet.": [ - "" - ], - "Permissions": [ - "" - ], - "(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": [ - "" - ], - "Next Steps": [ - "" - ], - "Try the demo": [ - "" - ], - "Learn how to top up your wallet balance": [ - "" - ], - "Could not load pay status": [ - "" - ], - "Could not load contract terms from merchant or wallet backend.": [ - "" - ], - "Pay with a mobile phone": [ - "" - ], - "Hide QR": [ - "" - ], - "Scan the QR code or %1$s": [ - "" - ], - "Processing": [ - "" - ], - "Pay %1$s": [ - "" - ], - "Your balance of %1$s is not enough to pay for this purchase": [ - "" - ], - "Your balance is not enough to pay for this purchase.": [ - "" - ], - "Withdraw digital cash": [ - "" - ], - "Merchant message": [ - "" - ], - "Digital cash payment": [ - "" - ], - "Already paid, you are going to be redirected to %1$s": [ - "" - ], - "Already paid": [ - "" - ], - "Already claimed": [ - "" - ], - "Payment complete": [ - "" - ], - "You are going to be redirected to $ %1$s": [ - "" - ], - "You can close this page.": [ - "" - ], - "Total to pay": [ - "" - ], - "List of products": [ - "" - ], - "Total": [ - "" - ], - "free": [ - "" - ], - "Refund Status": [ - "" - ], - "The product %1$s has received a total effective refund of": [ - "" - ], - "Refund processing is still in progress.": [ - "" - ], - "The refund amount of %1$s could not be applied.": [ - "" - ], - "missing taler refund uri": [ - "" - ], - "Error: %1$s": [ - "" - ], - "Updating refund status": [ - "" - ], - "Tip from %1$s accepted. Check your transactions list for more details.": [ - "" - ], + Balance: [""], + Backup: [""], + Settings: [""], + Dev: [""], + Loading: [""], + "Open reserve page": [""], + "Open pay page": [""], + "Open refund page": [""], + "Open tip page": [""], + "Open withdraw page": [""], + Back: [""], + "You have no balance to show.": [""], + 'To withdraw money you can start from your bank site or click the "withdraw" button to use a known exchange.': + [""], + Withdraw: [""], + "Could not load balance page": [""], + "Deposit %1$s": [""], + "Enter URI": [""], + "Diagnostics timed out. Could not talk to the wallet backend.": [""], + "Problems detected:": [""], + "Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": + [""], + "Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": + [""], + "Running diagnostics": [""], + "Debug tools": [""], + reset: [""], + "import database": [""], + "export database": [""], + "Database exported at %1$s %2$s to download": [""], + Coins: [""], + "Pending operations": [""], + "usable coins": [""], + id: [""], + denom: [""], + value: [""], + status: [""], + "from refresh?": [""], + "spent coins": [""], + "click to show": [""], + "Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": + [""], + "Taler Action": [""], + "This page has pay action.": [""], + "This page has a withdrawal action.": [""], + "This page has a tip action.": [""], + "This page has a notify reserve action.": [""], + Notify: [""], + "This page has a refund action.": [""], + "This page has a malformed taler uri.": [""], + Dismiss: [""], + "Could not load backup providers": [""], + "No backup providers configured": [""], + "Add provider": [""], + "Sync all backups": [""], + "Sync now": [""], + "Last synced": [""], + "Not synced": [""], + "Expires in": [""], + "Exchange doesn't have terms of service": [""], + "Review exchange terms of service": [""], + "Review new version of terms of service": [""], + "Show terms of service": [""], + "I accept the exchange terms of service": [""], + "The exchange reply with a empty terms of service": [""], + "Download Terms of Service": [""], + "Hide terms of service": [""], + "Review terms of service": [""], + "Exchange URL": [""], + Cancel: [""], + "Loading terms..": [""], + "Add exchange": [""], + "Add exchange anyway": [""], + "Add new exchange": [""], + "Add exchange for %1$s": [""], + "Enter the URL of an exchange you trust.": [""], + "An exchange has been found! Review the information and click next": [""], + "This exchange doesn't match the expected currency %1$s": [""], + "Unable to verify this exchange": [""], + "Unable to add this exchange": [""], + loading: [""], + Version: [""], + Currency: [""], + Next: [""], + "Add backup provider": [""], + "Could not get provider information": [""], + "Backup providers may charge for their service": [""], + URL: [""], + Name: [""], + "Provider URL": [""], + "Please review and accept this provider's terms of service": [""], + Pricing: [""], + "free of charge": [""], + "%1$s per year of service": [""], + Storage: [""], + "%1$s megabytes of storage per year of service": [""], + "Accept terms of service": [""], + 'There was an error loading the provider detail for "%1$s"': [""], + 'There is not known provider with url "%1$s".': [""], + "Last backup": [""], + "Back up": [""], + "Provider fee": [""], + "per year": [""], + Extend: [""], + "terms has changed, extending the service will imply accepting the new terms of service": + [""], + old: [""], + new: [""], + fee: [""], + storage: [""], + back: [""], + "Remove provider": [""], + "This provider has reported an error": [""], + "There is conflict with another backup from %1$s": [""], + "Backup is not readable": [""], + "Unknown backup problem: %1$s": [""], + "service paid": [""], + "Backup valid until": [""], + "this popup is being closed and you are being redirected to %1$s": [""], + "Select one option": [""], + "Manual Withdrawal": [""], + "Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": + [""], + "No exchange configured": [""], + "Can't create the reserve": [""], + Exchange: [""], + "Add Exchange": [""], + Amount: [""], + "Start withdrawal": [""], + "no balance": [""], + "There is no known bank account to send money to": [""], + "Send %1$s to your account": [""], + "Bank account IBAN number": [""], + "Deposit fee": [""], + "Total deposit": [""], + Deposit: [""], + "Deposit %1$s %2$s": [""], + "Waiting for confirmation": [""], + PENDING: [""], + "Could not load the list of transactions": [""], + "There is no history for this currency": [""], + Account: [""], + "Bank host": [""], + "Bank account": [""], + IBAN: [""], + "Chosen amount": [""], + Subject: [""], + "could not parse payto uri from exchange %1$s": [""], + "Exchange is ready for withdrawal": [""], + "To complete the process you need to wire %1$s to the exchange bank account": + [""], + "Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": + [""], + "Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": + [""], + "Cancel withdrawal": [""], + Display: [""], + "Current Language": [""], + Navigator: [""], + "Automatically open wallet based on page content": [""], + "Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": + [""], + Trust: [""], + "No exchange yet": [""], + "Term of Service": [""], + ok: [""], + changed: [""], + "not accepted": [""], + "Add an exchange": [""], + "Developer mode": [""], + "(More options and information useful for debugging)": [""], + "Could not load the transaction information": [""], + "There was an error trying to complete the transaction": [""], + "This transaction is not completed": [""], + Retry: [""], + Forget: [""], + "Caution!": [""], + "If you have already wired money to the exchange you will loose the chance to get the coins form it.": + [""], + Confirm: ["Confermare"], + Withdrawal: [""], + "Total withdrawn": [""], + "Exchange fee": [""], + "The bank is waiting for confirmation. Go to the %1$s": [""], + "Waiting for the coins to arrive": [""], + Payment: [""], + "Total paid": [""], + "Purchase amount": [""], + Fee: [""], + Merchant: [""], + Purchase: [""], + Receipt: [""], + "Total send": [""], + "Deposit amount": [""], + Refresh: [""], + "Total refresh": [""], + "Refresh amount": [""], + Tip: [""], + "Total tip": [""], + "Received amount": [""], + Refund: [""], + "Total refund": [""], + "Refund amount": [""], + "Browser Extension Installed!": [""], + "Thank you for installing the wallet.": [""], + Permissions: [""], + "(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": + [""], + "Next Steps": [""], + "Try the demo": [""], + "Learn how to top up your wallet balance": [""], + "Could not load pay status": [""], + "Could not load contract terms from merchant or wallet backend.": [""], + "Pay with a mobile phone": [""], + "Hide QR": [""], + "Scan the QR code or %1$s": [""], + Processing: [""], + "Pay %1$s": [""], + "Your balance of %1$s is not enough to pay for this purchase": [""], + "Your balance is not enough to pay for this purchase.": [""], + "Withdraw digital cash": [""], + "Merchant message": [""], + "Digital cash payment": [""], + "Already paid, you are going to be redirected to %1$s": [""], + "Already paid": [""], + "Already claimed": [""], + "Payment complete": [""], + "You are going to be redirected to $ %1$s": [""], + "You can close this page.": [""], + "Total to pay": [""], + "List of products": [""], + Total: [""], + free: [""], + "Refund Status": [""], + "The product %1$s has received a total effective refund of": [""], + "Refund processing is still in progress.": [""], + "The refund amount of %1$s could not be applied.": [""], + "missing taler refund uri": [""], + "Error: %1$s": [""], + "Updating refund status": [""], + "Tip from %1$s accepted. Check your transactions list for more details.": + [""], "The merchant %1$s is offering you a tip of %2$s via the exchange %3$s": [ - "" - ], - "Accept tip": [ - "" - ], - "Ignore": [ - "" - ], - "missing tip uri": [ - "" - ], - "You've ignored the tip.": [ - "" - ], - "Digital cash withdrawal": [ - "" - ], - "Could not finish the withdrawal operation": [ - "" - ], - "Total to withdraw": [ - "" - ], - "Known exchanges": [ - "" - ], - "Cancel exchange selection": [ - "" - ], - "Confirm exchange selection": [ - "" - ], - "Switch exchange": [ - "" - ], - "Confirm withdrawal": [ - "" - ], - "Withdraw anyway": [ - "" - ], - "Could not load the withdrawal details": [ - "" - ], - "missing withdraw uri": [ - "" - ], - "Could not get the info from the URI": [ - "" - ], - "Could not load the list of known exchanges": [ - "" - ], - "All done, your transaction is in progress": [ - "" - ], - "Edit": [ - "" - ], - "missing pay uri": [ - "" - ], - "Could not get the payment information for this order": [ - "" - ], - "Loading payment information": [ - "" - ], - "Digital cash deposit": [ - "" - ], - "You will now be sent back to the merchant you came from.": [ - "" - ], - "Manual Reset Required": [ - "" - ], - "The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": [ - "" - ], - "Once the database format has stabilized, we will provide automatic upgrades.": [ - "" - ], - "I understand that I will lose all my data": [ - "" - ], - "Reset": [ - "" - ], - "Everything is fine!": [ - "" - ], - "A reset is not required anymore, you can close this page.": [ - "" - ], - "Not implemented yet.": [ - "" - ] - } - } + "", + ], + "Accept tip": [""], + Ignore: [""], + "missing tip uri": [""], + "You've ignored the tip.": [""], + "Digital cash withdrawal": [""], + "Could not finish the withdrawal operation": [""], + "Total to withdraw": [""], + "Known exchanges": [""], + "Cancel exchange selection": [""], + "Confirm exchange selection": [""], + "Switch exchange": [""], + "Confirm withdrawal": [""], + "Withdraw anyway": [""], + "Could not load the withdrawal details": [""], + "missing withdraw uri": [""], + "Could not get the info from the URI": [""], + "Could not load the list of known exchanges": [""], + "All done, your transaction is in progress": [""], + Edit: [""], + "missing pay uri": [""], + "Could not get the payment information for this order": [""], + "Loading payment information": [""], + "Digital cash deposit": [""], + "You will now be sent back to the merchant you came from.": [""], + "Manual Reset Required": [""], + "The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": + [""], + "Once the database format has stabilized, we will provide automatic upgrades.": + [""], + "I understand that I will lose all my data": [""], + Reset: [""], + "Everything is fine!": [""], + "A reset is not required anymore, you can close this page.": [""], + "Not implemented yet.": [""], + }, + }, }; -strings['ja'] = { - "domain": "messages", - "locale_data": { - "messages": { +strings["ja"] = { + domain: "messages", + locale_data: { + messages: { "": { - "domain": "messages", - "plural_forms": "nplurals=2; plural=n != 1;", - "lang": "ja" + domain: "messages", + plural_forms: "nplurals=2; plural=n != 1;", + lang: "ja", }, - "Balance": [ - "残高" - ], - "Backup": [ - "バックアップ" - ], - "Settings": [ - "設定" - ], - "Dev": [ - "" - ], - "Loading": [ - "" - ], - "Open reserve page": [ - "" - ], - "Open pay page": [ - "" - ], - "Open refund page": [ - "" - ], - "Open tip page": [ - "" - ], - "Open withdraw page": [ - "" - ], - "Back": [ - "" - ], - "You have no balance to show.": [ - "表示するバランスがありません" - ], - "To withdraw money you can start from your bank site or click the \"withdraw\" button to use a known exchange.": [ - "お金を引き出すには、銀行のサイトから開始するか、[引き出し]ボタンをクリックして既知の取引所を使用します。" - ], - "Withdraw": [ - "撤退" - ], - "Could not load balance page": [ - "" - ], - "Deposit %1$s": [ - "" - ], - "Enter URI": [ - "" - ], - "Diagnostics timed out. Could not talk to the wallet backend.": [ - "" - ], - "Problems detected:": [ - "" - ], - "Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": [ - "" - ], - "Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": [ - "" - ], - "Running diagnostics": [ - "" - ], - "Debug tools": [ - "" - ], - "reset": [ - "" - ], - "import database": [ - "" - ], - "export database": [ - "" - ], - "Database exported at %1$s %2$s to download": [ - "" - ], - "Coins": [ - "" - ], - "Pending operations": [ - "" - ], - "usable coins": [ - "" - ], - "id": [ - "" - ], - "denom": [ - "" - ], - "value": [ - "" - ], - "status": [ - "" - ], - "from refresh?": [ - "" - ], - "spent coins": [ - "" - ], - "click to show": [ - "" - ], - "Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": [ - "" - ], - "Taler Action": [ - "" - ], - "This page has pay action.": [ - "" - ], - "This page has a withdrawal action.": [ - "" - ], - "This page has a tip action.": [ - "" - ], - "This page has a notify reserve action.": [ - "" - ], - "Notify": [ - "" - ], - "This page has a refund action.": [ - "" - ], - "This page has a malformed taler uri.": [ - "" - ], - "Dismiss": [ - "" - ], - "Could not load backup providers": [ - "" - ], - "No backup providers configured": [ - "" - ], - "Add provider": [ - "" - ], - "Sync all backups": [ - "" - ], - "Sync now": [ - "" - ], - "Last synced": [ - "" - ], - "Not synced": [ - "" - ], - "Expires in": [ - "" - ], - "Exchange doesn't have terms of service": [ - "" - ], - "Review exchange terms of service": [ - "" - ], - "Review new version of terms of service": [ - "" - ], - "Show terms of service": [ - "" - ], - "I accept the exchange terms of service": [ - "" - ], - "The exchange reply with a empty terms of service": [ - "" - ], - "Download Terms of Service": [ - "" - ], - "Hide terms of service": [ - "" - ], - "Review terms of service": [ - "" - ], - "Exchange URL": [ - "" - ], - "Cancel": [ - "" - ], - "Loading terms..": [ - "" - ], - "Add exchange": [ - "" - ], - "Add exchange anyway": [ - "" - ], - "Add new exchange": [ - "" - ], - "Add exchange for %1$s": [ - "" - ], - "Enter the URL of an exchange you trust.": [ - "" - ], - "An exchange has been found! Review the information and click next": [ - "" - ], - "This exchange doesn't match the expected currency %1$s": [ - "" - ], - "Unable to verify this exchange": [ - "" - ], - "Unable to add this exchange": [ - "" - ], - "loading": [ - "" - ], - "Version": [ - "" - ], - "Currency": [ - "" - ], - "Next": [ - "" - ], - "Add backup provider": [ - "" - ], - "Could not get provider information": [ - "" - ], - "Backup providers may charge for their service": [ - "" - ], - "URL": [ - "" - ], - "Name": [ - "" - ], - "Provider URL": [ - "" - ], - "Please review and accept this provider's terms of service": [ - "" - ], - "Pricing": [ - "" - ], - "free of charge": [ - "" - ], - "%1$s per year of service": [ - "" - ], - "Storage": [ - "" - ], - "%1$s megabytes of storage per year of service": [ - "" - ], - "Accept terms of service": [ - "" - ], - "There was an error loading the provider detail for \"%1$s\"": [ - "" - ], - "There is not known provider with url \"%1$s\".": [ - "" - ], - "Last backup": [ - "" - ], - "Back up": [ - "" - ], - "Provider fee": [ - "" - ], - "per year": [ - "" - ], - "Extend": [ - "" - ], - "terms has changed, extending the service will imply accepting the new terms of service": [ - "" - ], - "old": [ - "" - ], - "new": [ - "" - ], - "fee": [ - "" - ], - "storage": [ - "" - ], - "back": [ - "" - ], - "Remove provider": [ - "" - ], - "This provider has reported an error": [ - "" - ], - "There is conflict with another backup from %1$s": [ - "" - ], - "Backup is not readable": [ - "" - ], - "Unknown backup problem: %1$s": [ - "" - ], - "service paid": [ - "" - ], - "Backup valid until": [ - "" - ], - "this popup is being closed and you are being redirected to %1$s": [ - "" - ], - "Select one option": [ - "" - ], - "Manual Withdrawal": [ - "" - ], - "Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": [ - "" - ], - "No exchange configured": [ - "" - ], - "Can't create the reserve": [ - "" - ], - "Exchange": [ - "" - ], - "Add Exchange": [ - "" - ], - "Amount": [ - "" - ], - "Start withdrawal": [ - "" - ], - "no balance": [ - "" - ], - "There is no known bank account to send money to": [ - "" - ], - "Send %1$s to your account": [ - "" - ], - "Bank account IBAN number": [ - "" - ], - "Deposit fee": [ - "" - ], - "Total deposit": [ - "" - ], - "Deposit": [ - "" - ], - "Deposit %1$s %2$s": [ - "" - ], - "Waiting for confirmation": [ - "" - ], - "PENDING": [ - "" - ], - "Could not load the list of transactions": [ - "" - ], - "There is no history for this currency": [ - "" - ], - "Account": [ - "" - ], - "Bank host": [ - "" - ], - "Bank account": [ - "" - ], - "IBAN": [ - "" - ], - "Chosen amount": [ - "" - ], - "Subject": [ - "" - ], - "could not parse payto uri from exchange %1$s": [ - "" - ], - "Exchange is ready for withdrawal": [ - "" - ], - "To complete the process you need to wire %1$s to the exchange bank account": [ - "" - ], - "Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": [ - "" - ], - "Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": [ - "" - ], - "Cancel withdrawal": [ - "" - ], - "Display": [ - "" - ], - "Current Language": [ - "" - ], - "Navigator": [ - "" - ], - "Automatically open wallet based on page content": [ - "" - ], - "Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": [ - "" - ], - "Trust": [ - "" - ], - "No exchange yet": [ - "" - ], - "Term of Service": [ - "" - ], - "ok": [ - "" - ], - "changed": [ - "" - ], - "not accepted": [ - "" - ], - "Add an exchange": [ - "" - ], - "Developer mode": [ - "" - ], - "(More options and information useful for debugging)": [ - "" - ], - "Could not load the transaction information": [ - "" - ], - "There was an error trying to complete the transaction": [ - "" - ], - "This transaction is not completed": [ - "" - ], - "Retry": [ - "" - ], - "Forget": [ - "" - ], - "Caution!": [ - "" - ], - "If you have already wired money to the exchange you will loose the chance to get the coins form it.": [ - "" - ], - "Confirm": [ - "" - ], - "Withdrawal": [ - "" - ], - "Total withdrawn": [ - "" - ], - "Exchange fee": [ - "" - ], - "The bank is waiting for confirmation. Go to the %1$s": [ - "" - ], - "Waiting for the coins to arrive": [ - "" - ], - "Payment": [ - "" - ], - "Total paid": [ - "" - ], - "Purchase amount": [ - "" - ], - "Fee": [ - "" - ], - "Merchant": [ - "" - ], - "Purchase": [ - "" - ], - "Receipt": [ - "" - ], - "Total send": [ - "" - ], - "Deposit amount": [ - "" - ], - "Refresh": [ - "" - ], - "Total refresh": [ - "" - ], - "Refresh amount": [ - "" - ], - "Tip": [ - "" - ], - "Total tip": [ - "" - ], - "Received amount": [ - "" - ], - "Refund": [ - "" - ], - "Total refund": [ - "" - ], - "Refund amount": [ - "" - ], - "Browser Extension Installed!": [ - "" - ], - "Thank you for installing the wallet.": [ - "" - ], - "Permissions": [ - "" - ], - "(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": [ - "" - ], - "Next Steps": [ - "" - ], - "Try the demo": [ - "" - ], - "Learn how to top up your wallet balance": [ - "" - ], - "Could not load pay status": [ - "" - ], - "Could not load contract terms from merchant or wallet backend.": [ - "" - ], - "Pay with a mobile phone": [ - "" - ], - "Hide QR": [ - "" - ], - "Scan the QR code or %1$s": [ - "" - ], - "Processing": [ - "" - ], - "Pay %1$s": [ - "" - ], - "Your balance of %1$s is not enough to pay for this purchase": [ - "" - ], - "Your balance is not enough to pay for this purchase.": [ - "" - ], - "Withdraw digital cash": [ - "" - ], - "Merchant message": [ - "" - ], - "Digital cash payment": [ - "" - ], - "Already paid, you are going to be redirected to %1$s": [ - "" - ], - "Already paid": [ - "" - ], - "Already claimed": [ - "" - ], - "Payment complete": [ - "" - ], - "You are going to be redirected to $ %1$s": [ - "" - ], - "You can close this page.": [ - "" - ], - "Total to pay": [ - "" - ], - "List of products": [ - "" - ], - "Total": [ - "" - ], - "free": [ - "" - ], - "Refund Status": [ - "" - ], - "The product %1$s has received a total effective refund of": [ - "" - ], - "Refund processing is still in progress.": [ - "" - ], - "The refund amount of %1$s could not be applied.": [ - "" - ], - "missing taler refund uri": [ - "" - ], - "Error: %1$s": [ - "" - ], - "Updating refund status": [ - "" - ], - "Tip from %1$s accepted. Check your transactions list for more details.": [ - "" - ], + Balance: ["残高"], + Backup: ["バックアップ"], + Settings: ["設定"], + Dev: [""], + Loading: [""], + "Open reserve page": [""], + "Open pay page": [""], + "Open refund page": [""], + "Open tip page": [""], + "Open withdraw page": [""], + Back: [""], + "You have no balance to show.": ["表示するバランスがありません"], + 'To withdraw money you can start from your bank site or click the "withdraw" button to use a known exchange.': + [ + "お金を引き出すには、銀行のサイトから開始するか、[引き出し]ボタンをクリックして既知の取引所を使用します。", + ], + Withdraw: ["撤退"], + "Could not load balance page": [""], + "Deposit %1$s": [""], + "Enter URI": [""], + "Diagnostics timed out. Could not talk to the wallet backend.": [""], + "Problems detected:": [""], + "Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": + [""], + "Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": + [""], + "Running diagnostics": [""], + "Debug tools": [""], + reset: [""], + "import database": [""], + "export database": [""], + "Database exported at %1$s %2$s to download": [""], + Coins: [""], + "Pending operations": [""], + "usable coins": [""], + id: [""], + denom: [""], + value: [""], + status: [""], + "from refresh?": [""], + "spent coins": [""], + "click to show": [""], + "Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": + [""], + "Taler Action": [""], + "This page has pay action.": [""], + "This page has a withdrawal action.": [""], + "This page has a tip action.": [""], + "This page has a notify reserve action.": [""], + Notify: [""], + "This page has a refund action.": [""], + "This page has a malformed taler uri.": [""], + Dismiss: [""], + "Could not load backup providers": [""], + "No backup providers configured": [""], + "Add provider": [""], + "Sync all backups": [""], + "Sync now": [""], + "Last synced": [""], + "Not synced": [""], + "Expires in": [""], + "Exchange doesn't have terms of service": [""], + "Review exchange terms of service": [""], + "Review new version of terms of service": [""], + "Show terms of service": [""], + "I accept the exchange terms of service": [""], + "The exchange reply with a empty terms of service": [""], + "Download Terms of Service": [""], + "Hide terms of service": [""], + "Review terms of service": [""], + "Exchange URL": [""], + Cancel: [""], + "Loading terms..": [""], + "Add exchange": [""], + "Add exchange anyway": [""], + "Add new exchange": [""], + "Add exchange for %1$s": [""], + "Enter the URL of an exchange you trust.": [""], + "An exchange has been found! Review the information and click next": [""], + "This exchange doesn't match the expected currency %1$s": [""], + "Unable to verify this exchange": [""], + "Unable to add this exchange": [""], + loading: [""], + Version: [""], + Currency: [""], + Next: [""], + "Add backup provider": [""], + "Could not get provider information": [""], + "Backup providers may charge for their service": [""], + URL: [""], + Name: [""], + "Provider URL": [""], + "Please review and accept this provider's terms of service": [""], + Pricing: [""], + "free of charge": [""], + "%1$s per year of service": [""], + Storage: [""], + "%1$s megabytes of storage per year of service": [""], + "Accept terms of service": [""], + 'There was an error loading the provider detail for "%1$s"': [""], + 'There is not known provider with url "%1$s".': [""], + "Last backup": [""], + "Back up": [""], + "Provider fee": [""], + "per year": [""], + Extend: [""], + "terms has changed, extending the service will imply accepting the new terms of service": + [""], + old: [""], + new: [""], + fee: [""], + storage: [""], + back: [""], + "Remove provider": [""], + "This provider has reported an error": [""], + "There is conflict with another backup from %1$s": [""], + "Backup is not readable": [""], + "Unknown backup problem: %1$s": [""], + "service paid": [""], + "Backup valid until": [""], + "this popup is being closed and you are being redirected to %1$s": [""], + "Select one option": [""], + "Manual Withdrawal": [""], + "Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": + [""], + "No exchange configured": [""], + "Can't create the reserve": [""], + Exchange: [""], + "Add Exchange": [""], + Amount: [""], + "Start withdrawal": [""], + "no balance": [""], + "There is no known bank account to send money to": [""], + "Send %1$s to your account": [""], + "Bank account IBAN number": [""], + "Deposit fee": [""], + "Total deposit": [""], + Deposit: [""], + "Deposit %1$s %2$s": [""], + "Waiting for confirmation": [""], + PENDING: [""], + "Could not load the list of transactions": [""], + "There is no history for this currency": [""], + Account: [""], + "Bank host": [""], + "Bank account": [""], + IBAN: [""], + "Chosen amount": [""], + Subject: [""], + "could not parse payto uri from exchange %1$s": [""], + "Exchange is ready for withdrawal": [""], + "To complete the process you need to wire %1$s to the exchange bank account": + [""], + "Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": + [""], + "Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": + [""], + "Cancel withdrawal": [""], + Display: [""], + "Current Language": [""], + Navigator: [""], + "Automatically open wallet based on page content": [""], + "Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": + [""], + Trust: [""], + "No exchange yet": [""], + "Term of Service": [""], + ok: [""], + changed: [""], + "not accepted": [""], + "Add an exchange": [""], + "Developer mode": [""], + "(More options and information useful for debugging)": [""], + "Could not load the transaction information": [""], + "There was an error trying to complete the transaction": [""], + "This transaction is not completed": [""], + Retry: [""], + Forget: [""], + "Caution!": [""], + "If you have already wired money to the exchange you will loose the chance to get the coins form it.": + [""], + Confirm: [""], + Withdrawal: [""], + "Total withdrawn": [""], + "Exchange fee": [""], + "The bank is waiting for confirmation. Go to the %1$s": [""], + "Waiting for the coins to arrive": [""], + Payment: [""], + "Total paid": [""], + "Purchase amount": [""], + Fee: [""], + Merchant: [""], + Purchase: [""], + Receipt: [""], + "Total send": [""], + "Deposit amount": [""], + Refresh: [""], + "Total refresh": [""], + "Refresh amount": [""], + Tip: [""], + "Total tip": [""], + "Received amount": [""], + Refund: [""], + "Total refund": [""], + "Refund amount": [""], + "Browser Extension Installed!": [""], + "Thank you for installing the wallet.": [""], + Permissions: [""], + "(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": + [""], + "Next Steps": [""], + "Try the demo": [""], + "Learn how to top up your wallet balance": [""], + "Could not load pay status": [""], + "Could not load contract terms from merchant or wallet backend.": [""], + "Pay with a mobile phone": [""], + "Hide QR": [""], + "Scan the QR code or %1$s": [""], + Processing: [""], + "Pay %1$s": [""], + "Your balance of %1$s is not enough to pay for this purchase": [""], + "Your balance is not enough to pay for this purchase.": [""], + "Withdraw digital cash": [""], + "Merchant message": [""], + "Digital cash payment": [""], + "Already paid, you are going to be redirected to %1$s": [""], + "Already paid": [""], + "Already claimed": [""], + "Payment complete": [""], + "You are going to be redirected to $ %1$s": [""], + "You can close this page.": [""], + "Total to pay": [""], + "List of products": [""], + Total: [""], + free: [""], + "Refund Status": [""], + "The product %1$s has received a total effective refund of": [""], + "Refund processing is still in progress.": [""], + "The refund amount of %1$s could not be applied.": [""], + "missing taler refund uri": [""], + "Error: %1$s": [""], + "Updating refund status": [""], + "Tip from %1$s accepted. Check your transactions list for more details.": + [""], "The merchant %1$s is offering you a tip of %2$s via the exchange %3$s": [ - "" - ], - "Accept tip": [ - "" - ], - "Ignore": [ - "" - ], - "missing tip uri": [ - "" - ], - "You've ignored the tip.": [ - "" - ], - "Digital cash withdrawal": [ - "" - ], - "Could not finish the withdrawal operation": [ - "" - ], - "Total to withdraw": [ - "" - ], - "Known exchanges": [ - "" - ], - "Cancel exchange selection": [ - "" - ], - "Confirm exchange selection": [ - "" - ], - "Switch exchange": [ - "" - ], - "Confirm withdrawal": [ - "" - ], - "Withdraw anyway": [ - "" - ], - "Could not load the withdrawal details": [ - "" - ], - "missing withdraw uri": [ - "" - ], - "Could not get the info from the URI": [ - "" - ], - "Could not load the list of known exchanges": [ - "" - ], - "All done, your transaction is in progress": [ - "" - ], - "Edit": [ - "" - ], - "missing pay uri": [ - "" - ], - "Could not get the payment information for this order": [ - "" - ], - "Loading payment information": [ - "" - ], - "Digital cash deposit": [ - "" - ], - "You will now be sent back to the merchant you came from.": [ - "" - ], - "Manual Reset Required": [ - "" - ], - "The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": [ - "" - ], - "Once the database format has stabilized, we will provide automatic upgrades.": [ - "" - ], - "I understand that I will lose all my data": [ - "" - ], - "Reset": [ - "" - ], - "Everything is fine!": [ - "" - ], - "A reset is not required anymore, you can close this page.": [ - "" - ], - "Not implemented yet.": [ - "" - ] - } - } + "", + ], + "Accept tip": [""], + Ignore: [""], + "missing tip uri": [""], + "You've ignored the tip.": [""], + "Digital cash withdrawal": [""], + "Could not finish the withdrawal operation": [""], + "Total to withdraw": [""], + "Known exchanges": [""], + "Cancel exchange selection": [""], + "Confirm exchange selection": [""], + "Switch exchange": [""], + "Confirm withdrawal": [""], + "Withdraw anyway": [""], + "Could not load the withdrawal details": [""], + "missing withdraw uri": [""], + "Could not get the info from the URI": [""], + "Could not load the list of known exchanges": [""], + "All done, your transaction is in progress": [""], + Edit: [""], + "missing pay uri": [""], + "Could not get the payment information for this order": [""], + "Loading payment information": [""], + "Digital cash deposit": [""], + "You will now be sent back to the merchant you came from.": [""], + "Manual Reset Required": [""], + "The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": + [""], + "Once the database format has stabilized, we will provide automatic upgrades.": + [""], + "I understand that I will lose all my data": [""], + Reset: [""], + "Everything is fine!": [""], + "A reset is not required anymore, you can close this page.": [""], + "Not implemented yet.": [""], + }, + }, }; -strings['sv'] = { - "domain": "messages", - "locale_data": { - "messages": { +strings["sv"] = { + domain: "messages", + locale_data: { + messages: { "": { - "domain": "messages", - "plural_forms": "nplurals=2; plural=n != 1;", - "lang": "sv" + domain: "messages", + plural_forms: "nplurals=2; plural=n != 1;", + lang: "sv", }, - "Balance": [ - "Balans" - ], - "Backup": [ - "" - ], - "Settings": [ - "" - ], - "Dev": [ - "" - ], - "Loading": [ - "" - ], - "Open reserve page": [ - "" - ], - "Open pay page": [ - "" - ], - "Open refund page": [ - "" - ], - "Open tip page": [ - "" - ], - "Open withdraw page": [ - "Utbetalnings avgift" - ], - "Back": [ - "" - ], + Balance: ["Balans"], + Backup: [""], + Settings: [""], + Dev: [""], + Loading: [""], + "Open reserve page": [""], + "Open pay page": [""], + "Open refund page": [""], + "Open tip page": [""], + "Open withdraw page": ["Utbetalnings avgift"], + Back: [""], "You have no balance to show.": [ - "Du har ingen balans att visa. Behöver du\n %1$s att börja?\n" - ], - "To withdraw money you can start from your bank site or click the \"withdraw\" button to use a known exchange.": [ - "" - ], - "Withdraw": [ - "Utbetalnings avgift" - ], - "Could not load balance page": [ - "" - ], - "Deposit %1$s": [ - "Depostitions avgift" - ], - "Enter URI": [ - "" - ], - "Diagnostics timed out. Could not talk to the wallet backend.": [ - "" - ], - "Problems detected:": [ - "" - ], - "Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": [ - "" - ], - "Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": [ - "" - ], - "Running diagnostics": [ - "" - ], - "Debug tools": [ - "" - ], - "reset": [ - "" - ], - "import database": [ - "" - ], - "export database": [ - "" - ], - "Database exported at %1$s %2$s to download": [ - "" - ], - "Coins": [ - "# Mynt" - ], - "Pending operations": [ - "" - ], - "usable coins": [ - "" - ], - "id": [ - "" - ], - "denom": [ - "" - ], - "value": [ - "Värde" - ], - "status": [ - "" - ], - "from refresh?": [ - "" - ], - "spent coins": [ - "" - ], - "click to show": [ - "" - ], - "Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": [ - "" - ], - "Taler Action": [ - "" - ], - "This page has pay action.": [ - "" - ], - "This page has a withdrawal action.": [ - "" - ], - "This page has a tip action.": [ - "" - ], - "This page has a notify reserve action.": [ - "" - ], - "Notify": [ - "" - ], - "This page has a refund action.": [ - "" - ], - "This page has a malformed taler uri.": [ - "" - ], - "Dismiss": [ - "" - ], - "Could not load backup providers": [ - "" - ], - "No backup providers configured": [ - "" - ], - "Add provider": [ - "" - ], - "Sync all backups": [ - "" - ], - "Sync now": [ - "" - ], - "Last synced": [ - "" - ], - "Not synced": [ - "" - ], - "Expires in": [ - "" - ], - "Exchange doesn't have terms of service": [ - "" - ], - "Review exchange terms of service": [ - "" - ], - "Review new version of terms of service": [ - "" - ], - "Show terms of service": [ - "" - ], - "I accept the exchange terms of service": [ - "" - ], - "The exchange reply with a empty terms of service": [ - "" - ], - "Download Terms of Service": [ - "" - ], - "Hide terms of service": [ - "" - ], - "Review terms of service": [ - "" - ], - "Exchange URL": [ - "" - ], - "Cancel": [ - "Avbryt" - ], - "Loading terms..": [ - "" - ], - "Add exchange": [ - "Accepterade tjänsteleverantörer:" - ], - "Add exchange anyway": [ - "" - ], - "Add new exchange": [ - "Accepterade tjänsteleverantörer:" - ], - "Add exchange for %1$s": [ - "Accepterade tjänsteleverantörer:" - ], - "Enter the URL of an exchange you trust.": [ - "" - ], - "An exchange has been found! Review the information and click next": [ - "" - ], - "This exchange doesn't match the expected currency %1$s": [ - "" - ], - "Unable to verify this exchange": [ - "" - ], - "Unable to add this exchange": [ - "" - ], - "loading": [ - "" - ], - "Version": [ - "" - ], - "Currency": [ - "" - ], - "Next": [ - "" - ], - "Add backup provider": [ - "" - ], - "Could not get provider information": [ - "" - ], - "Backup providers may charge for their service": [ - "" - ], - "URL": [ - "" - ], - "Name": [ - "" - ], - "Provider URL": [ - "" - ], - "Please review and accept this provider's terms of service": [ - "" - ], - "Pricing": [ - "" - ], - "free of charge": [ - "" - ], - "%1$s per year of service": [ - "" - ], - "Storage": [ - "" - ], - "%1$s megabytes of storage per year of service": [ - "" - ], - "Accept terms of service": [ - "" - ], - "There was an error loading the provider detail for \"%1$s\"": [ - "" - ], - "There is not known provider with url \"%1$s\".": [ - "" - ], - "Last backup": [ - "" - ], - "Back up": [ - "" - ], - "Provider fee": [ - "" - ], - "per year": [ - "" - ], - "Extend": [ - "" - ], - "terms has changed, extending the service will imply accepting the new terms of service": [ - "" - ], - "old": [ - "" - ], - "new": [ - "" - ], - "fee": [ - "" - ], - "storage": [ - "" - ], - "back": [ - "Återbetalning" - ], - "Remove provider": [ - "" - ], - "This provider has reported an error": [ - "" - ], - "There is conflict with another backup from %1$s": [ - "" - ], - "Backup is not readable": [ - "" - ], - "Unknown backup problem: %1$s": [ - "" - ], - "service paid": [ - "" - ], - "Backup valid until": [ - "" - ], - "this popup is being closed and you are being redirected to %1$s": [ - "" - ], - "Select one option": [ - "" - ], - "Manual Withdrawal": [ - "Utbetalnings avgift" - ], - "Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": [ - "" - ], - "No exchange configured": [ - "" - ], - "Can't create the reserve": [ - "" - ], - "Exchange": [ - "" - ], - "Add Exchange": [ - "Accepterade tjänsteleverantörer:" - ], - "Amount": [ - "" - ], - "Start withdrawal": [ - "" - ], - "no balance": [ - "Balans" - ], - "There is no known bank account to send money to": [ - "" - ], - "Send %1$s to your account": [ - "" - ], - "Bank account IBAN number": [ - "" - ], - "Deposit fee": [ - "Depostitions avgift" - ], - "Total deposit": [ - "" - ], - "Deposit": [ - "Depostitions avgift" - ], - "Deposit %1$s %2$s": [ - "" - ], - "Waiting for confirmation": [ - "" - ], - "PENDING": [ - "" - ], - "Could not load the list of transactions": [ - "" - ], - "There is no history for this currency": [ - "" - ], - "Account": [ - "" - ], - "Bank host": [ - "" - ], - "Bank account": [ - "Övervisa till bank konto" - ], - "IBAN": [ - "" - ], - "Chosen amount": [ - "" - ], - "Subject": [ - "" - ], - "could not parse payto uri from exchange %1$s": [ - "" - ], - "Exchange is ready for withdrawal": [ - "Tjänsteleverantörer i plånboken:" - ], - "To complete the process you need to wire %1$s to the exchange bank account": [ - "" - ], - "Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": [ - "" - ], - "Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": [ - "" - ], - "Cancel withdrawal": [ - "" - ], - "Display": [ - "" - ], - "Current Language": [ - "" - ], - "Navigator": [ - "" - ], - "Automatically open wallet based on page content": [ - "" - ], - "Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": [ - "" - ], - "Trust": [ - "" - ], - "No exchange yet": [ - "" - ], - "Term of Service": [ - "" - ], - "ok": [ - "" - ], - "changed": [ - "" - ], - "not accepted": [ - "" - ], - "Add an exchange": [ - "Accepterade tjänsteleverantörer:" - ], - "Developer mode": [ - "" - ], - "(More options and information useful for debugging)": [ - "" - ], - "Could not load the transaction information": [ - "" - ], - "There was an error trying to complete the transaction": [ - "" - ], - "This transaction is not completed": [ - "" - ], - "Retry": [ - "" - ], - "Forget": [ - "" - ], - "Caution!": [ - "" - ], - "If you have already wired money to the exchange you will loose the chance to get the coins form it.": [ - "" - ], - "Confirm": [ - "Bekräfta" - ], - "Withdrawal": [ - "Utbetalnings avgift" - ], - "Total withdrawn": [ - "Utbetalnings avgift" - ], - "Exchange fee": [ - "Tjänsteleverantörer i plånboken:" - ], - "The bank is waiting for confirmation. Go to the %1$s": [ - "" - ], - "Waiting for the coins to arrive": [ - "" - ], - "Payment": [ - "Godkän betalning" - ], - "Total paid": [ - "" - ], - "Purchase amount": [ - "" - ], - "Fee": [ - "" - ], - "Merchant": [ - "" - ], - "Purchase": [ - "" - ], - "Receipt": [ - "" - ], - "Total send": [ - "" - ], - "Deposit amount": [ - "Depostitions avgift" - ], - "Refresh": [ - "Återhämtnings avgift" - ], - "Total refresh": [ - "" - ], - "Refresh amount": [ - "Återhämtnings avgift" - ], - "Tip": [ - "" - ], - "Total tip": [ - "" - ], - "Received amount": [ - "" - ], - "Refund": [ - "" - ], - "Total refund": [ - "" - ], - "Refund amount": [ - "" - ], - "Browser Extension Installed!": [ - "" - ], - "Thank you for installing the wallet.": [ - "" - ], - "Permissions": [ - "" - ], - "(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": [ - "" - ], - "Next Steps": [ - "" - ], - "Try the demo": [ - "" - ], - "Learn how to top up your wallet balance": [ - "" - ], - "Could not load pay status": [ - "" - ], - "Could not load contract terms from merchant or wallet backend.": [ - "" - ], - "Pay with a mobile phone": [ - "" - ], - "Hide QR": [ - "" - ], - "Scan the QR code or %1$s": [ - "" - ], - "Processing": [ - "" - ], - "Pay %1$s": [ - "" - ], - "Your balance of %1$s is not enough to pay for this purchase": [ - "" - ], - "Your balance is not enough to pay for this purchase.": [ - "" - ], - "Withdraw digital cash": [ - "Utbetalnings avgifter:" - ], - "Merchant message": [ - "" - ], - "Digital cash payment": [ - "" - ], - "Already paid, you are going to be redirected to %1$s": [ - "" - ], - "Already paid": [ - "" - ], - "Already claimed": [ - "" - ], - "Payment complete": [ - "" - ], - "You are going to be redirected to $ %1$s": [ - "" - ], - "You can close this page.": [ - "" - ], - "Total to pay": [ - "" - ], - "List of products": [ - "" - ], - "Total": [ - "" - ], - "free": [ - "" - ], - "Refund Status": [ - "" - ], - "The product %1$s has received a total effective refund of": [ - "" - ], - "Refund processing is still in progress.": [ - "" - ], - "The refund amount of %1$s could not be applied.": [ - "" - ], - "missing taler refund uri": [ - "" - ], - "Error: %1$s": [ - "" - ], - "Updating refund status": [ - "" - ], - "Tip from %1$s accepted. Check your transactions list for more details.": [ - "" - ], + "Du har ingen balans att visa. Behöver du\n %1$s att börja?\n", + ], + 'To withdraw money you can start from your bank site or click the "withdraw" button to use a known exchange.': + [""], + Withdraw: ["Utbetalnings avgift"], + "Could not load balance page": [""], + "Deposit %1$s": ["Depostitions avgift"], + "Enter URI": [""], + "Diagnostics timed out. Could not talk to the wallet backend.": [""], + "Problems detected:": [""], + "Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": + [""], + "Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": + [""], + "Running diagnostics": [""], + "Debug tools": [""], + reset: [""], + "import database": [""], + "export database": [""], + "Database exported at %1$s %2$s to download": [""], + Coins: ["# Mynt"], + "Pending operations": [""], + "usable coins": [""], + id: [""], + denom: [""], + value: ["Värde"], + status: [""], + "from refresh?": [""], + "spent coins": [""], + "click to show": [""], + "Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": + [""], + "Taler Action": [""], + "This page has pay action.": [""], + "This page has a withdrawal action.": [""], + "This page has a tip action.": [""], + "This page has a notify reserve action.": [""], + Notify: [""], + "This page has a refund action.": [""], + "This page has a malformed taler uri.": [""], + Dismiss: [""], + "Could not load backup providers": [""], + "No backup providers configured": [""], + "Add provider": [""], + "Sync all backups": [""], + "Sync now": [""], + "Last synced": [""], + "Not synced": [""], + "Expires in": [""], + "Exchange doesn't have terms of service": [""], + "Review exchange terms of service": [""], + "Review new version of terms of service": [""], + "Show terms of service": [""], + "I accept the exchange terms of service": [""], + "The exchange reply with a empty terms of service": [""], + "Download Terms of Service": [""], + "Hide terms of service": [""], + "Review terms of service": [""], + "Exchange URL": [""], + Cancel: ["Avbryt"], + "Loading terms..": [""], + "Add exchange": ["Accepterade tjänsteleverantörer:"], + "Add exchange anyway": [""], + "Add new exchange": ["Accepterade tjänsteleverantörer:"], + "Add exchange for %1$s": ["Accepterade tjänsteleverantörer:"], + "Enter the URL of an exchange you trust.": [""], + "An exchange has been found! Review the information and click next": [""], + "This exchange doesn't match the expected currency %1$s": [""], + "Unable to verify this exchange": [""], + "Unable to add this exchange": [""], + loading: [""], + Version: [""], + Currency: [""], + Next: [""], + "Add backup provider": [""], + "Could not get provider information": [""], + "Backup providers may charge for their service": [""], + URL: [""], + Name: [""], + "Provider URL": [""], + "Please review and accept this provider's terms of service": [""], + Pricing: [""], + "free of charge": [""], + "%1$s per year of service": [""], + Storage: [""], + "%1$s megabytes of storage per year of service": [""], + "Accept terms of service": [""], + 'There was an error loading the provider detail for "%1$s"': [""], + 'There is not known provider with url "%1$s".': [""], + "Last backup": [""], + "Back up": [""], + "Provider fee": [""], + "per year": [""], + Extend: [""], + "terms has changed, extending the service will imply accepting the new terms of service": + [""], + old: [""], + new: [""], + fee: [""], + storage: [""], + back: ["Återbetalning"], + "Remove provider": [""], + "This provider has reported an error": [""], + "There is conflict with another backup from %1$s": [""], + "Backup is not readable": [""], + "Unknown backup problem: %1$s": [""], + "service paid": [""], + "Backup valid until": [""], + "this popup is being closed and you are being redirected to %1$s": [""], + "Select one option": [""], + "Manual Withdrawal": ["Utbetalnings avgift"], + "Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": + [""], + "No exchange configured": [""], + "Can't create the reserve": [""], + Exchange: [""], + "Add Exchange": ["Accepterade tjänsteleverantörer:"], + Amount: [""], + "Start withdrawal": [""], + "no balance": ["Balans"], + "There is no known bank account to send money to": [""], + "Send %1$s to your account": [""], + "Bank account IBAN number": [""], + "Deposit fee": ["Depostitions avgift"], + "Total deposit": [""], + Deposit: ["Depostitions avgift"], + "Deposit %1$s %2$s": [""], + "Waiting for confirmation": [""], + PENDING: [""], + "Could not load the list of transactions": [""], + "There is no history for this currency": [""], + Account: [""], + "Bank host": [""], + "Bank account": ["Övervisa till bank konto"], + IBAN: [""], + "Chosen amount": [""], + Subject: [""], + "could not parse payto uri from exchange %1$s": [""], + "Exchange is ready for withdrawal": ["Tjänsteleverantörer i plånboken:"], + "To complete the process you need to wire %1$s to the exchange bank account": + [""], + "Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": + [""], + "Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": + [""], + "Cancel withdrawal": [""], + Display: [""], + "Current Language": [""], + Navigator: [""], + "Automatically open wallet based on page content": [""], + "Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": + [""], + Trust: [""], + "No exchange yet": [""], + "Term of Service": [""], + ok: [""], + changed: [""], + "not accepted": [""], + "Add an exchange": ["Accepterade tjänsteleverantörer:"], + "Developer mode": [""], + "(More options and information useful for debugging)": [""], + "Could not load the transaction information": [""], + "There was an error trying to complete the transaction": [""], + "This transaction is not completed": [""], + Retry: [""], + Forget: [""], + "Caution!": [""], + "If you have already wired money to the exchange you will loose the chance to get the coins form it.": + [""], + Confirm: ["Bekräfta"], + Withdrawal: ["Utbetalnings avgift"], + "Total withdrawn": ["Utbetalnings avgift"], + "Exchange fee": ["Tjänsteleverantörer i plånboken:"], + "The bank is waiting for confirmation. Go to the %1$s": [""], + "Waiting for the coins to arrive": [""], + Payment: ["Godkän betalning"], + "Total paid": [""], + "Purchase amount": [""], + Fee: [""], + Merchant: [""], + Purchase: [""], + Receipt: [""], + "Total send": [""], + "Deposit amount": ["Depostitions avgift"], + Refresh: ["Återhämtnings avgift"], + "Total refresh": [""], + "Refresh amount": ["Återhämtnings avgift"], + Tip: [""], + "Total tip": [""], + "Received amount": [""], + Refund: [""], + "Total refund": [""], + "Refund amount": [""], + "Browser Extension Installed!": [""], + "Thank you for installing the wallet.": [""], + Permissions: [""], + "(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": + [""], + "Next Steps": [""], + "Try the demo": [""], + "Learn how to top up your wallet balance": [""], + "Could not load pay status": [""], + "Could not load contract terms from merchant or wallet backend.": [""], + "Pay with a mobile phone": [""], + "Hide QR": [""], + "Scan the QR code or %1$s": [""], + Processing: [""], + "Pay %1$s": [""], + "Your balance of %1$s is not enough to pay for this purchase": [""], + "Your balance is not enough to pay for this purchase.": [""], + "Withdraw digital cash": ["Utbetalnings avgifter:"], + "Merchant message": [""], + "Digital cash payment": [""], + "Already paid, you are going to be redirected to %1$s": [""], + "Already paid": [""], + "Already claimed": [""], + "Payment complete": [""], + "You are going to be redirected to $ %1$s": [""], + "You can close this page.": [""], + "Total to pay": [""], + "List of products": [""], + Total: [""], + free: [""], + "Refund Status": [""], + "The product %1$s has received a total effective refund of": [""], + "Refund processing is still in progress.": [""], + "The refund amount of %1$s could not be applied.": [""], + "missing taler refund uri": [""], + "Error: %1$s": [""], + "Updating refund status": [""], + "Tip from %1$s accepted. Check your transactions list for more details.": + [""], "The merchant %1$s is offering you a tip of %2$s via the exchange %3$s": [ - "Säljaren %1$s erbjuder följande:" - ], - "Accept tip": [ - "" - ], - "Ignore": [ - "" - ], - "missing tip uri": [ - "" - ], - "You've ignored the tip.": [ - "" - ], - "Digital cash withdrawal": [ - "" - ], - "Could not finish the withdrawal operation": [ - "" - ], - "Total to withdraw": [ - "" - ], - "Known exchanges": [ - "" - ], - "Cancel exchange selection": [ - "" - ], - "Confirm exchange selection": [ - "" - ], - "Switch exchange": [ - "" - ], - "Confirm withdrawal": [ - "" - ], - "Withdraw anyway": [ - "Utbetalnings avgift" - ], - "Could not load the withdrawal details": [ - "" - ], - "missing withdraw uri": [ - "" - ], - "Could not get the info from the URI": [ - "" - ], - "Could not load the list of known exchanges": [ - "" - ], - "All done, your transaction is in progress": [ - "" - ], - "Edit": [ - "" - ], - "missing pay uri": [ - "" - ], - "Could not get the payment information for this order": [ - "" - ], - "Loading payment information": [ - "" - ], - "Digital cash deposit": [ - "" - ], - "You will now be sent back to the merchant you came from.": [ - "" - ], - "Manual Reset Required": [ - "" - ], - "The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": [ - "" - ], - "Once the database format has stabilized, we will provide automatic upgrades.": [ - "" - ], - "I understand that I will lose all my data": [ - "" - ], - "Reset": [ - "" - ], - "Everything is fine!": [ - "" - ], - "A reset is not required anymore, you can close this page.": [ - "" - ], - "Not implemented yet.": [ - "" - ] - } - } + "Säljaren %1$s erbjuder följande:", + ], + "Accept tip": [""], + Ignore: [""], + "missing tip uri": [""], + "You've ignored the tip.": [""], + "Digital cash withdrawal": [""], + "Could not finish the withdrawal operation": [""], + "Total to withdraw": [""], + "Known exchanges": [""], + "Cancel exchange selection": [""], + "Confirm exchange selection": [""], + "Switch exchange": [""], + "Confirm withdrawal": [""], + "Withdraw anyway": ["Utbetalnings avgift"], + "Could not load the withdrawal details": [""], + "missing withdraw uri": [""], + "Could not get the info from the URI": [""], + "Could not load the list of known exchanges": [""], + "All done, your transaction is in progress": [""], + Edit: [""], + "missing pay uri": [""], + "Could not get the payment information for this order": [""], + "Loading payment information": [""], + "Digital cash deposit": [""], + "You will now be sent back to the merchant you came from.": [""], + "Manual Reset Required": [""], + "The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": + [""], + "Once the database format has stabilized, we will provide automatic upgrades.": + [""], + "I understand that I will lose all my data": [""], + Reset: [""], + "Everything is fine!": [""], + "A reset is not required anymore, you can close this page.": [""], + "Not implemented yet.": [""], + }, + }, }; -strings['tr'] = { - "domain": "messages", - "locale_data": { - "messages": { +strings["tr"] = { + domain: "messages", + locale_data: { + messages: { "": { - "domain": "messages", - "plural_forms": "nplurals=2; plural=n != 1;", - "lang": "tr" + domain: "messages", + plural_forms: "nplurals=2; plural=n != 1;", + lang: "tr", }, - "Balance": [ - "Bakiye" - ], - "Backup": [ - "Yedek" - ], - "Settings": [ - "Ayarlar" - ], - "Dev": [ - "Gelişim" - ], - "Loading": [ - "Yükleniyor" - ], - "Open reserve page": [ - "Rezerv sayfasını açın" - ], - "Open pay page": [ - "Ödeme sayfasını açın" - ], - "Open refund page": [ - "Geri ödeme sayfasını açın" - ], - "Open tip page": [ - "" - ], - "Open withdraw page": [ - "" - ], - "Back": [ - "" - ], - "You have no balance to show.": [ - "" - ], - "To withdraw money you can start from your bank site or click the \"withdraw\" button to use a known exchange.": [ - "" - ], - "Withdraw": [ - "" - ], - "Could not load balance page": [ - "" - ], - "Deposit %1$s": [ - "" - ], - "Enter URI": [ - "" - ], - "Diagnostics timed out. Could not talk to the wallet backend.": [ - "" - ], - "Problems detected:": [ - "" - ], - "Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": [ - "" - ], - "Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": [ - "" - ], - "Running diagnostics": [ - "" - ], - "Debug tools": [ - "" - ], - "reset": [ - "" - ], - "import database": [ - "" - ], - "export database": [ - "" - ], - "Database exported at %1$s %2$s to download": [ - "" - ], - "Coins": [ - "" - ], - "Pending operations": [ - "" - ], - "usable coins": [ - "" - ], - "id": [ - "" - ], - "denom": [ - "" - ], - "value": [ - "" - ], - "status": [ - "" - ], - "from refresh?": [ - "" - ], - "spent coins": [ - "" - ], - "click to show": [ - "" - ], - "Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": [ - "" - ], - "Taler Action": [ - "" - ], - "This page has pay action.": [ - "" - ], - "This page has a withdrawal action.": [ - "" - ], - "This page has a tip action.": [ - "" - ], - "This page has a notify reserve action.": [ - "" - ], - "Notify": [ - "" - ], - "This page has a refund action.": [ - "" - ], - "This page has a malformed taler uri.": [ - "" - ], - "Dismiss": [ - "" - ], - "Could not load backup providers": [ - "" - ], - "No backup providers configured": [ - "" - ], - "Add provider": [ - "" - ], - "Sync all backups": [ - "" - ], - "Sync now": [ - "" - ], - "Last synced": [ - "" - ], - "Not synced": [ - "" - ], - "Expires in": [ - "" - ], - "Exchange doesn't have terms of service": [ - "" - ], - "Review exchange terms of service": [ - "" - ], - "Review new version of terms of service": [ - "" - ], - "Show terms of service": [ - "" - ], - "I accept the exchange terms of service": [ - "" - ], - "The exchange reply with a empty terms of service": [ - "" - ], - "Download Terms of Service": [ - "" - ], - "Hide terms of service": [ - "" - ], - "Review terms of service": [ - "" - ], - "Exchange URL": [ - "" - ], - "Cancel": [ - "Bakiye" - ], - "Loading terms..": [ - "" - ], - "Add exchange": [ - "" - ], - "Add exchange anyway": [ - "" - ], - "Add new exchange": [ - "" - ], - "Add exchange for %1$s": [ - "" - ], - "Enter the URL of an exchange you trust.": [ - "" - ], - "An exchange has been found! Review the information and click next": [ - "" - ], - "This exchange doesn't match the expected currency %1$s": [ - "" - ], - "Unable to verify this exchange": [ - "" - ], - "Unable to add this exchange": [ - "" - ], - "loading": [ - "" - ], - "Version": [ - "" - ], - "Currency": [ - "" - ], - "Next": [ - "" - ], - "Add backup provider": [ - "" - ], - "Could not get provider information": [ - "" - ], - "Backup providers may charge for their service": [ - "" - ], - "URL": [ - "" - ], - "Name": [ - "" - ], - "Provider URL": [ - "" - ], - "Please review and accept this provider's terms of service": [ - "" - ], - "Pricing": [ - "" - ], - "free of charge": [ - "" - ], - "%1$s per year of service": [ - "" - ], - "Storage": [ - "" - ], - "%1$s megabytes of storage per year of service": [ - "" - ], - "Accept terms of service": [ - "" - ], - "There was an error loading the provider detail for \"%1$s\"": [ - "" - ], - "There is not known provider with url \"%1$s\".": [ - "" - ], - "Last backup": [ - "" - ], - "Back up": [ - "" - ], - "Provider fee": [ - "" - ], - "per year": [ - "" - ], - "Extend": [ - "" - ], - "terms has changed, extending the service will imply accepting the new terms of service": [ - "" - ], - "old": [ - "" - ], - "new": [ - "" - ], - "fee": [ - "" - ], - "storage": [ - "" - ], - "back": [ - "" - ], - "Remove provider": [ - "" - ], - "This provider has reported an error": [ - "" - ], - "There is conflict with another backup from %1$s": [ - "" - ], - "Backup is not readable": [ - "" - ], - "Unknown backup problem: %1$s": [ - "" - ], - "service paid": [ - "" - ], - "Backup valid until": [ - "" - ], - "this popup is being closed and you are being redirected to %1$s": [ - "" - ], - "Select one option": [ - "" - ], - "Manual Withdrawal": [ - "" - ], - "Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": [ - "" - ], - "No exchange configured": [ - "" - ], - "Can't create the reserve": [ - "" - ], - "Exchange": [ - "Exchange" - ], - "Add Exchange": [ - "" - ], - "Amount": [ - "" - ], - "Start withdrawal": [ - "" - ], - "no balance": [ - "Bakiye" - ], - "There is no known bank account to send money to": [ - "" - ], - "Send %1$s to your account": [ - "" - ], - "Bank account IBAN number": [ - "" - ], - "Deposit fee": [ - "" - ], - "Total deposit": [ - "" - ], - "Deposit": [ - "" - ], - "Deposit %1$s %2$s": [ - "Test Havale Hesap #%1$s üzerinde %2$s" - ], - "Waiting for confirmation": [ - "" - ], - "PENDING": [ - "" - ], - "Could not load the list of transactions": [ - "" - ], - "There is no history for this currency": [ - "" - ], - "Account": [ - "" - ], - "Bank host": [ - "" - ], - "Bank account": [ - "" - ], - "IBAN": [ - "" - ], - "Chosen amount": [ - "" - ], - "Subject": [ - "" - ], - "could not parse payto uri from exchange %1$s": [ - "" - ], - "Exchange is ready for withdrawal": [ - "" - ], - "To complete the process you need to wire %1$s to the exchange bank account": [ - "" - ], - "Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": [ - "" - ], - "Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": [ - "" - ], - "Cancel withdrawal": [ - "" - ], - "Display": [ - "" - ], - "Current Language": [ - "" - ], - "Navigator": [ - "" - ], - "Automatically open wallet based on page content": [ - "" - ], - "Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": [ - "" - ], - "Trust": [ - "" - ], - "No exchange yet": [ - "" - ], - "Term of Service": [ - "" - ], - "ok": [ - "" - ], - "changed": [ - "" - ], - "not accepted": [ - "" - ], - "Add an exchange": [ - "" - ], - "Developer mode": [ - "" - ], - "(More options and information useful for debugging)": [ - "" - ], - "Could not load the transaction information": [ - "" - ], - "There was an error trying to complete the transaction": [ - "" - ], - "This transaction is not completed": [ - "" - ], - "Retry": [ - "Yeniden deneyin" - ], - "Forget": [ - "" - ], - "Caution!": [ - "" - ], - "If you have already wired money to the exchange you will loose the chance to get the coins form it.": [ - "" - ], - "Confirm": [ - "Onaylamak" - ], - "Withdrawal": [ - "Çekildi" - ], - "Total withdrawn": [ - "Çekildi" - ], - "Exchange fee": [ - "" - ], - "The bank is waiting for confirmation. Go to the %1$s": [ - "" - ], - "Waiting for the coins to arrive": [ - "" - ], - "Payment": [ - "Ödeme gönderildi" - ], - "Total paid": [ - "" - ], - "Purchase amount": [ - "" - ], - "Fee": [ - "Ücretler" - ], - "Merchant": [ - "" - ], - "Purchase": [ - "" - ], - "Receipt": [ - "" - ], - "Total send": [ - "" - ], - "Deposit amount": [ - "Depozito Ücreti" - ], - "Refresh": [ - "Ücreti yenile" - ], - "Total refresh": [ - "" - ], - "Refresh amount": [ - "Ücreti yenile" - ], - "Tip": [ - "" - ], - "Total tip": [ - "" - ], - "Received amount": [ - "" - ], - "Refund": [ - "" - ], - "Total refund": [ - "" - ], - "Refund amount": [ - "" - ], - "Browser Extension Installed!": [ - "" - ], - "Thank you for installing the wallet.": [ - "" - ], - "Permissions": [ - "" - ], - "(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": [ - "" - ], - "Next Steps": [ - "" - ], - "Try the demo": [ - "" - ], - "Learn how to top up your wallet balance": [ - "" - ], - "Could not load pay status": [ - "" - ], - "Could not load contract terms from merchant or wallet backend.": [ - "" - ], - "Pay with a mobile phone": [ - "" - ], - "Hide QR": [ - "" - ], - "Scan the QR code or %1$s": [ - "" - ], - "Processing": [ - "" - ], - "Pay %1$s": [ - "" - ], - "Your balance of %1$s is not enough to pay for this purchase": [ - "" - ], - "Your balance is not enough to pay for this purchase.": [ - "" - ], - "Withdraw digital cash": [ - "" - ], - "Merchant message": [ - "" - ], - "Digital cash payment": [ - "" - ], - "Already paid, you are going to be redirected to %1$s": [ - "" - ], - "Already paid": [ - "" - ], - "Already claimed": [ - "" - ], - "Payment complete": [ - "" - ], - "You are going to be redirected to $ %1$s": [ - "" - ], - "You can close this page.": [ - "" - ], - "Total to pay": [ - "" - ], - "List of products": [ - "" - ], - "Total": [ - "" - ], - "free": [ - "" - ], - "Refund Status": [ - "" - ], - "The product %1$s has received a total effective refund of": [ - "" - ], - "Refund processing is still in progress.": [ - "" - ], - "The refund amount of %1$s could not be applied.": [ - "" - ], - "missing taler refund uri": [ - "" - ], - "Error: %1$s": [ - "" - ], - "Updating refund status": [ - "" - ], - "Tip from %1$s accepted. Check your transactions list for more details.": [ - "" - ], + Balance: ["Bakiye"], + Backup: ["Yedek"], + Settings: ["Ayarlar"], + Dev: ["Gelişim"], + Loading: ["Yükleniyor"], + "Open reserve page": ["Rezerv sayfasını açın"], + "Open pay page": ["Ödeme sayfasını açın"], + "Open refund page": ["Geri ödeme sayfasını açın"], + "Open tip page": [""], + "Open withdraw page": [""], + Back: [""], + "You have no balance to show.": [""], + 'To withdraw money you can start from your bank site or click the "withdraw" button to use a known exchange.': + [""], + Withdraw: [""], + "Could not load balance page": [""], + "Deposit %1$s": [""], + "Enter URI": [""], + "Diagnostics timed out. Could not talk to the wallet backend.": [""], + "Problems detected:": [""], + "Please check in your %1$s settings that you have IndexedDB enabled (check the preference name %2$s).": + [""], + "Your wallet database is outdated. Currently automatic migration is not supported. Please go %1$s to reset the wallet database.": + [""], + "Running diagnostics": [""], + "Debug tools": [""], + reset: [""], + "import database": [""], + "export database": [""], + "Database exported at %1$s %2$s to download": [""], + Coins: [""], + "Pending operations": [""], + "usable coins": [""], + id: [""], + denom: [""], + value: [""], + status: [""], + "from refresh?": [""], + "spent coins": [""], + "click to show": [""], + "Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?": + [""], + "Taler Action": [""], + "This page has pay action.": [""], + "This page has a withdrawal action.": [""], + "This page has a tip action.": [""], + "This page has a notify reserve action.": [""], + Notify: [""], + "This page has a refund action.": [""], + "This page has a malformed taler uri.": [""], + Dismiss: [""], + "Could not load backup providers": [""], + "No backup providers configured": [""], + "Add provider": [""], + "Sync all backups": [""], + "Sync now": [""], + "Last synced": [""], + "Not synced": [""], + "Expires in": [""], + "Exchange doesn't have terms of service": [""], + "Review exchange terms of service": [""], + "Review new version of terms of service": [""], + "Show terms of service": [""], + "I accept the exchange terms of service": [""], + "The exchange reply with a empty terms of service": [""], + "Download Terms of Service": [""], + "Hide terms of service": [""], + "Review terms of service": [""], + "Exchange URL": [""], + Cancel: ["Bakiye"], + "Loading terms..": [""], + "Add exchange": [""], + "Add exchange anyway": [""], + "Add new exchange": [""], + "Add exchange for %1$s": [""], + "Enter the URL of an exchange you trust.": [""], + "An exchange has been found! Review the information and click next": [""], + "This exchange doesn't match the expected currency %1$s": [""], + "Unable to verify this exchange": [""], + "Unable to add this exchange": [""], + loading: [""], + Version: [""], + Currency: [""], + Next: [""], + "Add backup provider": [""], + "Could not get provider information": [""], + "Backup providers may charge for their service": [""], + URL: [""], + Name: [""], + "Provider URL": [""], + "Please review and accept this provider's terms of service": [""], + Pricing: [""], + "free of charge": [""], + "%1$s per year of service": [""], + Storage: [""], + "%1$s megabytes of storage per year of service": [""], + "Accept terms of service": [""], + 'There was an error loading the provider detail for "%1$s"': [""], + 'There is not known provider with url "%1$s".': [""], + "Last backup": [""], + "Back up": [""], + "Provider fee": [""], + "per year": [""], + Extend: [""], + "terms has changed, extending the service will imply accepting the new terms of service": + [""], + old: [""], + new: [""], + fee: [""], + storage: [""], + back: [""], + "Remove provider": [""], + "This provider has reported an error": [""], + "There is conflict with another backup from %1$s": [""], + "Backup is not readable": [""], + "Unknown backup problem: %1$s": [""], + "service paid": [""], + "Backup valid until": [""], + "this popup is being closed and you are being redirected to %1$s": [""], + "Select one option": [""], + "Manual Withdrawal": [""], + "Choose a exchange from where the coins will be withdrawn. The exchange will send the coins to this wallet after receiving a wire transfer with the correct subject.": + [""], + "No exchange configured": [""], + "Can't create the reserve": [""], + Exchange: ["Exchange"], + "Add Exchange": [""], + Amount: [""], + "Start withdrawal": [""], + "no balance": ["Bakiye"], + "There is no known bank account to send money to": [""], + "Send %1$s to your account": [""], + "Bank account IBAN number": [""], + "Deposit fee": [""], + "Total deposit": [""], + Deposit: [""], + "Deposit %1$s %2$s": ["Test Havale Hesap #%1$s üzerinde %2$s"], + "Waiting for confirmation": [""], + PENDING: [""], + "Could not load the list of transactions": [""], + "There is no history for this currency": [""], + Account: [""], + "Bank host": [""], + "Bank account": [""], + IBAN: [""], + "Chosen amount": [""], + Subject: [""], + "could not parse payto uri from exchange %1$s": [""], + "Exchange is ready for withdrawal": [""], + "To complete the process you need to wire %1$s to the exchange bank account": + [""], + "Make sure to use the correct subject, otherwise the money will not arrive in this wallet.": + [""], + "Alternative, you can also scan this QR code or open %1$s if you have a banking app installed that supports RFC 8905": + [""], + "Cancel withdrawal": [""], + Display: [""], + "Current Language": [""], + Navigator: [""], + "Automatically open wallet based on page content": [""], + "Enabling this option below will make using the wallet faster, but requires more permissions from your browser.": + [""], + Trust: [""], + "No exchange yet": [""], + "Term of Service": [""], + ok: [""], + changed: [""], + "not accepted": [""], + "Add an exchange": [""], + "Developer mode": [""], + "(More options and information useful for debugging)": [""], + "Could not load the transaction information": [""], + "There was an error trying to complete the transaction": [""], + "This transaction is not completed": [""], + Retry: ["Yeniden deneyin"], + Forget: [""], + "Caution!": [""], + "If you have already wired money to the exchange you will loose the chance to get the coins form it.": + [""], + Confirm: ["Onaylamak"], + Withdrawal: ["Çekildi"], + "Total withdrawn": ["Çekildi"], + "Exchange fee": [""], + "The bank is waiting for confirmation. Go to the %1$s": [""], + "Waiting for the coins to arrive": [""], + Payment: ["Ödeme gönderildi"], + "Total paid": [""], + "Purchase amount": [""], + Fee: ["Ücretler"], + Merchant: [""], + Purchase: [""], + Receipt: [""], + "Total send": [""], + "Deposit amount": ["Depozito Ücreti"], + Refresh: ["Ücreti yenile"], + "Total refresh": [""], + "Refresh amount": ["Ücreti yenile"], + Tip: [""], + "Total tip": [""], + "Received amount": [""], + Refund: [""], + "Total refund": [""], + "Refund amount": [""], + "Browser Extension Installed!": [""], + "Thank you for installing the wallet.": [""], + Permissions: [""], + "(Enabling this option below will make using the wallet faster, but requires more permissions from your browser.)": + [""], + "Next Steps": [""], + "Try the demo": [""], + "Learn how to top up your wallet balance": [""], + "Could not load pay status": [""], + "Could not load contract terms from merchant or wallet backend.": [""], + "Pay with a mobile phone": [""], + "Hide QR": [""], + "Scan the QR code or %1$s": [""], + Processing: [""], + "Pay %1$s": [""], + "Your balance of %1$s is not enough to pay for this purchase": [""], + "Your balance is not enough to pay for this purchase.": [""], + "Withdraw digital cash": [""], + "Merchant message": [""], + "Digital cash payment": [""], + "Already paid, you are going to be redirected to %1$s": [""], + "Already paid": [""], + "Already claimed": [""], + "Payment complete": [""], + "You are going to be redirected to $ %1$s": [""], + "You can close this page.": [""], + "Total to pay": [""], + "List of products": [""], + Total: [""], + free: [""], + "Refund Status": [""], + "The product %1$s has received a total effective refund of": [""], + "Refund processing is still in progress.": [""], + "The refund amount of %1$s could not be applied.": [""], + "missing taler refund uri": [""], + "Error: %1$s": [""], + "Updating refund status": [""], + "Tip from %1$s accepted. Check your transactions list for more details.": + [""], "The merchant %1$s is offering you a tip of %2$s via the exchange %3$s": [ - "" - ], - "Accept tip": [ - "" - ], - "Ignore": [ - "" - ], - "missing tip uri": [ - "" - ], - "You've ignored the tip.": [ - "" - ], - "Digital cash withdrawal": [ - "" - ], - "Could not finish the withdrawal operation": [ - "" - ], - "Total to withdraw": [ - "" - ], - "Known exchanges": [ - "" - ], - "Cancel exchange selection": [ - "" - ], - "Confirm exchange selection": [ - "" - ], - "Switch exchange": [ - "" - ], - "Confirm withdrawal": [ - "" - ], - "Withdraw anyway": [ - "" - ], - "Could not load the withdrawal details": [ - "" - ], - "missing withdraw uri": [ - "" - ], - "Could not get the info from the URI": [ - "" - ], - "Could not load the list of known exchanges": [ - "" - ], - "All done, your transaction is in progress": [ - "" - ], - "Edit": [ - "Lütfen bir exchange seçin. Detayları seçiminizden önce inceleyebilirsiniz." - ], - "missing pay uri": [ - "" - ], - "Could not get the payment information for this order": [ - "" - ], - "Loading payment information": [ - "" - ], - "Digital cash deposit": [ - "" - ], - "You will now be sent back to the merchant you came from.": [ - "" - ], - "Manual Reset Required": [ - "" - ], - "The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": [ - "" - ], - "Once the database format has stabilized, we will provide automatic upgrades.": [ - "" - ], - "I understand that I will lose all my data": [ - "" - ], - "Reset": [ - "" - ], - "Everything is fine!": [ - "" - ], - "A reset is not required anymore, you can close this page.": [ - "" - ], - "Not implemented yet.": [ - "" - ] - } - } + "", + ], + "Accept tip": [""], + Ignore: [""], + "missing tip uri": [""], + "You've ignored the tip.": [""], + "Digital cash withdrawal": [""], + "Could not finish the withdrawal operation": [""], + "Total to withdraw": [""], + "Known exchanges": [""], + "Cancel exchange selection": [""], + "Confirm exchange selection": [""], + "Switch exchange": [""], + "Confirm withdrawal": [""], + "Withdraw anyway": [""], + "Could not load the withdrawal details": [""], + "missing withdraw uri": [""], + "Could not get the info from the URI": [""], + "Could not load the list of known exchanges": [""], + "All done, your transaction is in progress": [""], + Edit: [ + "Lütfen bir exchange seçin. Detayları seçiminizden önce inceleyebilirsiniz.", + ], + "missing pay uri": [""], + "Could not get the payment information for this order": [""], + "Loading payment information": [""], + "Digital cash deposit": [""], + "You will now be sent back to the merchant you came from.": [""], + "Manual Reset Required": [""], + "The wallet's database in your browser is incompatible with the currently installed wallet. Please reset manually.": + [""], + "Once the database format has stabilized, we will provide automatic upgrades.": + [""], + "I understand that I will lose all my data": [""], + Reset: [""], + "Everything is fine!": [""], + "A reset is not required anymore, you can close this page.": [""], + "Not implemented yet.": [""], + }, + }, }; - diff --git a/packages/taler-wallet-webextension/src/mui/colors/constants.ts b/packages/taler-wallet-webextension/src/mui/colors/constants.ts index a6e58caa9..c9e74b6d3 100644 --- a/packages/taler-wallet-webextension/src/mui/colors/constants.ts +++ b/packages/taler-wallet-webextension/src/mui/colors/constants.ts @@ -1,348 +1,327 @@ export const amber = { - 50: '#fff8e1', - 100: '#ffecb3', - 200: '#ffe082', - 300: '#ffd54f', - 400: '#ffca28', - 500: '#ffc107', - 600: '#ffb300', - 700: '#ffa000', - 800: '#ff8f00', - 900: '#ff6f00', - A100: '#ffe57f', - A200: '#ffd740', - A400: '#ffc400', - A700: '#ffab00', + 50: "#fff8e1", + 100: "#ffecb3", + 200: "#ffe082", + 300: "#ffd54f", + 400: "#ffca28", + 500: "#ffc107", + 600: "#ffb300", + 700: "#ffa000", + 800: "#ff8f00", + 900: "#ff6f00", + A100: "#ffe57f", + A200: "#ffd740", + A400: "#ffc400", + A700: "#ffab00", }; - export const blueGrey = { - 50: '#eceff1', - 100: '#cfd8dc', - 200: '#b0bec5', - 300: '#90a4ae', - 400: '#78909c', - 500: '#607d8b', - 600: '#546e7a', - 700: '#455a64', - 800: '#37474f', - 900: '#263238', - A100: '#cfd8dc', - A200: '#b0bec5', - A400: '#78909c', - A700: '#455a64', + 50: "#eceff1", + 100: "#cfd8dc", + 200: "#b0bec5", + 300: "#90a4ae", + 400: "#78909c", + 500: "#607d8b", + 600: "#546e7a", + 700: "#455a64", + 800: "#37474f", + 900: "#263238", + A100: "#cfd8dc", + A200: "#b0bec5", + A400: "#78909c", + A700: "#455a64", }; - export const blue = { - 50: '#e3f2fd', - 100: '#bbdefb', - 200: '#90caf9', - 300: '#64b5f6', - 400: '#42a5f5', - 500: '#2196f3', - 600: '#1e88e5', - 700: '#1976d2', - 800: '#1565c0', - 900: '#0d47a1', - A100: '#82b1ff', - A200: '#448aff', - A400: '#2979ff', - A700: '#2962ff', + 50: "#e3f2fd", + 100: "#bbdefb", + 200: "#90caf9", + 300: "#64b5f6", + 400: "#42a5f5", + 500: "#2196f3", + 600: "#1e88e5", + 700: "#1976d2", + 800: "#1565c0", + 900: "#0d47a1", + A100: "#82b1ff", + A200: "#448aff", + A400: "#2979ff", + A700: "#2962ff", }; - export const brown = { - 50: '#efebe9', - 100: '#d7ccc8', - 200: '#bcaaa4', - 300: '#a1887f', - 400: '#8d6e63', - 500: '#795548', - 600: '#6d4c41', - 700: '#5d4037', - 800: '#4e342e', - 900: '#3e2723', - A100: '#d7ccc8', - A200: '#bcaaa4', - A400: '#8d6e63', - A700: '#5d4037', + 50: "#efebe9", + 100: "#d7ccc8", + 200: "#bcaaa4", + 300: "#a1887f", + 400: "#8d6e63", + 500: "#795548", + 600: "#6d4c41", + 700: "#5d4037", + 800: "#4e342e", + 900: "#3e2723", + A100: "#d7ccc8", + A200: "#bcaaa4", + A400: "#8d6e63", + A700: "#5d4037", }; - export const common = { - black: '#000', - white: '#fff', + black: "#000", + white: "#fff", }; - export const cyan = { - 50: '#e0f7fa', - 100: '#b2ebf2', - 200: '#80deea', - 300: '#4dd0e1', - 400: '#26c6da', - 500: '#00bcd4', - 600: '#00acc1', - 700: '#0097a7', - 800: '#00838f', - 900: '#006064', - A100: '#84ffff', - A200: '#18ffff', - A400: '#00e5ff', - A700: '#00b8d4', + 50: "#e0f7fa", + 100: "#b2ebf2", + 200: "#80deea", + 300: "#4dd0e1", + 400: "#26c6da", + 500: "#00bcd4", + 600: "#00acc1", + 700: "#0097a7", + 800: "#00838f", + 900: "#006064", + A100: "#84ffff", + A200: "#18ffff", + A400: "#00e5ff", + A700: "#00b8d4", }; - export const deepOrange = { - 50: '#fbe9e7', - 100: '#ffccbc', - 200: '#ffab91', - 300: '#ff8a65', - 400: '#ff7043', - 500: '#ff5722', - 600: '#f4511e', - 700: '#e64a19', - 800: '#d84315', - 900: '#bf360c', - A100: '#ff9e80', - A200: '#ff6e40', - A400: '#ff3d00', - A700: '#dd2c00', + 50: "#fbe9e7", + 100: "#ffccbc", + 200: "#ffab91", + 300: "#ff8a65", + 400: "#ff7043", + 500: "#ff5722", + 600: "#f4511e", + 700: "#e64a19", + 800: "#d84315", + 900: "#bf360c", + A100: "#ff9e80", + A200: "#ff6e40", + A400: "#ff3d00", + A700: "#dd2c00", }; - export const deepPurple = { - 50: '#ede7f6', - 100: '#d1c4e9', - 200: '#b39ddb', - 300: '#9575cd', - 400: '#7e57c2', - 500: '#673ab7', - 600: '#5e35b1', - 700: '#512da8', - 800: '#4527a0', - 900: '#311b92', - A100: '#b388ff', - A200: '#7c4dff', - A400: '#651fff', - A700: '#6200ea', + 50: "#ede7f6", + 100: "#d1c4e9", + 200: "#b39ddb", + 300: "#9575cd", + 400: "#7e57c2", + 500: "#673ab7", + 600: "#5e35b1", + 700: "#512da8", + 800: "#4527a0", + 900: "#311b92", + A100: "#b388ff", + A200: "#7c4dff", + A400: "#651fff", + A700: "#6200ea", }; - export const green = { - 50: '#e8f5e9', - 100: '#c8e6c9', - 200: '#a5d6a7', - 300: '#81c784', - 400: '#66bb6a', - 500: '#4caf50', - 600: '#43a047', - 700: '#388e3c', - 800: '#2e7d32', - 900: '#1b5e20', - A100: '#b9f6ca', - A200: '#69f0ae', - A400: '#00e676', - A700: '#00c853', + 50: "#e8f5e9", + 100: "#c8e6c9", + 200: "#a5d6a7", + 300: "#81c784", + 400: "#66bb6a", + 500: "#4caf50", + 600: "#43a047", + 700: "#388e3c", + 800: "#2e7d32", + 900: "#1b5e20", + A100: "#b9f6ca", + A200: "#69f0ae", + A400: "#00e676", + A700: "#00c853", }; - export const grey = { - 50: '#fafafa', - 100: '#f5f5f5', - 200: '#eeeeee', - 300: '#e0e0e0', - 400: '#bdbdbd', - 500: '#9e9e9e', - 600: '#757575', - 700: '#616161', - 800: '#424242', - 900: '#212121', - A100: '#f5f5f5', - A200: '#eeeeee', - A400: '#bdbdbd', - A700: '#616161', + 50: "#fafafa", + 100: "#f5f5f5", + 200: "#eeeeee", + 300: "#e0e0e0", + 400: "#bdbdbd", + 500: "#9e9e9e", + 600: "#757575", + 700: "#616161", + 800: "#424242", + 900: "#212121", + A100: "#f5f5f5", + A200: "#eeeeee", + A400: "#bdbdbd", + A700: "#616161", }; - export const indigo = { - 50: '#e8eaf6', - 100: '#c5cae9', - 200: '#9fa8da', - 300: '#7986cb', - 400: '#5c6bc0', - 500: '#3f51b5', - 600: '#3949ab', - 700: '#303f9f', - 800: '#283593', - 900: '#1a237e', - A100: '#8c9eff', - A200: '#536dfe', - A400: '#3d5afe', - A700: '#304ffe', + 50: "#e8eaf6", + 100: "#c5cae9", + 200: "#9fa8da", + 300: "#7986cb", + 400: "#5c6bc0", + 500: "#3f51b5", + 600: "#3949ab", + 700: "#303f9f", + 800: "#283593", + 900: "#1a237e", + A100: "#8c9eff", + A200: "#536dfe", + A400: "#3d5afe", + A700: "#304ffe", }; - export const lightBlue = { - 50: '#e1f5fe', - 100: '#b3e5fc', - 200: '#81d4fa', - 300: '#4fc3f7', - 400: '#29b6f6', - 500: '#03a9f4', - 600: '#039be5', - 700: '#0288d1', - 800: '#0277bd', - 900: '#01579b', - A100: '#80d8ff', - A200: '#40c4ff', - A400: '#00b0ff', - A700: '#0091ea', + 50: "#e1f5fe", + 100: "#b3e5fc", + 200: "#81d4fa", + 300: "#4fc3f7", + 400: "#29b6f6", + 500: "#03a9f4", + 600: "#039be5", + 700: "#0288d1", + 800: "#0277bd", + 900: "#01579b", + A100: "#80d8ff", + A200: "#40c4ff", + A400: "#00b0ff", + A700: "#0091ea", }; - export const lightGreen = { - 50: '#f1f8e9', - 100: '#dcedc8', - 200: '#c5e1a5', - 300: '#aed581', - 400: '#9ccc65', - 500: '#8bc34a', - 600: '#7cb342', - 700: '#689f38', - 800: '#558b2f', - 900: '#33691e', - A100: '#ccff90', - A200: '#b2ff59', - A400: '#76ff03', - A700: '#64dd17', + 50: "#f1f8e9", + 100: "#dcedc8", + 200: "#c5e1a5", + 300: "#aed581", + 400: "#9ccc65", + 500: "#8bc34a", + 600: "#7cb342", + 700: "#689f38", + 800: "#558b2f", + 900: "#33691e", + A100: "#ccff90", + A200: "#b2ff59", + A400: "#76ff03", + A700: "#64dd17", }; - export const lime = { - 50: '#f9fbe7', - 100: '#f0f4c3', - 200: '#e6ee9c', - 300: '#dce775', - 400: '#d4e157', - 500: '#cddc39', - 600: '#c0ca33', - 700: '#afb42b', - 800: '#9e9d24', - 900: '#827717', - A100: '#f4ff81', - A200: '#eeff41', - A400: '#c6ff00', - A700: '#aeea00', + 50: "#f9fbe7", + 100: "#f0f4c3", + 200: "#e6ee9c", + 300: "#dce775", + 400: "#d4e157", + 500: "#cddc39", + 600: "#c0ca33", + 700: "#afb42b", + 800: "#9e9d24", + 900: "#827717", + A100: "#f4ff81", + A200: "#eeff41", + A400: "#c6ff00", + A700: "#aeea00", }; - export const orange = { - 50: '#fff3e0', - 100: '#ffe0b2', - 200: '#ffcc80', - 300: '#ffb74d', - 400: '#ffa726', - 500: '#ff9800', - 600: '#fb8c00', - 700: '#f57c00', - 800: '#ef6c00', - 900: '#e65100', - A100: '#ffd180', - A200: '#ffab40', - A400: '#ff9100', - A700: '#ff6d00', + 50: "#fff3e0", + 100: "#ffe0b2", + 200: "#ffcc80", + 300: "#ffb74d", + 400: "#ffa726", + 500: "#ff9800", + 600: "#fb8c00", + 700: "#f57c00", + 800: "#ef6c00", + 900: "#e65100", + A100: "#ffd180", + A200: "#ffab40", + A400: "#ff9100", + A700: "#ff6d00", }; - export const pink = { - 50: '#fce4ec', - 100: '#f8bbd0', - 200: '#f48fb1', - 300: '#f06292', - 400: '#ec407a', - 500: '#e91e63', - 600: '#d81b60', - 700: '#c2185b', - 800: '#ad1457', - 900: '#880e4f', - A100: '#ff80ab', - A200: '#ff4081', - A400: '#f50057', - A700: '#c51162', + 50: "#fce4ec", + 100: "#f8bbd0", + 200: "#f48fb1", + 300: "#f06292", + 400: "#ec407a", + 500: "#e91e63", + 600: "#d81b60", + 700: "#c2185b", + 800: "#ad1457", + 900: "#880e4f", + A100: "#ff80ab", + A200: "#ff4081", + A400: "#f50057", + A700: "#c51162", }; - export const purple = { - 50: '#f3e5f5', - 100: '#e1bee7', - 200: '#ce93d8', - 300: '#ba68c8', - 400: '#ab47bc', - 500: '#9c27b0', - 600: '#8e24aa', - 700: '#7b1fa2', - 800: '#6a1b9a', - 900: '#4a148c', - A100: '#ea80fc', - A200: '#e040fb', - A400: '#d500f9', - A700: '#aa00ff', + 50: "#f3e5f5", + 100: "#e1bee7", + 200: "#ce93d8", + 300: "#ba68c8", + 400: "#ab47bc", + 500: "#9c27b0", + 600: "#8e24aa", + 700: "#7b1fa2", + 800: "#6a1b9a", + 900: "#4a148c", + A100: "#ea80fc", + A200: "#e040fb", + A400: "#d500f9", + A700: "#aa00ff", }; - export const red = { - 50: '#ffebee', - 100: '#ffcdd2', - 200: '#ef9a9a', - 300: '#e57373', - 400: '#ef5350', - 500: '#f44336', - 600: '#e53935', - 700: '#d32f2f', - 800: '#c62828', - 900: '#b71c1c', - A100: '#ff8a80', - A200: '#ff5252', - A400: '#ff1744', - A700: '#d50000', + 50: "#ffebee", + 100: "#ffcdd2", + 200: "#ef9a9a", + 300: "#e57373", + 400: "#ef5350", + 500: "#f44336", + 600: "#e53935", + 700: "#d32f2f", + 800: "#c62828", + 900: "#b71c1c", + A100: "#ff8a80", + A200: "#ff5252", + A400: "#ff1744", + A700: "#d50000", }; - export const teal = { - 50: '#e0f2f1', - 100: '#b2dfdb', - 200: '#80cbc4', - 300: '#4db6ac', - 400: '#26a69a', - 500: '#009688', - 600: '#00897b', - 700: '#00796b', - 800: '#00695c', - 900: '#004d40', - A100: '#a7ffeb', - A200: '#64ffda', - A400: '#1de9b6', - A700: '#00bfa5', + 50: "#e0f2f1", + 100: "#b2dfdb", + 200: "#80cbc4", + 300: "#4db6ac", + 400: "#26a69a", + 500: "#009688", + 600: "#00897b", + 700: "#00796b", + 800: "#00695c", + 900: "#004d40", + A100: "#a7ffeb", + A200: "#64ffda", + A400: "#1de9b6", + A700: "#00bfa5", }; - export const yellow = { - 50: '#fffde7', - 100: '#fff9c4', - 200: '#fff59d', - 300: '#fff176', - 400: '#ffee58', - 500: '#ffeb3b', - 600: '#fdd835', - 700: '#fbc02d', - 800: '#f9a825', - 900: '#f57f17', - A100: '#ffff8d', - A200: '#ffff00', - A400: '#ffea00', - A700: '#ffd600', + 50: "#fffde7", + 100: "#fff9c4", + 200: "#fff59d", + 300: "#fff176", + 400: "#ffee58", + 500: "#ffeb3b", + 600: "#fdd835", + 700: "#fbc02d", + 800: "#f9a825", + 900: "#f57f17", + A100: "#ffff8d", + A200: "#ffff00", + A400: "#ffea00", + A700: "#ffd600", }; - - diff --git a/packages/taler-wallet-webextension/src/mui/colors/manipulation.test.ts b/packages/taler-wallet-webextension/src/mui/colors/manipulation.test.ts index 192e9f402..5f551eedd 100644 --- a/packages/taler-wallet-webextension/src/mui/colors/manipulation.test.ts +++ b/packages/taler-wallet-webextension/src/mui/colors/manipulation.test.ts @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { expect } from "chai"; import { recomposeColor, hexToRgb, @@ -11,295 +11,308 @@ import { getContrastRatio, getLuminance, lighten, -} from './manipulation.js'; +} from "./manipulation.js"; -describe('utils/colorManipulator', () => { - describe('recomposeColor', () => { - it('converts a decomposed rgb color object to a string` ', () => { +describe("utils/colorManipulator", () => { + describe("recomposeColor", () => { + it("converts a decomposed rgb color object to a string` ", () => { expect( recomposeColor({ - type: 'rgb', + type: "rgb", values: [255, 255, 255], }), - ).to.equal('rgb(255, 255, 255)'); + ).to.equal("rgb(255, 255, 255)"); }); - it('converts a decomposed rgba color object to a string` ', () => { + it("converts a decomposed rgba color object to a string` ", () => { expect( recomposeColor({ - type: 'rgba', + type: "rgba", values: [255, 255, 255, 0.5], }), - ).to.equal('rgba(255, 255, 255, 0.5)'); + ).to.equal("rgba(255, 255, 255, 0.5)"); }); - it('converts a decomposed hsl color object to a string` ', () => { + it("converts a decomposed hsl color object to a string` ", () => { expect( recomposeColor({ - type: 'hsl', + type: "hsl", values: [100, 50, 25], }), - ).to.equal('hsl(100, 50%, 25%)'); + ).to.equal("hsl(100, 50%, 25%)"); }); - it('converts a decomposed hsla color object to a string` ', () => { + it("converts a decomposed hsla color object to a string` ", () => { expect( recomposeColor({ - type: 'hsla', + type: "hsla", values: [100, 50, 25, 0.5], }), - ).to.equal('hsla(100, 50%, 25%, 0.5)'); + ).to.equal("hsla(100, 50%, 25%, 0.5)"); }); }); - describe('hexToRgb', () => { - it('converts a short hex color to an rgb color` ', () => { - expect(hexToRgb('#9f3')).to.equal('rgb(153, 255, 51)'); + describe("hexToRgb", () => { + it("converts a short hex color to an rgb color` ", () => { + expect(hexToRgb("#9f3")).to.equal("rgb(153, 255, 51)"); }); - it('converts a long hex color to an rgb color` ', () => { - expect(hexToRgb('#a94fd3')).to.equal('rgb(169, 79, 211)'); + it("converts a long hex color to an rgb color` ", () => { + expect(hexToRgb("#a94fd3")).to.equal("rgb(169, 79, 211)"); }); - it('converts a long alpha hex color to an argb color` ', () => { - expect(hexToRgb('#111111f8')).to.equal('rgba(17, 17, 17, 0.973)'); + it("converts a long alpha hex color to an argb color` ", () => { + expect(hexToRgb("#111111f8")).to.equal("rgba(17, 17, 17, 0.973)"); }); }); - describe('rgbToHex', () => { - it('converts an rgb color to a hex color` ', () => { - expect(rgbToHex('rgb(169, 79, 211)')).to.equal('#a94fd3'); + describe("rgbToHex", () => { + it("converts an rgb color to a hex color` ", () => { + expect(rgbToHex("rgb(169, 79, 211)")).to.equal("#a94fd3"); }); - it('converts an rgba color to a hex color` ', () => { - expect(rgbToHex('rgba(169, 79, 211, 1)')).to.equal('#a94fd3ff'); + it("converts an rgba color to a hex color` ", () => { + expect(rgbToHex("rgba(169, 79, 211, 1)")).to.equal("#a94fd3ff"); }); - it('idempotent', () => { - expect(rgbToHex('#A94FD3')).to.equal('#A94FD3'); + it("idempotent", () => { + expect(rgbToHex("#A94FD3")).to.equal("#A94FD3"); }); }); - describe('hslToRgb', () => { - it('converts an hsl color to an rgb color` ', () => { - expect(hslToRgb('hsl(281, 60%, 57%)')).to.equal('rgb(169, 80, 211)'); + describe("hslToRgb", () => { + it("converts an hsl color to an rgb color` ", () => { + expect(hslToRgb("hsl(281, 60%, 57%)")).to.equal("rgb(169, 80, 211)"); }); - it('converts an hsla color to an rgba color` ', () => { - expect(hslToRgb('hsla(281, 60%, 57%, 0.5)')).to.equal('rgba(169, 80, 211, 0.5)'); + it("converts an hsla color to an rgba color` ", () => { + expect(hslToRgb("hsla(281, 60%, 57%, 0.5)")).to.equal( + "rgba(169, 80, 211, 0.5)", + ); }); - it('allow to convert values only', () => { - expect(hslToRgb('hsl(281, 60%, 57%)')).to.equal('rgb(169, 80, 211)'); + it("allow to convert values only", () => { + expect(hslToRgb("hsl(281, 60%, 57%)")).to.equal("rgb(169, 80, 211)"); }); }); - describe('decomposeColor', () => { - it('converts an rgb color string to an object with `type` and `value` keys', () => { - const { type, values } = decomposeColor('rgb(255, 255, 255)'); - expect(type).to.equal('rgb'); + describe("decomposeColor", () => { + it("converts an rgb color string to an object with `type` and `value` keys", () => { + const { type, values } = decomposeColor("rgb(255, 255, 255)"); + expect(type).to.equal("rgb"); expect(values).to.deep.equal([255, 255, 255]); }); - it('converts an rgba color string to an object with `type` and `value` keys', () => { - const { type, values } = decomposeColor('rgba(255, 255, 255, 0.5)'); - expect(type).to.equal('rgba'); + it("converts an rgba color string to an object with `type` and `value` keys", () => { + const { type, values } = decomposeColor("rgba(255, 255, 255, 0.5)"); + expect(type).to.equal("rgba"); expect(values).to.deep.equal([255, 255, 255, 0.5]); }); - it('converts an hsl color string to an object with `type` and `value` keys', () => { - const { type, values } = decomposeColor('hsl(100, 50%, 25%)'); - expect(type).to.equal('hsl'); + it("converts an hsl color string to an object with `type` and `value` keys", () => { + const { type, values } = decomposeColor("hsl(100, 50%, 25%)"); + expect(type).to.equal("hsl"); expect(values).to.deep.equal([100, 50, 25]); }); - it('converts an hsla color string to an object with `type` and `value` keys', () => { - const { type, values } = decomposeColor('hsla(100, 50%, 25%, 0.5)'); - expect(type).to.equal('hsla'); + it("converts an hsla color string to an object with `type` and `value` keys", () => { + const { type, values } = decomposeColor("hsla(100, 50%, 25%, 0.5)"); + expect(type).to.equal("hsla"); expect(values).to.deep.equal([100, 50, 25, 0.5]); }); - it('converts rgba hex', () => { - const decomposed = decomposeColor('#111111f8'); + it("converts rgba hex", () => { + const decomposed = decomposeColor("#111111f8"); expect(decomposed).to.deep.equal({ - type: 'rgba', + type: "rgba", colorSpace: undefined, values: [17, 17, 17, 0.973], }); }); }); - describe('getContrastRatio', () => { - it('returns a ratio for black : white', () => { - expect(getContrastRatio('#000', '#FFF')).to.equal(21); + describe("getContrastRatio", () => { + it("returns a ratio for black : white", () => { + expect(getContrastRatio("#000", "#FFF")).to.equal(21); }); - it('returns a ratio for black : black', () => { - expect(getContrastRatio('#000', '#000')).to.equal(1); + it("returns a ratio for black : black", () => { + expect(getContrastRatio("#000", "#000")).to.equal(1); }); - it('returns a ratio for white : white', () => { - expect(getContrastRatio('#FFF', '#FFF')).to.equal(1); + it("returns a ratio for white : white", () => { + expect(getContrastRatio("#FFF", "#FFF")).to.equal(1); }); - it('returns a ratio for dark-grey : light-grey', () => { - expect(getContrastRatio('#707070', '#E5E5E5')).to.be.approximately(3.93, 0.01); + it("returns a ratio for dark-grey : light-grey", () => { + expect(getContrastRatio("#707070", "#E5E5E5")).to.be.approximately( + 3.93, + 0.01, + ); }); - it('returns a ratio for black : light-grey', () => { - expect(getContrastRatio('#000', '#888')).to.be.approximately(5.92, 0.01); + it("returns a ratio for black : light-grey", () => { + expect(getContrastRatio("#000", "#888")).to.be.approximately(5.92, 0.01); }); }); - describe('getLuminance', () => { - - it('returns a valid luminance for rgb white ', () => { - expect(getLuminance('rgba(255, 255, 255)')).to.equal(1); - expect(getLuminance('rgb(255, 255, 255)')).to.equal(1); + describe("getLuminance", () => { + it("returns a valid luminance for rgb white ", () => { + expect(getLuminance("rgba(255, 255, 255)")).to.equal(1); + expect(getLuminance("rgb(255, 255, 255)")).to.equal(1); }); - it('returns a valid luminance for rgb mid-grey', () => { - expect(getLuminance('rgba(127, 127, 127)')).to.equal(0.212); - expect(getLuminance('rgb(127, 127, 127)')).to.equal(0.212); + it("returns a valid luminance for rgb mid-grey", () => { + expect(getLuminance("rgba(127, 127, 127)")).to.equal(0.212); + expect(getLuminance("rgb(127, 127, 127)")).to.equal(0.212); }); - it('returns a valid luminance for an rgb color', () => { - expect(getLuminance('rgb(255, 127, 0)')).to.equal(0.364); + it("returns a valid luminance for an rgb color", () => { + expect(getLuminance("rgb(255, 127, 0)")).to.equal(0.364); }); - it('returns a valid luminance from an hsl color', () => { - expect(getLuminance('hsl(100, 100%, 50%)')).to.equal(0.735); + it("returns a valid luminance from an hsl color", () => { + expect(getLuminance("hsl(100, 100%, 50%)")).to.equal(0.735); }); - it('returns an equal luminance for the same color in different formats', () => { - const hsl = 'hsl(100, 100%, 50%)'; - const rgb = 'rgb(85, 255, 0)'; + it("returns an equal luminance for the same color in different formats", () => { + const hsl = "hsl(100, 100%, 50%)"; + const rgb = "rgb(85, 255, 0)"; expect(getLuminance(hsl)).to.equal(getLuminance(rgb)); }); - }); - describe('emphasize', () => { - it('lightens a dark rgb color with the coefficient provided', () => { - expect(emphasize('rgb(1, 2, 3)', 0.4)).to.equal(lighten('rgb(1, 2, 3)', 0.4)); + describe("emphasize", () => { + it("lightens a dark rgb color with the coefficient provided", () => { + expect(emphasize("rgb(1, 2, 3)", 0.4)).to.equal( + lighten("rgb(1, 2, 3)", 0.4), + ); }); - it('darkens a light rgb color with the coefficient provided', () => { - expect(emphasize('rgb(250, 240, 230)', 0.3)).to.equal(darken('rgb(250, 240, 230)', 0.3)); + it("darkens a light rgb color with the coefficient provided", () => { + expect(emphasize("rgb(250, 240, 230)", 0.3)).to.equal( + darken("rgb(250, 240, 230)", 0.3), + ); }); - it('lightens a dark rgb color with the coefficient 0.15 by default', () => { - expect(emphasize('rgb(1, 2, 3)')).to.equal(lighten('rgb(1, 2, 3)', 0.15)); + it("lightens a dark rgb color with the coefficient 0.15 by default", () => { + expect(emphasize("rgb(1, 2, 3)")).to.equal(lighten("rgb(1, 2, 3)", 0.15)); }); - it('darkens a light rgb color with the coefficient 0.15 by default', () => { - expect(emphasize('rgb(250, 240, 230)')).to.equal(darken('rgb(250, 240, 230)', 0.15)); + it("darkens a light rgb color with the coefficient 0.15 by default", () => { + expect(emphasize("rgb(250, 240, 230)")).to.equal( + darken("rgb(250, 240, 230)", 0.15), + ); }); - }); - describe('alpha', () => { - it('converts an rgb color to an rgba color with the value provided', () => { - expect(alpha('rgb(1, 2, 3)', 0.4)).to.equal('rgba(1, 2, 3, 0.4)'); + describe("alpha", () => { + it("converts an rgb color to an rgba color with the value provided", () => { + expect(alpha("rgb(1, 2, 3)", 0.4)).to.equal("rgba(1, 2, 3, 0.4)"); }); - it('updates an rgba color with the alpha value provided', () => { - expect(alpha('rgba(255, 0, 0, 0.2)', 0.5)).to.equal('rgba(255, 0, 0, 0.5)'); + it("updates an rgba color with the alpha value provided", () => { + expect(alpha("rgba(255, 0, 0, 0.2)", 0.5)).to.equal( + "rgba(255, 0, 0, 0.5)", + ); }); - it('converts an hsl color to an hsla color with the value provided', () => { - expect(alpha('hsl(0, 100%, 50%)', 0.1)).to.equal('hsla(0, 100%, 50%, 0.1)'); + it("converts an hsl color to an hsla color with the value provided", () => { + expect(alpha("hsl(0, 100%, 50%)", 0.1)).to.equal( + "hsla(0, 100%, 50%, 0.1)", + ); }); - it('updates an hsla color with the alpha value provided', () => { - expect(alpha('hsla(0, 100%, 50%, 0.2)', 0.5)).to.equal('hsla(0, 100%, 50%, 0.5)'); + it("updates an hsla color with the alpha value provided", () => { + expect(alpha("hsla(0, 100%, 50%, 0.2)", 0.5)).to.equal( + "hsla(0, 100%, 50%, 0.5)", + ); }); - }); - describe('darken', () => { + describe("darken", () => { it("doesn't modify rgb black", () => { - expect(darken('rgb(0, 0, 0)', 0.1)).to.equal('rgb(0, 0, 0)'); + expect(darken("rgb(0, 0, 0)", 0.1)).to.equal("rgb(0, 0, 0)"); }); - it('darkens rgb white to black when coefficient is 1', () => { - expect(darken('rgb(255, 255, 255)', 1)).to.equal('rgb(0, 0, 0)'); + it("darkens rgb white to black when coefficient is 1", () => { + expect(darken("rgb(255, 255, 255)", 1)).to.equal("rgb(0, 0, 0)"); }); - it('retains the alpha value in an rgba color', () => { - expect(darken('rgba(0, 0, 0, 0.5)', 0.1)).to.equal('rgba(0, 0, 0, 0.5)'); + it("retains the alpha value in an rgba color", () => { + expect(darken("rgba(0, 0, 0, 0.5)", 0.1)).to.equal("rgba(0, 0, 0, 0.5)"); }); - it('darkens rgb white by 10% when coefficient is 0.1', () => { - expect(darken('rgb(255, 255, 255)', 0.1)).to.equal('rgb(229, 229, 229)'); + it("darkens rgb white by 10% when coefficient is 0.1", () => { + expect(darken("rgb(255, 255, 255)", 0.1)).to.equal("rgb(229, 229, 229)"); }); - it('darkens rgb red by 50% when coefficient is 0.5', () => { - expect(darken('rgb(255, 0, 0)', 0.5)).to.equal('rgb(127, 0, 0)'); + it("darkens rgb red by 50% when coefficient is 0.5", () => { + expect(darken("rgb(255, 0, 0)", 0.5)).to.equal("rgb(127, 0, 0)"); }); - it('darkens rgb grey by 50% when coefficient is 0.5', () => { - expect(darken('rgb(127, 127, 127)', 0.5)).to.equal('rgb(63, 63, 63)'); + it("darkens rgb grey by 50% when coefficient is 0.5", () => { + expect(darken("rgb(127, 127, 127)", 0.5)).to.equal("rgb(63, 63, 63)"); }); it("doesn't modify rgb colors when coefficient is 0", () => { - expect(darken('rgb(255, 255, 255)', 0)).to.equal('rgb(255, 255, 255)'); + expect(darken("rgb(255, 255, 255)", 0)).to.equal("rgb(255, 255, 255)"); }); - it('darkens hsl red by 50% when coefficient is 0.5', () => { - expect(darken('hsl(0, 100%, 50%)', 0.5)).to.equal('hsl(0, 100%, 25%)'); + it("darkens hsl red by 50% when coefficient is 0.5", () => { + expect(darken("hsl(0, 100%, 50%)", 0.5)).to.equal("hsl(0, 100%, 25%)"); }); it("doesn't modify hsl colors when coefficient is 0", () => { - expect(darken('hsl(0, 100%, 50%)', 0)).to.equal('hsl(0, 100%, 50%)'); + expect(darken("hsl(0, 100%, 50%)", 0)).to.equal("hsl(0, 100%, 50%)"); }); it("doesn't modify hsl colors when l is 0%", () => { - expect(darken('hsl(0, 50%, 0%)', 0.5)).to.equal('hsl(0, 50%, 0%)'); + expect(darken("hsl(0, 50%, 0%)", 0.5)).to.equal("hsl(0, 50%, 0%)"); }); - }); - describe('lighten', () => { + describe("lighten", () => { it("doesn't modify rgb white", () => { - expect(lighten('rgb(255, 255, 255)', 0.1)).to.equal('rgb(255, 255, 255)'); + expect(lighten("rgb(255, 255, 255)", 0.1)).to.equal("rgb(255, 255, 255)"); }); - it('lightens rgb black to white when coefficient is 1', () => { - expect(lighten('rgb(0, 0, 0)', 1)).to.equal('rgb(255, 255, 255)'); + it("lightens rgb black to white when coefficient is 1", () => { + expect(lighten("rgb(0, 0, 0)", 1)).to.equal("rgb(255, 255, 255)"); }); - it('retains the alpha value in an rgba color', () => { - expect(lighten('rgba(255, 255, 255, 0.5)', 0.1)).to.equal('rgba(255, 255, 255, 0.5)'); + it("retains the alpha value in an rgba color", () => { + expect(lighten("rgba(255, 255, 255, 0.5)", 0.1)).to.equal( + "rgba(255, 255, 255, 0.5)", + ); }); - it('lightens rgb black by 10% when coefficient is 0.1', () => { - expect(lighten('rgb(0, 0, 0)', 0.1)).to.equal('rgb(25, 25, 25)'); + it("lightens rgb black by 10% when coefficient is 0.1", () => { + expect(lighten("rgb(0, 0, 0)", 0.1)).to.equal("rgb(25, 25, 25)"); }); - it('lightens rgb red by 50% when coefficient is 0.5', () => { - expect(lighten('rgb(255, 0, 0)', 0.5)).to.equal('rgb(255, 127, 127)'); + it("lightens rgb red by 50% when coefficient is 0.5", () => { + expect(lighten("rgb(255, 0, 0)", 0.5)).to.equal("rgb(255, 127, 127)"); }); - it('lightens rgb grey by 50% when coefficient is 0.5', () => { - expect(lighten('rgb(127, 127, 127)', 0.5)).to.equal('rgb(191, 191, 191)'); + it("lightens rgb grey by 50% when coefficient is 0.5", () => { + expect(lighten("rgb(127, 127, 127)", 0.5)).to.equal("rgb(191, 191, 191)"); }); it("doesn't modify rgb colors when coefficient is 0", () => { - expect(lighten('rgb(127, 127, 127)', 0)).to.equal('rgb(127, 127, 127)'); + expect(lighten("rgb(127, 127, 127)", 0)).to.equal("rgb(127, 127, 127)"); }); - it('lightens hsl red by 50% when coefficient is 0.5', () => { - expect(lighten('hsl(0, 100%, 50%)', 0.5)).to.equal('hsl(0, 100%, 75%)'); + it("lightens hsl red by 50% when coefficient is 0.5", () => { + expect(lighten("hsl(0, 100%, 50%)", 0.5)).to.equal("hsl(0, 100%, 75%)"); }); it("doesn't modify hsl colors when coefficient is 0", () => { - expect(lighten('hsl(0, 100%, 50%)', 0)).to.equal('hsl(0, 100%, 50%)'); + expect(lighten("hsl(0, 100%, 50%)", 0)).to.equal("hsl(0, 100%, 50%)"); }); it("doesn't modify hsl colors when `l` is 100%", () => { - expect(lighten('hsl(0, 50%, 100%)', 0.5)).to.equal('hsl(0, 50%, 100%)'); + expect(lighten("hsl(0, 50%, 100%)", 0.5)).to.equal("hsl(0, 50%, 100%)"); }); - }); }); diff --git a/packages/taler-wallet-webextension/src/mui/colors/manipulation.ts b/packages/taler-wallet-webextension/src/mui/colors/manipulation.ts index d1181b6d6..c7ec6e684 100644 --- a/packages/taler-wallet-webextension/src/mui/colors/manipulation.ts +++ b/packages/taler-wallet-webextension/src/mui/colors/manipulation.ts @@ -1,20 +1,18 @@ - -export type ColorFormat = ColorFormatWithAlpha | ColorFormatWithoutAlpha -export type ColorFormatWithAlpha = 'rgb' | 'hsl'; -export type ColorFormatWithoutAlpha = 'rgba' | 'hsla'; -export type ColorObject = ColorObjectWithAlpha | ColorObjectWithoutAlpha +export type ColorFormat = ColorFormatWithAlpha | ColorFormatWithoutAlpha; +export type ColorFormatWithAlpha = "rgb" | "hsl"; +export type ColorFormatWithoutAlpha = "rgba" | "hsla"; +export type ColorObject = ColorObjectWithAlpha | ColorObjectWithoutAlpha; export interface ColorObjectWithAlpha { type: ColorFormatWithAlpha; values: [number, number, number]; - colorSpace?: 'srgb' | 'display-p3' | 'a98-rgb' | 'prophoto-rgb' | 'rec-2020'; + colorSpace?: "srgb" | "display-p3" | "a98-rgb" | "prophoto-rgb" | "rec-2020"; } export interface ColorObjectWithoutAlpha { type: ColorFormatWithoutAlpha; values: [number, number, number, number]; - colorSpace?: 'srgb' | 'display-p3' | 'a98-rgb' | 'prophoto-rgb' | 'rec-2020'; + colorSpace?: "srgb" | "display-p3" | "a98-rgb" | "prophoto-rgb" | "rec-2020"; } - /** * Returns a number whose value is limited to the given range. * @param {number} value The value to be clamped @@ -40,7 +38,7 @@ function clamp(value: number, min = 0, max = 1): number { export function hexToRgb(color: string): string { color = color.substr(1); - const re = new RegExp(`.{1,${color.length >= 6 ? 2 : 1}}`, 'g'); + const re = new RegExp(`.{1,${color.length >= 6 ? 2 : 1}}`, "g"); let colors = color.match(re); if (colors && colors[0].length === 1) { @@ -48,12 +46,14 @@ export function hexToRgb(color: string): string { } return colors - ? `rgb${colors.length === 4 ? 'a' : ''}(${colors - .map((n, index) => { - return index < 3 ? parseInt(n, 16) : Math.round((parseInt(n, 16) / 255) * 1000) / 1000; - }) - .join(', ')})` - : ''; + ? `rgb${colors.length === 4 ? "a" : ""}(${colors + .map((n, index) => { + return index < 3 + ? parseInt(n, 16) + : Math.round((parseInt(n, 16) / 255) * 1000) / 1000; + }) + .join(", ")})` + : ""; } function intToHex(int: number): string { @@ -70,23 +70,42 @@ function intToHex(int: number): string { */ export function decomposeColor(color: string): ColorObject { const colorSpace = undefined; - if (color.charAt(0) === '#') { + if (color.charAt(0) === "#") { return decomposeColor(hexToRgb(color)); } - const marker = color.indexOf('('); + const marker = color.indexOf("("); const type = color.substring(0, marker); // if (type != 'rgba' && type != 'hsla' && type != 'rgb' && type != 'hsl') { // } - const values = color.substring(marker + 1, color.length - 1).split(',') - if (type == 'rgb' || type == 'hsl') { - return { type, colorSpace, values: [parseFloat(values[0]), parseFloat(values[1]), parseFloat(values[2])] } + const values = color.substring(marker + 1, color.length - 1).split(","); + if (type == "rgb" || type == "hsl") { + return { + type, + colorSpace, + values: [ + parseFloat(values[0]), + parseFloat(values[1]), + parseFloat(values[2]), + ], + }; } - if (type == 'rgba' || type == 'hsla') { - return { type, colorSpace, values: [parseFloat(values[0]), parseFloat(values[1]), parseFloat(values[2]), parseFloat(values[3])] } + if (type == "rgba" || type == "hsla") { + return { + type, + colorSpace, + values: [ + parseFloat(values[0]), + parseFloat(values[1]), + parseFloat(values[2]), + parseFloat(values[3]), + ], + }; } - throw new Error(`Unsupported '${color}' color. The following formats are supported: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()`) + throw new Error( + `Unsupported '${color}' color. The following formats are supported: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla()`, + ); } /** @@ -100,19 +119,21 @@ export function recomposeColor(color: ColorObject): string { const { type, values: valuesNum } = color; const valuesStr: string[] = []; - if (type.indexOf('rgb') !== -1) { + if (type.indexOf("rgb") !== -1) { // Only convert the first 3 values to int (i.e. not alpha) - valuesNum.map((n, i) => (i < 3 ? parseInt(String(n), 10) : n)).forEach((n, i) => valuesStr[i] = String(n)); - } else if (type.indexOf('hsl') !== -1) { - valuesStr[0] = String(valuesNum[0]) + valuesNum + .map((n, i) => (i < 3 ? parseInt(String(n), 10) : n)) + .forEach((n, i) => (valuesStr[i] = String(n))); + } else if (type.indexOf("hsl") !== -1) { + valuesStr[0] = String(valuesNum[0]); valuesStr[1] = `${valuesNum[1]}%`; valuesStr[2] = `${valuesNum[2]}%`; - if (type === 'hsla') { - valuesStr[3] = String(valuesNum[3]) + if (type === "hsla") { + valuesStr[3] = String(valuesNum[3]); } } - return `${type}(${valuesStr.join(', ')})`; + return `${type}(${valuesStr.join(", ")})`; } /** @@ -122,12 +143,14 @@ export function recomposeColor(color: ColorObject): string { */ export function rgbToHex(color: string): string { // Idempotent - if (color.indexOf('#') === 0) { + if (color.indexOf("#") === 0) { return color; } const { values } = decomposeColor(color); - return `#${values.map((n, i) => intToHex(i === 3 ? Math.round(255 * n) : n)).join('')}`; + return `#${values + .map((n, i) => intToHex(i === 3 ? Math.round(255 * n) : n)) + .join("")}`; } /** @@ -142,24 +165,28 @@ export function hslToRgb(color: string): string { const s = values[1] / 100; const l = values[2] / 100; const a = s * Math.min(l, 1 - l); - const f = (n: number, k = (n + h / 30) % 12): number => l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1); + const f = (n: number, k = (n + h / 30) % 12): number => + l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1); - if (colorObj.type === 'hsla') { + if (colorObj.type === "hsla") { return recomposeColor({ - type: 'rgba', values: [ + type: "rgba", + values: [ Math.round(f(0) * 255), Math.round(f(8) * 255), Math.round(f(4) * 255), - colorObj.values[3] - ] - }) + colorObj.values[3], + ], + }); } return recomposeColor({ - type: 'rgb', values: [ + type: "rgb", + values: [ Math.round(f(0) * 255), Math.round(f(8) * 255), - Math.round(f(4) * 255)] + Math.round(f(4) * 255), + ], }); } /** @@ -173,14 +200,19 @@ export function hslToRgb(color: string): string { export function getLuminance(color: string): number { const colorObj = decomposeColor(color); - const rgb2 = colorObj.type === 'hsl' ? decomposeColor(hslToRgb(color)).values : colorObj.values; + const rgb2 = + colorObj.type === "hsl" + ? decomposeColor(hslToRgb(color)).values + : colorObj.values; const rgb = rgb2.map((val) => { val /= 255; // normalized return val <= 0.03928 ? val / 12.92 : ((val + 0.055) / 1.055) ** 2.4; }) as typeof rgb2; // Truncate at 3 digits - return Number((0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2]).toFixed(3)); + return Number( + (0.2126 * rgb[0] + 0.7152 * rgb[1] + 0.0722 * rgb[2]).toFixed(3), + ); } /** @@ -191,7 +223,10 @@ export function getLuminance(color: string): number { * @param {string} background - CSS color, i.e. one of: #nnn, #nnnnnn, rgb(), rgba(), hsl(), hsla() * @returns {number} A contrast ratio value in the range 0 - 21. */ -export function getContrastRatio(foreground: string, background: string): number { +export function getContrastRatio( + foreground: string, + background: string, +): number { const lumA = getLuminance(foreground); const lumB = getLuminance(background); return (Math.max(lumA, lumB) + 0.05) / (Math.min(lumA, lumB) + 0.05); @@ -208,8 +243,8 @@ export function alpha(color: string, value: number): string { const colorObj = decomposeColor(color); value = clamp(value); - if (colorObj.type === 'rgb' || colorObj.type === 'hsl') { - colorObj.type += 'a'; + if (colorObj.type === "rgb" || colorObj.type === "hsl") { + colorObj.type += "a"; } colorObj.values[3] = value; @@ -226,9 +261,12 @@ export function darken(color: string, coefficient: number): string { const colorObj = decomposeColor(color); coefficient = clamp(coefficient); - if (colorObj.type.indexOf('hsl') !== -1) { + if (colorObj.type.indexOf("hsl") !== -1) { colorObj.values[2] *= 1 - coefficient; - } else if (colorObj.type.indexOf('rgb') !== -1 || colorObj.type.indexOf('color') !== -1) { + } else if ( + colorObj.type.indexOf("rgb") !== -1 || + colorObj.type.indexOf("color") !== -1 + ) { for (let i = 0; i < 3; i += 1) { colorObj.values[i] *= 1 - coefficient; } @@ -246,13 +284,13 @@ export function lighten(color: string, coefficient: number): string { const colorObj = decomposeColor(color); coefficient = clamp(coefficient); - if (colorObj.type.indexOf('hsl') !== -1) { + if (colorObj.type.indexOf("hsl") !== -1) { colorObj.values[2] += (100 - colorObj.values[2]) * coefficient; - } else if (colorObj.type.indexOf('rgb') !== -1) { + } else if (colorObj.type.indexOf("rgb") !== -1) { for (let i = 0; i < 3; i += 1) { colorObj.values[i] += (255 - colorObj.values[i]) * coefficient; } - } else if (colorObj.type.indexOf('color') !== -1) { + } else if (colorObj.type.indexOf("color") !== -1) { for (let i = 0; i < 3; i += 1) { colorObj.values[i] += (1 - colorObj.values[i]) * coefficient; } @@ -269,5 +307,7 @@ export function lighten(color: string, coefficient: number): string { * @returns {string} A CSS color string. Hex input values are returned as rgb */ export function emphasize(color: string, coefficient = 0.15): string { - return getLuminance(color) > 0.5 ? darken(color, coefficient) : lighten(color, coefficient); + return getLuminance(color) > 0.5 + ? darken(color, coefficient) + : lighten(color, coefficient); } diff --git a/packages/taler-wallet-webextension/src/mui/handlers.ts b/packages/taler-wallet-webextension/src/mui/handlers.ts index 646bdcf17..0f8d873e3 100644 --- a/packages/taler-wallet-webextension/src/mui/handlers.ts +++ b/packages/taler-wallet-webextension/src/mui/handlers.ts @@ -23,4 +23,3 @@ export interface SelectFieldHandler { isDirty?: boolean; list: Record<string, string>; } - diff --git a/packages/taler-wallet-webextension/src/platform/api.ts b/packages/taler-wallet-webextension/src/platform/api.ts index 4713d5d00..e66185b95 100644 --- a/packages/taler-wallet-webextension/src/platform/api.ts +++ b/packages/taler-wallet-webextension/src/platform/api.ts @@ -22,12 +22,11 @@ export interface Permissions { */ permissions?: string[] | undefined; /** - * List of origin permissions. Anything listed here must be a subset of a - * host that appears in the optional_permissions list in the manifest. - * + * List of origin permissions. Anything listed here must be a subset of a + * host that appears in the optional_permissions list in the manifest. + * */ origins?: string[] | undefined; - } /** @@ -38,8 +37,9 @@ export interface CrossBrowserPermissionsApi { requestHostPermissions(): Promise<boolean>; removeHostPermissions(): Promise<boolean>; - addPermissionsListener(callback: (p: Permissions, lastError?: string) => void): void; - + addPermissionsListener( + callback: (p: Permissions, lastError?: string) => void, + ): void; } export type MessageFromBackend = { @@ -57,12 +57,12 @@ export interface WalletVersion { */ export interface PlatformAPI { /** - * Garantee that the + * Garantee that the */ keepAlive(cb: VoidFunction): void; /** * FIXME: should not be needed - * + * * check if the platform is firefox */ isFirefox(): boolean; @@ -74,46 +74,46 @@ export interface PlatformAPI { /** * Backend API - * + * * Register a callback to be called when the wallet is ready to start - * @param callback + * @param callback */ notifyWhenAppIsReady(callback: () => void): void; /** * Popup API - * + * * Used when an TalerURI is found and open up from the popup UI. * Closes the popup and open the URI into the wallet UI. - * - * @param talerUri + * + * @param talerUri */ openWalletURIFromPopup(talerUri: string): void; /** * Backend API - * + * * Open a page into the wallet UI - * @param page + * @param page */ openWalletPage(page: string): void; /** * Popup API - * + * * Open a page into the wallet UI and closed the popup - * @param page + * @param page */ openWalletPageFromPopup(page: string): void; /** * Backend API - * + * * When a tab has been detected to have a Taler action the background process * can use this function to redirect the tab to the wallet UI - * - * @param tabId - * @param page + * + * @param tabId + * @param page */ redirectTabToWalletPage(tabId: number, page: string): void; @@ -122,7 +122,6 @@ export interface PlatformAPI { */ getWalletVersion(): WalletVersion; - /** * Backend API */ @@ -134,7 +133,9 @@ export interface PlatformAPI { /** * Backend API */ - registerTalerHeaderListener(onHeader: (tabId: number, url: string) => void): void; + registerTalerHeaderListener( + onHeader: (tabId: number, url: string) => void, + ): void; /** * Frontend API */ @@ -146,49 +147,60 @@ export interface PlatformAPI { /** * Backend API - * - * Check if background process run as service worker. This is used from the + * + * Check if background process run as service worker. This is used from the * wallet use different http api and crypto worker. */ useServiceWorkerAsBackgroundProcess(): boolean; /** * Popup API - * + * * Read the current tab html and try to find any Taler URI or QR code present. - * + * * @return Taler URI if found */ findTalerUriInActiveTab(): Promise<string | undefined>; /** * Used from the frontend to send commands to the wallet - * - * @param operation - * @param payload - * + * + * @param operation + * @param payload + * * @return response from the backend */ - sendMessageToWalletBackground(operation: string, payload: any): Promise<CoreApiResponse>; + sendMessageToWalletBackground( + operation: string, + payload: any, + ): Promise<CoreApiResponse>; /** * Used from the frontend to receive notifications about new information - * @param listener - * @return function to unsubscribe the listener + * @param listener + * @return function to unsubscribe the listener */ - listenToWalletBackground(listener: (message: MessageFromBackend) => void): () => void; + listenToWalletBackground( + listener: (message: MessageFromBackend) => void, + ): () => void; /** * Use by the wallet backend to receive operations from frontend (popup & wallet) * and send a response back. - * - * @param onNewMessage + * + * @param onNewMessage */ - listenToAllChannels(onNewMessage: (message: any, sender: any, sendResponse: (r: CoreApiResponse) => void) => void): void; + listenToAllChannels( + onNewMessage: ( + message: any, + sender: any, + sendResponse: (r: CoreApiResponse) => void, + ) => void, + ): void; /** * Used by the wallet backend to send notification about new information - * @param message + * @param message */ sendMessageToAllChannels(message: MessageFromBackend): void; } diff --git a/packages/taler-wallet-webextension/src/platform/chrome.ts b/packages/taler-wallet-webextension/src/platform/chrome.ts index e097baaa1..9caf42a58 100644 --- a/packages/taler-wallet-webextension/src/platform/chrome.ts +++ b/packages/taler-wallet-webextension/src/platform/chrome.ts @@ -15,8 +15,18 @@ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { classifyTalerUri, CoreApiResponse, Logger, TalerUriType } from "@gnu-taler/taler-util"; -import { CrossBrowserPermissionsApi, MessageFromBackend, Permissions, PlatformAPI } from "./api.js"; +import { + classifyTalerUri, + CoreApiResponse, + Logger, + TalerUriType, +} from "@gnu-taler/taler-util"; +import { + CrossBrowserPermissionsApi, + MessageFromBackend, + Permissions, + PlatformAPI, +} from "./api.js"; const api: PlatformAPI = { isFirefox, @@ -39,7 +49,7 @@ const api: PlatformAPI = { useServiceWorkerAsBackgroundProcess, containsTalerHeaderListener, keepAlive, -} +}; export default api; @@ -47,16 +57,15 @@ const logger = new Logger("chrome.ts"); function keepAlive(callback: any): void { if (extensionIsManifestV3()) { - chrome.alarms.create("wallet-worker", { periodInMinutes: 1 }) + chrome.alarms.create("wallet-worker", { periodInMinutes: 1 }); chrome.alarms.onAlarm.addListener((a) => { - logger.trace(`kee p alive alarm: ${a.name}`) + logger.trace(`kee p alive alarm: ${a.name}`); // callback() - }) + }); // } else { } callback(); - } function isFirefox(): boolean { @@ -66,34 +75,35 @@ function isFirefox(): boolean { const hostPermissions = { permissions: ["webRequest"], origins: ["http://*/*", "https://*/*"], -} - +}; export function containsHostPermissions(): Promise<boolean> { return new Promise((res, rej) => { chrome.permissions.contains(hostPermissions, (resp) => { - const le = chrome.runtime.lastError?.message + const le = chrome.runtime.lastError?.message; if (le) { - rej(le) + rej(le); } - res(resp) - }) - }) + res(resp); + }); + }); } export async function requestHostPermissions(): Promise<boolean> { return new Promise((res, rej) => { chrome.permissions.request(hostPermissions, (resp) => { - const le = chrome.runtime.lastError?.message + const le = chrome.runtime.lastError?.message; if (le) { - rej(le) + rej(le); } - res(resp) - }) - }) + res(resp); + }); + }); } -type HeaderListenerFunc = (details: chrome.webRequest.WebResponseHeadersDetails) => void +type HeaderListenerFunc = ( + details: chrome.webRequest.WebResponseHeadersDetails, +) => void; let currentHeaderListener: HeaderListenerFunc | undefined = undefined; export function containsTalerHeaderListener(): boolean { @@ -128,57 +138,69 @@ export async function removeHostPermissions(): Promise<boolean> { } return new Promise((res, rej) => { chrome.permissions.remove(hostPermissions, (resp) => { - const le = chrome.runtime.lastError?.message + const le = chrome.runtime.lastError?.message; if (le) { - rej(le) + rej(le); } - res(resp) - }) - }) + res(resp); + }); + }); } -function addPermissionsListener(callback: (p: Permissions, lastError?: string) => void): void { +function addPermissionsListener( + callback: (p: Permissions, lastError?: string) => void, +): void { chrome.permissions.onAdded.addListener((perm: Permissions) => { const lastError = chrome.runtime.lastError?.message; - callback(perm, lastError) - }) + callback(perm, lastError); + }); } function getPermissionsApi(): CrossBrowserPermissionsApi { return { - addPermissionsListener, containsHostPermissions, requestHostPermissions, removeHostPermissions - } + addPermissionsListener, + containsHostPermissions, + requestHostPermissions, + removeHostPermissions, + }; } /** - * + * * @param callback function to be called */ function notifyWhenAppIsReady(callback: () => void): void { if (extensionIsManifestV3()) { - callback() + callback(); } else { window.addEventListener("load", callback); } } - function openWalletURIFromPopup(talerUri: string): void { const uriType = classifyTalerUri(talerUri); let url: string | undefined = undefined; switch (uriType) { case TalerUriType.TalerWithdraw: - url = chrome.runtime.getURL(`static/wallet.html#/cta/withdraw?talerWithdrawUri=${talerUri}`); + url = chrome.runtime.getURL( + `static/wallet.html#/cta/withdraw?talerWithdrawUri=${talerUri}`, + ); break; case TalerUriType.TalerPay: - url = chrome.runtime.getURL(`static/wallet.html#/cta/pay?talerPayUri=${talerUri}`); + url = chrome.runtime.getURL( + `static/wallet.html#/cta/pay?talerPayUri=${talerUri}`, + ); break; case TalerUriType.TalerTip: - url = chrome.runtime.getURL(`static/wallet.html#/cta/tip?talerTipUri=${talerUri}`); + url = chrome.runtime.getURL( + `static/wallet.html#/cta/tip?talerTipUri=${talerUri}`, + ); break; case TalerUriType.TalerRefund: - url = chrome.runtime.getURL(`static/wallet.html#/cta/refund?talerRefundUri=${talerUri}`); + url = chrome.runtime.getURL( + `static/wallet.html#/cta/refund?talerRefundUri=${talerUri}`, + ); break; default: logger.warn( @@ -187,56 +209,54 @@ function openWalletURIFromPopup(talerUri: string): void { return; } - chrome.tabs.create( - { active: true, url, }, - () => { window.close(); }, - ); + chrome.tabs.create({ active: true, url }, () => { + window.close(); + }); } function openWalletPage(page: string): void { - const url = chrome.runtime.getURL(`/static/wallet.html#${page}`) - chrome.tabs.create( - { active: true, url, }, - ); + const url = chrome.runtime.getURL(`/static/wallet.html#${page}`); + chrome.tabs.create({ active: true, url }); } function openWalletPageFromPopup(page: string): void { - const url = chrome.runtime.getURL(`/static/wallet.html#${page}`) - chrome.tabs.create( - { active: true, url, }, - () => { window.close(); }, - ); + const url = chrome.runtime.getURL(`/static/wallet.html#${page}`); + chrome.tabs.create({ active: true, url }, () => { + window.close(); + }); } -async function sendMessageToWalletBackground(operation: string, payload: any): Promise<any> { +async function sendMessageToWalletBackground( + operation: string, + payload: any, +): Promise<any> { return new Promise<any>((resolve, reject) => { - logger.trace("send operation to the wallet background", operation) + logger.trace("send operation to the wallet background", operation); chrome.runtime.sendMessage({ operation, payload, id: "(none)" }, (resp) => { if (chrome.runtime.lastError) { - reject(chrome.runtime.lastError.message) + reject(chrome.runtime.lastError.message); } - resolve(resp) + resolve(resp); // return true to keep the channel open return true; - }) - }) + }); + }); } let notificationPort: chrome.runtime.Port | undefined; function listenToWalletBackground(listener: (m: any) => void): () => void { if (notificationPort === undefined) { - notificationPort = chrome.runtime.connect({ name: "notifications" }) + notificationPort = chrome.runtime.connect({ name: "notifications" }); } - notificationPort.onMessage.addListener(listener) + notificationPort.onMessage.addListener(listener); function removeListener(): void { if (notificationPort !== undefined) { - notificationPort.onMessage.removeListener(listener) + notificationPort.onMessage.removeListener(listener); } } - return removeListener + return removeListener; } - const allPorts: chrome.runtime.Port[] = []; function sendMessageToAllChannels(message: MessageFromBackend): void { @@ -262,9 +282,15 @@ function registerAllIncomingConnections(): void { }); } -function listenToAllChannels(cb: (message: any, sender: any, callback: (r: CoreApiResponse) => void) => void): void { +function listenToAllChannels( + cb: ( + message: any, + sender: any, + callback: (r: CoreApiResponse) => void, + ) => void, +): void { chrome.runtime.onMessage.addListener((m, s, c) => { - cb(m, s, c) + cb(m, s, c); // keep the connection open return true; @@ -278,13 +304,9 @@ function registerReloadOnNewVersion(): void { logger.info("update available:", details); chrome.runtime.reload(); }); - } -function redirectTabToWalletPage( - tabId: number, - page: string, -): void { +function redirectTabToWalletPage(tabId: number, page: string): void { const url = chrome.runtime.getURL(`/static/wallet.html#${page}`); logger.trace("redirecting tabId: ", tabId, " to: ", url); chrome.tabs.update(tabId, { url }); @@ -300,7 +322,9 @@ function getWalletVersion(): WalletVersion { return manifestData; } -function registerTalerHeaderListener(callback: (tabId: number, url: string) => void): void { +function registerTalerHeaderListener( + callback: (tabId: number, url: string) => void, +): void { logger.trace("setting up header listener"); function headerListener( @@ -316,44 +340,45 @@ function registerTalerHeaderListener(callback: (tabId: number, url: string) => v details.statusCode === 200 ) { const values = (details.responseHeaders || []) - .filter(h => h.name.toLowerCase() === 'taler') - .map(h => h.value) - .filter((value): value is string => !!value) + .filter((h) => h.name.toLowerCase() === "taler") + .map((h) => h.value) + .filter((value): value is string => !!value); if (values.length > 0) { - callback(details.tabId, values[0]) + callback(details.tabId, values[0]); } } return; } const prevHeaderListener = currentHeaderListener; - getPermissionsApi().containsHostPermissions().then(result => { - //if there is a handler already, remove it - if ( - prevHeaderListener && - chrome?.webRequest?.onHeadersReceived?.hasListener(prevHeaderListener) - ) { - chrome.webRequest.onHeadersReceived.removeListener(prevHeaderListener); - } - //if the result was positive, add the headerListener - if (result) { - const listener: chrome.webRequest.WebResponseHeadersEvent | undefined = chrome?.webRequest?.onHeadersReceived; - if (listener) { - listener.addListener( - headerListener, - { urls: ["<all_urls>"] }, - ["responseHeaders"], - ); - currentHeaderListener = headerListener; + getPermissionsApi() + .containsHostPermissions() + .then((result) => { + //if there is a handler already, remove it + if ( + prevHeaderListener && + chrome?.webRequest?.onHeadersReceived?.hasListener(prevHeaderListener) + ) { + chrome.webRequest.onHeadersReceived.removeListener(prevHeaderListener); } - } - //notify the browser about this change, this operation is expensive - chrome?.webRequest?.handlerBehaviorChanged(() => { - if (chrome.runtime.lastError) { - logger.error(JSON.stringify(chrome.runtime.lastError)); + //if the result was positive, add the headerListener + if (result) { + const listener: chrome.webRequest.WebResponseHeadersEvent | undefined = + chrome?.webRequest?.onHeadersReceived; + if (listener) { + listener.addListener(headerListener, { urls: ["<all_urls>"] }, [ + "responseHeaders", + ]); + currentHeaderListener = headerListener; + } } + //notify the browser about this change, this operation is expensive + chrome?.webRequest?.handlerBehaviorChanged(() => { + if (chrome.runtime.lastError) { + logger.error(JSON.stringify(chrome.runtime.lastError)); + } + }); }); - }); } const alertIcons = { @@ -365,8 +390,8 @@ const alertIcons = { "64": "/static/img/taler-alert-64.png", "128": "/static/img/taler-alert-128.png", "256": "/static/img/taler-alert-256.png", - "512": "/static/img/taler-alert-512.png" -} + "512": "/static/img/taler-alert-512.png", +}; const normalIcons = { "16": "/static/img/taler-logo-16.png", "19": "/static/img/taler-logo-19.png", @@ -376,70 +401,99 @@ const normalIcons = { "64": "/static/img/taler-logo-64.png", "128": "/static/img/taler-logo-128.png", "256": "/static/img/taler-logo-256.png", - "512": "/static/img/taler-logo-512.png" -} + "512": "/static/img/taler-logo-512.png", +}; function setNormalIcon(): void { if (extensionIsManifestV3()) { - chrome.action.setIcon({ path: normalIcons }) + chrome.action.setIcon({ path: normalIcons }); } else { - chrome.browserAction.setIcon({ path: normalIcons }) + chrome.browserAction.setIcon({ path: normalIcons }); } } function setAlertedIcon(): void { if (extensionIsManifestV3()) { - chrome.action.setIcon({ path: alertIcons }) + chrome.action.setIcon({ path: alertIcons }); } else { - chrome.browserAction.setIcon({ path: alertIcons }) + chrome.browserAction.setIcon({ path: alertIcons }); } } - -interface OffscreenCanvasRenderingContext2D extends CanvasState, CanvasTransform, CanvasCompositing, CanvasImageSmoothing, CanvasFillStrokeStyles, CanvasShadowStyles, CanvasFilters, CanvasRect, CanvasDrawPath, CanvasUserInterface, CanvasText, CanvasDrawImage, CanvasImageData, CanvasPathDrawingStyles, CanvasTextDrawingStyles, CanvasPath { +interface OffscreenCanvasRenderingContext2D + extends CanvasState, + CanvasTransform, + CanvasCompositing, + CanvasImageSmoothing, + CanvasFillStrokeStyles, + CanvasShadowStyles, + CanvasFilters, + CanvasRect, + CanvasDrawPath, + CanvasUserInterface, + CanvasText, + CanvasDrawImage, + CanvasImageData, + CanvasPathDrawingStyles, + CanvasTextDrawingStyles, + CanvasPath { readonly canvas: OffscreenCanvas; } declare const OffscreenCanvasRenderingContext2D: { prototype: OffscreenCanvasRenderingContext2D; - new(): OffscreenCanvasRenderingContext2D; -} + new (): OffscreenCanvasRenderingContext2D; +}; interface OffscreenCanvas extends EventTarget { width: number; height: number; - getContext(contextId: "2d", contextAttributes?: CanvasRenderingContext2DSettings): OffscreenCanvasRenderingContext2D | null; + getContext( + contextId: "2d", + contextAttributes?: CanvasRenderingContext2DSettings, + ): OffscreenCanvasRenderingContext2D | null; } declare const OffscreenCanvas: { prototype: OffscreenCanvas; - new(width: number, height: number): OffscreenCanvas; -} + new (width: number, height: number): OffscreenCanvas; +}; function createCanvas(size: number): OffscreenCanvas { if (extensionIsManifestV3()) { - return new OffscreenCanvas(size, size) + return new OffscreenCanvas(size, size); } else { - const c = document.createElement("canvas") + const c = document.createElement("canvas"); c.height = size; c.width = size; return c; } } - async function createImage(size: number, file: string): Promise<ImageData> { - const r = await fetch(file) - const b = await r.blob() - const image = await createImageBitmap(b) + const r = await fetch(file); + const b = await r.blob(); + const image = await createImageBitmap(b); const canvas = createCanvas(size); - const canvasContext = canvas.getContext('2d')!; + const canvasContext = canvas.getContext("2d")!; canvasContext.clearRect(0, 0, canvas.width, canvas.height); canvasContext.drawImage(image, 0, 0, canvas.width, canvas.height); - const imageData = canvasContext.getImageData(0, 0, canvas.width, canvas.height); + const imageData = canvasContext.getImageData( + 0, + 0, + canvas.width, + canvas.height, + ); return imageData; } async function registerIconChangeOnTalerContent(): Promise<void> { - const imgs = await Promise.all(Object.entries(alertIcons).map(([key, value]) => createImage(parseInt(key, 10), value))) - const imageData = imgs.reduce((prev, cur) => ({ ...prev, [cur.width]: cur }), {} as { [size: string]: ImageData }) + const imgs = await Promise.all( + Object.entries(alertIcons).map(([key, value]) => + createImage(parseInt(key, 10), value), + ), + ); + const imageData = imgs.reduce( + (prev, cur) => ({ ...prev, [cur.width]: cur }), + {} as { [size: string]: ImageData }, + ); if (chrome.declarativeContent) { // using declarative content does not need host permission @@ -447,49 +501,54 @@ async function registerIconChangeOnTalerContent(): Promise<void> { const secureTalerUrlLookup = { conditions: [ new chrome.declarativeContent.PageStateMatcher({ - css: ["a[href^='taler://'"] - }) + css: ["a[href^='taler://'"], + }), ], - actions: [new chrome.declarativeContent.SetIcon({ imageData })] + actions: [new chrome.declarativeContent.SetIcon({ imageData })], }; const inSecureTalerUrlLookup = { conditions: [ new chrome.declarativeContent.PageStateMatcher({ - css: ["a[href^='taler+http://'"] - }) + css: ["a[href^='taler+http://'"], + }), ], - actions: [new chrome.declarativeContent.SetIcon({ imageData })] + actions: [new chrome.declarativeContent.SetIcon({ imageData })], }; chrome.declarativeContent.onPageChanged.removeRules(undefined, function () { - chrome.declarativeContent.onPageChanged.addRules([secureTalerUrlLookup, inSecureTalerUrlLookup]); + chrome.declarativeContent.onPageChanged.addRules([ + secureTalerUrlLookup, + inSecureTalerUrlLookup, + ]); }); return; } //this browser doesn't have declarativeContent //we need host_permission and we will check the content for changing the icon - chrome.tabs.onUpdated.addListener(async (tabId, info: chrome.tabs.TabChangeInfo) => { - if (tabId < 0) return; - logger.info("tab updated", tabId, info); - if (info.status !== "complete") return; - const uri = await findTalerUriInTab(tabId); - if (uri) { - setAlertedIcon() - } else { - setNormalIcon() - } - - }); - chrome.tabs.onActivated.addListener(async ({ tabId }: chrome.tabs.TabActiveInfo) => { - if (tabId < 0) return; - const uri = await findTalerUriInTab(tabId); - if (uri) { - setAlertedIcon() - } else { - setNormalIcon() - } - }) - + chrome.tabs.onUpdated.addListener( + async (tabId, info: chrome.tabs.TabChangeInfo) => { + if (tabId < 0) return; + logger.info("tab updated", tabId, info); + if (info.status !== "complete") return; + const uri = await findTalerUriInTab(tabId); + if (uri) { + setAlertedIcon(); + } else { + setNormalIcon(); + } + }, + ); + chrome.tabs.onActivated.addListener( + async ({ tabId }: chrome.tabs.TabActiveInfo) => { + if (tabId < 0) return; + const uri = await findTalerUriInTab(tabId); + if (uri) { + setAlertedIcon(); + } else { + setNormalIcon(); + } + }, + ); } function registerOnInstalled(callback: () => void): void { @@ -498,27 +557,27 @@ function registerOnInstalled(callback: () => void): void { chrome.runtime.onInstalled.addListener(async (details) => { logger.info(`onInstalled with reason: "${details.reason}"`); if (details.reason === chrome.runtime.OnInstalledReason.INSTALL) { - callback() + callback(); } - registerIconChangeOnTalerContent() + registerIconChangeOnTalerContent(); }); } function extensionIsManifestV3(): boolean { - return chrome.runtime.getManifest().manifest_version === 3 + return chrome.runtime.getManifest().manifest_version === 3; } function useServiceWorkerAsBackgroundProcess(): boolean { - return extensionIsManifestV3() + return extensionIsManifestV3(); } function searchForTalerLinks(): string | undefined { let found; - found = document.querySelector("a[href^='taler://'") - if (found) return found.toString() - found = document.querySelector("a[href^='taler+http://'") - if (found) return found.toString() - return undefined + found = document.querySelector("a[href^='taler://'"); + if (found) return found.toString(); + found = document.querySelector("a[href^='taler+http://'"); + if (found) return found.toString(); + return undefined; } async function getCurrentTab(): Promise<chrome.tabs.Tab> { @@ -526,12 +585,12 @@ async function getCurrentTab(): Promise<chrome.tabs.Tab> { return new Promise<chrome.tabs.Tab>((resolve, reject) => { chrome.tabs.query(queryOptions, (tabs) => { if (chrome.runtime.lastError) { - reject(chrome.runtime.lastError) + reject(chrome.runtime.lastError); return; } - resolve(tabs[0]) + resolve(tabs[0]); }); - }) + }); } async function findTalerUriInTab(tabId: number): Promise<string | undefined> { @@ -541,16 +600,17 @@ async function findTalerUriInTab(tabId: number): Promise<string | undefined> { const res = await chrome.scripting.executeScript({ target: { tabId, allFrames: true }, func: searchForTalerLinks, - args: [] - }) - return res[0].result + args: [], + }); + return res[0].result; } catch (e) { return; } } else { return new Promise((resolve, reject) => { //manifest v2 - chrome.tabs.executeScript(tabId, + chrome.tabs.executeScript( + tabId, { code: ` (() => { @@ -576,6 +636,5 @@ async function findTalerUriInTab(tabId: number): Promise<string | undefined> { async function findTalerUriInActiveTab(): Promise<string | undefined> { const tab = await getCurrentTab(); if (!tab || tab.id === undefined) return; - return findTalerUriInTab(tab.id) + return findTalerUriInTab(tab.id); } - diff --git a/packages/taler-wallet-webextension/src/platform/dev.ts b/packages/taler-wallet-webextension/src/platform/dev.ts index 59e6738c5..fbbb4d231 100644 --- a/packages/taler-wallet-webextension/src/platform/dev.ts +++ b/packages/taler-wallet-webextension/src/platform/dev.ts @@ -17,50 +17,55 @@ import { CoreApiResponse } from "@gnu-taler/taler-util"; import { MessageFromBackend, PlatformAPI } from "./api.js"; -const frames = ["popup", "wallet"] +const frames = ["popup", "wallet"]; -const api: PlatformAPI = ({ +const api: PlatformAPI = { isFirefox: () => false, keepAlive: (cb: VoidFunction) => cb(), findTalerUriInActiveTab: async () => undefined, - containsTalerHeaderListener: () => { return true }, + containsTalerHeaderListener: () => { + return true; + }, getPermissionsApi: () => ({ - addPermissionsListener: () => undefined, containsHostPermissions: async () => true, removeHostPermissions: async () => false, requestHostPermissions: async () => false + addPermissionsListener: () => undefined, + containsHostPermissions: async () => true, + removeHostPermissions: async () => false, + requestHostPermissions: async () => false, }), getWalletVersion: () => ({ - version: 'none' + version: "none", }), notifyWhenAppIsReady: (fn: () => void) => { - let total = frames.length + let total = frames.length; function waitAndNotify(): void { - total-- + total--; if (total < 1) { - console.log('done') - fn() + console.log("done"); + fn(); } } - frames.forEach(f => { - const theFrame = window.frames[f as any] - if (theFrame.location.href === 'about:blank') { - waitAndNotify() + frames.forEach((f) => { + const theFrame = window.frames[f as any]; + if (theFrame.location.href === "about:blank") { + waitAndNotify(); } else { - theFrame.addEventListener("load", waitAndNotify) + theFrame.addEventListener("load", waitAndNotify); } - }) + }); }, openWalletPage: (page: string) => { - window.frames['wallet' as any].location = `/wallet.html#${page}` + window.frames["wallet" as any].location = `/wallet.html#${page}`; }, openWalletPageFromPopup: (page: string) => { - window.parent.frames['wallet' as any].location = `/wallet.html#${page}` - window.location.href = "about:blank" + window.parent.frames["wallet" as any].location = `/wallet.html#${page}`; + window.location.href = "about:blank"; }, openWalletURIFromPopup: (page: string) => { - alert('openWalletURIFromPopup not implemented yet') + alert("openWalletURIFromPopup not implemented yet"); }, redirectTabToWalletPage: (tabId: number, page: string) => { - alert('redirectTabToWalletPage not implemented yet') + alert("redirectTabToWalletPage not implemented yet"); }, registerAllIncomingConnections: () => undefined, @@ -70,91 +75,101 @@ const api: PlatformAPI = ({ useServiceWorkerAsBackgroundProcess: () => false, - listenToAllChannels: (fn: (m: any, s: any, c: (r: CoreApiResponse) => void) => void) => { - window.addEventListener("message", (event: MessageEvent<IframeMessageType>) => { - if (event.data.type !== 'command') return - const sender = event.data.header.replyMe - fn(event.data.body, sender, (resp: CoreApiResponse) => { - if (event.source) { - const msg: IframeMessageResponse = { - type: "response", - header: { responseId: sender }, - body: resp + listenToAllChannels: ( + fn: (m: any, s: any, c: (r: CoreApiResponse) => void) => void, + ) => { + window.addEventListener( + "message", + (event: MessageEvent<IframeMessageType>) => { + if (event.data.type !== "command") return; + const sender = event.data.header.replyMe; + fn(event.data.body, sender, (resp: CoreApiResponse) => { + if (event.source) { + const msg: IframeMessageResponse = { + type: "response", + header: { responseId: sender }, + body: resp, + }; + window.parent.postMessage(msg); } - window.parent.postMessage(msg) - } - }) - }) + }); + }, + ); }, sendMessageToAllChannels: (message: MessageFromBackend) => { - Array.from(window.frames).forEach(w => { + Array.from(window.frames).forEach((w) => { try { w.postMessage({ - header: {}, body: message + header: {}, + body: message, }); } catch (e) { - console.error(e) + console.error(e); } - }) + }); }, listenToWalletBackground: (onNewMessage: (m: MessageFromBackend) => void) => { function listener(event: MessageEvent<IframeMessageType>): void { - if (event.data.type !== 'notification') return - onNewMessage(event.data.body) + if (event.data.type !== "notification") return; + onNewMessage(event.data.body); } - window.parent.addEventListener("message", listener) + window.parent.addEventListener("message", listener); return () => { - window.parent.removeEventListener("message", listener) - } + window.parent.removeEventListener("message", listener); + }; }, sendMessageToWalletBackground: async (operation: string, payload: any) => { - const replyMe = `reply-${Math.floor(Math.random() * 100000)}` + const replyMe = `reply-${Math.floor(Math.random() * 100000)}`; const message: IframeMessageCommand = { - type: 'command', + type: "command", header: { replyMe }, - body: { operation, payload, id: "(none)" } - } - window.parent.postMessage(message) + body: { operation, payload, id: "(none)" }, + }; + window.parent.postMessage(message); return new Promise((res, rej) => { function listener(event: MessageEvent<IframeMessageType>): void { - if (event.data.type !== "response" || event.data.header.responseId !== replyMe) { - return + if ( + event.data.type !== "response" || + event.data.header.responseId !== replyMe + ) { + return; } - res(event.data.body) - window.parent.removeEventListener("message", listener) + res(event.data.body); + window.parent.removeEventListener("message", listener); } - window.parent.addEventListener("message", listener, { - - }) - }) - + window.parent.addEventListener("message", listener, {}); + }); }, -}) +}; -type IframeMessageType = IframeMessageNotification | IframeMessageResponse | IframeMessageCommand; +type IframeMessageType = + | IframeMessageNotification + | IframeMessageResponse + | IframeMessageCommand; interface IframeMessageNotification { type: "notification"; - header: Record<string, never>, - body: MessageFromBackend + header: Record<string, never>; + body: MessageFromBackend; } interface IframeMessageResponse { type: "response"; header: { responseId: string; - }, - body: CoreApiResponse + }; + body: CoreApiResponse; } interface IframeMessageCommand { type: "command"; header: { replyMe: string; - }, + }; body: { - operation: any, id: string, payload: any - } + operation: any; + id: string; + payload: any; + }; } export default api; - diff --git a/packages/taler-wallet-webextension/src/platform/firefox.ts b/packages/taler-wallet-webextension/src/platform/firefox.ts index d5beda324..32733f6c4 100644 --- a/packages/taler-wallet-webextension/src/platform/firefox.ts +++ b/packages/taler-wallet-webextension/src/platform/firefox.ts @@ -15,7 +15,11 @@ */ import { CrossBrowserPermissionsApi, Permissions, PlatformAPI } from "./api.js"; -import chromePlatform, { containsHostPermissions as chromeContains, removeHostPermissions as chromeRemove, requestHostPermissions as chromeRequest } from "./chrome.js"; +import chromePlatform, { + containsHostPermissions as chromeContains, + removeHostPermissions as chromeRemove, + requestHostPermissions as chromeRequest, +} from "./chrome.js"; const api: PlatformAPI = { ...chromePlatform, @@ -23,18 +27,17 @@ const api: PlatformAPI = { getPermissionsApi, notifyWhenAppIsReady, redirectTabToWalletPage, - useServiceWorkerAsBackgroundProcess + useServiceWorkerAsBackgroundProcess, }; export default api; function isFirefox(): boolean { - return true + return true; } - function addPermissionsListener(callback: (p: Permissions) => void): void { - console.log("addPermissionListener is not supported for Firefox") + console.log("addPermissionListener is not supported for Firefox"); } function getPermissionsApi(): CrossBrowserPermissionsApi { @@ -42,33 +45,28 @@ function getPermissionsApi(): CrossBrowserPermissionsApi { addPermissionsListener, containsHostPermissions: chromeContains, requestHostPermissions: chromeRequest, - removeHostPermissions: chromeRemove - } + removeHostPermissions: chromeRemove, + }; } /** - * + * * @param callback function to be called */ function notifyWhenAppIsReady(callback: () => void): void { if (chrome.runtime && chrome.runtime.getManifest().manifest_version === 3) { - callback() + callback(); } else { window.addEventListener("load", callback); } } - -function redirectTabToWalletPage( - tabId: number, - page: string, -): void { +function redirectTabToWalletPage(tabId: number, page: string): void { const url = chrome.runtime.getURL(`/static/wallet.html#${page}`); console.log("redirecting tabId: ", tabId, " to: ", url); chrome.tabs.update(tabId, { url, loadReplace: true } as any); } - function useServiceWorkerAsBackgroundProcess(): false { - return false + return false; } diff --git a/packages/taler-wallet-webextension/src/serviceWorkerHttpLib.ts b/packages/taler-wallet-webextension/src/serviceWorkerHttpLib.ts index d07cb564d..ec88d57a8 100644 --- a/packages/taler-wallet-webextension/src/serviceWorkerHttpLib.ts +++ b/packages/taler-wallet-webextension/src/serviceWorkerHttpLib.ts @@ -93,7 +93,7 @@ export class ServiceWorkerHttpLib implements HttpRequestLibrary { ): Promise<HttpResponse> { return this.fetch(url, { method: "POST", - headers: {"Content-Type": "application/json"}, + headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), ...opt, }); diff --git a/packages/taler-wallet-webextension/src/stories.test.ts b/packages/taler-wallet-webextension/src/stories.test.ts index ef8b4de53..d5e801947 100644 --- a/packages/taler-wallet-webextension/src/stories.test.ts +++ b/packages/taler-wallet-webextension/src/stories.test.ts @@ -47,9 +47,9 @@ function testThisStory(st: any): any { describe("render every storybook example", () => { [popup, wallet, cta, mui, components].forEach(function testAll(st: any) { if (Array.isArray(st.default)) { - st.default.forEach(testAll) + st.default.forEach(testAll); } else { - testThisStory(st) + testThisStory(st); } }); }); diff --git a/packages/taler-wallet-webextension/src/test-utils.ts b/packages/taler-wallet-webextension/src/test-utils.ts index 9e219daa6..d9b97e4ab 100644 --- a/packages/taler-wallet-webextension/src/test-utils.ts +++ b/packages/taler-wallet-webextension/src/test-utils.ts @@ -14,15 +14,23 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { ComponentChildren, Fragment, FunctionalComponent, h as create, options, render as renderIntoDom, VNode } from "preact"; +import { + ComponentChildren, + Fragment, + FunctionalComponent, + h as create, + options, + render as renderIntoDom, + VNode, +} from "preact"; import { render as renderToString } from "preact-render-to-string"; // When doing tests we want the requestAnimationFrame to be as fast as possible. // without this option the RAF will timeout after 100ms making the tests slower options.requestAnimationFrame = (fn: () => void) => { // console.log("RAF called") - return fn() -} + return fn(); +}; export function createExample<Props>( Component: FunctionalComponent<Props>, @@ -30,8 +38,8 @@ export function createExample<Props>( ): ComponentChildren { //FIXME: props are evaluated on build time // in some cases we want to evaluated the props on render time so we can get some relative timestamp - // check how we can build evaluatedProps in render time - const evaluatedProps = typeof props === "function" ? props() : props + // check how we can build evaluatedProps in render time + const evaluatedProps = typeof props === "function" ? props() : props; const Render = (args: any): VNode => create(Component, args); Render.args = evaluatedProps; return Render; @@ -43,14 +51,22 @@ export function createExampleWithCustomContext<Props, ContextProps>( ContextProvider: FunctionalComponent<ContextProps>, contextProps: Partial<ContextProps>, ): ComponentChildren { - const evaluatedProps = typeof props === "function" ? props() : props + const evaluatedProps = typeof props === "function" ? props() : props; const Render = (args: any): VNode => create(Component, args); - const WithContext = (args: any): VNode => create(ContextProvider, { ...contextProps, children: [Render(args)] } as any); - WithContext.args = evaluatedProps - return WithContext + const WithContext = (args: any): VNode => + create(ContextProvider, { + ...contextProps, + children: [Render(args)], + } as any); + WithContext.args = evaluatedProps; + return WithContext; } -export function NullLink({ children }: { children?: ComponentChildren }): VNode { +export function NullLink({ + children, +}: { + children?: ComponentChildren; +}): VNode { return create("a", { children, href: "javascript:void(0);" }); } @@ -74,53 +90,59 @@ interface Mounted<T> { waitNextUpdate: (s?: string) => Promise<void>; } -const isNode = typeof window === "undefined" +const isNode = typeof window === "undefined"; -export function mountHook<T>(callback: () => T, Context?: ({ children }: { children: any }) => VNode): Mounted<T> { +export function mountHook<T>( + callback: () => T, + Context?: ({ children }: { children: any }) => VNode, +): Mounted<T> { // const result: { current: T | null } = { // current: null // } let lastResult: T | Error | null = null; - const listener: Array<() => void> = [] + const listener: Array<() => void> = []; // component that's going to hold the hook function Component(): VNode { - try { - lastResult = callback() + lastResult = callback(); } catch (e) { if (e instanceof Error) { - lastResult = e + lastResult = e; } else { - lastResult = new Error(`mounting the hook throw an exception: ${e}`) + lastResult = new Error(`mounting the hook throw an exception: ${e}`); } } // notify to everyone waiting for an update and clean the queue - listener.splice(0, listener.length).forEach(cb => cb()) - return create(Fragment, {}) + listener.splice(0, listener.length).forEach((cb) => cb()); + return create(Fragment, {}); } // create the vdom with context if required - const vdom = !Context ? create(Component, {}) : create(Context, { children: [create(Component, {})] },); + const vdom = !Context + ? create(Component, {}) + : create(Context, { children: [create(Component, {})] }); // waiter callback async function waitNextUpdate(_label = ""): Promise<void> { - if (_label) _label = `. label: "${_label}"` + if (_label) _label = `. label: "${_label}"`; await new Promise((res, rej) => { const tid = setTimeout(() => { - rej(Error(`waiting for an update but the hook didn't make one${_label}`)) - }, 100) + rej( + Error(`waiting for an update but the hook didn't make one${_label}`), + ); + }, 100); listener.push(() => { - clearTimeout(tid) - res(undefined) - }) - }) + clearTimeout(tid); + res(undefined); + }); + }); } - const customElement = {} as Element + const customElement = {} as Element; const parentElement = isNode ? customElement : document.createElement("div"); if (!isNode) { document.body.appendChild(parentElement); @@ -136,38 +158,44 @@ export function mountHook<T>(callback: () => T, Context?: ({ children }: { child } function getLastResult(): T | Error | null { - const copy = lastResult - lastResult = null + const copy = lastResult; + lastResult = null; return copy; } function getLastResultOrThrow(): T { - const r = getLastResult() + const r = getLastResult(); if (r instanceof Error) throw r; - if (!r) throw Error('there was no last result') + if (!r) throw Error("there was no last result"); return r; } async function assertNoPendingUpdate(): Promise<void> { await new Promise((res, rej) => { const tid = setTimeout(() => { - res(undefined) - }, 10) + res(undefined); + }, 10); listener.push(() => { - clearTimeout(tid) - rej(Error(`Expecting no pending result but the hook got updated. + clearTimeout(tid); + rej( + Error(`Expecting no pending result but the hook got updated. If the update was not intended you need to check the hook dependencies (or dependencies of the internal state) but otherwise make - sure to consume the result before ending the test.`)) - }) - }) - - const r = getLastResult() - if (r) throw Error(`There are still pending results. + sure to consume the result before ending the test.`), + ); + }); + }); + + const r = getLastResult(); + if (r) + throw Error(`There are still pending results. This may happen because the hook did a new update but the test didn't consume the result using getLastResult`); } return { - unmount, getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate - } + unmount, + getLastResultOrThrow, + waitNextUpdate, + assertNoPendingUpdate, + }; } diff --git a/packages/taler-wallet-webextension/src/utils/index.ts b/packages/taler-wallet-webextension/src/utils/index.ts index 9181ee5b6..ae2705eb2 100644 --- a/packages/taler-wallet-webextension/src/utils/index.ts +++ b/packages/taler-wallet-webextension/src/utils/index.ts @@ -14,8 +14,11 @@ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ -import { AmountJson, Amounts, GetExchangeTosResult } from "@gnu-taler/taler-util"; - +import { + AmountJson, + Amounts, + GetExchangeTosResult, +} from "@gnu-taler/taler-util"; function getJsonIfOk(r: Response): Promise<any> { if (r.ok) { @@ -27,15 +30,13 @@ function getJsonIfOk(r: Response): Promise<any> { } throw new Error( - `Try another server: (${r.status}) ${r.statusText || "internal server error" + `Try another server: (${r.status}) ${ + r.statusText || "internal server error" }`, ); - } -export async function queryToSlashConfig<T>( - url: string, -): Promise<T> { +export async function queryToSlashConfig<T>(url: string): Promise<T> { return fetch(new URL("config", url).href) .catch(() => { throw new Error(`Network error`); @@ -46,25 +47,27 @@ export async function queryToSlashConfig<T>( function timeout<T>(ms: number, promise: Promise<T>): Promise<T> { return new Promise((resolve, reject) => { const timer = setTimeout(() => { - reject(new Error(`Timeout: the query took longer than ${Math.floor(ms / 1000)} secs`)) - }, ms) + reject( + new Error( + `Timeout: the query took longer than ${Math.floor(ms / 1000)} secs`, + ), + ); + }, ms); promise - .then(value => { - clearTimeout(timer) - resolve(value) + .then((value) => { + clearTimeout(timer); + resolve(value); }) - .catch(reason => { - clearTimeout(timer) - reject(reason) - }) - }) + .catch((reason) => { + clearTimeout(timer); + reject(reason); + }); + }); } -export async function queryToSlashKeys<T>( - url: string, -): Promise<T> { - const endpoint = new URL("keys", url) +export async function queryToSlashKeys<T>(url: string): Promise<T> { + const endpoint = new URL("keys", url); endpoint.searchParams.set("cacheBreaker", new Date().getTime() + ""); const query = fetch(endpoint.href) @@ -73,29 +76,37 @@ export async function queryToSlashKeys<T>( }) .then(getJsonIfOk); - return timeout(3000, query) + return timeout(3000, query); } -export function buildTermsOfServiceState(tos: GetExchangeTosResult): TermsState { - +export function buildTermsOfServiceState( + tos: GetExchangeTosResult, +): TermsState { const content: TermsDocument | undefined = parseTermsOfServiceContent( tos.contentType, tos.content, ); - const status: TermsStatus = buildTermsOfServiceStatus(tos.content, tos.acceptedEtag, tos.currentEtag); - - return { content, status, version: tos.currentEtag } + const status: TermsStatus = buildTermsOfServiceStatus( + tos.content, + tos.acceptedEtag, + tos.currentEtag, + ); + return { content, status, version: tos.currentEtag }; } -export function buildTermsOfServiceStatus(content: string | undefined, acceptedVersion: string | undefined, currentVersion: string | undefined): TermsStatus { +export function buildTermsOfServiceStatus( + content: string | undefined, + acceptedVersion: string | undefined, + currentVersion: string | undefined, +): TermsStatus { return !content ? "notfound" : !acceptedVersion - ? "new" - : acceptedVersion !== currentVersion - ? "changed" - : "accepted"; + ? "new" + : acceptedVersion !== currentVersion + ? "changed" + : "accepted"; } function parseTermsOfServiceContent( diff --git a/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.test.ts b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.test.ts index 7a9a5314b..3cfd6930d 100644 --- a/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.test.ts +++ b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.test.ts @@ -25,15 +25,13 @@ import { SelectFieldHandler, TextFieldHandler } from "../mui/handlers.js"; import { mountHook } from "../test-utils.js"; import { useComponentState } from "./CreateManualWithdraw.js"; - const exchangeListWithARSandUSD = { - "url1": "USD", - "url2": "ARS", - "url3": "ARS", + url1: "USD", + url2: "ARS", + url3: "ARS", }; -const exchangeListEmpty = { -}; +const exchangeListEmpty = {}; describe("CreateManualWithdraw states", () => { it("should set noExchangeFound when exchange list is empty", () => { @@ -41,9 +39,9 @@ describe("CreateManualWithdraw states", () => { useComponentState(exchangeListEmpty, undefined, undefined), ); - const { noExchangeFound } = getLastResultOrThrow() + const { noExchangeFound } = getLastResultOrThrow(); - expect(noExchangeFound).equal(true) + expect(noExchangeFound).equal(true); }); it("should set noExchangeFound when exchange list doesn't include selected currency", () => { @@ -51,20 +49,19 @@ describe("CreateManualWithdraw states", () => { useComponentState(exchangeListWithARSandUSD, undefined, "COL"), ); - const { noExchangeFound } = getLastResultOrThrow() + const { noExchangeFound } = getLastResultOrThrow(); - expect(noExchangeFound).equal(true) + expect(noExchangeFound).equal(true); }); - it("should select the first exchange from the list", () => { const { getLastResultOrThrow } = mountHook(() => useComponentState(exchangeListWithARSandUSD, undefined, undefined), ); - const { exchange } = getLastResultOrThrow() + const { exchange } = getLastResultOrThrow(); - expect(exchange.value).equal("url1") + expect(exchange.value).equal("url1"); }); it("should select the first exchange with the selected currency", () => { @@ -72,9 +69,9 @@ describe("CreateManualWithdraw states", () => { useComponentState(exchangeListWithARSandUSD, undefined, "ARS"), ); - const { exchange } = getLastResultOrThrow() + const { exchange } = getLastResultOrThrow(); - expect(exchange.value).equal("url2") + expect(exchange.value).equal("url2"); }); it("should change the exchange when currency change", async () => { @@ -82,22 +79,20 @@ describe("CreateManualWithdraw states", () => { useComponentState(exchangeListWithARSandUSD, undefined, "ARS"), ); - { - const { exchange, currency } = getLastResultOrThrow() + const { exchange, currency } = getLastResultOrThrow(); - expect(exchange.value).equal("url2") + expect(exchange.value).equal("url2"); if (currency.onChange === undefined) expect.fail(); - currency.onChange("USD") + currency.onChange("USD"); } - await waitNextUpdate() + await waitNextUpdate(); { - const { exchange } = getLastResultOrThrow() - expect(exchange.value).equal("url1") + const { exchange } = getLastResultOrThrow(); + expect(exchange.value).equal("url1"); } - }); it("should change the currency when exchange change", async () => { @@ -106,22 +101,22 @@ describe("CreateManualWithdraw states", () => { ); { - const { exchange, currency } = getLastResultOrThrow() + const { exchange, currency } = getLastResultOrThrow(); - expect(exchange.value).equal("url2") - expect(currency.value).equal("ARS") + expect(exchange.value).equal("url2"); + expect(currency.value).equal("ARS"); if (exchange.onChange === undefined) expect.fail(); - exchange.onChange("url1") + exchange.onChange("url1"); } - await waitNextUpdate() + await waitNextUpdate(); { - const { exchange, currency } = getLastResultOrThrow() + const { exchange, currency } = getLastResultOrThrow(); - expect(exchange.value).equal("url1") - expect(currency.value).equal("USD") + expect(exchange.value).equal("url1"); + expect(currency.value).equal("USD"); } }); @@ -131,21 +126,23 @@ describe("CreateManualWithdraw states", () => { ); { - const { amount, parsedAmount } = getLastResultOrThrow() + const { amount, parsedAmount } = getLastResultOrThrow(); - expect(parsedAmount).equal(undefined) + expect(parsedAmount).equal(undefined); - amount.onInput("12") + amount.onInput("12"); } - await waitNextUpdate() + await waitNextUpdate(); { - const { parsedAmount } = getLastResultOrThrow() + const { parsedAmount } = getLastResultOrThrow(); expect(parsedAmount).deep.equals({ - value: 12, fraction: 0, currency: "ARS" - }) + value: 12, + fraction: 0, + currency: "ARS", + }); } }); @@ -154,67 +151,79 @@ describe("CreateManualWithdraw states", () => { useComponentState(exchangeListWithARSandUSD, undefined, "ARS"), ); - await defaultTestForInputText(waitNextUpdate, () => getLastResultOrThrow().amount) - }) + await defaultTestForInputText( + waitNextUpdate, + () => getLastResultOrThrow().amount, + ); + }); it("should have an exchange selector ", async () => { const { getLastResultOrThrow, waitNextUpdate } = mountHook(() => useComponentState(exchangeListWithARSandUSD, undefined, "ARS"), ); - await defaultTestForInputSelect(waitNextUpdate, () => getLastResultOrThrow().exchange) - }) + await defaultTestForInputSelect( + waitNextUpdate, + () => getLastResultOrThrow().exchange, + ); + }); it("should have a currency selector ", async () => { const { getLastResultOrThrow, waitNextUpdate } = mountHook(() => useComponentState(exchangeListWithARSandUSD, undefined, "ARS"), ); - await defaultTestForInputSelect(waitNextUpdate, () => getLastResultOrThrow().currency) - }) - + await defaultTestForInputSelect( + waitNextUpdate, + () => getLastResultOrThrow().currency, + ); + }); }); - -async function defaultTestForInputText(awaiter: () => Promise<void>, getField: () => TextFieldHandler): Promise<void> { - let nextValue = '' +async function defaultTestForInputText( + awaiter: () => Promise<void>, + getField: () => TextFieldHandler, +): Promise<void> { + let nextValue = ""; { - const field = getField() + const field = getField(); const initialValue = field.value; - nextValue = `${initialValue} something else` - field.onInput(nextValue) + nextValue = `${initialValue} something else`; + field.onInput(nextValue); } - await awaiter() + await awaiter(); { - const field = getField() - expect(field.value).equal(nextValue) + const field = getField(); + expect(field.value).equal(nextValue); } } - -async function defaultTestForInputSelect(awaiter: () => Promise<void>, getField: () => SelectFieldHandler): Promise<void> { - let nextValue = '' +async function defaultTestForInputSelect( + awaiter: () => Promise<void>, + getField: () => SelectFieldHandler, +): Promise<void> { + let nextValue = ""; { const field = getField(); const initialValue = field.value; - const keys = Object.keys(field.list) - const nextIdx = keys.indexOf(initialValue) + 1 + const keys = Object.keys(field.list); + const nextIdx = keys.indexOf(initialValue) + 1; if (keys.length < nextIdx) { - throw new Error('no enough values') + throw new Error("no enough values"); } - nextValue = keys[nextIdx] + nextValue = keys[nextIdx]; if (field.onChange === undefined) expect.fail(); - field.onChange(nextValue) + field.onChange(nextValue); } - await awaiter() + await awaiter(); { const field = getField(); - expect(field.value).equal(nextValue) + expect(field.value).equal(nextValue); } } diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage.test.ts b/packages/taler-wallet-webextension/src/wallet/DepositPage.test.ts index 5fc55934d..cea5dd5ca 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage.test.ts +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage.test.ts @@ -19,392 +19,412 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { Amounts, Balance, BalancesResponse, parsePaytoUri } from "@gnu-taler/taler-util"; +import { + Amounts, + Balance, + BalancesResponse, + parsePaytoUri, +} from "@gnu-taler/taler-util"; import { DepositGroupFees } from "@gnu-taler/taler-wallet-core/src/operations/deposits"; import { expect } from "chai"; import { mountHook } from "../test-utils.js"; import { useComponentState } from "./DepositPage.js"; import * as wxApi from "../wxApi.js"; - -const currency = "EUR" +const currency = "EUR"; const withoutFee = async (): Promise<DepositGroupFees> => ({ coin: Amounts.parseOrThrow(`${currency}:0`), wire: Amounts.parseOrThrow(`${currency}:0`), - refresh: Amounts.parseOrThrow(`${currency}:0`) -}) + refresh: Amounts.parseOrThrow(`${currency}:0`), +}); const withSomeFee = async (): Promise<DepositGroupFees> => ({ coin: Amounts.parseOrThrow(`${currency}:1`), wire: Amounts.parseOrThrow(`${currency}:1`), - refresh: Amounts.parseOrThrow(`${currency}:1`) -}) + refresh: Amounts.parseOrThrow(`${currency}:1`), +}); -const freeJustForIBAN = async (account: string): Promise<DepositGroupFees> => /IBAN/i.test(account) ? withoutFee() : withSomeFee() +const freeJustForIBAN = async (account: string): Promise<DepositGroupFees> => + /IBAN/i.test(account) ? withoutFee() : withSomeFee(); -const someBalance = [{ - available: 'EUR:10' -} as Balance] +const someBalance = [ + { + available: "EUR:10", + } as Balance, +]; const nullFunction: any = () => null; type VoidFunction = () => void; describe("DepositPage states", () => { it("should have status 'no-balance' when balance is empty", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState(currency, nullFunction, nullFunction, { - getBalance: async () => ({ - balances: [{ available: `${currency}:0`, }] - } as Partial<BalancesResponse>), - listKnownBankAccounts: async () => ({ accounts: [] }) - } as Partial<typeof wxApi> as any) - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState(currency, nullFunction, nullFunction, { + getBalance: async () => + ({ + balances: [{ available: `${currency}:0` }], + } as Partial<BalancesResponse>), + listKnownBankAccounts: async () => ({ accounts: [] }), + } as Partial<typeof wxApi> as any), + ); { - const { status } = getLastResultOrThrow() - expect(status).equal("loading") + const { status } = getLastResultOrThrow(); + expect(status).equal("loading"); } - await waitNextUpdate() + await waitNextUpdate(); { - const { status } = getLastResultOrThrow() - expect(status).equal("no-balance") + const { status } = getLastResultOrThrow(); + expect(status).equal("no-balance"); } - await assertNoPendingUpdate() - + await assertNoPendingUpdate(); }); it("should have status 'no-accounts' when balance is not empty and accounts is empty", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState(currency, nullFunction, nullFunction, { - getBalance: async () => ({ - balances: [{ available: `${currency}:1`, }] - } as Partial<BalancesResponse>), - listKnownBankAccounts: async () => ({ accounts: [] }) - } as Partial<typeof wxApi> as any) - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState(currency, nullFunction, nullFunction, { + getBalance: async () => + ({ + balances: [{ available: `${currency}:1` }], + } as Partial<BalancesResponse>), + listKnownBankAccounts: async () => ({ accounts: [] }), + } as Partial<typeof wxApi> as any), + ); { - const { status } = getLastResultOrThrow() - expect(status).equal("loading") + const { status } = getLastResultOrThrow(); + expect(status).equal("loading"); } - await waitNextUpdate() + await waitNextUpdate(); { - const r = getLastResultOrThrow() + const r = getLastResultOrThrow(); if (r.status !== "no-accounts") expect.fail(); expect(r.cancelHandler.onClick).not.undefined; } - await assertNoPendingUpdate() - + await assertNoPendingUpdate(); }); const ibanPayto = parsePaytoUri("payto://iban/ES8877998399652238")!; - const talerBankPayto = parsePaytoUri("payto://x-taler-bank/ES8877998399652238")!; + const talerBankPayto = parsePaytoUri( + "payto://x-taler-bank/ES8877998399652238", + )!; it("should have status 'ready' but unable to deposit ", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState(currency, nullFunction, nullFunction, { - getBalance: async () => ({ - balances: [{ available: `${currency}:1`, }] - } as Partial<BalancesResponse>), - listKnownBankAccounts: async () => ({ accounts: [ibanPayto] }) - } as Partial<typeof wxApi> as any) - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState(currency, nullFunction, nullFunction, { + getBalance: async () => + ({ + balances: [{ available: `${currency}:1` }], + } as Partial<BalancesResponse>), + listKnownBankAccounts: async () => ({ accounts: [ibanPayto] }), + } as Partial<typeof wxApi> as any), + ); { - const { status } = getLastResultOrThrow() - expect(status).equal("loading") + const { status } = getLastResultOrThrow(); + expect(status).equal("loading"); } - await waitNextUpdate() + await waitNextUpdate(); { - const r = getLastResultOrThrow() + const r = getLastResultOrThrow(); if (r.status !== "ready") expect.fail(); expect(r.cancelHandler.onClick).not.undefined; expect(r.currency).eq(currency); - expect(r.account.value).eq("0") - expect(r.amount.value).eq("0") + expect(r.account.value).eq("0"); + expect(r.amount.value).eq("0"); expect(r.depositHandler.onClick).undefined; } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should not be able to deposit more than the balance ", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState(currency, nullFunction, nullFunction, { - getBalance: async () => ({ - balances: [{ available: `${currency}:1`, }] - } as Partial<BalancesResponse>), - listKnownBankAccounts: async () => ({ accounts: [ibanPayto] }), - getFeeForDeposit: withoutFee - } as Partial<typeof wxApi> as any) - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState(currency, nullFunction, nullFunction, { + getBalance: async () => + ({ + balances: [{ available: `${currency}:1` }], + } as Partial<BalancesResponse>), + listKnownBankAccounts: async () => ({ accounts: [ibanPayto] }), + getFeeForDeposit: withoutFee, + } as Partial<typeof wxApi> as any), + ); { - const { status } = getLastResultOrThrow() - expect(status).equal("loading") + const { status } = getLastResultOrThrow(); + expect(status).equal("loading"); } - await waitNextUpdate() + await waitNextUpdate(); { - const r = getLastResultOrThrow() + const r = getLastResultOrThrow(); if (r.status !== "ready") expect.fail(); expect(r.cancelHandler.onClick).not.undefined; expect(r.currency).eq(currency); - expect(r.account.value).eq("0") - expect(r.amount.value).eq("0") + expect(r.account.value).eq("0"); + expect(r.amount.value).eq("0"); expect(r.depositHandler.onClick).undefined; - expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)) + expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)); - r.amount.onInput("10") + r.amount.onInput("10"); } - await waitNextUpdate() + await waitNextUpdate(); { - const r = getLastResultOrThrow() + const r = getLastResultOrThrow(); if (r.status !== "ready") expect.fail(); expect(r.cancelHandler.onClick).not.undefined; expect(r.currency).eq(currency); - expect(r.account.value).eq("0") - expect(r.amount.value).eq("10") - expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)) + expect(r.account.value).eq("0"); + expect(r.amount.value).eq("10"); + expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)); expect(r.depositHandler.onClick).undefined; } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should calculate the fee upon entering amount ", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState(currency, nullFunction, nullFunction, { - getBalance: async () => ({ - balances: [{ available: `${currency}:1`, }] - } as Partial<BalancesResponse>), - listKnownBankAccounts: async () => ({ accounts: [ibanPayto] }), - getFeeForDeposit: withSomeFee - } as Partial<typeof wxApi> as any) - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState(currency, nullFunction, nullFunction, { + getBalance: async () => + ({ + balances: [{ available: `${currency}:1` }], + } as Partial<BalancesResponse>), + listKnownBankAccounts: async () => ({ accounts: [ibanPayto] }), + getFeeForDeposit: withSomeFee, + } as Partial<typeof wxApi> as any), + ); { - const { status } = getLastResultOrThrow() - expect(status).equal("loading") + const { status } = getLastResultOrThrow(); + expect(status).equal("loading"); } - await waitNextUpdate() + await waitNextUpdate(); { - const r = getLastResultOrThrow() + const r = getLastResultOrThrow(); if (r.status !== "ready") expect.fail(); expect(r.cancelHandler.onClick).not.undefined; expect(r.currency).eq(currency); - expect(r.account.value).eq("0") - expect(r.amount.value).eq("0") + expect(r.account.value).eq("0"); + expect(r.amount.value).eq("0"); expect(r.depositHandler.onClick).undefined; - expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)) + expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)); - r.amount.onInput("10") + r.amount.onInput("10"); } - await waitNextUpdate() + await waitNextUpdate(); { - const r = getLastResultOrThrow() + const r = getLastResultOrThrow(); if (r.status !== "ready") expect.fail(); expect(r.cancelHandler.onClick).not.undefined; expect(r.currency).eq(currency); - expect(r.account.value).eq("0") - expect(r.amount.value).eq("10") - expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)) - expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:7`)) + expect(r.account.value).eq("0"); + expect(r.amount.value).eq("10"); + expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)); + expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:7`)); expect(r.depositHandler.onClick).undefined; } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); it("should calculate the fee upon selecting account ", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState(currency, nullFunction, nullFunction, { - getBalance: async () => ({ - balances: [{ available: `${currency}:1`, }] - } as Partial<BalancesResponse>), - listKnownBankAccounts: async () => ({ accounts: [ibanPayto, talerBankPayto] }), - getFeeForDeposit: freeJustForIBAN - } as Partial<typeof wxApi> as any) - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState(currency, nullFunction, nullFunction, { + getBalance: async () => + ({ + balances: [{ available: `${currency}:1` }], + } as Partial<BalancesResponse>), + listKnownBankAccounts: async () => ({ + accounts: [ibanPayto, talerBankPayto], + }), + getFeeForDeposit: freeJustForIBAN, + } as Partial<typeof wxApi> as any), + ); { - const { status } = getLastResultOrThrow() - expect(status).equal("loading") + const { status } = getLastResultOrThrow(); + expect(status).equal("loading"); } - await waitNextUpdate() + await waitNextUpdate(); { - const r = getLastResultOrThrow() + const r = getLastResultOrThrow(); if (r.status !== "ready") expect.fail(); expect(r.cancelHandler.onClick).not.undefined; expect(r.currency).eq(currency); - expect(r.account.value).eq("0") - expect(r.amount.value).eq("0") + expect(r.account.value).eq("0"); + expect(r.amount.value).eq("0"); expect(r.depositHandler.onClick).undefined; - expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)) + expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)); if (r.account.onChange === undefined) expect.fail(); - r.account.onChange("1") + r.account.onChange("1"); } - await waitNextUpdate() + await waitNextUpdate(); { - const r = getLastResultOrThrow() + const r = getLastResultOrThrow(); if (r.status !== "ready") expect.fail(); expect(r.cancelHandler.onClick).not.undefined; expect(r.currency).eq(currency); - expect(r.account.value).eq("1") - expect(r.amount.value).eq("0") - expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)) - expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:0`)) + expect(r.account.value).eq("1"); + expect(r.amount.value).eq("0"); + expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)); + expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:0`)); expect(r.depositHandler.onClick).undefined; - r.amount.onInput("10") + r.amount.onInput("10"); } - await waitNextUpdate() + await waitNextUpdate(); { - const r = getLastResultOrThrow() + const r = getLastResultOrThrow(); if (r.status !== "ready") expect.fail(); expect(r.cancelHandler.onClick).not.undefined; expect(r.currency).eq(currency); - expect(r.account.value).eq("1") - expect(r.amount.value).eq("10") - expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)) - expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:7`)) + expect(r.account.value).eq("1"); + expect(r.amount.value).eq("10"); + expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)); + expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:7`)); expect(r.depositHandler.onClick).undefined; if (r.account.onChange === undefined) expect.fail(); - r.account.onChange("0") + r.account.onChange("0"); } - await waitNextUpdate() + await waitNextUpdate(); { - const r = getLastResultOrThrow() + const r = getLastResultOrThrow(); if (r.status !== "ready") expect.fail(); expect(r.cancelHandler.onClick).not.undefined; expect(r.currency).eq(currency); - expect(r.account.value).eq("0") - expect(r.amount.value).eq("10") - expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)) - expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:10`)) + expect(r.account.value).eq("0"); + expect(r.amount.value).eq("10"); + expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)); + expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:10`)); expect(r.depositHandler.onClick).undefined; - } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); - it("should be able to deposit if has the enough balance ", async () => { - const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = mountHook(() => - useComponentState(currency, nullFunction, nullFunction, { - getBalance: async () => ({ - balances: [{ available: `${currency}:15`, }] - } as Partial<BalancesResponse>), - listKnownBankAccounts: async () => ({ accounts: [ibanPayto] }), - getFeeForDeposit: withSomeFee - } as Partial<typeof wxApi> as any) - ); + const { getLastResultOrThrow, waitNextUpdate, assertNoPendingUpdate } = + mountHook(() => + useComponentState(currency, nullFunction, nullFunction, { + getBalance: async () => + ({ + balances: [{ available: `${currency}:15` }], + } as Partial<BalancesResponse>), + listKnownBankAccounts: async () => ({ accounts: [ibanPayto] }), + getFeeForDeposit: withSomeFee, + } as Partial<typeof wxApi> as any), + ); { - const { status } = getLastResultOrThrow() - expect(status).equal("loading") + const { status } = getLastResultOrThrow(); + expect(status).equal("loading"); } - await waitNextUpdate() + await waitNextUpdate(); { - const r = getLastResultOrThrow() + const r = getLastResultOrThrow(); if (r.status !== "ready") expect.fail(); expect(r.cancelHandler.onClick).not.undefined; expect(r.currency).eq(currency); - expect(r.account.value).eq("0") - expect(r.amount.value).eq("0") + expect(r.account.value).eq("0"); + expect(r.amount.value).eq("0"); expect(r.depositHandler.onClick).undefined; - expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)) + expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:0`)); - r.amount.onInput("10") + r.amount.onInput("10"); } - await waitNextUpdate() + await waitNextUpdate(); { - const r = getLastResultOrThrow() + const r = getLastResultOrThrow(); if (r.status !== "ready") expect.fail(); expect(r.cancelHandler.onClick).not.undefined; expect(r.currency).eq(currency); - expect(r.account.value).eq("0") - expect(r.amount.value).eq("10") - expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)) - expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:7`)) + expect(r.account.value).eq("0"); + expect(r.amount.value).eq("10"); + expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)); + expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:7`)); expect(r.depositHandler.onClick).not.undefined; - r.amount.onInput("13") + r.amount.onInput("13"); } - await waitNextUpdate() + await waitNextUpdate(); { - const r = getLastResultOrThrow() + const r = getLastResultOrThrow(); if (r.status !== "ready") expect.fail(); expect(r.cancelHandler.onClick).not.undefined; expect(r.currency).eq(currency); - expect(r.account.value).eq("0") - expect(r.amount.value).eq("13") - expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)) - expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:10`)) + expect(r.account.value).eq("0"); + expect(r.amount.value).eq("13"); + expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)); + expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:10`)); expect(r.depositHandler.onClick).not.undefined; - r.amount.onInput("15") + r.amount.onInput("15"); } - await waitNextUpdate() + await waitNextUpdate(); { - const r = getLastResultOrThrow() + const r = getLastResultOrThrow(); if (r.status !== "ready") expect.fail(); expect(r.cancelHandler.onClick).not.undefined; expect(r.currency).eq(currency); - expect(r.account.value).eq("0") - expect(r.amount.value).eq("15") - expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)) - expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:12`)) + expect(r.account.value).eq("0"); + expect(r.amount.value).eq("15"); + expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)); + expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:12`)); expect(r.depositHandler.onClick).not.undefined; - r.amount.onInput("17") + r.amount.onInput("17"); } - await waitNextUpdate() + await waitNextUpdate(); { - const r = getLastResultOrThrow() + const r = getLastResultOrThrow(); if (r.status !== "ready") expect.fail(); expect(r.cancelHandler.onClick).not.undefined; expect(r.currency).eq(currency); - expect(r.account.value).eq("0") - expect(r.amount.value).eq("17") - expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)) - expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:14`)) + expect(r.account.value).eq("0"); + expect(r.amount.value).eq("17"); + expect(r.totalFee).deep.eq(Amounts.parseOrThrow(`${currency}:3`)); + expect(r.totalToDeposit).deep.eq(Amounts.parseOrThrow(`${currency}:14`)); expect(r.depositHandler.onClick).undefined; } - await assertNoPendingUpdate() + await assertNoPendingUpdate(); }); - -});
\ No newline at end of file +}); diff --git a/packages/taler-wallet-webextension/src/wxApi.ts b/packages/taler-wallet-webextension/src/wxApi.ts index 63840017b..dd26d1b5b 100644 --- a/packages/taler-wallet-webextension/src/wxApi.ts +++ b/packages/taler-wallet-webextension/src/wxApi.ts @@ -151,7 +151,6 @@ export function runGarbageCollector(): Promise<void> { return callBackend("run-gc", {}); } - export function getFeeForDeposit( depositPaytoUri: string, amount: AmountString, @@ -338,7 +337,7 @@ export function acceptWithdrawal( return callBackend("acceptBankIntegratedWithdrawal", { talerWithdrawUri, exchangeBaseUrl: selectedExchange, - restrictAge + restrictAge, }); } @@ -356,7 +355,7 @@ export function acceptManualWithdrawal( return callBackend("acceptManualWithdrawal", { amount, exchangeBaseUrl, - restrictAge + restrictAge, }); } @@ -432,11 +431,12 @@ export function addExchange(req: AddExchangeRequest): Promise<void> { return callBackend("addExchange", req); } -export function prepareRefund(req: PrepareRefundRequest): Promise<PrepareRefundResult> { +export function prepareRefund( + req: PrepareRefundRequest, +): Promise<PrepareRefundResult> { return callBackend("prepareRefund", req); } - export function prepareTip(req: PrepareTipRequest): Promise<PrepareTipResult> { return callBackend("prepareTip", req); } diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts b/packages/taler-wallet-webextension/src/wxBackend.ts index 532b28622..89031ebc9 100644 --- a/packages/taler-wallet-webextension/src/wxBackend.ts +++ b/packages/taler-wallet-webextension/src/wxBackend.ts @@ -26,9 +26,11 @@ import { classifyTalerUri, CoreApiResponse, - CoreApiResponseSuccess, Logger, TalerErrorCode, + CoreApiResponseSuccess, + Logger, + TalerErrorCode, TalerUriType, - WalletDiagnostics + WalletDiagnostics, } from "@gnu-taler/taler-util"; import { DbAccess, @@ -40,7 +42,7 @@ import { openPromise, openTalerDatabase, Wallet, - WalletStoresV1 + WalletStoresV1, } from "@gnu-taler/taler-wallet-core"; import { SetTimeoutTimerAPI } from "@gnu-taler/taler-wallet-core"; import { BrowserCryptoWorkerFactory } from "./browserCryptoWorkerFactory.js"; @@ -133,14 +135,14 @@ async function dispatch( break; } case "run-gc": { - logger.info("gc") + logger.info("gc"); const dump = await exportDb(currentDatabase!.idbHandle()); await deleteTalerDatabase(indexedDB as any); - logger.info("cleaned") + logger.info("cleaned"); await reinitWallet(); - logger.info("init") - await importDb(currentDatabase!.idbHandle(), dump) - logger.info("imported") + logger.info("init"); + await importDb(currentDatabase!.idbHandle(), dump); + logger.info("imported"); r = wrapResponse({ result: true }); break; } @@ -156,7 +158,9 @@ async function dispatch( platform.registerTalerHeaderListener(parseTalerUriAndRedirect); r = wrapResponse({ newValue: true }); } else { - const rem = await platform.getPermissionsApi().removeHostPermissions(); + const rem = await platform + .getPermissionsApi() + .removeHostPermissions(); logger.trace("permissions removed:", rem); r = wrapResponse({ newVal: false }); } @@ -184,7 +188,7 @@ async function dispatch( sendResponse(r); } catch (e) { - logger.error(`Error sending operation: ${req.operation}`, e) + logger.error(`Error sending operation: ${req.operation}`, e); // might fail if tab disconnected } } @@ -218,7 +222,12 @@ async function reinitWallet(): Promise<void> { } logger.info("Setting up wallet"); - const wallet = await Wallet.create(currentDatabase, httpLib, timer, cryptoWorker); + const wallet = await Wallet.create( + currentDatabase, + httpLib, + timer, + cryptoWorker, + ); try { await wallet.handleCoreApiRequest("initWallet", "native-init", {}); } catch (e) { @@ -228,14 +237,14 @@ async function reinitWallet(): Promise<void> { } wallet.addNotificationListener((x) => { const message: MessageFromBackend = { type: x.type }; - platform.sendMessageToAllChannels(message) + platform.sendMessageToAllChannels(message); }); platform.keepAlive(() => { return wallet.runTaskLoop().catch((e) => { logger.error("error during wallet task loop", e); }); - }) + }); // Useful for debugging in the background page. if (typeof window !== "undefined") { (window as any).talerWallet = wallet; @@ -279,14 +288,13 @@ function parseTalerUriAndRedirect(tabId: number, talerUri: string): void { } } - /** * Main function to run for the WebExtension backend. * * Sets up all event handlers and other machinery. */ export async function wxMain(): Promise<void> { - logger.trace("starting") + logger.trace("starting"); const afterWalletIsInitialized = reinitWallet(); platform.registerReloadOnNewVersion(); @@ -297,9 +305,9 @@ export async function wxMain(): Promise<void> { afterWalletIsInitialized.then(() => { dispatch(message, sender, callback); }); - }) + }); - platform.registerAllIncomingConnections() + platform.registerAllIncomingConnections(); try { platform.registerTalerHeaderListener(parseTalerUriAndRedirect); @@ -311,7 +319,10 @@ export async function wxMain(): Promise<void> { // modification of permissions. platform.getPermissionsApi().addPermissionsListener((perm, lastError) => { if (lastError) { - logger.error(`there was a problem trying to get permission ${perm}`, lastError); + logger.error( + `there was a problem trying to get permission ${perm}`, + lastError, + ); return; } platform.registerTalerHeaderListener(parseTalerUriAndRedirect); diff --git a/packages/taler-wallet-webextension/tsconfig.json b/packages/taler-wallet-webextension/tsconfig.json index 9d5f05c5e..012e4eee9 100644 --- a/packages/taler-wallet-webextension/tsconfig.json +++ b/packages/taler-wallet-webextension/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "composite": true, "lib": [ - "es6", + "es2021", "DOM" ], "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ @@ -37,4 +37,4 @@ "include": [ "src/**/*" ] -} +}
\ No newline at end of file |