@odus/checkout 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,2016 @@
1
+ const P = ({ name: r }) => {
2
+ const [e, ...t] = r?.split(" ") || [], [a] = t.reverse();
3
+ return { firstName: e, lastName: a };
4
+ };
5
+ class D {
6
+ apiKey;
7
+ baseUrl;
8
+ browserInfo;
9
+ constructor(e, t = "http://localhost:3000", a) {
10
+ this.apiKey = e, this.baseUrl = t, this.browserInfo = a || { userAgent: navigator.userAgent };
11
+ }
12
+ async fetchApi({
13
+ endpoint: e,
14
+ method: t = "POST",
15
+ body: a,
16
+ customHeaders: i = {}
17
+ }) {
18
+ const s = {
19
+ Authorization: `Bearer ${this.apiKey}`,
20
+ "Content-Type": "application/json",
21
+ ...i
22
+ };
23
+ try {
24
+ const n = await fetch(`${this.baseUrl}${e}`, {
25
+ method: t,
26
+ headers: s,
27
+ body: a ? JSON.stringify(a) : void 0
28
+ });
29
+ if (!n.ok) {
30
+ let o;
31
+ try {
32
+ o = await n.json();
33
+ } catch (d) {
34
+ console.log("error", d);
35
+ }
36
+ throw {
37
+ message: o?.message[0] || `API request failed: ${n.status} ${n.statusText}`,
38
+ status: n.status,
39
+ statusText: n.statusText,
40
+ details: o
41
+ };
42
+ }
43
+ return n.json();
44
+ } catch (n) {
45
+ throw n instanceof Error ? {
46
+ message: n.message,
47
+ status: 0,
48
+ // Use 0 for network/client errors
49
+ statusText: "Network Error",
50
+ details: { message: n.message }
51
+ } : n;
52
+ }
53
+ }
54
+ async authorizePayment({
55
+ paymentId: e,
56
+ checkoutKey: t,
57
+ formData: a,
58
+ token: i,
59
+ returnUrl: s
60
+ }) {
61
+ let n = {};
62
+ if (i && a) {
63
+ const o = a.cardExpiry.replace(/\s+/g, "").split("/"), l = o[0], d = o[1], { firstName: c, lastName: m } = P({ name: a.name });
64
+ n = {
65
+ paymentMethodData: {
66
+ type: "card",
67
+ card: {
68
+ token: i,
69
+ expMonth: l,
70
+ expYear: `20${d}`,
71
+ cardholderName: a.name
72
+ }
73
+ },
74
+ customerData: {
75
+ email: a.email,
76
+ firstName: c,
77
+ lastName: m
78
+ },
79
+ context: {
80
+ returnUrl: s,
81
+ browserInfo: this.browserInfo
82
+ }
83
+ };
84
+ } else
85
+ n = {
86
+ paymentMethodData: {
87
+ type: "paypal"
88
+ },
89
+ context: {
90
+ returnUrl: s,
91
+ browserInfo: this.browserInfo
92
+ }
93
+ };
94
+ return await this.fetchApi({
95
+ endpoint: `/payments/${e}/authorize`,
96
+ customHeaders: {
97
+ Authorization: `Bearer ${t}`
98
+ },
99
+ body: n
100
+ });
101
+ }
102
+ }
103
+ const A = "http://localhost:3000", $ = async ({ id: r, apiKey: e }) => {
104
+ const t = await fetch(`${A}/checkout-profiles/${r}`, {
105
+ method: "GET",
106
+ headers: {
107
+ "Content-Type": "application/json",
108
+ Authorization: `Bearer ${e}`
109
+ }
110
+ });
111
+ if (!t.ok)
112
+ throw new Error(`HTTP error! Status: ${t.status}`);
113
+ return await t.json();
114
+ };
115
+ class V {
116
+ events = /* @__PURE__ */ new Map();
117
+ /**
118
+ * Subscribe to an event
119
+ * @param eventName - The name of the event to subscribe to
120
+ * @param callback - The callback function to be called when the event is published
121
+ * @returns A function to unsubscribe from the event
122
+ */
123
+ subscribe(e, t) {
124
+ return this.events.has(e) || this.events.set(e, /* @__PURE__ */ new Set()), this.events.get(e)?.add(t), () => {
125
+ const a = this.events.get(e);
126
+ a && (a.delete(t), a.size === 0 && this.events.delete(e));
127
+ };
128
+ }
129
+ /**
130
+ * Publish an event with data
131
+ * @param eventName - The name of the event to publish
132
+ * @param data - The data to pass to subscribers
133
+ */
134
+ publish(e, t) {
135
+ const a = this.events.get(e);
136
+ a && a.forEach((i) => i(t));
137
+ }
138
+ /**
139
+ * Clear all event subscriptions
140
+ */
141
+ clear() {
142
+ this.events.clear();
143
+ }
144
+ /**
145
+ * Get the number of subscribers for an event
146
+ * @param eventName - The name of the event
147
+ * @returns The number of subscribers
148
+ */
149
+ subscriberCount(e) {
150
+ return this.events.get(e)?.size || 0;
151
+ }
152
+ }
153
+ const R = new V();
154
+ class B {
155
+ state;
156
+ initialState;
157
+ eventBus;
158
+ stateChangedEvent = "state-changed";
159
+ constructor(e, t = R) {
160
+ this.initialState = { ...e }, this.state = { ...e }, this.eventBus = t;
161
+ }
162
+ /**
163
+ * Get the current state
164
+ */
165
+ getState() {
166
+ return Object.freeze({ ...this.state });
167
+ }
168
+ /**
169
+ * Update the state
170
+ * @param partialState - Partial state to merge with current state
171
+ */
172
+ setState(e) {
173
+ const t = { ...this.state, ...e };
174
+ JSON.stringify(this.state) !== JSON.stringify(t) && (this.state = t, this.eventBus.publish(this.stateChangedEvent, this.getState()));
175
+ }
176
+ /**
177
+ * Reset the state to initial values
178
+ */
179
+ resetState() {
180
+ this.state = { ...this.initialState }, this.eventBus.publish(this.stateChangedEvent, this.getState());
181
+ }
182
+ /**
183
+ * Subscribe to state changes
184
+ * @param callback - Function to call when state changes
185
+ * @returns Unsubscribe function
186
+ */
187
+ subscribe(e) {
188
+ return this.eventBus.subscribe(this.stateChangedEvent, e);
189
+ }
190
+ /**
191
+ * Get a specific value from the state
192
+ * @param key - The key to get the value for
193
+ * @returns The value for the key
194
+ */
195
+ getValue(e) {
196
+ return this.state[e];
197
+ }
198
+ }
199
+ function x(r) {
200
+ return new B(r);
201
+ }
202
+ function O({
203
+ apiKey: r,
204
+ profileId: e
205
+ }) {
206
+ const t = x({
207
+ checkoutProfile: void 0,
208
+ isLoading: !0,
209
+ error: null
210
+ }), a = async () => {
211
+ try {
212
+ t.setState({ isLoading: !0 });
213
+ const i = await $({ apiKey: r, id: e });
214
+ i && t.setState({
215
+ checkoutProfile: i,
216
+ isLoading: !1,
217
+ error: null
218
+ });
219
+ } catch (i) {
220
+ t.setState({
221
+ error: "Failed to load checkout profile",
222
+ isLoading: !1
223
+ }), console.error(i);
224
+ }
225
+ };
226
+ return a(), {
227
+ getState: t.getState.bind(t),
228
+ subscribe: t.subscribe.bind(t),
229
+ reload: a
230
+ };
231
+ }
232
+ const k = {
233
+ cardNumber: (r) => (r.replace(/\s/g, "").match(/.{1,4}/g) || []).join(" "),
234
+ cardExpiry: (r) => {
235
+ const t = r.replace(/\D/g, "").slice(0, 4);
236
+ return t.length > 2 ? `${t.slice(0, 2)} / ${t.slice(2)}` : t;
237
+ }
238
+ }, z = {
239
+ "gmail.com": [
240
+ "gmal.com",
241
+ "gmil.com",
242
+ "gmai.com",
243
+ "gmial.com",
244
+ "gmail.co",
245
+ "gmaill.com",
246
+ "gamil.com",
247
+ "gmailcom",
248
+ "gmail.cm",
249
+ "gmail.om"
250
+ ],
251
+ "yahoo.com": [
252
+ "yaho.com",
253
+ "yahooo.com",
254
+ "yahoo.co",
255
+ "yhoo.com",
256
+ "yahocom",
257
+ "yahoo.cm",
258
+ "yah00.com",
259
+ "yaho0.com",
260
+ "hoo.com"
261
+ ],
262
+ "hotmail.com": [
263
+ "hotmal.com",
264
+ "hotamail.com",
265
+ "hotmai.com",
266
+ "hotmial.com",
267
+ "hotmail.co",
268
+ "hotmailcom",
269
+ "hotmail.cm",
270
+ "htmail.com",
271
+ "hotmil.com"
272
+ ],
273
+ "outlook.com": [
274
+ "outlok.com",
275
+ "outloo.com",
276
+ "outlook.co",
277
+ "outllok.com",
278
+ "outlook.cm",
279
+ "outlookcom",
280
+ "outloook.com",
281
+ "outook.com",
282
+ "otlook.com"
283
+ ],
284
+ "icloud.com": [
285
+ "iclod.com",
286
+ "iclud.com",
287
+ "icloud.co",
288
+ "icloudcom",
289
+ "icloud.cm",
290
+ "iclou.com",
291
+ "icloude.com",
292
+ "icld.com",
293
+ "iclould.com"
294
+ ],
295
+ "aol.com": ["aol.co", "aolcom", "aol.cm", "aolmail.com", "al.com", "ao.com", "aol.comm"],
296
+ "protonmail.com": [
297
+ "protonmal.com",
298
+ "protonmai.com",
299
+ "protonmial.com",
300
+ "protonmail.co",
301
+ "protonmailcom",
302
+ "protonmail.cm",
303
+ "protonmil.com"
304
+ ],
305
+ "zoho.com": ["zoho.co", "zohocom", "zoho.cm", "zoh.com", "zohomail.com", "zho.com"],
306
+ "mail.com": ["mail.co", "mailcom", "mail.cm", "mal.com", "mial.com", "mail.comm"],
307
+ "comcast.net": ["comcast.com", "comcat.net", "comcst.net", "comcastnet", "comcast.nt", "comcas.net"],
308
+ "verizon.net": ["verizon.com", "verizon.nt", "verizonnet", "verizn.net", "verizon.ne", "verzon.net"],
309
+ "att.net": ["att.com", "at.net", "att.nt", "attnet", "att.ne", "attt.net"]
310
+ }, H = (r) => {
311
+ if (!r || r.includes("."))
312
+ return null;
313
+ const e = ["com", "net", "org", "edu", "gov", "io", "co"];
314
+ for (const t of e) {
315
+ if (r === "companycok" && t === "co")
316
+ return "company.co";
317
+ if (r.endsWith(t) && !r.includes(".")) {
318
+ const a = r.length - t.length;
319
+ return `${r.substring(0, a)}.${t}`;
320
+ }
321
+ }
322
+ return null;
323
+ }, j = (r, e) => {
324
+ if (r.length === 0) return e.length;
325
+ if (e.length === 0) return r.length;
326
+ const t = e.length + 1, a = r.length + 1, i = Array.from(
327
+ { length: t },
328
+ (s, n) => Array.from({ length: a }, (o, l) => n === 0 ? l : l === 0 ? n : 0)
329
+ );
330
+ for (let s = 1; s < t; s++)
331
+ for (let n = 1; n < a; n++) {
332
+ const o = r[n - 1] === e[s - 1] ? 0 : 1;
333
+ i[s][n] = Math.min(
334
+ i[s - 1][n] + 1,
335
+ // deletion
336
+ i[s][n - 1] + 1,
337
+ // insertion
338
+ i[s - 1][n - 1] + o
339
+ // substitution
340
+ );
341
+ }
342
+ return i[e.length][r.length];
343
+ }, K = (r) => {
344
+ let t = null, a = 3;
345
+ const i = r.toLowerCase();
346
+ for (const s of Object.keys(z)) {
347
+ const n = j(i, s);
348
+ n <= 2 && n < a && (a = n, t = s);
349
+ }
350
+ return t;
351
+ }, U = () => {
352
+ const { t: r } = L();
353
+ return {
354
+ validateEmail: (t) => {
355
+ const a = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
356
+ if (!t)
357
+ return {
358
+ isValid: !1,
359
+ message: r("validation.emailInvalid"),
360
+ suggestion: null
361
+ };
362
+ const i = t.indexOf("@");
363
+ if (i === -1)
364
+ return {
365
+ isValid: !1,
366
+ message: r("validation.emailInvalid"),
367
+ suggestion: null
368
+ };
369
+ const s = t.substring(0, i), n = t.substring(i + 1);
370
+ if (!n.includes(".")) {
371
+ const l = H(n);
372
+ if (l)
373
+ return {
374
+ isValid: !1,
375
+ message: r("validation.emailSuggestion", {
376
+ email: `${s}@${l}`
377
+ }),
378
+ suggestion: `${s}@${l}`
379
+ };
380
+ for (const d of Object.keys(z))
381
+ if (d.replace(/\./g, "") === n)
382
+ return {
383
+ isValid: !1,
384
+ message: r("validation.emailSuggestion", {
385
+ email: `${s}@${d}`
386
+ }),
387
+ suggestion: `${s}@${d}`
388
+ };
389
+ }
390
+ if (!a.test(t))
391
+ return {
392
+ isValid: !1,
393
+ message: r("validation.emailInvalid"),
394
+ suggestion: null
395
+ };
396
+ const o = K(n);
397
+ if (o && o !== n) {
398
+ const l = `${s}@${o}`;
399
+ return {
400
+ isValid: !1,
401
+ message: r("validation.emailSuggestion", { email: l }),
402
+ suggestion: l
403
+ };
404
+ }
405
+ return {
406
+ isValid: !0,
407
+ message: "Email is valid",
408
+ suggestion: null
409
+ };
410
+ }
411
+ };
412
+ }, q = () => {
413
+ const { t: r } = L(), { validateEmail: e } = U();
414
+ return {
415
+ email: (t) => {
416
+ const a = e(t);
417
+ return a.isValid ? void 0 : a.message;
418
+ },
419
+ name: (t) => {
420
+ if (!t.trim())
421
+ return r("validation.nameRequired");
422
+ },
423
+ cardExpiry: (t) => {
424
+ const a = t.replace(/\s/g, ""), [i, s] = a.split("/").map((m) => m.trim());
425
+ if (!i || !s || i.length !== 2 || s.length !== 2)
426
+ return r("validation.cardExpiryFormat");
427
+ const n = /* @__PURE__ */ new Date(), o = n.getFullYear() % 100, l = n.getMonth() + 1, d = parseInt(i, 10), c = parseInt(s, 10);
428
+ if (d < 1 || d > 12)
429
+ return r("validation.cardExpiryFormat");
430
+ if (c < o || c === o && d < l)
431
+ return r("validation.cardExpiryInvalid");
432
+ }
433
+ };
434
+ }, G = () => {
435
+ const r = q(), e = x({
436
+ formData: {
437
+ name: "",
438
+ email: "",
439
+ cardExpiry: ""
440
+ },
441
+ errors: {},
442
+ touched: {
443
+ email: !1,
444
+ name: !1,
445
+ cardExpiry: !1
446
+ },
447
+ isValid: !1
448
+ }), t = (l, d) => {
449
+ const c = r[l];
450
+ return c?.(d);
451
+ }, a = (l) => {
452
+ const d = {};
453
+ return Object.keys(l).forEach((c) => {
454
+ const m = t(c, l[c]);
455
+ m && (d[c] = m);
456
+ }), d;
457
+ }, i = (l) => {
458
+ const d = a(l);
459
+ return Object.keys(d).length === 0;
460
+ }, s = (l, d) => {
461
+ const c = e.getState();
462
+ let m = d;
463
+ l in k && (m = k[l](d));
464
+ const p = {
465
+ ...c.formData,
466
+ [l]: m
467
+ }, u = { ...c.errors };
468
+ if (c.touched[l]) {
469
+ const f = t(l, m);
470
+ f ? u[l] = f : delete u[l];
471
+ }
472
+ e.setState({
473
+ formData: p,
474
+ errors: u,
475
+ isValid: i(p)
476
+ });
477
+ }, n = (l, d) => {
478
+ const c = e.getState(), m = {
479
+ ...c.touched,
480
+ [l]: !0
481
+ }, p = t(l, d), u = { ...c.errors };
482
+ p ? u[l] = p : delete u[l], e.setState({
483
+ touched: m,
484
+ errors: u
485
+ });
486
+ }, o = (l) => {
487
+ const c = {
488
+ ...e.getState().formData,
489
+ ...l
490
+ };
491
+ e.setState({
492
+ formData: c,
493
+ isValid: i(c)
494
+ });
495
+ };
496
+ return {
497
+ getFormState: e.getState.bind(e),
498
+ subscribe: e.subscribe.bind(e),
499
+ handleChange: s,
500
+ handleBlur: n,
501
+ setFormData: o,
502
+ reset: e.resetState.bind(e)
503
+ };
504
+ }, _ = "http://localhost:3000", Z = async ({ props: r, apiKey: e }) => {
505
+ const t = await fetch(`${_}/tokenization/generate-iframe-configuration`, {
506
+ method: "POST",
507
+ headers: {
508
+ "Content-Type": "application/json",
509
+ Authorization: `Bearer ${e}`
510
+ },
511
+ body: JSON.stringify(r)
512
+ });
513
+ if (!t.ok)
514
+ throw new Error(`HTTP error! Status: ${t.status}`);
515
+ return await t.json();
516
+ };
517
+ function Y({
518
+ apiKey: r,
519
+ // scriptLoaded,
520
+ checkoutProfile: e,
521
+ inputStyles: t,
522
+ setFormData: a
523
+ }) {
524
+ const i = x({
525
+ iframeConfig: void 0,
526
+ loadingIframe: !0,
527
+ isCcValid: !1,
528
+ isCvvValid: !1,
529
+ isFocused: !1,
530
+ isCvvFocused: !1,
531
+ possibleCardType: "unknown"
532
+ });
533
+ let s = null;
534
+ const n = async () => {
535
+ try {
536
+ const c = await Z({
537
+ props: {
538
+ allowedOrigins: [globalThis.location.origin]
539
+ },
540
+ apiKey: r
541
+ });
542
+ c && (i.setState({
543
+ iframeConfig: {
544
+ ...c,
545
+ origin: globalThis.location.origin
546
+ }
547
+ }), o());
548
+ } catch (c) {
549
+ console.error("Failed to generate iframe config:", c);
550
+ }
551
+ }, o = () => {
552
+ const c = i.getState();
553
+ if (c.iframeConfig && e) {
554
+ if (!globalThis.TokenEx?.Iframe) {
555
+ console.error("TokenEx script not loaded correctly");
556
+ return;
557
+ }
558
+ s = new globalThis.TokenEx.Iframe("card-element", {
559
+ ...c.iframeConfig,
560
+ placeholder: "1234 1234 1234 1234",
561
+ cvvPlaceholder: "CVC",
562
+ cvv: !0,
563
+ cvvContainerID: "card-cvv-element",
564
+ enableValidateOnBlur: !1,
565
+ enableValidateOnKeyUp: !0,
566
+ enableValidateOnCvvKeyUp: !0,
567
+ enablePrettyFormat: !0,
568
+ inputMode: "numeric",
569
+ cvvInputType: "numeric",
570
+ font: e.styles.fontFamily,
571
+ enableAutoComplete: !0,
572
+ returnAutoCompleteValues: !0,
573
+ useExtendedBIN: !0,
574
+ styles: {
575
+ ...t,
576
+ base: `${t.base}; sans-serif; border-radius: ${e.styles.borderRadius}px ${e.styles.borderRadius}px 0px 0px`,
577
+ cvv: {
578
+ ...t,
579
+ base: `${t.base}; border-radius: 0px 0px ${e.styles.borderRadius}px 0px`
580
+ }
581
+ }
582
+ }), s.on("load", () => {
583
+ i.setState({ loadingIframe: !1 });
584
+ }), s.on("autoCompleteValues", function(m) {
585
+ const { nameOnCard: p, cardExp: u } = m;
586
+ a({
587
+ name: p,
588
+ cardExpiry: u
589
+ });
590
+ }), s.on("validate", function(m) {
591
+ const { isValid: p, isCvvValid: u } = m;
592
+ i.setState({
593
+ isCcValid: p,
594
+ isCvvValid: u
595
+ });
596
+ }), s.on("focus", function() {
597
+ i.setState({ isFocused: !0 });
598
+ }), s.on("blur", function() {
599
+ i.setState({ isFocused: !1 });
600
+ }), s.on("cvvFocus", function() {
601
+ i.setState({ isCvvFocused: !0 });
602
+ }), s.on("cvvBlur", function() {
603
+ i.setState({ isCvvFocused: !1 });
604
+ }), s.on(
605
+ "cardTypeChange",
606
+ function({ possibleCardType: m }) {
607
+ i.setState({ possibleCardType: m });
608
+ }
609
+ ), s.load();
610
+ }
611
+ };
612
+ r && n();
613
+ const l = () => {
614
+ s && (s.remove(), s = null);
615
+ }, d = async (c) => {
616
+ s && (s.on("tokenize", async function(m) {
617
+ await c(m);
618
+ }), s.tokenize());
619
+ };
620
+ return {
621
+ getState: i.getState.bind(i),
622
+ subscribe: i.subscribe.bind(i),
623
+ tokenize: d,
624
+ cleanup: l
625
+ };
626
+ }
627
+ const J = "E-Mail", W = "Name des/der Karteninhaber/in", X = "Kartendaten", Q = "Vollständiger Name", ee = "MM / JJ", te = "Das Fenster nicht schließen", ae = { pay: "ZAHLEN", submit: "ABSENDEN", getPlan: "MEINEN PLAN ERHALTEN", donate: "spenden", book: "jetzt buchen", order: "jetzt bestellen" }, ie = { emailSuggestion: "Meinten Sie {{email}}?", emailInvalid: "Ihre E-Mail-Adresse ist nicht korrekt", cardExpiryInvalid: "Das Ablaufdatum Ihrer Karte liegt in der Vergangenheit", cardExpiryFormat: "Das Ablaufdatum Ihrer Karte ist unvollständig", cardSecurityFormat: "Der Sicherheitscode Ihrer Karte ist unvollständig", nameRequired: "Gib deinen Namen genau so ein, wie er auf deiner Karte steht", cardNumberInvalid: "Die Kartennummer ist unvollständig" }, se = {
628
+ email: J,
629
+ cardholderNameLabel: W,
630
+ cardInformation: X,
631
+ cardholderNamePlaceholder: Q,
632
+ cardExpiry: ee,
633
+ loading: te,
634
+ buttonTexts: ae,
635
+ validation: ie
636
+ }, re = "Email", ne = "Cardholder name", oe = "Card information", le = "Full name on card", ce = "MM / YY", de = "Do not close the window", he = { pay: "PAY", submit: "SUBMIT", getPlan: "GET MY PLAN", donate: "DONATE", book: "BOOK NOW", order: "ORDER NOW" }, me = { emailSuggestion: "Did you mean {{email}}?", emailInvalid: "Your email is not correct", cardExpiryInvalid: "Your card's expiration date is in the past", cardExpiryFormat: "Your card’s expiration date is incomplete", cardSecurityFormat: "Your card’s security code is incomplete", nameRequired: "Please enter the name as it appears on your card", cardNumberInvalid: "Your card number is invalid" }, ue = {
637
+ email: re,
638
+ cardholderNameLabel: ne,
639
+ cardInformation: oe,
640
+ cardholderNamePlaceholder: le,
641
+ cardExpiry: ce,
642
+ loading: de,
643
+ buttonTexts: he,
644
+ validation: me
645
+ }, pe = "Correo electrónico", fe = "Nombre del titular de la tarjeta", ge = "Información de la tarjeta", ye = "Nombre completo en la tarjeta", ve = "MM / AA", Ee = "Por favor, no cierre esta ventana", be = { pay: "PAGAR", submit: "ENVIAR", getPlan: "OBTENER MI PLAN", donate: "DONAR", book: "RESERVAR AHORA", order: "ORDENAR AHORA" }, Ce = { emailSuggestion: "¿Quisiste decir {{email}}?", emailInvalid: "Su correo electrónico no es válido", cardExpiryInvalid: "La fecha de vencimiento de la tarjeta ya pasó", cardExpiryFormat: "La fecha de vencimiento de su tarjeta está incompleta", cardSecurityFormat: "El código de seguridad de su tarjeta está incompleto", nameRequired: "Por favor, ingrese el nombre tal como aparece en su tarjeta", cardNumberInvalid: "Su número de tarjeta no es válido" }, Se = {
646
+ email: pe,
647
+ cardholderNameLabel: fe,
648
+ cardInformation: ge,
649
+ cardholderNamePlaceholder: ye,
650
+ cardExpiry: ve,
651
+ loading: Ee,
652
+ buttonTexts: be,
653
+ validation: Ce
654
+ }, xe = "E-mail", Fe = "Nom du titulaire de la carte", we = "Informations de la carte", Le = "Nom complet figurant sur la carte", Me = "MM / AA", ke = "Veuillez ne pas fermer cette fenêtre", Te = { pay: "PAYER", submit: "ENVOYER", getPlan: "OBTENIR MON PLAN", donate: "FAIRE UN DON", book: "RÉSERVER MAINTENANT", order: "COMMANDER MAINTENANT" }, Ie = { emailSuggestion: "Vouliez-vous dire {{email}}?", emailInvalid: "Votre adresse e-mail n’est pas valide", cardExpiryInvalid: "La date d'expiration de votre carte est dans le passé", cardExpiryFormat: "La date d’expiration de votre carte est incomplète", cardSecurityFormat: "Le code de sécurité de votre carte est incomplet", nameRequired: "Veuillez saisir le nom tel qu’il figure sur votre carte", cardNumberInvalid: "Votre numéro de carte est invalide" }, ze = {
655
+ email: xe,
656
+ cardholderNameLabel: Fe,
657
+ cardInformation: we,
658
+ cardholderNamePlaceholder: Le,
659
+ cardExpiry: Me,
660
+ loading: ke,
661
+ buttonTexts: Te,
662
+ validation: Ie
663
+ }, Ne = "Adres e-mail", Pe = "Imię i nazwisko posiadacza karty", De = "Informacje o karcie", Ae = "Imię i nazwisko na karcie", $e = "MM / RR", Ve = "Proszę nie zamykać tego okna", Re = { pay: "ZAPŁAĆ", submit: "WYŚLIJ", getPlan: "POBIERZ MÓJ PLAN", donate: "PRZEKAŻ DAROWIZNĘ", book: "ZAREZERWUJ TERAZ", order: "ZAMÓW TERAZ" }, Be = { emailSuggestion: "Czy chodziło Ci o {{email}}?", emailInvalid: "Państwa adres e-mail jest nieprawidłowy", cardExpiryInvalid: "Data ważności Państwa karty jest w przeszłości", cardExpiryFormat: "Data ważności Państwa karty jest niekompletna", cardSecurityFormat: "Kod zabezpieczający Państwa karty jest niekompletny", nameRequired: "Proszę wpisać imię i nazwisko tak, jak widnieje na karcie", cardNumberInvalid: "Numer Państwa karty jest nieprawidłowy" }, Oe = {
664
+ email: Ne,
665
+ cardholderNameLabel: Pe,
666
+ cardInformation: De,
667
+ cardholderNamePlaceholder: Ae,
668
+ cardExpiry: $e,
669
+ loading: Ve,
670
+ buttonTexts: Re,
671
+ validation: Be
672
+ }, He = "E-mail", je = "Nome do titular do cartão", Ke = "Informações do cartão", Ue = "Nome completo no cartão", qe = "MM / AA", Ge = "Por favor, não feche esta janela", _e = { pay: "PAGAR", submit: "ENVIAR", getPlan: "OBTER MEU PLANO", donate: "DOAR", book: "RESERVAR AGORA", order: "FAZER PEDIDO" }, Ze = { emailSuggestion: "Você quis dizer {{email}}?", emailInvalid: "O seu endereço de e-mail não é válido", cardExpiryInvalid: "A data de validade do seu cartão está no passado", cardExpiryFormat: "A data de validade do seu cartão está incompleta", cardSecurityFormat: "O código de segurança do seu cartão está incompleto", nameRequired: "Por favor, insira o nome conforme aparece no cartão", cardNumberInvalid: "O número do seu cartão é inválido" }, Ye = {
673
+ email: He,
674
+ cardholderNameLabel: je,
675
+ cardInformation: Ke,
676
+ cardholderNamePlaceholder: Ue,
677
+ cardExpiry: qe,
678
+ loading: Ge,
679
+ buttonTexts: _e,
680
+ validation: Ze
681
+ }, T = {
682
+ en: ue,
683
+ de: se,
684
+ es: Se,
685
+ fr: ze,
686
+ pl: Oe,
687
+ pt: Ye
688
+ // Add other locales here
689
+ };
690
+ class Je {
691
+ locale;
692
+ loadedLocales = /* @__PURE__ */ new Set();
693
+ constructor(e = "en") {
694
+ this.locale = e, this.loadedLocales.add(e);
695
+ }
696
+ setLocale(e) {
697
+ this.locale = e, this.loadedLocales.add(e);
698
+ }
699
+ getLocale() {
700
+ return this.locale;
701
+ }
702
+ translate(e, t) {
703
+ const a = this.getNestedTranslation(e);
704
+ return !t || a === e ? a : this.interpolate(a, t);
705
+ }
706
+ /* eslint-disable @typescript-eslint/no-explicit-any */
707
+ getNestedTranslation(e) {
708
+ const t = this.locale in T ? T[this.locale] : {}, a = this.findNestedValue(t, e);
709
+ return a === void 0 ? e : a;
710
+ }
711
+ findNestedValue(e, t) {
712
+ const a = t.split(".");
713
+ let i = e;
714
+ for (const s of a) {
715
+ if (i == null || !Object.prototype.hasOwnProperty.call(i, s))
716
+ return;
717
+ i = i[s];
718
+ }
719
+ return typeof i == "string" ? i : void 0;
720
+ }
721
+ interpolate(e, t) {
722
+ return e.replace(/{{(\w+)}}/g, (a, i) => {
723
+ const s = t[i];
724
+ return s === void 0 ? a : String(s);
725
+ });
726
+ }
727
+ }
728
+ const I = ["en", "de", "es", "fr", "pl", "pt"], We = "en";
729
+ function Xe(r) {
730
+ const e = new Je(), a = (() => {
731
+ const o = navigator?.language?.split("-")[0]?.toLowerCase();
732
+ return I.includes(o) ? o : We;
733
+ })();
734
+ e.setLocale(a);
735
+ const i = x({
736
+ locale: a,
737
+ translationService: e
738
+ });
739
+ return {
740
+ store: i,
741
+ translate: (o, l) => i.getState().translationService.translate(o, l),
742
+ setLocale: (o) => {
743
+ I.includes(o) && (i.getState().translationService.setLocale(o), i.setState({ locale: o }));
744
+ },
745
+ getLocale: () => i.getValue("locale"),
746
+ subscribe: i.subscribe.bind(i)
747
+ };
748
+ }
749
+ const Qe = Xe(), L = () => {
750
+ const { translate: r, getLocale: e, setLocale: t, subscribe: a } = Qe;
751
+ return {
752
+ t: r,
753
+ translate: r,
754
+ locale: e(),
755
+ setLocale: t,
756
+ subscribe: a
757
+ };
758
+ }, et = ({ fontFamily: r }) => {
759
+ if (!r)
760
+ return { cleanup: () => {
761
+ } };
762
+ const e = r.replace(/\s+/g, "+"), t = `https://fonts.googleapis.com/css2?family=${e}:wght@400;700&display=swap`, a = [...document.head.querySelectorAll("link")].filter(
763
+ (o) => o.href.includes("fonts.googleapis.com/css2") && o.rel === "stylesheet"
764
+ ), i = document.createElement("link");
765
+ i.rel = "stylesheet", i.href = t;
766
+ const s = a.find(
767
+ (o) => o.href.includes(`family=${e}`)
768
+ );
769
+ if (s)
770
+ s.href = t;
771
+ else if (a.length > 0) {
772
+ const o = a.at(
773
+ -1
774
+ );
775
+ o?.nextSibling ? document.head.insertBefore(i, o.nextSibling) : document.head.appendChild(i);
776
+ } else
777
+ document.head.appendChild(i);
778
+ return { cleanup: () => {
779
+ document.head.contains(i) && document.head.removeChild(i);
780
+ } };
781
+ }, tt = ({
782
+ scriptSrc: r,
783
+ async: e = !1
784
+ }) => {
785
+ if ([...document.head.querySelectorAll("script")].filter(
786
+ (n) => n.src === r
787
+ ).length > 0)
788
+ return {
789
+ cleanup: () => {
790
+ },
791
+ isLoaded: Promise.resolve(!0)
792
+ };
793
+ const a = document.createElement("script");
794
+ a.src = r, a.async = e;
795
+ const i = new Promise((n, o) => {
796
+ a.onload = () => n(!0), a.onerror = () => {
797
+ console.error(`Failed to load script: ${r}`), o(new Error(`Failed to load script: ${r}`));
798
+ };
799
+ });
800
+ return document.head.appendChild(a), {
801
+ cleanup: () => {
802
+ document.head.contains(a) && document.head.removeChild(a);
803
+ },
804
+ isLoaded: i
805
+ };
806
+ }, S = (r) => Object.entries(r).map(([e, t]) => {
807
+ const a = e.replace(/([A-Z])/g, "-$1").toLowerCase(), i = typeof t == "number" ? `${t}px` : t;
808
+ return `${a}: ${i}`;
809
+ }).join("; ");
810
+ function at(r) {
811
+ if (!r)
812
+ return {
813
+ formContainerStyle: {},
814
+ baseStyles: {},
815
+ placeholderStyles: {},
816
+ errorStyles: {},
817
+ focusStyles: {},
818
+ inputStyles: {
819
+ base: "",
820
+ error: "",
821
+ focus: "",
822
+ placeholder: ""
823
+ }
824
+ };
825
+ const e = {
826
+ opacity: "1",
827
+ background: "#fff",
828
+ border: "none",
829
+ outline: "none",
830
+ fontSize: `${r.styles.fontSize}px`,
831
+ lineHeight: 30,
832
+ boxSizing: "border-box",
833
+ padding: "0px 12px",
834
+ height: 33,
835
+ width: "100%",
836
+ fontFamily: `${r.styles.fontFamily}, sans-serif`
837
+ }, t = {
838
+ color: "#717173",
839
+ opacity: "0.3",
840
+ fontFamily: `${r.styles.fontFamily}, sans-serif`
841
+ }, a = {
842
+ color: "#dc2727"
843
+ }, i = {
844
+ outline: 0
845
+ }, s = {
846
+ fontFamily: `${r.styles.fontFamily}, sans-serif`
847
+ }, n = {
848
+ base: S(e),
849
+ error: S(a),
850
+ focus: S(i),
851
+ placeholder: S(t)
852
+ };
853
+ return {
854
+ formContainerStyle: s,
855
+ baseStyles: e,
856
+ placeholderStyles: t,
857
+ errorStyles: a,
858
+ focusStyles: i,
859
+ inputStyles: n
860
+ };
861
+ }
862
+ class h {
863
+ element;
864
+ children = [];
865
+ eventListeners = [];
866
+ /**
867
+ * Create a new component with the specified element
868
+ * @param tagName The HTML tag name to create
869
+ * @param classNames Optional CSS class names to add
870
+ * @param attributes Optional attributes to set on the element
871
+ */
872
+ constructor(e, t = [], a = {}) {
873
+ this.element = document.createElement(e), t.length > 0 && this.addClass(...t), Object.entries(a).forEach(([i, s]) => {
874
+ this.setAttribute(i, s);
875
+ });
876
+ }
877
+ /**
878
+ * Get the DOM element for this component
879
+ */
880
+ getElement() {
881
+ return this.element;
882
+ }
883
+ /**
884
+ * Add CSS classes to the element
885
+ */
886
+ addClass(...e) {
887
+ return this.element.classList.add(...e), this;
888
+ }
889
+ /**
890
+ * Remove CSS classes from the element
891
+ */
892
+ removeClass(...e) {
893
+ return this.element.classList.remove(...e), this;
894
+ }
895
+ /**
896
+ * Set an attribute on the element
897
+ */
898
+ setAttribute(e, t) {
899
+ return this.element.setAttribute(e, t), this;
900
+ }
901
+ /**
902
+ * Set the inner text of the element
903
+ */
904
+ setText(e) {
905
+ return this.element.textContent = e, this;
906
+ }
907
+ /**
908
+ * Set the inner HTML of the element
909
+ * Note: Use with caution to avoid XSS vulnerabilities
910
+ */
911
+ setHTML(e) {
912
+ return this.element.innerHTML = e, this;
913
+ }
914
+ /**
915
+ * Append a child component to this component
916
+ */
917
+ appendChild(e) {
918
+ return this.children.push(e), this.element.appendChild(e.getElement()), this;
919
+ }
920
+ /**
921
+ * Append this component to a parent element
922
+ */
923
+ appendTo(e) {
924
+ return e instanceof h ? e.appendChild(this) : e.appendChild(this.element), this;
925
+ }
926
+ /**
927
+ * Add an event listener to the element
928
+ */
929
+ addEventListener(e, t, a) {
930
+ return this.element.addEventListener(e, t, a), this.eventListeners.push({ type: e, listener: t }), this;
931
+ }
932
+ /**
933
+ * Remove an event listener from the element
934
+ */
935
+ removeEventListener(e, t, a) {
936
+ return this.element.removeEventListener(e, t, a), this;
937
+ }
938
+ /**
939
+ * Hide this component
940
+ */
941
+ hide() {
942
+ return this.element.style.display = "none", this;
943
+ }
944
+ /**
945
+ * Show this component
946
+ */
947
+ show() {
948
+ return this.element.style.display = "", this;
949
+ }
950
+ /**
951
+ * Destroy this component and clean up resources
952
+ */
953
+ destroy() {
954
+ this.eventListeners.forEach(({ type: e, listener: t }) => {
955
+ this.element.removeEventListener(e, t);
956
+ }), this.eventListeners = [], this.children.forEach((e) => e.destroy()), this.children = [], this.element.parentNode && this.element.parentNode.removeChild(this.element);
957
+ }
958
+ }
959
+ class y {
960
+ /**
961
+ * Create a div element
962
+ */
963
+ static createDiv(e = [], t = {}) {
964
+ return new h("div", e, t);
965
+ }
966
+ /**
967
+ * Create a span element
968
+ */
969
+ static createSpan(e = [], t = {}) {
970
+ return new h("span", e, t);
971
+ }
972
+ /**
973
+ * Create a button element
974
+ */
975
+ static createButton(e, t = [], a = {}) {
976
+ const i = new h("button", t, a);
977
+ return i.setText(e), i;
978
+ }
979
+ /**
980
+ * Create an input element
981
+ */
982
+ static createInput(e, t = [], a = {}) {
983
+ const i = { type: e, ...a };
984
+ return new h("input", t, i);
985
+ }
986
+ /**
987
+ * Create a text input
988
+ */
989
+ static createTextInput(e = "", t = [], a = {}) {
990
+ const i = {
991
+ type: "text",
992
+ placeholder: e,
993
+ ...a
994
+ };
995
+ return new h("input", t, i);
996
+ }
997
+ /**
998
+ * Create a form element
999
+ */
1000
+ static createForm(e = [], t = {}) {
1001
+ return new h("form", e, t);
1002
+ }
1003
+ /**
1004
+ * Create a label element
1005
+ */
1006
+ static createLabel(e, t = "", a = [], i = {}) {
1007
+ const s = t ? { for: t, ...i } : i, n = new h("label", a, s);
1008
+ return n.setText(e), n;
1009
+ }
1010
+ /**
1011
+ * Create a select element
1012
+ */
1013
+ static createSelect(e, t = [], a = {}) {
1014
+ const i = new h("select", t, a);
1015
+ return e.forEach((s) => {
1016
+ const n = document.createElement("option");
1017
+ n.value = s.value, n.textContent = s.text, s.selected && (n.selected = !0), i.getElement().appendChild(n);
1018
+ }), i;
1019
+ }
1020
+ /**
1021
+ * Create an image element
1022
+ */
1023
+ static createImage(e, t = "", a = [], i = {}) {
1024
+ const s = { src: e, alt: t, ...i };
1025
+ return new h("img", a, s);
1026
+ }
1027
+ }
1028
+ class it extends h {
1029
+ messageComponent;
1030
+ constructor(e) {
1031
+ super("div", []);
1032
+ const t = y.createDiv(["error-alert"], {
1033
+ role: "alert",
1034
+ "aria-live": "polite"
1035
+ }), a = y.createDiv(["error-alert-content"]), i = y.createDiv([
1036
+ "error-alert-icon-container"
1037
+ ]);
1038
+ i.getElement().innerHTML = this.createAlertCircleSVG();
1039
+ const s = y.createDiv([
1040
+ "error-alert-text-container"
1041
+ ]), n = new h("h4", [
1042
+ "error-alert-title"
1043
+ ]);
1044
+ n.setText("Checkout Error"), this.messageComponent = new h("p", [
1045
+ "error-alert-message"
1046
+ ]), this.messageComponent.setText(e.message || "Bad request"), s.appendChild(n), s.appendChild(this.messageComponent), a.appendChild(i), a.appendChild(s), t.appendChild(a), this.appendChild(t);
1047
+ }
1048
+ createAlertCircleSVG() {
1049
+ return `
1050
+ <svg
1051
+ xmlns="http://www.w3.org/2000/svg"
1052
+ width="14"
1053
+ height="14"
1054
+ viewBox="0 0 24 24"
1055
+ fill="none"
1056
+ stroke="currentColor"
1057
+ stroke-width="2"
1058
+ stroke-linecap="round"
1059
+ stroke-linejoin="round"
1060
+ >
1061
+ <circle cx="12" cy="12" r="10" />
1062
+ <line x1="12" x2="12" y1="8" y2="12" />
1063
+ <line x1="12" x2="12.01" y1="16" y2="16" />
1064
+ </svg>
1065
+ `;
1066
+ }
1067
+ setMessage(e) {
1068
+ return this.messageComponent.setText(e), this;
1069
+ }
1070
+ }
1071
+ class st extends h {
1072
+ titleElement;
1073
+ constructor(e) {
1074
+ super("div", ["blur-bg"]);
1075
+ const t = y.createDiv(["loader"]);
1076
+ this.titleElement = new h("h3", ["title"]), this.titleElement.setText(e.text), this.appendChild(t), this.appendChild(this.titleElement);
1077
+ }
1078
+ setText(e) {
1079
+ return this.titleElement.setText(e), this;
1080
+ }
1081
+ }
1082
+ class v extends h {
1083
+ constructor(e) {
1084
+ super("div", []);
1085
+ const t = document.createElement("span");
1086
+ t.className = "form-helper-text", t.textContent = e.text || "", this.getElement().appendChild(t);
1087
+ }
1088
+ setText(e) {
1089
+ const t = this.getElement().querySelector(".form-helper-text");
1090
+ return t && (t.textContent = e), this;
1091
+ }
1092
+ }
1093
+ class rt extends h {
1094
+ constructor(e) {
1095
+ super("label", ["input-label"], {
1096
+ for: e.id
1097
+ }), this.setText(e.label);
1098
+ const t = this.getElement();
1099
+ t.style.fontFamily = "inherit", t.style.color = e.styles.color, t.style.fontSize = `${e.styles.fontSize}px`;
1100
+ }
1101
+ }
1102
+ class M extends h {
1103
+ inputElement;
1104
+ helperText = null;
1105
+ constructor(e) {
1106
+ if (super("div", ["input-wrapper"]), e.label && e.styles) {
1107
+ const a = new rt({
1108
+ styles: {
1109
+ color: e.styles.color,
1110
+ fontSize: e.styles.fontSize
1111
+ },
1112
+ label: e.label,
1113
+ id: e.name
1114
+ });
1115
+ this.appendChild(a);
1116
+ }
1117
+ const t = {
1118
+ id: e.name,
1119
+ name: e.name,
1120
+ class: `form-input ${e.error ? "form-input-error" : ""}`
1121
+ };
1122
+ if (e.placeholder && (t.placeholder = e.placeholder), e.value && (t.value = e.value), e.required && (t.required = String(e.required)), e.disabled && (t.disabled = String(e.disabled)), this.inputElement = y.createInput(
1123
+ e.type || "text",
1124
+ [],
1125
+ t
1126
+ ), e.styles) {
1127
+ const a = this.inputElement.getElement();
1128
+ a.style.fontFamily = `"${e.styles.fontFamily}", sans-serif`, a.style.color = e.styles.color, a.style.fontSize = `${e.styles.fontSize}px`, a.style.borderRadius = e.styles.borderRadius;
1129
+ }
1130
+ e.onChange && this.inputElement.getElement().addEventListener("input", e.onChange), this.getElement().appendChild(this.inputElement.getElement()), e.error && (this.helperText = new v({ text: e.errorMsg }), this.appendChild(this.helperText));
1131
+ }
1132
+ getValue() {
1133
+ return this.inputElement.getElement().value;
1134
+ }
1135
+ setValue(e) {
1136
+ return this.inputElement.getElement().value = e, this;
1137
+ }
1138
+ setError(e, t) {
1139
+ const a = this.inputElement.getElement();
1140
+ return e ? (a.classList.add("form-input-error"), !this.helperText && t ? (this.helperText = new v({ text: t }), this.appendChild(this.helperText)) : this.helperText && t && this.helperText.setText(t)) : (a.classList.remove("form-input-error"), this.helperText && (this.helperText.getElement().remove(), this.helperText = null)), this;
1141
+ }
1142
+ addEventListener(e, t, a) {
1143
+ return this.inputElement.getElement().addEventListener(e, t, a), this;
1144
+ }
1145
+ }
1146
+ class nt {
1147
+ input;
1148
+ constructor(e) {
1149
+ const {
1150
+ value: t,
1151
+ onChange: a,
1152
+ onBlur: i,
1153
+ error: s,
1154
+ errorMsg: n,
1155
+ checkoutProfile: o,
1156
+ translationFunc: l
1157
+ } = e;
1158
+ this.input = new M({
1159
+ name: "name",
1160
+ label: l("cardholderNameLabel"),
1161
+ error: s,
1162
+ errorMsg: n,
1163
+ styles: {
1164
+ color: o.styles.textColor,
1165
+ borderRadius: `${o.styles.borderRadius}px`,
1166
+ fontSize: o.styles.fontSize,
1167
+ fontFamily: o.styles.fontFamily
1168
+ },
1169
+ placeholder: l("cardholderNamePlaceholder"),
1170
+ value: t,
1171
+ onChange: a
1172
+ }), this.input.addEventListener("blur", i);
1173
+ }
1174
+ getValue() {
1175
+ return this.input.getValue();
1176
+ }
1177
+ setValue(e) {
1178
+ return this.input.setValue(e), this;
1179
+ }
1180
+ setError(e, t) {
1181
+ return this.input.setError(e, t), this;
1182
+ }
1183
+ getElement() {
1184
+ return this.input.getElement();
1185
+ }
1186
+ appendTo(e) {
1187
+ return this.input.appendTo(e), this;
1188
+ }
1189
+ }
1190
+ class ot extends h {
1191
+ constructor(e) {
1192
+ super("div", []);
1193
+ const t = document.createElement("div");
1194
+ t.className = e.isLoading ? "loading" : "", t.style.borderRadius = `0px 0px ${e.styles.borderRadius}px 0px`;
1195
+ const a = document.createElement("div");
1196
+ a.id = "card-cvv-element", a.className = `card-element ${e.isFocused ? "card-element-focus" : ""}`, a.style.zIndex = e.isFocused ? "2" : "0", t.appendChild(a), this.getElement().appendChild(t);
1197
+ }
1198
+ setFocused(e) {
1199
+ const t = this.getElement().querySelector("#card-cvv-element");
1200
+ return t && (e ? (t.classList.add("card-element-focus"), t.setAttribute("style", "z-index: 2")) : (t.classList.remove("card-element-focus"), t.setAttribute("style", "z-index: 0"))), this;
1201
+ }
1202
+ setLoading(e) {
1203
+ const t = this.getElement().querySelector("div");
1204
+ return t && (e ? t.classList.add("loading") : t.classList.remove("loading")), this;
1205
+ }
1206
+ }
1207
+ const lt = "data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='iso-8859-1'?%3e%3c!--%20Uploaded%20to:%20SVG%20Repo,%20www.svgrepo.com,%20Generator:%20SVG%20Repo%20Mixer%20Tools%20--%3e%3csvg%20height='30px'%20width='30px'%20version='1.1'%20id='Capa_1'%20xmlns='http://www.w3.org/2000/svg'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20viewBox='0%200%20512%20512'%20xml:space='preserve'%3e%3cpath%20style='fill:%23306FC5;'%20d='M512,402.281c0,16.716-13.55,30.267-30.265,30.267H30.265C13.55,432.549,0,418.997,0,402.281V109.717%20c0-16.715,13.55-30.266,30.265-30.266h451.47c16.716,0,30.265,13.551,30.265,30.266V402.281L512,402.281z'/%3e%3cpath%20style='opacity:0.15;fill:%23202121;enable-background:new%20;'%20d='M21.517,402.281V109.717%20c0-16.715,13.552-30.266,30.267-30.266h-21.52C13.55,79.451,0,93.001,0,109.717v292.565c0,16.716,13.55,30.267,30.265,30.267h21.52%20C35.07,432.549,21.517,418.997,21.517,402.281z'/%3e%3cg%3e%3cpolygon%20style='fill:%23FFFFFF;'%20points='74.59,220.748%2089.888,220.748%2082.241,201.278%20'/%3e%3cpolygon%20style='fill:%23FFFFFF;'%20points='155.946,286.107%20155.946,295.148%20181.675,295.148%20181.675,304.885%20155.946,304.885%20155.946,315.318%20184.455,315.318%20197.666,300.712%20185.151,286.107%20'/%3e%3cpolygon%20style='fill:%23FFFFFF;'%20points='356.898,201.278%20348.553,220.748%20364.548,220.748%20'/%3e%3cpolygon%20style='fill:%23FFFFFF;'%20points='230.348,320.875%20230.348,281.241%20212.268,300.712%20'/%3e%3cpath%20style='fill:%23FFFFFF;'%20d='M264.42,292.368c-0.696-4.172-3.48-6.261-7.654-6.261h-14.599v12.516h15.299%20C261.637,298.624,264.42,296.539,264.42,292.368z'/%3e%3cpath%20style='fill:%23FFFFFF;'%20d='M313.09,297.236c1.391-0.697,2.089-2.785,2.089-4.867c0.696-2.779-0.698-4.172-2.089-4.868%20c-1.387-0.696-3.476-0.696-5.559-0.696h-13.91v11.127h13.909C309.613,297.932,311.702,297.932,313.09,297.236z'/%3e%3cpath%20style='fill:%23FFFFFF;'%20d='M413.217,183.198v8.344l-4.169-8.344H376.37v8.344l-4.174-8.344h-44.502%20c-7.648,0-13.909,1.392-19.469,4.173v-4.173h-31.289v0.696v3.477c-3.476-2.78-7.648-4.173-13.211-4.173h-111.95l-7.652,17.384%20l-7.647-17.384h-25.031h-10.431v8.344l-3.477-8.344h-0.696H66.942l-13.909,32.68L37.042,251.34l-0.294,0.697h0.294h35.463h0.444%20l0.252-0.697l4.174-10.428h9.039l4.172,11.125h40.326v-0.697v-7.647l3.479,8.343h20.163l3.475-8.343v7.647v0.697h15.993h79.965%20h0.696v-18.08h1.394c1.389,0,1.389,0,1.389,2.087v15.297h50.065v-4.172c4.172,2.089,10.426,4.172,18.771,4.172h20.863l4.172-11.123%20h9.732l4.172,11.123h40.328v-6.952v-3.476l6.261,10.428h1.387h0.698h30.595v-68.143h-31.291l0,0H413.217z%20M177.501,241.609h-6.955%20h-4.171v-4.169v-34.076l-0.696,1.595v-0.019l-16.176,36.669h-0.512h-3.719h-6.017l-16.687-38.245v38.245h-23.64l-4.867-10.43%20H70.417l-4.868,10.43H53.326l20.57-48.675h17.382l19.469,46.587v-46.587h4.171h14.251l0.328,0.697h0.024l8.773,19.094l6.3,14.306%20l0.223-0.721l13.906-33.375H177.5v48.674H177.501L177.501,241.609z%20M225.481,203.364h-27.119v9.039h26.423v9.734h-26.423v9.738%20h27.119v10.427h-38.939v-49.367h38.939V203.364L225.481,203.364z%20M275.076,221.294c0.018,0.016,0.041,0.027,0.063,0.042%20c0.263,0.278,0.488,0.557,0.68,0.824c1.332,1.746,2.409,4.343,2.463,8.151c0.004,0.066,0.007,0.131,0.011,0.197%20c0,0.038,0.007,0.071,0.007,0.11c0,0.022-0.002,0.039-0.002,0.06c0.016,0.383,0.026,0.774,0.026,1.197v9.735h-10.428v-5.565%20c0-2.781,0-6.954-2.089-9.735c-0.657-0.657-1.322-1.09-2.046-1.398c-1.042-0.675-3.017-0.686-6.295-0.686h-12.52v17.384h-11.818%20v-48.675h26.425c6.254,0,10.428,0,13.906,2.086c3.407,2.046,5.465,5.439,5.543,10.812c-0.161,7.4-4.911,11.46-8.326,12.829%20C270.676,218.662,272.996,219.129,275.076,221.294z%20M298.491,241.609h-11.822v-48.675h11.822V241.609z%20M434.083,241.609h-15.3%20l-22.25-36.855v30.595l-0.073-0.072v6.362h-11.747v-0.029h-11.822l-4.172-10.43H344.38l-4.172,11.123h-13.211%20c-5.559,0-12.517-1.389-16.687-5.561c-4.172-4.172-6.256-9.735-6.256-18.773c0-6.953,1.389-13.911,6.256-19.472%20c3.474-4.175,9.735-5.562,17.382-5.562h11.128v10.429h-11.128c-4.172,0-6.254,0.693-9.041,2.783%20c-2.082,2.085-3.474,6.256-3.474,11.123c0,5.564,0.696,9.04,3.474,11.821c2.091,2.089,4.87,2.785,8.346,2.785h4.867l15.991-38.243%20h6.957h10.428l19.472,46.587v-2.376v-15.705v-1.389v-27.116h17.382l20.161,34.07v-34.07h11.826v47.977h0.002L434.083,241.609%20L434.083,241.609z'/%3e%3cpath%20style='fill:%23FFFFFF;'%20d='M265.161,213.207c0.203-0.217,0.387-0.463,0.543-0.745c0.63-0.997,1.352-2.793,0.963-5.244%20c-0.016-0.225-0.057-0.433-0.105-0.634c-0.013-0.056-0.011-0.105-0.026-0.161l-0.007,0.001c-0.346-1.191-1.229-1.923-2.11-2.367%20c-1.394-0.693-3.48-0.693-5.565-0.693h-13.909v11.127h13.909c2.085,0,4.172,0,5.565-0.697c0.209-0.106,0.395-0.25,0.574-0.413%20l0.002,0.009C264.996,213.389,265.067,213.315,265.161,213.207z'/%3e%3cpath%20style='fill:%23FFFFFF;'%20d='M475.105,311.144c0-4.867-1.389-9.736-3.474-13.212v-31.289h-0.032v-2.089c0,0-29.145,0-33.483,0%20c-4.336,0-9.598,4.171-9.598,4.171v-4.171h-31.984c-4.87,0-11.124,1.392-13.909,4.171v-4.171h-57.016v2.089v2.081%20c-4.169-3.474-11.824-4.171-15.298-4.171h-37.549v2.089v2.081c-3.476-3.474-11.824-4.171-15.998-4.171H215.05l-9.737,10.431%20l-9.04-10.431h-2.911h-4.737h-54.93v2.089v5.493v62.651h61.19l10.054-10.057l8.715,10.057h0.698h35.258h1.598h0.696h0.692v-6.953%20v-9.039h3.479c4.863,0,11.124,0,15.991-2.089v17.382v1.394h31.291v-1.394V317.4h1.387c2.089,0,2.089,0,2.089,2.086v14.6v1.394%20h94.563c6.263,0,12.517-1.394,15.993-4.175v2.781v1.394h29.902c6.254,0,12.517-0.695,16.689-3.478%20c6.402-3.841,10.437-10.64,11.037-18.749c0.028-0.24,0.063-0.48,0.085-0.721l-0.041-0.039%20C475.087,312.043,475.105,311.598,475.105,311.144z%20M256.076,306.973h-13.91v2.081v4.174v4.173v7.649h-22.855l-13.302-15.299%20l-0.046,0.051l-0.65-0.748l-15.297,15.996h-44.501v-48.673h45.197l12.348,13.525l2.596,2.832l0.352-0.365l14.604-15.991h36.852%20c7.152,0,15.161,1.765,18.196,9.042c0.365,1.441,0.577,3.043,0.577,4.863C276.237,304.189,266.502,306.973,256.076,306.973z%20M325.609,306.276c1.389,2.081,2.085,4.867,2.085,9.041v9.732h-11.819v-6.256c0-2.786,0-7.65-2.089-9.739%20c-1.387-2.081-4.172-2.081-8.341-2.081H292.93v18.077h-11.82v-49.369h26.421c5.559,0,10.426,0,13.909,2.084%20c3.474,2.088,6.254,5.565,6.254,11.128c0,7.647-4.865,11.819-8.343,13.212C322.829,303.49,324.914,304.885,325.609,306.276z%20M373.589,286.107h-27.122v9.04h26.424v9.737h-26.424v9.736h27.122v10.429H334.65V275.68h38.939V286.107z%20M402.791,325.05h-22.252%20v-10.429h22.252c2.082,0,3.476,0,4.87-1.392c0.696-0.697,1.387-2.085,1.387-3.477c0-1.394-0.691-2.778-1.387-3.475%20c-0.698-0.695-2.091-1.391-4.176-1.391c-11.126-0.696-24.337,0-24.337-15.296c0-6.954,4.172-14.604,16.689-14.604h22.945v11.819%20h-21.554c-2.085,0-3.478,0-4.87,0.696c-1.387,0.697-1.387,2.089-1.387,3.478c0,2.087,1.387,2.783,2.778,3.473%20c1.394,0.697,2.783,0.697,4.172,0.697h6.259c6.259,0,10.43,1.391,13.211,4.173c2.087,2.087,3.478,5.564,3.478,10.43%20C420.869,320.179,414.611,325.05,402.791,325.05z%20M462.59,320.179c-2.778,2.785-7.648,4.871-14.604,4.871H425.74v-10.429h22.245%20c2.087,0,3.481,0,4.87-1.392c0.693-0.697,1.391-2.085,1.391-3.477c0-1.394-0.698-2.778-1.391-3.475%20c-0.696-0.695-2.085-1.391-4.172-1.391c-11.122-0.696-24.337,0-24.337-15.295c0-6.609,3.781-12.579,13.106-14.352%20c1.115-0.154,2.293-0.253,3.583-0.253h22.948v11.819h-15.3h-5.561h-0.696c-2.087,0-3.476,0-4.865,0.696%20c-0.7,0.697-1.396,2.089-1.396,3.478c0,2.087,0.696,2.783,2.785,3.473c1.389,0.697,2.78,0.697,4.172,0.697h0.691h5.565%20c3.039,0,5.337,0.375,7.44,1.114c1.926,0.697,8.302,3.549,9.728,10.994c0.124,0.78,0.215,1.594,0.215,2.495%20C466.761,313.925,465.37,317.401,462.59,320.179z'/%3e%3c/g%3e%3c/svg%3e", ct = "data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='iso-8859-1'?%3e%3c!--%20Uploaded%20to:%20SVG%20Repo,%20www.svgrepo.com,%20Generator:%20SVG%20Repo%20Mixer%20Tools%20--%3e%3csvg%20height='30px'%20width='30px'%20version='1.1'%20id='Capa_1'%20xmlns='http://www.w3.org/2000/svg'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20viewBox='0%200%20512%20512'%20xml:space='preserve'%3e%3cpath%20style='fill:%2334495E;'%20d='M512,402.282c0,16.716-13.55,30.267-30.265,30.267H30.265C13.55,432.549,0,418.996,0,402.282V109.717%20c0-16.716,13.55-30.266,30.265-30.266h451.469c16.716,0,30.265,13.551,30.265,30.266L512,402.282L512,402.282z'/%3e%3cpath%20style='opacity:0.15;fill:%23202121;enable-background:new%20;'%20d='M21.517,402.282V109.717%20c0-16.716,13.552-30.266,30.267-30.266h-21.52C13.55,79.451,0,93.003,0,109.717v292.565c0,16.716,13.55,30.267,30.265,30.267h21.52%20C35.07,432.549,21.517,418.996,21.517,402.282z'/%3e%3cpath%20style='fill:%23F26E21;'%20d='M309.389,255.801c0.041-9.636-3.572-19.286-10.843-26.558c-7.287-7.287-16.961-10.897-26.617-10.839%20c-0.046,0-0.091-0.003-0.139-0.003c-20.968,0-37.6,16.628-37.6,37.602c0,20.767,16.837,37.599,37.6,37.599%20c20.974,0,37.604-16.631,37.604-37.599C309.394,255.934,309.389,255.869,309.389,255.801z'/%3e%3cg%3e%3cpath%20style='fill:%23E7E8E3;'%20d='M227.198,271.909c-5.62,5.626-10.807,7.824-16.394,7.943c-13.611-0.122-23.618-10.202-23.618-24.573%20c0-7.234,2.739-13.163,7.078-18.228l0,0c4.069-3.863,9.311-6.359,15.339-6.359c6.507,0,11.571,2.169,17.352,7.954v-16.631%20c-5.78-2.891-10.846-4.338-17.352-4.338c-9.192,0.657-17.859,4.371-24.507,10.203l0,0c-1.916,1.724-3.752,3.627-5.309,5.805%20c-4.856,6.294-7.791,14.001-7.791,22.32c0,20.967,16.637,36.875,37.606,36.875c0.102,0,0.203-0.009,0.302-0.01%20c0.141,0.002,0.28,0.01,0.42,0.01c5.784,0,10.85-1.443,17.357-4.336L227.198,271.909c-0.244,0.244,0.242,0.471,0,0.702V271.909z'/%3e%3cpolygon%20style='fill:%23E7E8E3;'%20points='356.863,228.033%20356.863,228.033%20340.487,268.295%20321.685,220.566%20306.502,220.566%20336.148,293.601%20344.102,293.601%20375.196,220.566%20360.013,220.566%20'/%3e%3cpolygon%20style='fill:%23E7E8E3;'%20points='380.983,252.384%20380.983,291.435%20420.033,291.435%20420.753,291.435%20420.753,279.861%20408.461,279.861%20395.445,279.861%20395.445,266.848%20395.445,260.342%20420.033,260.342%20420.033,248.045%20395.445,248.045%20395.445,232.861%20420.753,232.861%20420.753,220.566%20380.983,220.566%20'/%3e%3cpath%20style='fill:%23E7E8E3;'%20d='M54.135,220.566H33.884v70.869h20.25c10.845,0,18.798-2.895,25.306-7.957%20c7.953-6.508,13.017-16.629,13.017-27.474C92.458,235.028,77.27,220.566,54.135,220.566z%20M70.765,274.08%20c-4.339,3.614-10.124,5.781-18.802,5.781h-4.339V232.86h3.615c8.678,0,14.463,1.446,18.803,5.783%20c5.061,4.336,7.955,10.848,7.955,17.358C78.72,262.509,75.828,269.737,70.765,274.08z'/%3e%3crect%20x='98.97'%20y='220.56'%20style='fill:%23E7E8E3;'%20width='13.739'%20height='70.867'/%3e%3cpath%20style='fill:%23E7E8E3;'%20d='M147.415,248.045c-8.676-2.892-10.848-5.063-10.848-8.677c0-4.339,4.339-7.954,10.124-7.954%20c4.339,0,7.954,1.447,11.57,5.786l7.233-9.4c-5.787-5.064-13.015-7.953-20.97-7.953c-12.296,0-22.42,8.678-22.42,20.244%20c0,10.126,4.343,14.464,17.357,19.526c5.785,2.166,7.955,2.892,9.404,4.338c2.887,1.444,4.336,4.339,4.336,7.228%20c0,5.786-4.336,10.126-10.848,10.126c-6.514,0-12.294-3.615-15.187-9.401l-8.678,8.678c6.511,9.4,14.465,13.738,24.589,13.738%20c14.461,0,24.58-9.4,24.58-23.141C167.659,258.893,163.324,253.831,147.415,248.045z'/%3e%3cpath%20style='fill:%23E7E8E3;'%20d='M459.804,261.783c10.843-2.166,16.63-9.4,16.63-20.244c0-13.014-9.402-20.973-25.308-20.973h-20.972%20v70.869h13.739V263.23h2.172l19.519,28.205h16.634L459.804,261.783z%20M448.23,253.105h-4.336v-21.691h4.336%20c8.678,0,13.742,3.614,13.742,10.85C461.972,249.492,456.909,253.105,448.23,253.105z'/%3e%3c/g%3e%3c/svg%3e", dt = "data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='iso-8859-1'?%3e%3c!--%20Uploaded%20to:%20SVG%20Repo,%20www.svgrepo.com,%20Generator:%20SVG%20Repo%20Mixer%20Tools%20--%3e%3csvg%20height='800px'%20width='800px'%20version='1.1'%20id='Layer_1'%20xmlns='http://www.w3.org/2000/svg'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20viewBox='0%200%20291.791%20291.791'%20xml:space='preserve'%3e%3cg%3e%3cpath%20style='fill:%23E2574C;'%20d='M182.298,145.895c0,50.366-40.801,91.176-91.149,91.176S0,196.252,0,145.895%20s40.811-91.176,91.149-91.176S182.298,95.538,182.298,145.895z'/%3e%3cpath%20style='fill:%23F4B459;'%20d='M200.616,54.719c-20.442,0-39.261,6.811-54.469,18.181l0.073,0.009%20c2.991,2.89,6.291,4.924,8.835,8.251l-18.965,0.301c-2.972,3-5.68,6.264-8.233,9.656H161.3c2.544,3.054,4.896,5.708,7.03,9.081%20h-46.536c-1.705,2.936-3.282,5.954-4.659,9.09h56.493c1.477,3.127,2.799,5.489,3.921,8.799h-63.76%20c-1.012,3.146-1.878,6.364-2.535,9.646h68.966c0.675,3.155,1.194,6.072,1.55,9.045h-71.884c-0.301,3-0.456,6.045-0.456,9.118%20h72.859c0,3.228-0.228,6.218-0.556,9.118h-71.847c0.31,3.091,0.766,6.127,1.368,9.118h68.856c-0.711,2.954-1.532,5.926-2.562,9.008%20h-63.969c0.966,3.118,2.143,6.145,3.428,9.099h56.621c-1.568,3.319-3.346,5.972-5.306,9.081h-46.691%20c1.842,3.191,3.875,6.236,6.081,9.154l33.589,0.501c-2.863,3.437-6.537,5.507-9.884,8.516c0.182,0.146-5.352-0.018-16.248-0.191%20c16.576,17.105,39.744,27.772,65.446,27.772c50.357,0,91.176-40.82,91.176-91.176S250.981,54.719,200.616,54.719z'/%3e%3c/g%3e%3c/svg%3e", ht = "data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='utf-8'?%3e%3c!--%20Uploaded%20to:%20SVG%20Repo,%20www.svgrepo.com,%20Generator:%20SVG%20Repo%20Mixer%20Tools%20--%3e%3csvg%20width='800px'%20height='800px'%20viewBox='0%20-140%20780%20780'%20enable-background='new%200%200%20780%20500'%20version='1.1'%20xml:space='preserve'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M40,0h700c22.092,0,40,17.909,40,40v420c0,22.092-17.908,40-40,40H40c-22.091,0-40-17.908-40-40V40%20C0,17.909,17.909,0,40,0z'%20fill='%230E4595'/%3e%3cpath%20d='m293.2%20348.73l33.361-195.76h53.36l-33.385%20195.76h-53.336zm246.11-191.54c-10.57-3.966-27.137-8.222-47.822-8.222-52.725%200-89.865%2026.55-90.18%2064.603-0.299%2028.13%2026.514%2043.822%2046.752%2053.186%2020.771%209.595%2027.752%2015.714%2027.654%2024.283-0.131%2013.121-16.586%2019.116-31.922%2019.116-21.357%200-32.703-2.967-50.227-10.276l-6.876-3.11-7.489%2043.823c12.463%205.464%2035.51%2010.198%2059.438%2010.443%2056.09%200%2092.5-26.246%2092.916-66.882%200.199-22.269-14.016-39.216-44.801-53.188-18.65-9.055-30.072-15.099-29.951-24.268%200-8.137%209.668-16.839%2030.557-16.839%2017.449-0.27%2030.09%203.535%2039.938%207.5l4.781%202.26%207.232-42.429m137.31-4.223h-41.232c-12.773%200-22.332%203.487-27.941%2016.234l-79.244%20179.4h56.031s9.16-24.123%2011.232-29.418c6.125%200%2060.555%200.084%2068.338%200.084%201.596%206.853%206.49%2029.334%206.49%2029.334h49.514l-43.188-195.64zm-65.418%20126.41c4.412-11.279%2021.26-54.723%2021.26-54.723-0.316%200.522%204.379-11.334%207.074-18.684l3.605%2016.879s10.219%2046.729%2012.354%2056.528h-44.293zm-363.3-126.41l-52.24%20133.5-5.567-27.13c-9.725-31.273-40.025-65.155-73.898-82.118l47.766%20171.2%2056.456-0.064%2084.004-195.39h-56.521'%20fill='%23ffffff'/%3e%3cpath%20d='m146.92%20152.96h-86.041l-0.681%204.073c66.938%2016.204%20111.23%2055.363%20129.62%20102.41l-18.71-89.96c-3.23-12.395-12.597-16.094-24.186-16.527'%20fill='%23F2AE14'/%3e%3c/svg%3e", E = [
1208
+ {
1209
+ type: "visa",
1210
+ imgSrc: ht
1211
+ },
1212
+ {
1213
+ type: "masterCard",
1214
+ imgSrc: dt
1215
+ },
1216
+ {
1217
+ type: "americanExpress",
1218
+ imgSrc: lt
1219
+ },
1220
+ {
1221
+ type: "discover",
1222
+ imgSrc: ct
1223
+ }
1224
+ ];
1225
+ class mt extends h {
1226
+ cardType;
1227
+ constructor(e) {
1228
+ super("div", []), this.cardType = e.cardType;
1229
+ const t = document.createElement("label");
1230
+ t.setAttribute("for", "cardNumber"), t.textContent = e.label, t.style.color = e.styles.color, t.style.fontSize = `${e.styles.fontSize}px`, t.style.display = "block", t.style.marginBottom = "6px", this.getElement().appendChild(t);
1231
+ const a = document.createElement("div");
1232
+ a.className = e.isLoading ? "loading" : "", a.style.borderRadius = `${e.styles.borderRadius}px ${e.styles.borderRadius}px 0px 0px`;
1233
+ const i = document.createElement("div");
1234
+ i.id = "card-element", i.className = `card-element ${e.isFocused ? "card-element-focus" : ""}`, i.style.zIndex = e.isFocused ? "2" : "0";
1235
+ const s = document.createElement("div");
1236
+ if (s.className = "cards-position", e.cardType === "unknown")
1237
+ E.forEach((n) => {
1238
+ s.appendChild(this.createCardIcon(n));
1239
+ });
1240
+ else {
1241
+ const n = E.find((o) => o.type === e.cardType);
1242
+ n && s.appendChild(this.createCardIcon(n));
1243
+ }
1244
+ i.appendChild(s), a.appendChild(i), this.getElement().appendChild(a);
1245
+ }
1246
+ createCardIcon(e) {
1247
+ const t = document.createElement("div");
1248
+ t.className = "card-icon";
1249
+ const a = document.createElement("img");
1250
+ return a.src = e.imgSrc, t.appendChild(a), t;
1251
+ }
1252
+ setFocused(e) {
1253
+ const t = this.getElement().querySelector(
1254
+ "#card-element"
1255
+ );
1256
+ return t && (e ? (t.classList.add("card-element-focus"), t.style.zIndex = "2") : (t.classList.remove("card-element-focus"), t.style.zIndex = "0")), this;
1257
+ }
1258
+ setLoading(e) {
1259
+ const t = this.getElement().querySelector("div");
1260
+ return t && (e ? t.classList.add("loading") : t.classList.remove("loading")), this;
1261
+ }
1262
+ updateCardType(e) {
1263
+ if (e === void 0 && this.cardType && this.cardType !== "unknown")
1264
+ return this;
1265
+ const t = e === void 0 ? "unknown" : e;
1266
+ if (this.cardType === t)
1267
+ return this;
1268
+ this.cardType = t;
1269
+ const a = this.getElement().querySelector(".cards-position");
1270
+ if (a)
1271
+ if (a.innerHTML = "", this.cardType === "unknown")
1272
+ E.forEach((i) => {
1273
+ a.appendChild(this.createCardIcon(i));
1274
+ });
1275
+ else {
1276
+ const i = E.find((s) => s.type === this.cardType);
1277
+ i ? a.appendChild(this.createCardIcon(i)) : E.forEach((s) => {
1278
+ a.appendChild(this.createCardIcon(s));
1279
+ });
1280
+ }
1281
+ return this;
1282
+ }
1283
+ }
1284
+ class ut extends h {
1285
+ cardNumber;
1286
+ cardExpiry;
1287
+ cardCvv;
1288
+ validationMessages = /* @__PURE__ */ new Map();
1289
+ constructor(e) {
1290
+ super("div", []);
1291
+ const {
1292
+ checkoutProfile: t,
1293
+ isLoading: a,
1294
+ isFocused: i,
1295
+ isCvvFocused: s,
1296
+ isCcValid: n,
1297
+ isCvvValid: o,
1298
+ cardType: l,
1299
+ cardExpiry: d,
1300
+ cardExpiryError: c,
1301
+ cardExpiryTouched: m,
1302
+ onChange: p,
1303
+ onBlur: u,
1304
+ translationFunc: f
1305
+ } = e, b = document.createElement("div");
1306
+ b.className = "card-grid", this.cardNumber = new mt({
1307
+ styles: {
1308
+ color: t.styles.textColor,
1309
+ fontSize: t.styles.fontSize,
1310
+ borderRadius: t.styles.borderRadius
1311
+ },
1312
+ label: f("cardInformation"),
1313
+ isLoading: a,
1314
+ isFocused: i,
1315
+ cardType: l
1316
+ }), b.appendChild(this.cardNumber.getElement());
1317
+ const C = document.createElement("div");
1318
+ C.className = "card-details", this.cardExpiry = new M({
1319
+ name: "cardExpiry",
1320
+ placeholder: f("cardExpiry"),
1321
+ error: !!(c && m),
1322
+ errorMsg: c,
1323
+ value: d,
1324
+ onChange: p,
1325
+ styles: {
1326
+ color: t.styles.textColor,
1327
+ borderRadius: `0px 0px 0px ${t.styles.borderRadius}px`,
1328
+ fontSize: t.styles.fontSize,
1329
+ fontFamily: t.styles.fontFamily
1330
+ }
1331
+ }), this.cardExpiry.addEventListener("blur", u), this.cardExpiry.addEventListener("keydown", (g) => {
1332
+ const w = g;
1333
+ ![
1334
+ "Backspace",
1335
+ "Delete",
1336
+ "ArrowLeft",
1337
+ "ArrowRight",
1338
+ "Tab"
1339
+ ].includes(w.key) && !/^\d$/.test(w.key) && w.preventDefault();
1340
+ });
1341
+ const N = this.cardExpiry.getElement();
1342
+ N.style.height = "100%";
1343
+ const F = document.createElement("div");
1344
+ if (F.className = "input-wrapper", this.cardCvv = new ot({
1345
+ styles: {
1346
+ borderRadius: typeof t.styles.borderRadius == "number" ? t.styles.borderRadius : 0
1347
+ },
1348
+ isLoading: a,
1349
+ isFocused: s
1350
+ }), F.appendChild(this.cardCvv.getElement()), C.appendChild(this.cardExpiry.getElement()), C.appendChild(F), b.appendChild(C), this.getElement().appendChild(b), i && !n) {
1351
+ const g = new v({
1352
+ text: f("validation.cardNumberInvalid")
1353
+ });
1354
+ this.validationMessages.set("cardNumber", g), this.appendChild(g);
1355
+ }
1356
+ if (s && !o) {
1357
+ const g = new v({
1358
+ text: f("validation.cardSecurityFormat")
1359
+ });
1360
+ this.validationMessages.set("cardCvv", g), this.appendChild(g);
1361
+ }
1362
+ }
1363
+ updateCardType(e) {
1364
+ return this.cardNumber.updateCardType(e), this;
1365
+ }
1366
+ updateCardExpiry(e, t, a) {
1367
+ return this.cardExpiry.setValue(e), t && a ? this.cardExpiry.setError(!0, t) : this.cardExpiry.setError(!1), this;
1368
+ }
1369
+ updateCardNumberValidation(e, t, a) {
1370
+ if (this.cardNumber.setFocused(e), e && !t) {
1371
+ if (!this.validationMessages.has("cardNumber")) {
1372
+ const i = new v({
1373
+ text: a("validation.cardNumberInvalid")
1374
+ });
1375
+ this.validationMessages.set("cardNumber", i), this.appendChild(i);
1376
+ }
1377
+ } else {
1378
+ const i = this.validationMessages.get("cardNumber");
1379
+ i && (i.getElement().remove(), this.validationMessages.delete("cardNumber"));
1380
+ }
1381
+ return this;
1382
+ }
1383
+ updateCardCvvValidation(e, t, a) {
1384
+ if (this.cardCvv.setFocused(e), e && !t) {
1385
+ if (!this.validationMessages.has("cardCvv")) {
1386
+ const i = new v({
1387
+ text: a("validation.cardSecurityFormat")
1388
+ });
1389
+ this.validationMessages.set("cardCvv", i), this.appendChild(i);
1390
+ }
1391
+ } else {
1392
+ const i = this.validationMessages.get("cardCvv");
1393
+ i && (i.getElement().remove(), this.validationMessages.delete("cardCvv"));
1394
+ }
1395
+ return this;
1396
+ }
1397
+ setLoading(e) {
1398
+ return this.cardNumber.setLoading(e), this.cardCvv.setLoading(e), this;
1399
+ }
1400
+ }
1401
+ class pt {
1402
+ input;
1403
+ constructor(e) {
1404
+ const {
1405
+ value: t,
1406
+ onChange: a,
1407
+ onBlur: i,
1408
+ error: s,
1409
+ errorMsg: n,
1410
+ checkoutProfile: o,
1411
+ translationFunc: l
1412
+ } = e;
1413
+ this.input = new M({
1414
+ name: "email",
1415
+ label: l("email"),
1416
+ error: s,
1417
+ errorMsg: n,
1418
+ styles: {
1419
+ color: o.styles.textColor,
1420
+ borderRadius: `${o.styles.borderRadius}px`,
1421
+ fontSize: o.styles.fontSize,
1422
+ fontFamily: o.styles.fontFamily
1423
+ },
1424
+ placeholder: l("email"),
1425
+ type: "email",
1426
+ value: t,
1427
+ onChange: a
1428
+ }), this.input.addEventListener("blur", i);
1429
+ }
1430
+ getValue() {
1431
+ return this.input.getValue();
1432
+ }
1433
+ setValue(e) {
1434
+ return this.input.setValue(e), this;
1435
+ }
1436
+ setError(e, t) {
1437
+ return this.input.setError(e, t), this;
1438
+ }
1439
+ getElement() {
1440
+ return this.input.getElement();
1441
+ }
1442
+ appendTo(e) {
1443
+ return this.input.appendTo(e), this;
1444
+ }
1445
+ }
1446
+ const ft = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='101px'%20height='32'%20viewBox='0%200%20101%2032'%20preserveAspectRatio='xMinYMin%20meet'%3e%3cpath%20fill='%23003087'%20d='M%2012.237%202.8%20L%204.437%202.8%20C%203.937%202.8%203.437%203.2%203.337%203.7%20L%200.237%2023.7%20C%200.137%2024.1%200.437%2024.4%200.837%2024.4%20L%204.537%2024.4%20C%205.037%2024.4%205.537%2024%205.637%2023.5%20L%206.437%2018.1%20C%206.537%2017.6%206.937%2017.2%207.537%2017.2%20L%2010.037%2017.2%20C%2015.137%2017.2%2018.137%2014.7%2018.937%209.8%20C%2019.237%207.7%2018.937%206%2017.937%204.8%20C%2016.837%203.5%2014.837%202.8%2012.237%202.8%20Z%20M%2013.137%2010.1%20C%2012.737%2012.9%2010.537%2012.9%208.537%2012.9%20L%207.337%2012.9%20L%208.137%207.7%20C%208.137%207.4%208.437%207.2%208.737%207.2%20L%209.237%207.2%20C%2010.637%207.2%2011.937%207.2%2012.637%208%20C%2013.137%208.4%2013.337%209.1%2013.137%2010.1%20Z'/%3e%3cpath%20fill='%23003087'%20d='M%2035.437%2010%20L%2031.737%2010%20C%2031.437%2010%2031.137%2010.2%2031.137%2010.5%20L%2030.937%2011.5%20L%2030.637%2011.1%20C%2029.837%209.9%2028.037%209.5%2026.237%209.5%20C%2022.137%209.5%2018.637%2012.6%2017.937%2017%20C%2017.537%2019.2%2018.037%2021.3%2019.337%2022.7%20C%2020.437%2024%2022.137%2024.6%2024.037%2024.6%20C%2027.337%2024.6%2029.237%2022.5%2029.237%2022.5%20L%2029.037%2023.5%20C%2028.937%2023.9%2029.237%2024.3%2029.637%2024.3%20L%2033.037%2024.3%20C%2033.537%2024.3%2034.037%2023.9%2034.137%2023.4%20L%2036.137%2010.6%20C%2036.237%2010.4%2035.837%2010%2035.437%2010%20Z%20M%2030.337%2017.2%20C%2029.937%2019.3%2028.337%2020.8%2026.137%2020.8%20C%2025.037%2020.8%2024.237%2020.5%2023.637%2019.8%20C%2023.037%2019.1%2022.837%2018.2%2023.037%2017.2%20C%2023.337%2015.1%2025.137%2013.6%2027.237%2013.6%20C%2028.337%2013.6%2029.137%2014%2029.737%2014.6%20C%2030.237%2015.3%2030.437%2016.2%2030.337%2017.2%20Z'/%3e%3cpath%20fill='%23003087'%20d='M%2055.337%2010%20L%2051.637%2010%20C%2051.237%2010%2050.937%2010.2%2050.737%2010.5%20L%2045.537%2018.1%20L%2043.337%2010.8%20C%2043.237%2010.3%2042.737%2010%2042.337%2010%20L%2038.637%2010%20C%2038.237%2010%2037.837%2010.4%2038.037%2010.9%20L%2042.137%2023%20L%2038.237%2028.4%20C%2037.937%2028.8%2038.237%2029.4%2038.737%2029.4%20L%2042.437%2029.4%20C%2042.837%2029.4%2043.137%2029.2%2043.337%2028.9%20L%2055.837%2010.9%20C%2056.137%2010.6%2055.837%2010%2055.337%2010%20Z'/%3e%3cpath%20fill='%23009cde'%20d='M%2067.737%202.8%20L%2059.937%202.8%20C%2059.437%202.8%2058.937%203.2%2058.837%203.7%20L%2055.737%2023.6%20C%2055.637%2024%2055.937%2024.3%2056.337%2024.3%20L%2060.337%2024.3%20C%2060.737%2024.3%2061.037%2024%2061.037%2023.7%20L%2061.937%2018%20C%2062.037%2017.5%2062.437%2017.1%2063.037%2017.1%20L%2065.537%2017.1%20C%2070.637%2017.1%2073.637%2014.6%2074.437%209.7%20C%2074.737%207.6%2074.437%205.9%2073.437%204.7%20C%2072.237%203.5%2070.337%202.8%2067.737%202.8%20Z%20M%2068.637%2010.1%20C%2068.237%2012.9%2066.037%2012.9%2064.037%2012.9%20L%2062.837%2012.9%20L%2063.637%207.7%20C%2063.637%207.4%2063.937%207.2%2064.237%207.2%20L%2064.737%207.2%20C%2066.137%207.2%2067.437%207.2%2068.137%208%20C%2068.637%208.4%2068.737%209.1%2068.637%2010.1%20Z'/%3e%3cpath%20fill='%23009cde'%20d='M%2090.937%2010%20L%2087.237%2010%20C%2086.937%2010%2086.637%2010.2%2086.637%2010.5%20L%2086.437%2011.5%20L%2086.137%2011.1%20C%2085.337%209.9%2083.537%209.5%2081.737%209.5%20C%2077.637%209.5%2074.137%2012.6%2073.437%2017%20C%2073.037%2019.2%2073.537%2021.3%2074.837%2022.7%20C%2075.937%2024%2077.637%2024.6%2079.537%2024.6%20C%2082.837%2024.6%2084.737%2022.5%2084.737%2022.5%20L%2084.537%2023.5%20C%2084.437%2023.9%2084.737%2024.3%2085.137%2024.3%20L%2088.537%2024.3%20C%2089.037%2024.3%2089.537%2023.9%2089.637%2023.4%20L%2091.637%2010.6%20C%2091.637%2010.4%2091.337%2010%2090.937%2010%20Z%20M%2085.737%2017.2%20C%2085.337%2019.3%2083.737%2020.8%2081.537%2020.8%20C%2080.437%2020.8%2079.637%2020.5%2079.037%2019.8%20C%2078.437%2019.1%2078.237%2018.2%2078.437%2017.2%20C%2078.737%2015.1%2080.537%2013.6%2082.637%2013.6%20C%2083.737%2013.6%2084.537%2014%2085.137%2014.6%20C%2085.737%2015.3%2085.937%2016.2%2085.737%2017.2%20Z'/%3e%3cpath%20fill='%23009cde'%20d='M%2095.337%203.3%20L%2092.137%2023.6%20C%2092.037%2024%2092.337%2024.3%2092.737%2024.3%20L%2095.937%2024.3%20C%2096.437%2024.3%2096.937%2023.9%2097.037%2023.4%20L%20100.237%203.5%20C%20100.337%203.1%20100.037%202.8%2099.637%202.8%20L%2096.037%202.8%20C%2095.637%202.8%2095.437%203%2095.337%203.3%20Z'/%3e%3c/svg%3e";
1447
+ class gt extends h {
1448
+ formData;
1449
+ onSubmit;
1450
+ isSubmitting = !1;
1451
+ constructor(e) {
1452
+ super("div", ["paypal"]);
1453
+ const { formData: t, onSubmit: a } = e;
1454
+ this.formData = t, this.onSubmit = a, this.getElement().style.cursor = a ? "pointer" : "default", this.getElement().style.opacity = "1";
1455
+ const i = document.createElement("div");
1456
+ i.className = "paypal-icon-container";
1457
+ const s = document.createElement("img");
1458
+ s.src = ft, s.style.width = "69px", s.style.height = "22px", s.style.maxWidth = "100%", s.style.display = "block", s.style.height = "auto", i.appendChild(s), this.getElement().appendChild(i), a && this.getElement().addEventListener("click", () => this.handleSubmit());
1459
+ }
1460
+ async handleSubmit() {
1461
+ if (!(!this.onSubmit || this.isSubmitting)) {
1462
+ this.isSubmitting = !0, this.getElement().style.opacity = "0.7";
1463
+ try {
1464
+ await this.onSubmit({ formData: this.formData });
1465
+ } catch (e) {
1466
+ console.error("Error during PayPal submission:", e);
1467
+ } finally {
1468
+ this.isSubmitting = !1, this.getElement().style.opacity = "1";
1469
+ }
1470
+ }
1471
+ }
1472
+ updateFormData(e) {
1473
+ return this.formData = e, this;
1474
+ }
1475
+ setSubmitting(e) {
1476
+ return this.isSubmitting = e, this.getElement().style.opacity = e ? "0.7" : "1", this;
1477
+ }
1478
+ }
1479
+ class yt extends h {
1480
+ paymentMethods = /* @__PURE__ */ new Map();
1481
+ constructor(e) {
1482
+ const { checkoutProfile: t, formData: a, onPaypalSubmit: i } = e;
1483
+ if (!t?.additionalPaymentMethods) {
1484
+ super("div", ["payment-methods"]), this.getElement().style.display = "none";
1485
+ return;
1486
+ }
1487
+ const s = Object.entries(
1488
+ t.additionalPaymentMethods
1489
+ ).filter(([, n]) => n.enabled).sort((n, o) => n[1].order - o[1].order);
1490
+ if (s.length === 0) {
1491
+ super("div", ["payment-methods"]), this.getElement().style.display = "none";
1492
+ return;
1493
+ }
1494
+ super("div", ["payment-methods"]);
1495
+ for (const [n] of s)
1496
+ switch (n) {
1497
+ case "paypal": {
1498
+ if (i) {
1499
+ const o = new gt({
1500
+ checkoutProfile: t,
1501
+ formData: a,
1502
+ onSubmit: i
1503
+ });
1504
+ this.paymentMethods.set("paypal", o), o.appendTo(this.getElement());
1505
+ }
1506
+ break;
1507
+ }
1508
+ }
1509
+ }
1510
+ updateFormData(e) {
1511
+ const t = this.paymentMethods.get("paypal");
1512
+ return t && t.updateFormData(e), this;
1513
+ }
1514
+ hasVisiblePaymentMethods() {
1515
+ return this.paymentMethods.size > 0 && this.getElement().style.display !== "none";
1516
+ }
1517
+ }
1518
+ const vt = 17;
1519
+ class Et extends h {
1520
+ styles;
1521
+ isHovered = !1;
1522
+ constructor(e) {
1523
+ super("button", ["button"], {
1524
+ type: "submit",
1525
+ disabled: e.disabled ? "true" : "false"
1526
+ }), this.styles = e.styles, this.setText(e.text), e.disabled ? this.addClass("disabled") : this.addClass("valid"), this.applyStyles(), this.addEventListener("mouseenter", () => this.handleMouseEnter()), this.addEventListener("mouseleave", () => this.handleMouseLeave());
1527
+ }
1528
+ applyStyles() {
1529
+ const e = this.getElement();
1530
+ e.style.backgroundColor = this.isHovered ? `color-mix(in srgb, ${this.styles.backgroundColor} 80%, transparent)` : this.styles.backgroundColor, e.disabled ? e.style.color = "#cccccc" : e.style.color = this.styles.color, e.style.borderRadius = this.styles.borderRadius === vt ? "100vmax" : `${this.styles.borderRadius}px`, e.style.fontSize = `${this.styles.fontSize}px`, e.style.fontFamily = `${this.styles.fontFamily}, sans-serif`;
1531
+ }
1532
+ handleMouseEnter() {
1533
+ this.isHovered = !0, this.applyStyles();
1534
+ }
1535
+ handleMouseLeave() {
1536
+ this.isHovered = !1, this.applyStyles();
1537
+ }
1538
+ setDisabled(e) {
1539
+ return this.getElement().disabled = e, e ? (this.addClass("disabled"), this.removeClass("valid")) : (this.removeClass("disabled"), this.addClass("valid")), this.applyStyles(), this;
1540
+ }
1541
+ }
1542
+ class bt {
1543
+ button;
1544
+ constructor(e) {
1545
+ const { disabled: t, checkoutProfile: a, translationFunc: i } = e;
1546
+ this.button = new Et({
1547
+ text: i(
1548
+ `buttonTexts.${a?.layout.actionButton.translationKey}`
1549
+ ),
1550
+ styles: {
1551
+ backgroundColor: a.styles.buttonColor,
1552
+ color: a.styles.buttonTextColor,
1553
+ fontFamily: a.styles.fontFamily,
1554
+ borderRadius: a.styles.borderRadius,
1555
+ fontSize: a.styles.buttonFontSize
1556
+ },
1557
+ disabled: t
1558
+ });
1559
+ }
1560
+ getElement() {
1561
+ return this.button.getElement();
1562
+ }
1563
+ setDisabled(e) {
1564
+ return this.button.setDisabled(e), this;
1565
+ }
1566
+ addEventListener(e, t, a) {
1567
+ return this.button.addEventListener(e, t, a), this;
1568
+ }
1569
+ appendTo(e) {
1570
+ return this.button.appendTo(e), this;
1571
+ }
1572
+ }
1573
+ const Ct = "https://test-htp.tokenex.com/Iframe/Iframe-v3.min.js";
1574
+ class St extends h {
1575
+ options;
1576
+ isSubmitting = !1;
1577
+ scriptCleanup;
1578
+ fontCleanup;
1579
+ // Form components
1580
+ emailField;
1581
+ cardSection;
1582
+ cardholderSection;
1583
+ submitButton;
1584
+ paymentMethods;
1585
+ spinner;
1586
+ alert;
1587
+ // factories
1588
+ formManager = G();
1589
+ checkoutProfile;
1590
+ translation = L();
1591
+ iframeHook;
1592
+ constructor(e) {
1593
+ super("form", ["form-container"]), this.options = e, this.checkoutProfile = O({
1594
+ apiKey: e.apiKey,
1595
+ profileId: e.profileId
1596
+ }), e.locale && this.translation.setLocale(e.locale), this.getElement().style.opacity = "0", this.getElement().style.transition = "opacity 0.5s ease-in-out", this.getElement().addEventListener("submit", this.handleSubmit), this.getElement().addEventListener("keydown", this.handleKeyDown), this.formManager.subscribe(this.handleFormStateChange), this.checkoutProfile.subscribe(this.handleProfileStateChange), this.initializeForm(), this.appendTo(e.container);
1597
+ }
1598
+ _getFormStateData() {
1599
+ const e = this.formManager.getFormState();
1600
+ return {
1601
+ formData: e.formData || {
1602
+ email: "",
1603
+ name: "",
1604
+ cardExpiry: ""
1605
+ },
1606
+ errors: e.errors || {},
1607
+ touched: e.touched || {}
1608
+ };
1609
+ }
1610
+ handleFormStateChange = () => {
1611
+ this.updateFormUI();
1612
+ };
1613
+ handleProfileStateChange = (e) => {
1614
+ if (!e.isLoading)
1615
+ if (this.hideSpinner(), e.checkoutProfile)
1616
+ try {
1617
+ if (e.checkoutProfile.styles?.fontFamily) {
1618
+ const { cleanup: t } = et({
1619
+ fontFamily: e.checkoutProfile.styles.fontFamily
1620
+ });
1621
+ this.fontCleanup = t;
1622
+ }
1623
+ this.initializeTokenExIframe();
1624
+ } catch {
1625
+ const t = e.error || "Failed to load checkout profile data";
1626
+ this.setErrorMessage(t);
1627
+ }
1628
+ else e.error && this.setErrorMessage(e.error);
1629
+ };
1630
+ applyFormContainerStyles(e) {
1631
+ e.fontFamily && (this.getElement().style.fontFamily = e.fontFamily);
1632
+ }
1633
+ initializeTokenExIframe = () => {
1634
+ const e = this.checkoutProfile.getState();
1635
+ if (e.checkoutProfile && !this.iframeHook)
1636
+ try {
1637
+ if (!("TokenEx" in globalThis)) {
1638
+ setTimeout(() => this.initializeTokenExIframe(), 500);
1639
+ return;
1640
+ }
1641
+ const { inputStyles: t, formContainerStyle: a } = at(
1642
+ e.checkoutProfile
1643
+ );
1644
+ this.applyFormContainerStyles(a), this.iframeHook = Y({
1645
+ apiKey: this.options.apiKey,
1646
+ checkoutProfile: e.checkoutProfile,
1647
+ inputStyles: t,
1648
+ setFormData: (i) => {
1649
+ this.formManager.setFormData(i);
1650
+ }
1651
+ }), this.iframeHook?.subscribe(this.handleIframeStateChange), this.renderFormComponents();
1652
+ } catch {
1653
+ this.setErrorMessage("Failed to initialize payment form");
1654
+ }
1655
+ else e.checkoutProfile ? this.iframeHook && console.log("TokenEx iframe already initialized") : console.error("Cannot initialize iframe: No checkout profile available");
1656
+ };
1657
+ handleIframeStateChange = (e) => {
1658
+ this.cardSection && (this.cardSection.updateCardNumberValidation(
1659
+ e.isFocused,
1660
+ e.isCcValid,
1661
+ this.translation.t
1662
+ ), this.cardSection.updateCardCvvValidation(
1663
+ e.isCvvFocused,
1664
+ e.isCvvValid,
1665
+ this.translation.t
1666
+ ), this.cardSection.updateCardType(e.possibleCardType), this.cardSection.setLoading(e.loadingIframe)), this.submitButton && this.submitButton.setDisabled(this.isFormDisabled());
1667
+ };
1668
+ createCardSection = (e) => {
1669
+ if (this.iframeHook && !this.cardSection)
1670
+ try {
1671
+ const { formData: t, errors: a, touched: i } = this._getFormStateData(), s = this.iframeHook.getState();
1672
+ this.cardSection = new ut({
1673
+ checkoutProfile: e,
1674
+ isLoading: s.loadingIframe,
1675
+ isFocused: s.isFocused,
1676
+ isCvvFocused: s.isCvvFocused,
1677
+ isCcValid: s.isCcValid,
1678
+ isCvvValid: s.isCvvValid,
1679
+ cardType: s.possibleCardType,
1680
+ cardExpiry: t.cardExpiry,
1681
+ cardExpiryError: a.cardExpiry,
1682
+ cardExpiryTouched: !!i.cardExpiry,
1683
+ onChange: this.handleChange,
1684
+ onBlur: this.handleBlur,
1685
+ translationFunc: this.translation.t
1686
+ }), this.element.appendChild(this.cardSection.getElement()), this.updateFormUI(), this.cardSection && this.emailField && this.cardholderSection && this.submitButton && this.animateFormVisibility();
1687
+ } catch {
1688
+ this.setErrorMessage("Card section temporarily unavailabl");
1689
+ }
1690
+ };
1691
+ initializeForm() {
1692
+ this.showSpinner("Loading checkout form..."), this.options.errorMsg && this.setErrorMessage(this.options.errorMsg);
1693
+ const { cleanup: e, isLoaded: t } = tt({
1694
+ scriptSrc: Ct
1695
+ });
1696
+ this.scriptCleanup = e, t.then(() => {
1697
+ }).catch(() => {
1698
+ this.setErrorMessage(
1699
+ "Failed to load payment system. Please try again later."
1700
+ );
1701
+ });
1702
+ }
1703
+ renderFormComponents() {
1704
+ if (!this.emailField)
1705
+ try {
1706
+ const e = this.checkoutProfile.getState();
1707
+ if (!e.checkoutProfile) {
1708
+ this.setErrorMessage("Failed to load checkout configuration");
1709
+ return;
1710
+ }
1711
+ this.createPaymentMethods(e.checkoutProfile), this.createEmailField(e.checkoutProfile), this.createCardSection(e.checkoutProfile), this.createCardholderSection(e.checkoutProfile), this.createSubmitButton(e.checkoutProfile), this.animateFormVisibility();
1712
+ } catch {
1713
+ this.setErrorMessage("Failed to render checkout form components");
1714
+ }
1715
+ }
1716
+ /**
1717
+ * Animate the form's visibility by transitioning opacity
1718
+ */
1719
+ animateFormVisibility() {
1720
+ setTimeout(() => {
1721
+ this.getElement().style.opacity = "1";
1722
+ }, 100);
1723
+ }
1724
+ createPaymentMethods(e) {
1725
+ if (!e?.additionalPaymentMethods || Object.entries(
1726
+ e.additionalPaymentMethods
1727
+ ).filter(([, i]) => i.enabled).length === 0)
1728
+ return;
1729
+ const { formData: a } = this._getFormStateData();
1730
+ this.paymentMethods = new yt({
1731
+ checkoutProfile: e,
1732
+ formData: a,
1733
+ onPaypalSubmit: async () => {
1734
+ await this.handlePaypalSubmit();
1735
+ }
1736
+ }), this.appendChild(this.paymentMethods);
1737
+ }
1738
+ createEmailField(e) {
1739
+ const { formData: t, errors: a, touched: i } = this._getFormStateData();
1740
+ this.emailField = new pt({
1741
+ value: t.email,
1742
+ onChange: this.handleChange,
1743
+ onBlur: this.handleBlur,
1744
+ error: !!(a.email && i.email),
1745
+ errorMsg: a.email,
1746
+ checkoutProfile: e,
1747
+ translationFunc: this.translation.t
1748
+ }), this.element.appendChild(this.emailField.getElement());
1749
+ }
1750
+ createCardholderSection(e) {
1751
+ const { formData: t, errors: a, touched: i } = this._getFormStateData();
1752
+ this.cardholderSection = new nt({
1753
+ value: t.name,
1754
+ onChange: this.handleChange,
1755
+ onBlur: this.handleBlur,
1756
+ error: !!(a.name && i.name),
1757
+ errorMsg: a.name,
1758
+ checkoutProfile: e,
1759
+ translationFunc: this.translation.t
1760
+ }), this.element.appendChild(this.cardholderSection.getElement());
1761
+ }
1762
+ createSubmitButton(e) {
1763
+ this.submitButton = new bt({
1764
+ disabled: this.isFormDisabled(),
1765
+ checkoutProfile: e,
1766
+ translationFunc: this.translation.t
1767
+ }), this.element.appendChild(this.submitButton.getElement());
1768
+ }
1769
+ handleChange = (e) => {
1770
+ const t = e.target, { name: a, value: i } = t;
1771
+ this.formManager.handleChange(a, i);
1772
+ };
1773
+ handleBlur = (e) => {
1774
+ const t = e.target, { name: a, value: i } = t;
1775
+ this.formManager.handleBlur(a, i);
1776
+ };
1777
+ updateFormUI() {
1778
+ const e = this.formManager.getFormState();
1779
+ this.checkoutProfile.getState().checkoutProfile && (this.paymentMethods && this.paymentMethods.updateFormData(e.formData), this.emailField && (this.emailField.setValue(e.formData.email), this.emailField.setError(
1780
+ !!(e.errors.email && e.touched.email),
1781
+ e.errors.email
1782
+ )), this.cardSection && this.cardSection.updateCardExpiry(
1783
+ e.formData.cardExpiry,
1784
+ e.errors.cardExpiry,
1785
+ !!e.touched.cardExpiry
1786
+ ), this.cardholderSection && (this.cardholderSection.setValue(e.formData.name), this.cardholderSection.setError(
1787
+ !!(e.errors.name && e.touched.name),
1788
+ e.errors.name
1789
+ )), this.submitButton && this.submitButton.setDisabled(this.isFormDisabled()));
1790
+ }
1791
+ isFormDisabled() {
1792
+ const e = this.formManager.getFormState();
1793
+ let t = {
1794
+ isCcValid: !1,
1795
+ isCvvValid: !1
1796
+ };
1797
+ this.iframeHook && (t = this.iframeHook.getState());
1798
+ const a = Object.keys(e.errors).length > 0, i = (
1799
+ // Only require card validation if CardSection exists
1800
+ (!this.cardSection || t.isCcValid && t.isCvvValid) && !!e.formData.email && !!e.formData.name && // Only require card expiry if CardSection exists
1801
+ (!this.cardSection || !!e.formData.cardExpiry)
1802
+ );
1803
+ return a || !i || this.isSubmitting;
1804
+ }
1805
+ showSpinner(e) {
1806
+ this.hideSpinner(), this.spinner = new st({ text: e }), this.appendChild(this.spinner);
1807
+ }
1808
+ hideSpinner() {
1809
+ this.spinner && (this.spinner.getElement().remove(), this.spinner = void 0);
1810
+ }
1811
+ handleSubmit = async (e) => {
1812
+ if (e.preventDefault(), !this.isFormDisabled())
1813
+ try {
1814
+ if (!this.iframeHook)
1815
+ throw new Error("TokenEx iframe not initialized");
1816
+ this.isSubmitting = !0, this.updateFormUI(), this.showSpinner(this.translation.t("loading")), await this.iframeHook.tokenize(async (t) => {
1817
+ try {
1818
+ await this.options.onSubmit({
1819
+ formData: this.formManager.getFormState().formData,
1820
+ tokenexData: t
1821
+ }), this.hideSpinner(), this.isSubmitting = !1, this.updateFormUI();
1822
+ } catch {
1823
+ this.handleSubmitError(
1824
+ "Payment processing failed. Please try again."
1825
+ );
1826
+ }
1827
+ });
1828
+ } catch {
1829
+ this.handleSubmitError("Payment processing failed. Please try again.");
1830
+ }
1831
+ };
1832
+ handleSubmitError(e) {
1833
+ this.hideSpinner(), this.isSubmitting = !1, this.setErrorMessage(e), this.updateFormUI();
1834
+ }
1835
+ handlePaypalSubmit = async () => {
1836
+ this.isSubmitting = !0, this.updateFormUI(), this.showSpinner(this.translation.t("loading"));
1837
+ try {
1838
+ await this.options.onSubmit({
1839
+ formData: null,
1840
+ tokenexData: null
1841
+ // No tokenization for PayPal
1842
+ }), this.hideSpinner(), this.isSubmitting = !1, this.updateFormUI();
1843
+ } catch {
1844
+ this.setErrorMessage("PayPal processing failed. Please try again.");
1845
+ } finally {
1846
+ this.hideSpinner(), this.isSubmitting = !1, this.updateFormUI();
1847
+ }
1848
+ };
1849
+ // Public methods
1850
+ /**
1851
+ * Update the form error message
1852
+ */
1853
+ setErrorMessage(e) {
1854
+ return this.alert && (this.alert.getElement().remove(), this.alert = void 0), this.alert = new it({ message: e }), this.element.insertBefore(this.alert.getElement(), this.element.firstChild), this.getElement().style.opacity === "0" && this.animateFormVisibility(), this;
1855
+ }
1856
+ /**
1857
+ * Clean up resources when the form is destroyed
1858
+ */
1859
+ destroy() {
1860
+ this.scriptCleanup && (this.scriptCleanup(), this.scriptCleanup = void 0), this.fontCleanup && (this.fontCleanup(), this.fontCleanup = void 0), this.iframeHook && this.iframeHook.cleanup(), this.getElement().removeEventListener("submit", this.handleSubmit), this.getElement().removeEventListener("keydown", this.handleKeyDown), this.getElement().removeEventListener("keydown", this.handleKeyDown), this.emailField && (this.emailField.getElement().remove(), this.emailField = void 0), this.cardSection && (this.cardSection.getElement().remove(), this.cardSection = void 0), this.cardholderSection && (this.cardholderSection.getElement().remove(), this.cardholderSection = void 0), this.submitButton && (this.submitButton.getElement().remove(), this.submitButton = void 0), this.paymentMethods && (this.paymentMethods.getElement().remove(), this.paymentMethods = void 0), this.spinner && (this.spinner.getElement().remove(), this.spinner = void 0), this.alert && (this.alert.getElement().remove(), this.alert = void 0), this.getElement().remove();
1861
+ }
1862
+ handleKeyDown = (e) => {
1863
+ e.key === "Enter" && !this.isFormDisabled() && (e.target instanceof HTMLTextAreaElement || (e.preventDefault(), this.handleSubmit(e)));
1864
+ };
1865
+ }
1866
+ class xt {
1867
+ container = null;
1868
+ options;
1869
+ onSubmit;
1870
+ form = null;
1871
+ constructor(e, t) {
1872
+ this.options = e, this.onSubmit = t;
1873
+ }
1874
+ mount(e) {
1875
+ this.unmount(), this.container = e, this.renderForm();
1876
+ }
1877
+ update(e) {
1878
+ this.container && this.form && (this.form && e.errorMsg && !this.options.disableErrorMessages ? this.form.setErrorMessage(e.errorMsg) : this.renderForm(e.errorMsg));
1879
+ }
1880
+ renderForm(e) {
1881
+ this.container && (this.form && (this.form.destroy(), this.form = null), this.form = new St({
1882
+ apiKey: this.options.apiKey,
1883
+ onSubmit: this.onSubmit,
1884
+ locale: this.options.locale,
1885
+ errorMsg: this.options.disableErrorMessages ? void 0 : e,
1886
+ profileId: this.options.profileId,
1887
+ container: this.container
1888
+ }));
1889
+ }
1890
+ unmount() {
1891
+ this.form && (this.form.destroy(), this.form = null);
1892
+ }
1893
+ }
1894
+ class Ft {
1895
+ state;
1896
+ listeners = /* @__PURE__ */ new Set();
1897
+ constructor(e) {
1898
+ this.state = e;
1899
+ }
1900
+ getState() {
1901
+ return { ...this.state };
1902
+ }
1903
+ updateState(e) {
1904
+ this.state = { ...this.state, ...e }, this.notifyListeners();
1905
+ }
1906
+ subscribe(e) {
1907
+ return this.listeners.add(e), () => {
1908
+ this.listeners.delete(e);
1909
+ };
1910
+ }
1911
+ notifyListeners() {
1912
+ const e = this.getState();
1913
+ this.listeners.forEach((t) => t(e));
1914
+ }
1915
+ }
1916
+ class wt {
1917
+ config;
1918
+ apiService;
1919
+ formManager;
1920
+ stateManager;
1921
+ constructor(e) {
1922
+ this.config = this.validateConfig(e), this.apiService = new D(this.config.apiKey), this.stateManager = new Ft({
1923
+ mounted: !1,
1924
+ form: null
1925
+ }), this.formManager = new xt(
1926
+ {
1927
+ locale: this.config.locale,
1928
+ apiKey: this.config.apiKey,
1929
+ profileId: this.config.profileId,
1930
+ disableErrorMessages: this.config.disableErrorMessages
1931
+ },
1932
+ this.handleSubmit.bind(this)
1933
+ );
1934
+ }
1935
+ validateConfig(e) {
1936
+ if (!e.apiKey)
1937
+ throw new Error("API key is required");
1938
+ return {
1939
+ profileId: e.profileId,
1940
+ apiKey: e.apiKey,
1941
+ checkoutKey: e.checkoutKey,
1942
+ paymentId: e.paymentId,
1943
+ returnUrl: e.returnUrl,
1944
+ locale: e.locale || null,
1945
+ disableErrorMessages: e.disableErrorMessages ?? !1,
1946
+ manualActionHandling: e.manualActionHandling ?? !1,
1947
+ callbacks: {
1948
+ onPaymentSucceeded: e.callbacks?.onPaymentSucceeded || void 0,
1949
+ onPaymentFailed: e.callbacks?.onPaymentFailed || void 0,
1950
+ onActionRequired: e.callbacks?.onActionRequired || void 0
1951
+ }
1952
+ };
1953
+ }
1954
+ mount(e) {
1955
+ const t = document.querySelector(e);
1956
+ if (!t)
1957
+ throw new Error(`Container ${e} not found`);
1958
+ const a = document.createElement("div");
1959
+ return t.appendChild(a), this.stateManager.updateState({
1960
+ form: a,
1961
+ mounted: !0
1962
+ }), this.formManager.mount(a), this;
1963
+ }
1964
+ unmount() {
1965
+ const { mounted: e } = this.stateManager.getState();
1966
+ e && Promise.resolve().then(() => {
1967
+ this.formManager.unmount();
1968
+ const { form: t } = this.stateManager.getState();
1969
+ t && t.remove(), this.stateManager.updateState({
1970
+ form: null,
1971
+ mounted: !1
1972
+ });
1973
+ });
1974
+ }
1975
+ async handleSubmit({
1976
+ tokenexData: e,
1977
+ formData: t
1978
+ }) {
1979
+ try {
1980
+ const a = await this.apiService.authorizePayment({
1981
+ checkoutKey: this.config.checkoutKey,
1982
+ formData: t || null,
1983
+ token: e?.token || null,
1984
+ paymentId: this.config.paymentId,
1985
+ returnUrl: this.config.returnUrl
1986
+ });
1987
+ this.handlePaymentResponse(a);
1988
+ } catch (a) {
1989
+ this.handleAuthorizationError(a);
1990
+ }
1991
+ }
1992
+ handlePaymentResponse(e) {
1993
+ if (e.latestTransaction.status === "authorized" && this.config.callbacks.onPaymentSucceeded?.(
1994
+ e.latestTransaction.status
1995
+ ), e.latestTransaction.status === "failed" && this.config.callbacks.onPaymentFailed?.(e.latestTransaction.status), e.status === "requires_action") {
1996
+ const { redirectUrl: t } = e.action;
1997
+ this.config.manualActionHandling ? this.config.callbacks.onActionRequired?.(t) : globalThis.location.href = t;
1998
+ }
1999
+ }
2000
+ handleAuthorizationError(e) {
2001
+ this.config.callbacks.onPaymentFailed?.(e.details?.message);
2002
+ const { form: t } = this.stateManager.getState();
2003
+ t && this.formManager.update({ errorMsg: e.details?.message });
2004
+ }
2005
+ }
2006
+ typeof globalThis < "u" && (globalThis.OdusCheckout = wt);
2007
+ export {
2008
+ wt as OdusCheckout,
2009
+ se as deLocale,
2010
+ ue as enLocale,
2011
+ Se as esLocale,
2012
+ ze as frLocale,
2013
+ Oe as plLocale,
2014
+ Ye as ptLocale
2015
+ };
2016
+ //# sourceMappingURL=index.mjs.map