@zoreal/oauth2-js 0.1.7 → 0.1.9

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.js CHANGED
@@ -14,7 +14,7 @@ function unsafeClaims(idToken) {
14
14
 
15
15
  // src/wire.ts
16
16
  var WIRE_VERSION = 1;
17
- var SDK_VERSION = "0.1.7";
17
+ var SDK_VERSION = "0.1.9";
18
18
  var SDK_NAME = "@zoreal/oauth2-js";
19
19
  var DEFAULT_ISSUER = "https://id.zoreal.com";
20
20
  var POLL_INTERVAL_MS = 2e3;
@@ -138,6 +138,1174 @@ function isMobileUserAgent() {
138
138
  return /android|iphone|ipad|ipod/i.test(navigator.userAgent);
139
139
  }
140
140
 
141
+ // src/i18n.ts
142
+ var en = {
143
+ title: "Scan to sign in",
144
+ titleApprove: "Approve on your phone",
145
+ bodyScan: "Scan with your phone camera or the ZOREAL ID app.",
146
+ bodyApprove: "Approve the login in your ZOREAL ID app.",
147
+ bodyEnrolling: "Finish setting up ZOREAL ID on your phone, then approve the login.",
148
+ waiting: "Waiting for scan",
149
+ waitingApproval: "Waiting for approval",
150
+ expiresIn: "Expires in {time}",
151
+ secured: "Proof-of-Human verification by ZOREAL",
152
+ noIdTitle: "No ZOREAL ID yet?",
153
+ noIdBody: "Scan the same code to download the app and create one for free. It only takes a minute.",
154
+ cancel: "Cancel",
155
+ close: "Close",
156
+ qrAlt: "QR code to sign in with ZOREAL"
157
+ };
158
+ var TRANSLATIONS = {
159
+ en,
160
+ sv: {
161
+ title: "Skanna f\xF6r att logga in",
162
+ titleApprove: "Godk\xE4nn p\xE5 telefonen",
163
+ bodyScan: "Skanna med telefonens kamera eller ZOREAL ID-appen.",
164
+ bodyApprove: "Godk\xE4nn inloggningen i ZOREAL ID-appen.",
165
+ bodyEnrolling: "Slutf\xF6r konfigurationen av ZOREAL ID p\xE5 telefonen och godk\xE4nn sedan inloggningen.",
166
+ waiting: "V\xE4ntar p\xE5 skanning",
167
+ waitingApproval: "V\xE4ntar p\xE5 godk\xE4nnande",
168
+ expiresIn: "Upph\xF6r om {time}",
169
+ secured: "Proof-of-Human-verifiering av ZOREAL",
170
+ noIdTitle: "Har du inget ZOREAL ID?",
171
+ noIdBody: "Skanna samma kod f\xF6r att ladda ner appen och skapa ett gratis. Det tar bara en minut.",
172
+ cancel: "Avbryt",
173
+ close: "St\xE4ng",
174
+ qrAlt: "QR-kod f\xF6r att logga in med ZOREAL"
175
+ },
176
+ es: {
177
+ title: "Escanea para iniciar sesi\xF3n",
178
+ titleApprove: "Apru\xE9balo en tu tel\xE9fono",
179
+ bodyScan: "Escanea con la c\xE1mara de tu tel\xE9fono o con la app ZOREAL ID.",
180
+ bodyApprove: "Aprueba el inicio de sesi\xF3n en tu app ZOREAL ID.",
181
+ bodyEnrolling: "Termina de configurar ZOREAL ID en tu tel\xE9fono y luego aprueba el inicio de sesi\xF3n.",
182
+ waiting: "Esperando el escaneo",
183
+ waitingApproval: "Esperando aprobaci\xF3n",
184
+ expiresIn: "Caduca en {time}",
185
+ secured: "Verificaci\xF3n Proof-of-Human de ZOREAL",
186
+ noIdTitle: "\xBFA\xFAn no tienes ZOREAL ID?",
187
+ noIdBody: "Escanea el mismo c\xF3digo para descargar la app y crear una gratis. Solo toma un minuto.",
188
+ cancel: "Cancelar",
189
+ close: "Cerrar",
190
+ qrAlt: "C\xF3digo QR para iniciar sesi\xF3n con ZOREAL"
191
+ },
192
+ pt: {
193
+ title: "Digitalize para entrar",
194
+ titleApprove: "Aprove no seu telefone",
195
+ bodyScan: "Digitalize com a c\xE2mara do seu telefone ou com a app ZOREAL ID.",
196
+ bodyApprove: "Aprove o login no app ZOREAL ID.",
197
+ bodyEnrolling: "Termine de configurar o ZOREAL ID no seu telefone e depois aprove o login.",
198
+ waiting: "Aguardando digitaliza\xE7\xE3o",
199
+ waitingApproval: "Aguardando aprova\xE7\xE3o",
200
+ expiresIn: "Expira em {time}",
201
+ secured: "Verifica\xE7\xE3o Proof-of-Human da ZOREAL",
202
+ noIdTitle: "Ainda n\xE3o tem ZOREAL ID?",
203
+ noIdBody: "Digitalize o mesmo c\xF3digo para baixar o app e criar uma conta gr\xE1tis. Leva s\xF3 um minuto.",
204
+ cancel: "Cancelar",
205
+ close: "Fechar",
206
+ qrAlt: "C\xF3digo QR para entrar com ZOREAL"
207
+ },
208
+ fr: {
209
+ title: "Scannez pour vous connecter",
210
+ titleApprove: "Approuvez sur votre t\xE9l\xE9phone",
211
+ bodyScan: "Scannez avec l'appareil photo de votre t\xE9l\xE9phone ou l'app ZOREAL ID.",
212
+ bodyApprove: "Approuvez la connexion dans votre app ZOREAL ID.",
213
+ bodyEnrolling: "Terminez la configuration de ZOREAL ID sur votre t\xE9l\xE9phone, puis approuvez la connexion.",
214
+ waiting: "En attente du scan",
215
+ waitingApproval: "En attente d'approbation",
216
+ expiresIn: "Expire dans {time}",
217
+ secured: "V\xE9rification Proof-of-Human par ZOREAL",
218
+ noIdTitle: "Pas encore de ZOREAL ID ?",
219
+ noIdBody: "Scannez le m\xEAme code pour t\xE9l\xE9charger l'app et en cr\xE9er un gratuitement. Cela prend une minute.",
220
+ cancel: "Annuler",
221
+ close: "Fermer",
222
+ qrAlt: "Code QR pour se connecter avec ZOREAL"
223
+ },
224
+ de: {
225
+ title: "Zum Anmelden scannen",
226
+ titleApprove: "Auf dem Handy best\xE4tigen",
227
+ bodyScan: "Mit der Handykamera oder der ZOREAL ID App scannen.",
228
+ bodyApprove: "Anmeldung in der ZOREAL ID App best\xE4tigen.",
229
+ bodyEnrolling: "ZOREAL ID auf dem Handy fertig einrichten und dann die Anmeldung best\xE4tigen.",
230
+ waiting: "Warten auf Scan",
231
+ waitingApproval: "Warten auf Best\xE4tigung",
232
+ expiresIn: "L\xE4uft ab in {time}",
233
+ secured: "Proof-of-Human-Verifizierung von ZOREAL",
234
+ noIdTitle: "Noch keine ZOREAL ID?",
235
+ noIdBody: "Denselben Code scannen, um die App zu laden und kostenlos eine zu erstellen. Dauert nur eine Minute.",
236
+ cancel: "Abbrechen",
237
+ close: "Schlie\xDFen",
238
+ qrAlt: "QR-Code f\xFCr die Anmeldung mit ZOREAL"
239
+ },
240
+ ru: {
241
+ title: "\u041E\u0442\u0441\u043A\u0430\u043D\u0438\u0440\u0443\u0439\u0442\u0435, \u0447\u0442\u043E\u0431\u044B \u0432\u043E\u0439\u0442\u0438",
242
+ titleApprove: "\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u043D\u0430 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0435",
243
+ bodyScan: "\u041E\u0442\u0441\u043A\u0430\u043D\u0438\u0440\u0443\u0439\u0442\u0435 \u043A\u0430\u043C\u0435\u0440\u043E\u0439 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0430 \u0438\u043B\u0438 \u0447\u0435\u0440\u0435\u0437 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 ZOREAL ID.",
244
+ bodyApprove: "\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u0432\u0445\u043E\u0434 \u0432 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0438 ZOREAL ID.",
245
+ bodyEnrolling: "\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0443 ZOREAL ID \u043D\u0430 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0435, \u0437\u0430\u0442\u0435\u043C \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u0432\u0445\u043E\u0434.",
246
+ waiting: "\u041E\u0436\u0438\u0434\u0430\u043D\u0438\u0435 \u0441\u043A\u0430\u043D\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F",
247
+ waitingApproval: "\u041E\u0436\u0438\u0434\u0430\u043D\u0438\u0435 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F",
248
+ expiresIn: "\u0418\u0441\u0442\u0435\u043A\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 {time}",
249
+ secured: "\u041F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 Proof-of-Human \u043E\u0442 ZOREAL",
250
+ noIdTitle: "\u0415\u0449\u0451 \u043D\u0435\u0442 ZOREAL ID?",
251
+ noIdBody: "\u041E\u0442\u0441\u043A\u0430\u043D\u0438\u0440\u0443\u0439\u0442\u0435 \u0442\u043E\u0442 \u0436\u0435 \u043A\u043E\u0434, \u0447\u0442\u043E\u0431\u044B \u0441\u043A\u0430\u0447\u0430\u0442\u044C \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u0438 \u0441\u043E\u0437\u0434\u0430\u0442\u044C \u0435\u0433\u043E \u0431\u0435\u0441\u043F\u043B\u0430\u0442\u043D\u043E. \u042D\u0442\u043E \u0437\u0430\u0439\u043C\u0451\u0442 \u043C\u0438\u043D\u0443\u0442\u0443.",
252
+ cancel: "\u041E\u0442\u043C\u0435\u043D\u0430",
253
+ close: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C",
254
+ qrAlt: "QR-\u043A\u043E\u0434 \u0434\u043B\u044F \u0432\u0445\u043E\u0434\u0430 \u0447\u0435\u0440\u0435\u0437 ZOREAL"
255
+ },
256
+ ja: {
257
+ title: "\u30B9\u30AD\u30E3\u30F3\u3057\u3066\u30ED\u30B0\u30A4\u30F3",
258
+ titleApprove: "\u30B9\u30DE\u30FC\u30C8\u30D5\u30A9\u30F3\u3067\u627F\u8A8D",
259
+ bodyScan: "\u30B9\u30DE\u30FC\u30C8\u30D5\u30A9\u30F3\u306E\u30AB\u30E1\u30E9\u307E\u305F\u306FZOREAL ID\u30A2\u30D7\u30EA\u3067\u30B9\u30AD\u30E3\u30F3\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
260
+ bodyApprove: "ZOREAL ID\u30A2\u30D7\u30EA\u3067\u30ED\u30B0\u30A4\u30F3\u3092\u627F\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
261
+ bodyEnrolling: "\u30B9\u30DE\u30FC\u30C8\u30D5\u30A9\u30F3\u3067ZOREAL ID\u306E\u8A2D\u5B9A\u3092\u5B8C\u4E86\u3057\u3001\u30ED\u30B0\u30A4\u30F3\u3092\u627F\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
262
+ waiting: "\u30B9\u30AD\u30E3\u30F3\u5F85\u3061",
263
+ waitingApproval: "\u627F\u8A8D\u5F85\u3061",
264
+ expiresIn: "\u6709\u52B9\u671F\u9650\u307E\u3067 {time}",
265
+ secured: "ZOREAL\u306B\u3088\u308BProof-of-Human\u8A8D\u8A3C",
266
+ noIdTitle: "ZOREAL ID\u3092\u304A\u6301\u3061\u3067\u306A\u3044\u3067\u3059\u304B\uFF1F",
267
+ noIdBody: "\u540C\u3058\u30B3\u30FC\u30C9\u3092\u30B9\u30AD\u30E3\u30F3\u3057\u3066\u30A2\u30D7\u30EA\u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u3057\u3001\u7121\u6599\u3067\u4F5C\u6210\u3067\u304D\u307E\u3059\u30021\u5206\u307B\u3069\u3067\u5B8C\u4E86\u3057\u307E\u3059\u3002",
268
+ cancel: "\u30AD\u30E3\u30F3\u30BB\u30EB",
269
+ close: "\u9589\u3058\u308B",
270
+ qrAlt: "ZOREAL\u3067\u30ED\u30B0\u30A4\u30F3\u3059\u308B\u305F\u3081\u306EQR\u30B3\u30FC\u30C9"
271
+ },
272
+ hi: {
273
+ title: "\u0938\u093E\u0907\u0928 \u0907\u0928 \u0915\u0930\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F \u0938\u094D\u0915\u0948\u0928 \u0915\u0930\u0947\u0902",
274
+ titleApprove: "\u0905\u092A\u0928\u0947 \u092B\u094B\u0928 \u092A\u0930 \u0938\u094D\u0935\u0940\u0915\u0943\u0924 \u0915\u0930\u0947\u0902",
275
+ bodyScan: "\u0905\u092A\u0928\u0947 \u092B\u094B\u0928 \u0915\u0947 \u0915\u0948\u092E\u0930\u0947 \u092F\u093E ZOREAL ID \u0910\u092A \u0938\u0947 \u0938\u094D\u0915\u0948\u0928 \u0915\u0930\u0947\u0902\u0964",
276
+ bodyApprove: "\u0905\u092A\u0928\u0947 ZOREAL ID \u0910\u092A \u092E\u0947\u0902 \u0932\u0949\u0917\u093F\u0928 \u0938\u094D\u0935\u0940\u0915\u0943\u0924 \u0915\u0930\u0947\u0902\u0964",
277
+ bodyEnrolling: "\u0905\u092A\u0928\u0947 \u092B\u094B\u0928 \u092A\u0930 ZOREAL ID \u0938\u0947\u091F\u0905\u092A \u092A\u0942\u0930\u093E \u0915\u0930\u0947\u0902, \u092B\u093F\u0930 \u0932\u0949\u0917\u093F\u0928 \u0938\u094D\u0935\u0940\u0915\u0943\u0924 \u0915\u0930\u0947\u0902\u0964",
278
+ waiting: "\u0938\u094D\u0915\u0948\u0928 \u0915\u0940 \u092A\u094D\u0930\u0924\u0940\u0915\u094D\u0937\u093E \u0939\u0948",
279
+ waitingApproval: "\u0938\u094D\u0935\u0940\u0915\u0943\u0924\u093F \u0915\u0940 \u092A\u094D\u0930\u0924\u0940\u0915\u094D\u0937\u093E \u0939\u0948",
280
+ expiresIn: "{time} \u092E\u0947\u0902 \u0938\u092E\u093E\u092A\u094D\u0924",
281
+ secured: "ZOREAL \u0926\u094D\u0935\u093E\u0930\u093E Proof-of-Human \u0938\u0924\u094D\u092F\u093E\u092A\u0928",
282
+ noIdTitle: "\u0905\u092D\u0940 \u0924\u0915 ZOREAL ID \u0928\u0939\u0940\u0902 \u0939\u0948?",
283
+ noIdBody: "\u0910\u092A \u0921\u093E\u0909\u0928\u0932\u094B\u0921 \u0915\u0930\u0928\u0947 \u0914\u0930 \u092E\u0941\u092B\u094D\u0924 \u092E\u0947\u0902 \u090F\u0915 \u092C\u0928\u093E\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F \u0935\u0939\u0940 \u0915\u094B\u0921 \u0938\u094D\u0915\u0948\u0928 \u0915\u0930\u0947\u0902\u0964 \u0907\u0938\u092E\u0947\u0902 \u092C\u0938 \u090F\u0915 \u092E\u093F\u0928\u091F \u0932\u0917\u0924\u093E \u0939\u0948\u0964",
284
+ cancel: "\u0930\u0926\u094D\u0926 \u0915\u0930\u0947\u0902",
285
+ close: "\u092C\u0902\u0926 \u0915\u0930\u0947\u0902",
286
+ qrAlt: "ZOREAL \u0938\u0947 \u0938\u093E\u0907\u0928 \u0907\u0928 \u0915\u0930\u0928\u0947 \u0915\u0947 \u0932\u093F\u090F QR \u0915\u094B\u0921"
287
+ },
288
+ zhs: {
289
+ title: "\u626B\u7801\u767B\u5F55",
290
+ titleApprove: "\u5728\u624B\u673A\u4E0A\u6279\u51C6",
291
+ bodyScan: "\u4F7F\u7528\u624B\u673A\u76F8\u673A\u6216 ZOREAL ID \u5E94\u7528\u626B\u63CF\u3002",
292
+ bodyApprove: "\u8BF7\u5728 ZOREAL ID \u5E94\u7528\u4E2D\u6279\u51C6\u767B\u5F55\u3002",
293
+ bodyEnrolling: "\u8BF7\u5728\u624B\u673A\u4E0A\u5B8C\u6210 ZOREAL ID \u8BBE\u7F6E\uFF0C\u7136\u540E\u6279\u51C6\u767B\u5F55\u3002",
294
+ waiting: "\u7B49\u5F85\u626B\u63CF",
295
+ waitingApproval: "\u7B49\u5F85\u6279\u51C6",
296
+ expiresIn: "{time} \u540E\u5931\u6548",
297
+ secured: "\u7531 ZOREAL \u63D0\u4F9B\u7684 Proof-of-Human \u9A8C\u8BC1",
298
+ noIdTitle: "\u8FD8\u6CA1\u6709 ZOREAL ID\uFF1F",
299
+ noIdBody: "\u626B\u63CF\u540C\u4E00\u4E2A\u4E8C\u7EF4\u7801\u5373\u53EF\u4E0B\u8F7D\u5E94\u7528\u5E76\u514D\u8D39\u521B\u5EFA\uFF0C\u53EA\u9700\u4E00\u5206\u949F\u3002",
300
+ cancel: "\u53D6\u6D88",
301
+ close: "\u5173\u95ED",
302
+ qrAlt: "\u4F7F\u7528 ZOREAL \u767B\u5F55\u7684\u4E8C\u7EF4\u7801"
303
+ },
304
+ zht: {
305
+ title: "\u6383\u78BC\u767B\u5165",
306
+ titleApprove: "\u5728\u624B\u6A5F\u4E0A\u6838\u51C6",
307
+ bodyScan: "\u4F7F\u7528\u624B\u6A5F\u76F8\u6A5F\u6216 ZOREAL ID \u61C9\u7528\u7A0B\u5F0F\u6383\u63CF\u3002",
308
+ bodyApprove: "\u8ACB\u5728 ZOREAL ID \u61C9\u7528\u7A0B\u5F0F\u4E2D\u6838\u51C6\u767B\u5165\u3002",
309
+ bodyEnrolling: "\u8ACB\u5728\u624B\u6A5F\u4E0A\u5B8C\u6210 ZOREAL ID \u8A2D\u5B9A\uFF0C\u7136\u5F8C\u6838\u51C6\u767B\u5165\u3002",
310
+ waiting: "\u7B49\u5F85\u6383\u63CF",
311
+ waitingApproval: "\u7B49\u5F85\u6838\u51C6",
312
+ expiresIn: "{time} \u5F8C\u5931\u6548",
313
+ secured: "\u7531 ZOREAL \u63D0\u4F9B\u7684 Proof-of-Human \u9A57\u8B49",
314
+ noIdTitle: "\u9084\u6C92\u6709 ZOREAL ID\uFF1F",
315
+ noIdBody: "\u6383\u63CF\u540C\u4E00\u500B QR code \u5373\u53EF\u4E0B\u8F09\u61C9\u7528\u7A0B\u5F0F\u4E26\u514D\u8CBB\u5EFA\u7ACB\uFF0C\u53EA\u9700\u4E00\u5206\u9418\u3002",
316
+ cancel: "\u53D6\u6D88",
317
+ close: "\u95DC\u9589",
318
+ qrAlt: "\u4F7F\u7528 ZOREAL \u767B\u5165\u7684 QR code"
319
+ },
320
+ ar: {
321
+ title: "\u0627\u0645\u0633\u062D \u0644\u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644",
322
+ titleApprove: "\u0648\u0627\u0641\u0642 \u0639\u0644\u0649 \u0647\u0627\u062A\u0641\u0643",
323
+ bodyScan: "\u0627\u0645\u0633\u062D \u0628\u0627\u0633\u062A\u062E\u062F\u0627\u0645 \u0643\u0627\u0645\u064A\u0631\u0627 \u0647\u0627\u062A\u0641\u0643 \u0623\u0648 \u062A\u0637\u0628\u064A\u0642 ZOREAL ID.",
324
+ bodyApprove: "\u0648\u0627\u0641\u0642 \u0639\u0644\u0649 \u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644 \u0641\u064A \u062A\u0637\u0628\u064A\u0642 ZOREAL ID.",
325
+ bodyEnrolling: "\u0623\u0643\u0645\u0644 \u0625\u0639\u062F\u0627\u062F ZOREAL ID \u0639\u0644\u0649 \u0647\u0627\u062A\u0641\u0643\u060C \u062B\u0645 \u0648\u0627\u0641\u0642 \u0639\u0644\u0649 \u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644.",
326
+ waiting: "\u0641\u064A \u0627\u0646\u062A\u0638\u0627\u0631 \u0627\u0644\u0645\u0633\u062D",
327
+ waitingApproval: "\u0641\u064A \u0627\u0646\u062A\u0638\u0627\u0631 \u0627\u0644\u0645\u0648\u0627\u0641\u0642\u0629",
328
+ expiresIn: "\u062A\u0646\u062A\u0647\u064A \u0627\u0644\u0635\u0644\u0627\u062D\u064A\u0629 \u062E\u0644\u0627\u0644 {time}",
329
+ secured: "\u0627\u0644\u062A\u062D\u0642\u0642 \u0645\u0646 Proof-of-Human \u0628\u0648\u0627\u0633\u0637\u0629 ZOREAL",
330
+ noIdTitle: "\u0644\u064A\u0633 \u0644\u062F\u064A\u0643 ZOREAL ID \u0628\u0639\u062F\u061F",
331
+ noIdBody: "\u0627\u0645\u0633\u062D \u0627\u0644\u0631\u0645\u0632 \u0646\u0641\u0633\u0647 \u0644\u062A\u0646\u0632\u064A\u0644 \u0627\u0644\u062A\u0637\u0628\u064A\u0642 \u0648\u0625\u0646\u0634\u0627\u0621 \u062D\u0633\u0627\u0628 \u0645\u062C\u0627\u0646\u064A. \u064A\u0633\u062A\u063A\u0631\u0642 \u0627\u0644\u0623\u0645\u0631 \u062F\u0642\u064A\u0642\u0629 \u0648\u0627\u062D\u062F\u0629 \u0641\u0642\u0637.",
332
+ cancel: "\u0625\u0644\u063A\u0627\u0621",
333
+ close: "\u0625\u063A\u0644\u0627\u0642",
334
+ qrAlt: "\u0631\u0645\u0632 QR \u0644\u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644 \u0628\u0627\u0633\u062A\u062E\u062F\u0627\u0645 ZOREAL"
335
+ },
336
+ ko: {
337
+ title: "\uC2A4\uCE94\uD558\uC5EC \uB85C\uADF8\uC778",
338
+ titleApprove: "\uD734\uB300\uD3F0\uC5D0\uC11C \uC2B9\uC778",
339
+ bodyScan: "\uD734\uB300\uD3F0 \uCE74\uBA54\uB77C \uB610\uB294 ZOREAL ID \uC571\uC73C\uB85C \uC2A4\uCE94\uD558\uC138\uC694.",
340
+ bodyApprove: "ZOREAL ID \uC571\uC5D0\uC11C \uB85C\uADF8\uC778\uC744 \uC2B9\uC778\uD558\uC138\uC694.",
341
+ bodyEnrolling: "\uD734\uB300\uD3F0\uC5D0\uC11C ZOREAL ID \uC124\uC815\uC744 \uC644\uB8CC\uD55C \uD6C4 \uB85C\uADF8\uC778\uC744 \uC2B9\uC778\uD558\uC138\uC694.",
342
+ waiting: "\uC2A4\uCE94 \uB300\uAE30 \uC911",
343
+ waitingApproval: "\uC2B9\uC778 \uB300\uAE30 \uC911",
344
+ expiresIn: "{time} \uD6C4 \uB9CC\uB8CC",
345
+ secured: "ZOREAL\uC758 Proof-of-Human \uC778\uC99D",
346
+ noIdTitle: "\uC544\uC9C1 ZOREAL ID\uAC00 \uC5C6\uC73C\uC2E0\uAC00\uC694?",
347
+ noIdBody: "\uAC19\uC740 \uCF54\uB4DC\uB97C \uC2A4\uCE94\uD574 \uC571\uC744 \uB0B4\uB824\uBC1B\uACE0 \uBB34\uB8CC\uB85C \uB9CC\uB4DC\uC138\uC694. 1\uBD84\uC774\uBA74 \uB429\uB2C8\uB2E4.",
348
+ cancel: "\uCDE8\uC18C",
349
+ close: "\uB2EB\uAE30",
350
+ qrAlt: "ZOREAL\uB85C \uB85C\uADF8\uC778\uD558\uAE30 \uC704\uD55C QR \uCF54\uB4DC"
351
+ },
352
+ // Български
353
+ bg: {
354
+ title: "\u0421\u043A\u0430\u043D\u0438\u0440\u0430\u0439\u0442\u0435 \u0437\u0430 \u0432\u0445\u043E\u0434",
355
+ titleApprove: "\u041F\u043E\u0442\u0432\u044A\u0440\u0434\u0435\u0442\u0435 \u043D\u0430 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0430 \u0441\u0438",
356
+ bodyScan: "\u0421\u043A\u0430\u043D\u0438\u0440\u0430\u0439\u0442\u0435 \u0441 \u043A\u0430\u043C\u0435\u0440\u0430\u0442\u0430 \u043D\u0430 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0430 \u0438\u043B\u0438 \u0441 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0442\u043E ZOREAL ID.",
357
+ bodyApprove: "\u041F\u043E\u0442\u0432\u044A\u0440\u0434\u0435\u0442\u0435 \u0432\u0445\u043E\u0434\u0430 \u0432 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0442\u043E ZOREAL ID.",
358
+ bodyEnrolling: "\u0414\u043E\u0432\u044A\u0440\u0448\u0435\u0442\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430\u0442\u0430 \u043D\u0430 ZOREAL ID \u043D\u0430 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0430 \u0441\u0438, \u0441\u043B\u0435\u0434 \u043A\u043E\u0435\u0442\u043E \u043F\u043E\u0442\u0432\u044A\u0440\u0434\u0435\u0442\u0435 \u0432\u0445\u043E\u0434\u0430.",
359
+ waiting: "\u0418\u0437\u0447\u0430\u043A\u0432\u0430\u043D\u0435 \u043D\u0430 \u0441\u043A\u0430\u043D\u0438\u0440\u0430\u043D\u0435",
360
+ waitingApproval: "\u0418\u0437\u0447\u0430\u043A\u0432\u0430\u043D\u0435 \u043D\u0430 \u043F\u043E\u0442\u0432\u044A\u0440\u0436\u0434\u0435\u043D\u0438\u0435",
361
+ expiresIn: "\u0418\u0437\u0442\u0438\u0447\u0430 \u0441\u043B\u0435\u0434 {time}",
362
+ secured: "\u041F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 Proof-of-Human \u043E\u0442 ZOREAL",
363
+ noIdTitle: "\u0412\u0441\u0435 \u043E\u0449\u0435 \u043D\u044F\u043C\u0430\u0442\u0435 ZOREAL ID?",
364
+ noIdBody: "\u0421\u043A\u0430\u043D\u0438\u0440\u0430\u0439\u0442\u0435 \u0441\u044A\u0449\u0438\u044F \u043A\u043E\u0434, \u0437\u0430 \u0434\u0430 \u0438\u0437\u0442\u0435\u0433\u043B\u0438\u0442\u0435 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0442\u043E \u0438 \u0434\u0430 \u0441\u0438 \u0441\u044A\u0437\u0434\u0430\u0434\u0435\u0442\u0435 \u0431\u0435\u0437\u043F\u043B\u0430\u0442\u0435\u043D \u0430\u043A\u0430\u0443\u043D\u0442. \u041E\u0442\u043D\u0435\u043C\u0430 \u0441\u0430\u043C\u043E \u043C\u0438\u043D\u0443\u0442\u0430.",
365
+ cancel: "\u041E\u0442\u043A\u0430\u0437",
366
+ close: "\u0417\u0430\u0442\u0432\u043E\u0440\u0438",
367
+ qrAlt: "QR \u043A\u043E\u0434 \u0437\u0430 \u0432\u0445\u043E\u0434 \u0441\u044A\u0441 ZOREAL"
368
+ },
369
+ // বাংলা
370
+ bn: {
371
+ title: "\u09B8\u09BE\u0987\u09A8 \u0987\u09A8 \u0995\u09B0\u09A4\u09C7 \u09B8\u09CD\u0995\u09CD\u09AF\u09BE\u09A8 \u0995\u09B0\u09C1\u09A8",
372
+ titleApprove: "\u0986\u09AA\u09A8\u09BE\u09B0 \u09AB\u09CB\u09A8\u09C7 \u0985\u09A8\u09C1\u09AE\u09CB\u09A6\u09A8 \u0995\u09B0\u09C1\u09A8",
373
+ bodyScan: "\u0986\u09AA\u09A8\u09BE\u09B0 \u09AB\u09CB\u09A8\u09C7\u09B0 \u0995\u09CD\u09AF\u09BE\u09AE\u09C7\u09B0\u09BE \u09AC\u09BE ZOREAL ID \u0985\u09CD\u09AF\u09BE\u09AA \u09A6\u09BF\u09AF\u09BC\u09C7 \u09B8\u09CD\u0995\u09CD\u09AF\u09BE\u09A8 \u0995\u09B0\u09C1\u09A8\u0964",
374
+ bodyApprove: "\u0986\u09AA\u09A8\u09BE\u09B0 ZOREAL ID \u0985\u09CD\u09AF\u09BE\u09AA\u09C7 \u09B2\u0997\u0987\u09A8 \u0985\u09A8\u09C1\u09AE\u09CB\u09A6\u09A8 \u0995\u09B0\u09C1\u09A8\u0964",
375
+ bodyEnrolling: "\u0986\u09AA\u09A8\u09BE\u09B0 \u09AB\u09CB\u09A8\u09C7 ZOREAL ID \u09B8\u09C7\u099F\u0986\u09AA \u09B8\u09AE\u09CD\u09AA\u09C2\u09B0\u09CD\u09A3 \u0995\u09B0\u09C1\u09A8, \u09A4\u09BE\u09B0\u09AA\u09B0 \u09B2\u0997\u0987\u09A8 \u0985\u09A8\u09C1\u09AE\u09CB\u09A6\u09A8 \u0995\u09B0\u09C1\u09A8\u0964",
376
+ waiting: "\u09B8\u09CD\u0995\u09CD\u09AF\u09BE\u09A8\u09C7\u09B0 \u0985\u09AA\u09C7\u0995\u09CD\u09B7\u09BE\u09AF\u09BC",
377
+ waitingApproval: "\u0985\u09A8\u09C1\u09AE\u09CB\u09A6\u09A8\u09C7\u09B0 \u0985\u09AA\u09C7\u0995\u09CD\u09B7\u09BE\u09AF\u09BC",
378
+ expiresIn: "{time} \u09AA\u09B0\u09C7 \u09AE\u09C7\u09AF\u09BC\u09BE\u09A6 \u09B6\u09C7\u09B7 \u09B9\u09AC\u09C7",
379
+ secured: "ZOREAL \u09A6\u09CD\u09AC\u09BE\u09B0\u09BE Proof-of-Human \u09AF\u09BE\u099A\u09BE\u0987\u0995\u09B0\u09A3",
380
+ noIdTitle: "\u098F\u0996\u09A8\u09CB ZOREAL ID \u09A8\u09C7\u0987?",
381
+ noIdBody: "\u0985\u09CD\u09AF\u09BE\u09AA \u09A1\u09BE\u0989\u09A8\u09B2\u09CB\u09A1 \u0995\u09B0\u09C7 \u09AC\u09BF\u09A8\u09BE\u09AE\u09C2\u09B2\u09CD\u09AF\u09C7 \u098F\u0995\u099F\u09BF \u09A4\u09C8\u09B0\u09BF \u0995\u09B0\u09A4\u09C7 \u098F\u0995\u0987 \u0995\u09CB\u09A1 \u09B8\u09CD\u0995\u09CD\u09AF\u09BE\u09A8 \u0995\u09B0\u09C1\u09A8\u0964 \u098F\u09A4\u09C7 \u09AE\u09BE\u09A4\u09CD\u09B0 \u098F\u0995 \u09AE\u09BF\u09A8\u09BF\u099F \u09B8\u09AE\u09AF\u09BC \u09B2\u09BE\u0997\u09C7\u0964",
382
+ cancel: "\u09AC\u09BE\u09A4\u09BF\u09B2",
383
+ close: "\u09AC\u09A8\u09CD\u09A7",
384
+ qrAlt: "ZOREAL \u09A6\u09BF\u09AF\u09BC\u09C7 \u09B8\u09BE\u0987\u09A8 \u0987\u09A8 \u0995\u09B0\u09BE\u09B0 \u099C\u09A8\u09CD\u09AF QR \u0995\u09CB\u09A1"
385
+ },
386
+ // Bosanski
387
+ bs: {
388
+ title: "Skenirajte za prijavu",
389
+ titleApprove: "Odobrite na svom telefonu",
390
+ bodyScan: "Skenirajte kamerom svog telefona ili aplikacijom ZOREAL ID.",
391
+ bodyApprove: "Odobrite prijavu u aplikaciji ZOREAL ID.",
392
+ bodyEnrolling: "Zavr\u0161ite pode\u0161avanje ZOREAL ID-a na svom telefonu, a zatim odobrite prijavu.",
393
+ waiting: "\u010Ceka se skeniranje",
394
+ waitingApproval: "\u010Ceka se odobrenje",
395
+ expiresIn: "Isti\u010De za {time}",
396
+ secured: "ZOREAL Proof-of-Human verifikacija",
397
+ noIdTitle: "Nemate ZOREAL ID?",
398
+ noIdBody: "Skenirajte isti kod da preuzmete aplikaciju i besplatno ga napravite. Traje samo minutu.",
399
+ cancel: "Otka\u017Ei",
400
+ close: "Zatvori",
401
+ qrAlt: "QR kod za prijavu putem ZOREAL-a"
402
+ },
403
+ // Čeština
404
+ cs: {
405
+ title: "P\u0159ihlaste se naskenov\xE1n\xEDm",
406
+ titleApprove: "Potvr\u010Fte v telefonu",
407
+ bodyScan: "Naskenujte fotoapar\xE1tem telefonu nebo aplikac\xED ZOREAL ID.",
408
+ bodyApprove: "Potvr\u010Fte p\u0159ihl\xE1\u0161en\xED v aplikaci ZOREAL ID.",
409
+ bodyEnrolling: "Dokon\u010Dete nastaven\xED ZOREAL ID v telefonu a pot\xE9 potvr\u010Fte p\u0159ihl\xE1\u0161en\xED.",
410
+ waiting: "\u010Cek\xE1n\xED na naskenov\xE1n\xED",
411
+ waitingApproval: "\u010Cek\xE1n\xED na potvrzen\xED",
412
+ expiresIn: "Vypr\u0161\xED za {time}",
413
+ secured: "Ov\u011B\u0159en\xED Proof-of-Human od ZOREAL",
414
+ noIdTitle: "Je\u0161t\u011B nem\xE1te ZOREAL ID?",
415
+ noIdBody: "Naskenov\xE1n\xEDm stejn\xE9ho k\xF3du si st\xE1hnete aplikaci a zdarma vytvo\u0159\xEDte ZOREAL ID. Zabere to jen minutu.",
416
+ cancel: "Zru\u0161it",
417
+ close: "Zav\u0159\xEDt",
418
+ qrAlt: "QR k\xF3d pro p\u0159ihl\xE1\u0161en\xED pomoc\xED ZOREAL"
419
+ },
420
+ // Dansk
421
+ da: {
422
+ title: "Scan for at logge ind",
423
+ titleApprove: "Godkend p\xE5 din telefon",
424
+ bodyScan: "Scan med telefonens kamera eller ZOREAL ID-appen.",
425
+ bodyApprove: "Godkend login i din ZOREAL ID-app.",
426
+ bodyEnrolling: "F\xE6rdigg\xF8r ops\xE6tningen af ZOREAL ID p\xE5 din telefon, og godkend derefter login.",
427
+ waiting: "Venter p\xE5 scanning",
428
+ waitingApproval: "Venter p\xE5 godkendelse",
429
+ expiresIn: "Udl\xF8ber om {time}",
430
+ secured: "Proof-of-Human-verificering af ZOREAL",
431
+ noIdTitle: "Har du ikke et ZOREAL ID endnu?",
432
+ noIdBody: "Scan den samme kode for at hente appen og oprette et gratis. Det tager kun et minut.",
433
+ cancel: "Annuller",
434
+ close: "Luk",
435
+ qrAlt: "QR-kode til at logge ind med ZOREAL"
436
+ },
437
+ // Ελληνικά
438
+ el: {
439
+ title: "\u03A3\u03AC\u03C1\u03C9\u03C3\u03B7 \u03B3\u03B9\u03B1 \u03C3\u03CD\u03BD\u03B4\u03B5\u03C3\u03B7",
440
+ titleApprove: "\u0388\u03B3\u03BA\u03C1\u03B9\u03C3\u03B7 \u03B1\u03C0\u03CC \u03C4\u03BF \u03BA\u03B9\u03BD\u03B7\u03C4\u03CC \u03C3\u03B1\u03C2",
441
+ bodyScan: "\u03A3\u03B1\u03C1\u03CE\u03C3\u03C4\u03B5 \u03BC\u03B5 \u03C4\u03B7\u03BD \u03BA\u03AC\u03BC\u03B5\u03C1\u03B1 \u03C4\u03BF\u03C5 \u03BA\u03B9\u03BD\u03B7\u03C4\u03BF\u03CD \u03C3\u03B1\u03C2 \u03AE \u03C4\u03B7\u03BD \u03B5\u03C6\u03B1\u03C1\u03BC\u03BF\u03B3\u03AE ZOREAL ID.",
442
+ bodyApprove: "\u0395\u03B3\u03BA\u03C1\u03AF\u03BD\u03B5\u03C4\u03B5 \u03C4\u03B7 \u03C3\u03CD\u03BD\u03B4\u03B5\u03C3\u03B7 \u03C3\u03C4\u03B7\u03BD \u03B5\u03C6\u03B1\u03C1\u03BC\u03BF\u03B3\u03AE ZOREAL ID.",
443
+ bodyEnrolling: "\u039F\u03BB\u03BF\u03BA\u03BB\u03B7\u03C1\u03CE\u03C3\u03C4\u03B5 \u03C4\u03B7 \u03C1\u03CD\u03B8\u03BC\u03B9\u03C3\u03B7 \u03C4\u03BF\u03C5 ZOREAL ID \u03C3\u03C4\u03BF \u03BA\u03B9\u03BD\u03B7\u03C4\u03CC \u03C3\u03B1\u03C2 \u03BA\u03B1\u03B9 \u03AD\u03C0\u03B5\u03B9\u03C4\u03B1 \u03B5\u03B3\u03BA\u03C1\u03AF\u03BD\u03B5\u03C4\u03B5 \u03C4\u03B7 \u03C3\u03CD\u03BD\u03B4\u03B5\u03C3\u03B7.",
444
+ waiting: "\u0391\u03BD\u03B1\u03BC\u03BF\u03BD\u03AE \u03C3\u03AC\u03C1\u03C9\u03C3\u03B7\u03C2",
445
+ waitingApproval: "\u0391\u03BD\u03B1\u03BC\u03BF\u03BD\u03AE \u03AD\u03B3\u03BA\u03C1\u03B9\u03C3\u03B7\u03C2",
446
+ expiresIn: "\u039B\u03AE\u03B3\u03B5\u03B9 \u03C3\u03B5 {time}",
447
+ secured: "\u0395\u03C0\u03B1\u03BB\u03AE\u03B8\u03B5\u03C5\u03C3\u03B7 Proof-of-Human \u03B1\u03C0\u03CC \u03C4\u03B7 ZOREAL",
448
+ noIdTitle: "\u0394\u03B5\u03BD \u03AD\u03C7\u03B5\u03C4\u03B5 \u03B1\u03BA\u03CC\u03BC\u03B1 ZOREAL ID;",
449
+ noIdBody: "\u03A3\u03B1\u03C1\u03CE\u03C3\u03C4\u03B5 \u03C4\u03BF\u03BD \u03AF\u03B4\u03B9\u03BF \u03BA\u03C9\u03B4\u03B9\u03BA\u03CC \u03B3\u03B9\u03B1 \u03BD\u03B1 \u03BA\u03B1\u03C4\u03B5\u03B2\u03AC\u03C3\u03B5\u03C4\u03B5 \u03C4\u03B7\u03BD \u03B5\u03C6\u03B1\u03C1\u03BC\u03BF\u03B3\u03AE \u03BA\u03B1\u03B9 \u03BD\u03B1 \u03B4\u03B7\u03BC\u03B9\u03BF\u03C5\u03C1\u03B3\u03AE\u03C3\u03B5\u03C4\u03B5 \u03AD\u03BD\u03B1 \u03B4\u03C9\u03C1\u03B5\u03AC\u03BD. \u03A7\u03C1\u03B5\u03B9\u03AC\u03B6\u03B5\u03C4\u03B1\u03B9 \u03BC\u03CC\u03BD\u03BF \u03AD\u03BD\u03B1 \u03BB\u03B5\u03C0\u03C4\u03CC.",
450
+ cancel: "\u0386\u03BA\u03C5\u03C1\u03BF",
451
+ close: "\u039A\u03BB\u03B5\u03AF\u03C3\u03B9\u03BC\u03BF",
452
+ qrAlt: "\u039A\u03C9\u03B4\u03B9\u03BA\u03CC\u03C2 QR \u03B3\u03B9\u03B1 \u03C3\u03CD\u03BD\u03B4\u03B5\u03C3\u03B7 \u03BC\u03B5 ZOREAL"
453
+ },
454
+ // Español (LA)
455
+ "es-419": {
456
+ title: "Escanea para iniciar sesi\xF3n",
457
+ titleApprove: "Aprueba desde tu celular",
458
+ bodyScan: "Escanea con la c\xE1mara de tu celular o con la app ZOREAL ID.",
459
+ bodyApprove: "Aprueba el inicio de sesi\xF3n en tu app ZOREAL ID.",
460
+ bodyEnrolling: "Termina de configurar ZOREAL ID en tu celular y luego aprueba el inicio de sesi\xF3n.",
461
+ waiting: "Esperando escaneo",
462
+ waitingApproval: "Esperando aprobaci\xF3n",
463
+ expiresIn: "Expira en {time}",
464
+ secured: "Verificaci\xF3n Proof-of-Human de ZOREAL",
465
+ noIdTitle: "\xBFTodav\xEDa no tienes ZOREAL ID?",
466
+ noIdBody: "Escanea el mismo c\xF3digo para descargar la app y crear uno gratis. Solo toma un minuto.",
467
+ cancel: "Cancelar",
468
+ close: "Cerrar",
469
+ qrAlt: "C\xF3digo QR para iniciar sesi\xF3n con ZOREAL"
470
+ },
471
+ // Suomi
472
+ fi: {
473
+ title: "Kirjaudu sis\xE4\xE4n skannaamalla",
474
+ titleApprove: "Hyv\xE4ksy puhelimessasi",
475
+ bodyScan: "Skannaa puhelimesi kameralla tai ZOREAL ID -sovelluksella.",
476
+ bodyApprove: "Hyv\xE4ksy kirjautuminen ZOREAL ID -sovelluksessasi.",
477
+ bodyEnrolling: "Viimeistele ZOREAL ID -sovelluksen k\xE4ytt\xF6\xF6notto puhelimellasi ja hyv\xE4ksy sitten kirjautuminen.",
478
+ waiting: "Odotetaan skannausta",
479
+ waitingApproval: "Odotetaan hyv\xE4ksynt\xE4\xE4",
480
+ expiresIn: "Vanhenee {time} kuluttua",
481
+ secured: "ZOREALin Proof-of-Human-vahvistus",
482
+ noIdTitle: "Eik\xF6 sinulla ole viel\xE4 ZOREAL ID:t\xE4?",
483
+ noIdBody: "Skannaa sama koodi ladataksesi sovelluksen ja luodaksesi tunnuksen ilmaiseksi. Se vie vain minuutin.",
484
+ cancel: "Peruuta",
485
+ close: "Sulje",
486
+ qrAlt: "QR-koodi ZOREAL-kirjautumista varten"
487
+ },
488
+ // עברית
489
+ he: {
490
+ title: "\u05E1\u05E8\u05D5\u05E7 \u05DB\u05D3\u05D9 \u05DC\u05D4\u05EA\u05D7\u05D1\u05E8",
491
+ titleApprove: "\u05D0\u05E9\u05E8 \u05D1\u05D8\u05DC\u05E4\u05D5\u05DF \u05E9\u05DC\u05DA",
492
+ bodyScan: "\u05E1\u05E8\u05D5\u05E7 \u05D1\u05D0\u05DE\u05E6\u05E2\u05D5\u05EA \u05DE\u05E6\u05DC\u05DE\u05EA \u05D4\u05D8\u05DC\u05E4\u05D5\u05DF \u05E9\u05DC\u05DA \u05D0\u05D5 \u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D9\u05EA ZOREAL ID.",
493
+ bodyApprove: "\u05D0\u05E9\u05E8 \u05D0\u05EA \u05D4\u05D4\u05EA\u05D7\u05D1\u05E8\u05D5\u05EA \u05D1\u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D9\u05EA ZOREAL ID \u05E9\u05DC\u05DA.",
494
+ bodyEnrolling: "\u05E1\u05D9\u05D9\u05DD \u05DC\u05D4\u05D2\u05D3\u05D9\u05E8 \u05D0\u05EA ZOREAL ID \u05D1\u05D8\u05DC\u05E4\u05D5\u05DF \u05E9\u05DC\u05DA, \u05D5\u05D0\u05D6 \u05D0\u05E9\u05E8 \u05D0\u05EA \u05D4\u05D4\u05EA\u05D7\u05D1\u05E8\u05D5\u05EA.",
495
+ waiting: "\u05DE\u05DE\u05EA\u05D9\u05DF \u05DC\u05E1\u05E8\u05D9\u05E7\u05D4",
496
+ waitingApproval: "\u05DE\u05DE\u05EA\u05D9\u05DF \u05DC\u05D0\u05D9\u05E9\u05D5\u05E8",
497
+ expiresIn: "\u05D9\u05E4\u05D5\u05D2 \u05D1\u05E2\u05D5\u05D3 {time}",
498
+ secured: "\u05D0\u05D9\u05DE\u05D5\u05EA Proof-of-Human \u05DE\u05D1\u05D9\u05EA ZOREAL",
499
+ noIdTitle: "\u05E2\u05D3\u05D9\u05D9\u05DF \u05D0\u05D9\u05DF \u05DC\u05DA ZOREAL ID?",
500
+ noIdBody: "\u05E1\u05E8\u05D5\u05E7 \u05D0\u05EA \u05D0\u05D5\u05EA\u05D5 \u05D4\u05E7\u05D5\u05D3 \u05DB\u05D3\u05D9 \u05DC\u05D4\u05D5\u05E8\u05D9\u05D3 \u05D0\u05EA \u05D4\u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D4 \u05D5\u05DC\u05D9\u05E6\u05D5\u05E8 \u05D0\u05D7\u05D3 \u05D1\u05D7\u05D9\u05E0\u05DD. \u05D6\u05D4 \u05DC\u05D5\u05E7\u05D7 \u05E8\u05E7 \u05D3\u05E7\u05D4.",
501
+ cancel: "\u05D1\u05D9\u05D8\u05D5\u05DC",
502
+ close: "\u05E1\u05D2\u05D5\u05E8",
503
+ qrAlt: "\u05E7\u05D5\u05D3 QR \u05DC\u05D4\u05EA\u05D7\u05D1\u05E8\u05D5\u05EA \u05E2\u05DD ZOREAL"
504
+ },
505
+ // Hrvatski
506
+ hr: {
507
+ title: "Skenirajte za prijavu",
508
+ titleApprove: "Odobrite na svom mobitelu",
509
+ bodyScan: "Skenirajte kamerom svog mobitela ili aplikacijom ZOREAL ID.",
510
+ bodyApprove: "Odobrite prijavu u aplikaciji ZOREAL ID.",
511
+ bodyEnrolling: "Dovr\u0161ite postavljanje ZOREAL ID-a na svom mobitelu, a zatim odobrite prijavu.",
512
+ waiting: "\u010Ceka se skeniranje",
513
+ waitingApproval: "\u010Ceka se odobrenje",
514
+ expiresIn: "Isti\u010De za {time}",
515
+ secured: "ZOREAL Proof-of-Human provjera",
516
+ noIdTitle: "Nemate ZOREAL ID?",
517
+ noIdBody: "Skenirajte isti kod da preuzmete aplikaciju i besplatno ga izradite. Traje samo minutu.",
518
+ cancel: "Odustani",
519
+ close: "Zatvori",
520
+ qrAlt: "QR kod za prijavu putem ZOREAL-a"
521
+ },
522
+ // Magyar
523
+ hu: {
524
+ title: "Bejelentkez\xE9s beolvas\xE1ssal",
525
+ titleApprove: "J\xF3v\xE1hagy\xE1s a telefonj\xE1n",
526
+ bodyScan: "Olvassa be a telefonja kamer\xE1j\xE1val, vagy a ZOREAL ID alkalmaz\xE1ssal.",
527
+ bodyApprove: "Hagyja j\xF3v\xE1 a bejelentkez\xE9st a ZOREAL ID alkalmaz\xE1sban.",
528
+ bodyEnrolling: "Fejezze be a ZOREAL ID be\xE1ll\xEDt\xE1s\xE1t a telefonj\xE1n, majd hagyja j\xF3v\xE1 a bejelentkez\xE9st.",
529
+ waiting: "V\xE1rakoz\xE1s beolvas\xE1sra",
530
+ waitingApproval: "V\xE1rakoz\xE1s j\xF3v\xE1hagy\xE1sra",
531
+ expiresIn: "Lej\xE1r {time} m\xFAlva",
532
+ secured: "Proof-of-Human hiteles\xEDt\xE9s a ZOREAL-t\xF3l",
533
+ noIdTitle: "M\xE9g nincs ZOREAL ID-je?",
534
+ noIdBody: "Olvassa be ugyanazt a k\xF3dot az alkalmaz\xE1s let\xF6lt\xE9s\xE9hez, \xE9s hozzon l\xE9tre egyet ingyenesen. Mind\xF6ssze egy percet vesz ig\xE9nybe.",
535
+ cancel: "M\xE9gse",
536
+ close: "Bez\xE1r\xE1s",
537
+ qrAlt: "QR-k\xF3d a ZOREAL-lal val\xF3 bejelentkez\xE9shez"
538
+ },
539
+ // Bahasa Indonesia
540
+ id: {
541
+ title: "Pindai untuk masuk",
542
+ titleApprove: "Setujui di ponsel Anda",
543
+ bodyScan: "Pindai dengan kamera ponsel atau aplikasi ZOREAL ID.",
544
+ bodyApprove: "Setujui proses masuk di aplikasi ZOREAL ID Anda.",
545
+ bodyEnrolling: "Selesaikan pengaturan ZOREAL ID di ponsel Anda, lalu setujui proses masuk.",
546
+ waiting: "Menunggu pemindaian",
547
+ waitingApproval: "Menunggu persetujuan",
548
+ expiresIn: "Berakhir dalam {time}",
549
+ secured: "Verifikasi Proof-of-Human oleh ZOREAL",
550
+ noIdTitle: "Belum punya ZOREAL ID?",
551
+ noIdBody: "Pindai kode yang sama untuk mengunduh aplikasi dan membuat akun secara gratis. Hanya butuh waktu satu menit.",
552
+ cancel: "Batal",
553
+ close: "Tutup",
554
+ qrAlt: "Kode QR untuk masuk dengan ZOREAL"
555
+ },
556
+ // Italiano
557
+ it: {
558
+ title: "Scansiona per accedere",
559
+ titleApprove: "Approva sul tuo telefono",
560
+ bodyScan: "Scansiona con la fotocamera del telefono o con l'app ZOREAL ID.",
561
+ bodyApprove: "Approva l'accesso nell'app ZOREAL ID.",
562
+ bodyEnrolling: "Completa la configurazione di ZOREAL ID sul telefono, poi approva l'accesso.",
563
+ waiting: "In attesa della scansione",
564
+ waitingApproval: "In attesa di approvazione",
565
+ expiresIn: "Scade tra {time}",
566
+ secured: "Verifica Proof-of-Human di ZOREAL",
567
+ noIdTitle: "Non hai ancora uno ZOREAL ID?",
568
+ noIdBody: "Scansiona lo stesso codice per scaricare l'app e crearne uno gratis. Basta un minuto.",
569
+ cancel: "Annulla",
570
+ close: "Chiudi",
571
+ qrAlt: "Codice QR per accedere con ZOREAL"
572
+ },
573
+ // Bahasa Melayu
574
+ ms: {
575
+ title: "Imbas untuk log masuk",
576
+ titleApprove: "Luluskan di telefon anda",
577
+ bodyScan: "Imbas dengan kamera telefon atau aplikasi ZOREAL ID.",
578
+ bodyApprove: "Luluskan log masuk dalam aplikasi ZOREAL ID anda.",
579
+ bodyEnrolling: "Selesaikan persediaan ZOREAL ID di telefon anda, kemudian luluskan log masuk.",
580
+ waiting: "Menunggu imbasan",
581
+ waitingApproval: "Menunggu kelulusan",
582
+ expiresIn: "Tamat tempoh dalam {time}",
583
+ secured: "Pengesahan Proof-of-Human oleh ZOREAL",
584
+ noIdTitle: "Belum ada ZOREAL ID?",
585
+ noIdBody: "Imbas kod yang sama untuk memuat turun aplikasi dan cipta satu secara percuma. Hanya mengambil masa seminit.",
586
+ cancel: "Batal",
587
+ close: "Tutup",
588
+ qrAlt: "Kod QR untuk log masuk dengan ZOREAL"
589
+ },
590
+ // Nederlands
591
+ nl: {
592
+ title: "Scan om in te loggen",
593
+ titleApprove: "Keur goed op je telefoon",
594
+ bodyScan: "Scan met de camera van je telefoon of de ZOREAL ID-app.",
595
+ bodyApprove: "Keur de aanmelding goed in je ZOREAL ID-app.",
596
+ bodyEnrolling: "Rond het instellen van ZOREAL ID op je telefoon af en keur daarna de aanmelding goed.",
597
+ waiting: "Wachten op scan",
598
+ waitingApproval: "Wachten op goedkeuring",
599
+ expiresIn: "Verloopt over {time}",
600
+ secured: "Proof-of-Human-verificatie door ZOREAL",
601
+ noIdTitle: "Nog geen ZOREAL ID?",
602
+ noIdBody: "Scan dezelfde code om de app te downloaden en gratis een account aan te maken. Dit duurt maar een minuut.",
603
+ cancel: "Annuleren",
604
+ close: "Sluiten",
605
+ qrAlt: "QR-code om in te loggen met ZOREAL"
606
+ },
607
+ // Norsk
608
+ no: {
609
+ title: "Skann for \xE5 logge inn",
610
+ titleApprove: "Godkjenn p\xE5 telefonen din",
611
+ bodyScan: "Skann med telefonens kamera eller ZOREAL ID-appen.",
612
+ bodyApprove: "Godkjenn innloggingen i ZOREAL ID-appen din.",
613
+ bodyEnrolling: "Fullf\xF8r oppsettet av ZOREAL ID p\xE5 telefonen din, og godkjenn deretter innloggingen.",
614
+ waiting: "Venter p\xE5 skanning",
615
+ waitingApproval: "Venter p\xE5 godkjenning",
616
+ expiresIn: "Utl\xF8per om {time}",
617
+ secured: "Proof-of-Human-verifisering av ZOREAL",
618
+ noIdTitle: "Har du ikke ZOREAL ID enn\xE5?",
619
+ noIdBody: "Skann den samme koden for \xE5 laste ned appen og opprette en gratis. Det tar bare et minutt.",
620
+ cancel: "Avbryt",
621
+ close: "Lukk",
622
+ qrAlt: "QR-kode for \xE5 logge inn med ZOREAL"
623
+ },
624
+ // Polski
625
+ pl: {
626
+ title: "Zeskanuj, aby si\u0119 zalogowa\u0107",
627
+ titleApprove: "Zatwierd\u017A w telefonie",
628
+ bodyScan: "Zeskanuj aparatem telefonu lub aplikacj\u0105 ZOREAL ID.",
629
+ bodyApprove: "Zatwierd\u017A logowanie w aplikacji ZOREAL ID.",
630
+ bodyEnrolling: "Doko\u0144cz konfiguracj\u0119 ZOREAL ID w telefonie, a nast\u0119pnie zatwierd\u017A logowanie.",
631
+ waiting: "Czekanie na skan",
632
+ waitingApproval: "Czekanie na zatwierdzenie",
633
+ expiresIn: "Wygasa za {time}",
634
+ secured: "Weryfikacja Proof-of-Human od ZOREAL",
635
+ noIdTitle: "Nie masz jeszcze ZOREAL ID?",
636
+ noIdBody: "Zeskanuj ten sam kod, aby pobra\u0107 aplikacj\u0119 i bezp\u0142atnie utworzy\u0107 ZOREAL ID. Zajmie to tylko minut\u0119.",
637
+ cancel: "Anuluj",
638
+ close: "Zamknij",
639
+ qrAlt: "Kod QR do logowania za pomoc\u0105 ZOREAL"
640
+ },
641
+ // Português (BR)
642
+ "pt-br": {
643
+ title: "Escaneie para entrar",
644
+ titleApprove: "Aprove no seu celular",
645
+ bodyScan: "Escaneie com a c\xE2mera do seu celular ou com o app ZOREAL ID.",
646
+ bodyApprove: "Aprove o login no app ZOREAL ID.",
647
+ bodyEnrolling: "Termine de configurar o ZOREAL ID no seu celular e depois aprove o login.",
648
+ waiting: "Aguardando escaneamento",
649
+ waitingApproval: "Aguardando aprova\xE7\xE3o",
650
+ expiresIn: "Expira em {time}",
651
+ secured: "Verifica\xE7\xE3o Proof-of-Human da ZOREAL",
652
+ noIdTitle: "Ainda n\xE3o tem um ZOREAL ID?",
653
+ noIdBody: "Escaneie o mesmo c\xF3digo para baixar o app e criar um de gra\xE7a. Leva s\xF3 um minuto.",
654
+ cancel: "Cancelar",
655
+ close: "Fechar",
656
+ qrAlt: "C\xF3digo QR para entrar com ZOREAL"
657
+ },
658
+ // Română
659
+ ro: {
660
+ title: "Scana\u021Bi pentru conectare",
661
+ titleApprove: "Aproba\u021Bi de pe telefon",
662
+ bodyScan: "Scana\u021Bi cu camera telefonului sau cu aplica\u021Bia ZOREAL ID.",
663
+ bodyApprove: "Aproba\u021Bi conectarea \xEEn aplica\u021Bia ZOREAL ID.",
664
+ bodyEnrolling: "Finaliza\u021Bi configurarea ZOREAL ID pe telefon, apoi aproba\u021Bi conectarea.",
665
+ waiting: "Se a\u0219teapt\u0103 scanarea",
666
+ waitingApproval: "Se a\u0219teapt\u0103 aprobarea",
667
+ expiresIn: "Expir\u0103 \xEEn {time}",
668
+ secured: "Verificare Proof-of-Human de la ZOREAL",
669
+ noIdTitle: "Nu ave\u021Bi \xEEnc\u0103 un ZOREAL ID?",
670
+ noIdBody: "Scana\u021Bi acela\u0219i cod pentru a desc\u0103rca aplica\u021Bia \u0219i a crea unul gratuit. Dureaz\u0103 doar un minut.",
671
+ cancel: "Anuleaz\u0103",
672
+ close: "\xCEnchide",
673
+ qrAlt: "Cod QR pentru conectare cu ZOREAL"
674
+ },
675
+ // Српски
676
+ sr: {
677
+ title: "\u0421\u043A\u0435\u043D\u0438\u0440\u0430\u0458\u0442\u0435 \u0437\u0430 \u043F\u0440\u0438\u0458\u0430\u0432\u0443",
678
+ titleApprove: "\u041E\u0434\u043E\u0431\u0440\u0438\u0442\u0435 \u043D\u0430 \u0441\u0432\u043E\u043C \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0443",
679
+ bodyScan: "\u0421\u043A\u0435\u043D\u0438\u0440\u0430\u0458\u0442\u0435 \u043A\u0430\u043C\u0435\u0440\u043E\u043C \u0441\u0432\u043E\u0433 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0430 \u0438\u043B\u0438 \u0430\u043F\u043B\u0438\u043A\u0430\u0446\u0438\u0458\u043E\u043C ZOREAL ID.",
680
+ bodyApprove: "\u041E\u0434\u043E\u0431\u0440\u0438\u0442\u0435 \u043F\u0440\u0438\u0458\u0430\u0432\u0443 \u0443 \u0430\u043F\u043B\u0438\u043A\u0430\u0446\u0438\u0458\u0438 ZOREAL ID.",
681
+ bodyEnrolling: "\u0414\u043E\u0432\u0440\u0448\u0438\u0442\u0435 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0435 ZOREAL ID-\u0430 \u043D\u0430 \u0441\u0432\u043E\u043C \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0443, \u043F\u0430 \u043E\u0434\u043E\u0431\u0440\u0438\u0442\u0435 \u043F\u0440\u0438\u0458\u0430\u0432\u0443.",
682
+ waiting: "\u0427\u0435\u043A\u0430 \u0441\u0435 \u0441\u043A\u0435\u043D\u0438\u0440\u0430\u045A\u0435",
683
+ waitingApproval: "\u0427\u0435\u043A\u0430 \u0441\u0435 \u043E\u0434\u043E\u0431\u0440\u0435\u045A\u0435",
684
+ expiresIn: "\u0418\u0441\u0442\u0438\u0447\u0435 \u0437\u0430 {time}",
685
+ secured: "ZOREAL Proof-of-Human \u0432\u0435\u0440\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u0458\u0430",
686
+ noIdTitle: "\u041D\u0435\u043C\u0430\u0442\u0435 ZOREAL ID?",
687
+ noIdBody: "\u0421\u043A\u0435\u043D\u0438\u0440\u0430\u0458\u0442\u0435 \u0438\u0441\u0442\u0438 \u043A\u043E\u0434 \u0434\u0430 \u043F\u0440\u0435\u0443\u0437\u043C\u0435\u0442\u0435 \u0430\u043F\u043B\u0438\u043A\u0430\u0446\u0438\u0458\u0443 \u0438 \u0431\u0435\u0441\u043F\u043B\u0430\u0442\u043D\u043E \u0433\u0430 \u043D\u0430\u043F\u0440\u0430\u0432\u0438\u0442\u0435. \u0422\u0440\u0430\u0458\u0435 \u0441\u0430\u043C\u043E \u043C\u0438\u043D\u0443\u0442.",
688
+ cancel: "\u041E\u0442\u043A\u0430\u0436\u0438",
689
+ close: "\u0417\u0430\u0442\u0432\u043E\u0440\u0438",
690
+ qrAlt: "QR \u043A\u043E\u0434 \u0437\u0430 \u043F\u0440\u0438\u0458\u0430\u0432\u0443 \u043F\u0440\u0435\u043A\u043E ZOREAL-\u0430"
691
+ },
692
+ // ไทย
693
+ th: {
694
+ title: "\u0E2A\u0E41\u0E01\u0E19\u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A",
695
+ titleApprove: "\u0E2D\u0E19\u0E38\u0E21\u0E31\u0E15\u0E34\u0E1A\u0E19\u0E42\u0E17\u0E23\u0E28\u0E31\u0E1E\u0E17\u0E4C\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13",
696
+ bodyScan: "\u0E2A\u0E41\u0E01\u0E19\u0E14\u0E49\u0E27\u0E22\u0E01\u0E25\u0E49\u0E2D\u0E07\u0E42\u0E17\u0E23\u0E28\u0E31\u0E1E\u0E17\u0E4C\u0E2B\u0E23\u0E37\u0E2D\u0E41\u0E2D\u0E1B ZOREAL ID",
697
+ bodyApprove: "\u0E2D\u0E19\u0E38\u0E21\u0E31\u0E15\u0E34\u0E01\u0E32\u0E23\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E43\u0E19\u0E41\u0E2D\u0E1B ZOREAL ID \u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13",
698
+ bodyEnrolling: "\u0E15\u0E31\u0E49\u0E07\u0E04\u0E48\u0E32 ZOREAL ID \u0E1A\u0E19\u0E42\u0E17\u0E23\u0E28\u0E31\u0E1E\u0E17\u0E4C\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E43\u0E2B\u0E49\u0E40\u0E2A\u0E23\u0E47\u0E08\u0E2A\u0E34\u0E49\u0E19 \u0E41\u0E25\u0E49\u0E27\u0E2D\u0E19\u0E38\u0E21\u0E31\u0E15\u0E34\u0E01\u0E32\u0E23\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A",
699
+ waiting: "\u0E23\u0E2D\u0E01\u0E32\u0E23\u0E2A\u0E41\u0E01\u0E19",
700
+ waitingApproval: "\u0E23\u0E2D\u0E01\u0E32\u0E23\u0E2D\u0E19\u0E38\u0E21\u0E31\u0E15\u0E34",
701
+ expiresIn: "\u0E2B\u0E21\u0E14\u0E2D\u0E32\u0E22\u0E38\u0E43\u0E19 {time}",
702
+ secured: "\u0E01\u0E32\u0E23\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19\u0E15\u0E31\u0E27\u0E15\u0E19 Proof-of-Human \u0E42\u0E14\u0E22 ZOREAL",
703
+ noIdTitle: "\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E21\u0E35 ZOREAL ID \u0E43\u0E0A\u0E48\u0E44\u0E2B\u0E21",
704
+ noIdBody: "\u0E2A\u0E41\u0E01\u0E19\u0E42\u0E04\u0E49\u0E14\u0E40\u0E14\u0E35\u0E22\u0E27\u0E01\u0E31\u0E19\u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E14\u0E32\u0E27\u0E19\u0E4C\u0E42\u0E2B\u0E25\u0E14\u0E41\u0E2D\u0E1B\u0E41\u0E25\u0E30\u0E2A\u0E23\u0E49\u0E32\u0E07\u0E1A\u0E31\u0E0D\u0E0A\u0E35\u0E1F\u0E23\u0E35 \u0E43\u0E0A\u0E49\u0E40\u0E27\u0E25\u0E32\u0E40\u0E1E\u0E35\u0E22\u0E07\u0E19\u0E32\u0E17\u0E35\u0E40\u0E14\u0E35\u0E22\u0E27",
705
+ cancel: "\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01",
706
+ close: "\u0E1B\u0E34\u0E14",
707
+ qrAlt: "\u0E04\u0E34\u0E27\u0E2D\u0E32\u0E23\u0E4C\u0E42\u0E04\u0E49\u0E14\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A\u0E40\u0E02\u0E49\u0E32\u0E2A\u0E39\u0E48\u0E23\u0E30\u0E1A\u0E1A\u0E14\u0E49\u0E27\u0E22 ZOREAL"
708
+ },
709
+ // Tagalog
710
+ tl: {
711
+ title: "I-scan para mag-sign in",
712
+ titleApprove: "I-approve sa iyong telepono",
713
+ bodyScan: "I-scan gamit ang camera ng iyong telepono o ang ZOREAL ID app.",
714
+ bodyApprove: "I-approve ang login sa iyong ZOREAL ID app.",
715
+ bodyEnrolling: "Tapusin muna ang pag-set up ng ZOREAL ID sa iyong telepono, pagkatapos ay i-approve ang login.",
716
+ waiting: "Naghihintay ng scan",
717
+ waitingApproval: "Naghihintay ng approval",
718
+ expiresIn: "Mag-e-expire sa {time}",
719
+ secured: "Proof-of-Human verification mula sa ZOREAL",
720
+ noIdTitle: "Wala ka pang ZOREAL ID?",
721
+ noIdBody: "I-scan ang parehong code para i-download ang app at gumawa ng iyong ZOREAL ID nang libre. Isang minuto lang ito.",
722
+ cancel: "Kanselahin",
723
+ close: "Isara",
724
+ qrAlt: "QR code para mag-sign in gamit ang ZOREAL"
725
+ },
726
+ // Türkçe
727
+ tr: {
728
+ title: "Giri\u015F i\xE7in taray\u0131n",
729
+ titleApprove: "Telefonunuzdan onaylay\u0131n",
730
+ bodyScan: "Telefonunuzun kameras\u0131yla veya ZOREAL ID uygulamas\u0131yla taray\u0131n.",
731
+ bodyApprove: "Giri\u015Fi ZOREAL ID uygulaman\u0131zdan onaylay\u0131n.",
732
+ bodyEnrolling: "Telefonunuzda ZOREAL ID kurulumunu tamamlay\u0131n, ard\u0131ndan giri\u015Fi onaylay\u0131n.",
733
+ waiting: "Tarama bekleniyor",
734
+ waitingApproval: "Onay bekleniyor",
735
+ expiresIn: "{time} i\xE7inde sona erer",
736
+ secured: "ZOREAL taraf\u0131ndan Proof-of-Human do\u011Frulamas\u0131",
737
+ noIdTitle: "Hen\xFCz ZOREAL ID'niz yok mu?",
738
+ noIdBody: "Uygulamay\u0131 indirmek ve \xFCcretsiz bir tane olu\u015Fturmak i\xE7in ayn\u0131 kodu taray\u0131n. Sadece bir dakikan\u0131z\u0131 al\u0131r.",
739
+ cancel: "\u0130ptal",
740
+ close: "Kapat",
741
+ qrAlt: "ZOREAL ile giri\u015F yapmak i\xE7in QR kodu"
742
+ },
743
+ // Українська
744
+ uk: {
745
+ title: "\u0421\u043A\u0430\u043D\u0443\u0439\u0442\u0435 \u0434\u043B\u044F \u0432\u0445\u043E\u0434\u0443",
746
+ titleApprove: "\u041F\u0456\u0434\u0442\u0432\u0435\u0440\u0434\u044C\u0442\u0435 \u043D\u0430 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0456",
747
+ bodyScan: "\u0421\u043A\u0430\u043D\u0443\u0439\u0442\u0435 \u043A\u0430\u043C\u0435\u0440\u043E\u044E \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0443 \u0430\u0431\u043E \u0434\u043E\u0434\u0430\u0442\u043A\u043E\u043C ZOREAL ID.",
748
+ bodyApprove: "\u041F\u0456\u0434\u0442\u0432\u0435\u0440\u0434\u044C\u0442\u0435 \u0432\u0445\u0456\u0434 \u0443 \u0434\u043E\u0434\u0430\u0442\u043A\u0443 ZOREAL ID.",
749
+ bodyEnrolling: "\u0417\u0430\u0432\u0435\u0440\u0448\u0456\u0442\u044C \u043D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F ZOREAL ID \u043D\u0430 \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0456, \u0430 \u043F\u043E\u0442\u0456\u043C \u043F\u0456\u0434\u0442\u0432\u0435\u0440\u0434\u044C\u0442\u0435 \u0432\u0445\u0456\u0434.",
750
+ waiting: "\u041E\u0447\u0456\u043A\u0443\u0432\u0430\u043D\u043D\u044F \u0441\u043A\u0430\u043D\u0443\u0432\u0430\u043D\u043D\u044F",
751
+ waitingApproval: "\u041E\u0447\u0456\u043A\u0443\u0432\u0430\u043D\u043D\u044F \u043F\u0456\u0434\u0442\u0432\u0435\u0440\u0434\u0436\u0435\u043D\u043D\u044F",
752
+ expiresIn: "\u0421\u043F\u043B\u0438\u0432\u0430\u0454 \u0447\u0435\u0440\u0435\u0437 {time}",
753
+ secured: "\u041F\u0435\u0440\u0435\u0432\u0456\u0440\u043A\u0430 Proof-of-Human \u0432\u0456\u0434 ZOREAL",
754
+ noIdTitle: "\u0429\u0435 \u043D\u0435\u043C\u0430\u0454 ZOREAL ID?",
755
+ noIdBody: "\u0421\u043A\u0430\u043D\u0443\u0439\u0442\u0435 \u0442\u043E\u0439 \u0441\u0430\u043C\u0438\u0439 \u043A\u043E\u0434, \u0449\u043E\u0431 \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0434\u043E\u0434\u0430\u0442\u043E\u043A \u0456 \u0431\u0435\u0437\u043A\u043E\u0448\u0442\u043E\u0432\u043D\u043E \u0441\u0442\u0432\u043E\u0440\u0438\u0442\u0438 \u0439\u043E\u0433\u043E. \u0426\u0435 \u0437\u0430\u0439\u043C\u0435 \u043B\u0438\u0448\u0435 \u0445\u0432\u0438\u043B\u0438\u043D\u0443.",
756
+ cancel: "\u0421\u043A\u0430\u0441\u0443\u0432\u0430\u0442\u0438",
757
+ close: "\u0417\u0430\u043A\u0440\u0438\u0442\u0438",
758
+ qrAlt: "QR-\u043A\u043E\u0434 \u0434\u043B\u044F \u0432\u0445\u043E\u0434\u0443 \u0447\u0435\u0440\u0435\u0437 ZOREAL"
759
+ },
760
+ // اردو
761
+ ur: {
762
+ title: "\u0644\u0627\u06AF \u0627\u0650\u0646 \u06A9\u0631\u0646\u06D2 \u06A9\u06D2 \u0644\u06CC\u06D2 \u0627\u0633\u06A9\u06CC\u0646 \u06A9\u0631\u06CC\u06BA",
763
+ titleApprove: "\u0627\u067E\u0646\u06D2 \u0641\u0648\u0646 \u067E\u0631 \u0645\u0646\u0638\u0648\u0631\u06CC \u062F\u06CC\u06BA",
764
+ bodyScan: "\u0627\u067E\u0646\u06D2 \u0641\u0648\u0646 \u06A9\u06D2 \u06A9\u06CC\u0645\u0631\u06D2 \u06CC\u0627 ZOREAL ID \u0627\u06CC\u067E \u0633\u06D2 \u0627\u0633\u06A9\u06CC\u0646 \u06A9\u0631\u06CC\u06BA\u06D4",
765
+ bodyApprove: "\u0627\u067E\u0646\u06CC ZOREAL ID \u0627\u06CC\u067E \u0645\u06CC\u06BA \u0644\u0627\u06AF \u0627\u0650\u0646 \u06A9\u06CC \u0645\u0646\u0638\u0648\u0631\u06CC \u062F\u06CC\u06BA\u06D4",
766
+ bodyEnrolling: "\u0627\u067E\u0646\u06D2 \u0641\u0648\u0646 \u067E\u0631 ZOREAL ID \u06A9\u06CC \u0633\u06CC\u0679 \u0627\u067E \u0645\u06A9\u0645\u0644 \u06A9\u0631\u06CC\u06BA\u060C \u067E\u06BE\u0631 \u0644\u0627\u06AF \u0627\u0650\u0646 \u06A9\u06CC \u0645\u0646\u0638\u0648\u0631\u06CC \u062F\u06CC\u06BA\u06D4",
767
+ waiting: "\u0627\u0633\u06A9\u06CC\u0646 \u06A9\u0627 \u0627\u0646\u062A\u0638\u0627\u0631",
768
+ waitingApproval: "\u0645\u0646\u0638\u0648\u0631\u06CC \u06A9\u0627 \u0627\u0646\u062A\u0638\u0627\u0631",
769
+ expiresIn: "{time} \u0645\u06CC\u06BA \u062E\u062A\u0645 \u06C1\u0648\u06AF\u0627",
770
+ secured: "ZOREAL \u06A9\u06CC \u062C\u0627\u0646\u0628 \u0633\u06D2 Proof-of-Human \u062A\u0635\u062F\u06CC\u0642",
771
+ noIdTitle: "\u0627\u0628\u06BE\u06CC \u062A\u06A9 ZOREAL ID \u0646\u06C1\u06CC\u06BA \u06C1\u06D2\u061F",
772
+ noIdBody: "\u0627\u06CC\u067E \u0688\u0627\u0624\u0646 \u0644\u0648\u0688 \u06A9\u0631\u0646\u06D2 \u0627\u0648\u0631 \u0645\u0641\u062A \u0645\u06CC\u06BA \u0627\u06CC\u06A9 \u0628\u0646\u0627\u0646\u06D2 \u06A9\u06D2 \u0644\u06CC\u06D2 \u0648\u06C1\u06CC \u06A9\u0648\u0688 \u0627\u0633\u06A9\u06CC\u0646 \u06A9\u0631\u06CC\u06BA\u06D4 \u0627\u0633 \u0645\u06CC\u06BA \u0635\u0631\u0641 \u0627\u06CC\u06A9 \u0645\u0646\u0679 \u0644\u06AF\u062A\u0627 \u06C1\u06D2\u06D4",
773
+ cancel: "\u0645\u0646\u0633\u0648\u062E \u06A9\u0631\u06CC\u06BA",
774
+ close: "\u0628\u0646\u062F \u06A9\u0631\u06CC\u06BA",
775
+ qrAlt: "ZOREAL \u06A9\u06D2 \u0633\u0627\u062A\u06BE \u0644\u0627\u06AF \u0627\u0650\u0646 \u06A9\u0631\u0646\u06D2 \u06A9\u06D2 \u0644\u06CC\u06D2 QR \u06A9\u0648\u0688"
776
+ },
777
+ // Tiếng Việt
778
+ vi: {
779
+ title: "Qu\xE9t \u0111\u1EC3 \u0111\u0103ng nh\u1EADp",
780
+ titleApprove: "Ph\xEA duy\u1EC7t tr\xEAn \u0111i\u1EC7n tho\u1EA1i c\u1EE7a b\u1EA1n",
781
+ bodyScan: "Qu\xE9t b\u1EB1ng camera \u0111i\u1EC7n tho\u1EA1i ho\u1EB7c \u1EE9ng d\u1EE5ng ZOREAL ID.",
782
+ bodyApprove: "Ph\xEA duy\u1EC7t \u0111\u0103ng nh\u1EADp trong \u1EE9ng d\u1EE5ng ZOREAL ID c\u1EE7a b\u1EA1n.",
783
+ bodyEnrolling: "Ho\xE0n t\u1EA5t thi\u1EBFt l\u1EADp ZOREAL ID tr\xEAn \u0111i\u1EC7n tho\u1EA1i, sau \u0111\xF3 ph\xEA duy\u1EC7t \u0111\u0103ng nh\u1EADp.",
784
+ waiting: "\u0110ang ch\u1EDD qu\xE9t m\xE3",
785
+ waitingApproval: "\u0110ang ch\u1EDD ph\xEA duy\u1EC7t",
786
+ expiresIn: "H\u1EBFt h\u1EA1n sau {time}",
787
+ secured: "X\xE1c minh Proof-of-Human b\u1EDFi ZOREAL",
788
+ noIdTitle: "Ch\u01B0a c\xF3 ZOREAL ID?",
789
+ noIdBody: "Qu\xE9t c\xF9ng m\xE3 n\xE0y \u0111\u1EC3 t\u1EA3i \u1EE9ng d\u1EE5ng v\xE0 t\u1EA1o t\xE0i kho\u1EA3n mi\u1EC5n ph\xED. Ch\u1EC9 m\u1EA5t m\u1ED9t ph\xFAt.",
790
+ cancel: "H\u1EE7y",
791
+ close: "\u0110\xF3ng",
792
+ qrAlt: "M\xE3 QR \u0111\u1EC3 \u0111\u0103ng nh\u1EADp b\u1EB1ng ZOREAL"
793
+ }
794
+ };
795
+ var RTL = /* @__PURE__ */ new Set(["ar", "he", "iw", "ur"]);
796
+ var ALIASES = {
797
+ nb: "no",
798
+ // Bokmål — what we actually wrote
799
+ nn: "no",
800
+ // Nynorsk reader, served Bokmål: closer than English
801
+ fil: "tl",
802
+ // Filipino / Tagalog
803
+ iw: "he",
804
+ // superseded code for Hebrew, still emitted by some platforms
805
+ in: "id"
806
+ // superseded code for Indonesian
807
+ };
808
+ var LATAM = /* @__PURE__ */ new Set([
809
+ "ar",
810
+ "bo",
811
+ "cl",
812
+ "co",
813
+ "cr",
814
+ "cu",
815
+ "do",
816
+ "ec",
817
+ "gt",
818
+ "hn",
819
+ "mx",
820
+ "ni",
821
+ "pa",
822
+ "pe",
823
+ "pr",
824
+ "py",
825
+ "sv",
826
+ "uy",
827
+ "ve",
828
+ "419"
829
+ ]);
830
+ function lookup(locale) {
831
+ const tag = locale.toLowerCase().replace(/_/g, "-");
832
+ const parts = tag.split("-");
833
+ const primary = ALIASES[parts[0]] ?? parts[0];
834
+ const region = parts[1];
835
+ if (primary === "zh") {
836
+ const simplified = /(^|-)(hans|cn|sg|my)(-|$)/.test(tag);
837
+ return TRANSLATIONS[simplified ? "zhs" : "zht"];
838
+ }
839
+ if (primary === "es" && region && LATAM.has(region)) return TRANSLATIONS["es-419"];
840
+ if (primary === "pt" && region === "br") return TRANSLATIONS["pt-br"];
841
+ return TRANSLATIONS[tag] ?? TRANSLATIONS[primary];
842
+ }
843
+ function browserLocales() {
844
+ if (typeof navigator === "undefined") return [];
845
+ const nav = navigator;
846
+ if (nav.languages && nav.languages.length) return [...nav.languages];
847
+ return nav.language ? [nav.language] : [];
848
+ }
849
+ function strings(locale) {
850
+ if (locale) return lookup(locale) ?? en;
851
+ for (const candidate of browserLocales()) {
852
+ const hit = lookup(candidate);
853
+ if (hit) return hit;
854
+ }
855
+ return en;
856
+ }
857
+ function isRtl(locale) {
858
+ const tag = locale ?? browserLocales()[0];
859
+ if (!tag) return false;
860
+ return RTL.has(tag.toLowerCase().replace(/_/g, "-").split("-")[0]);
861
+ }
862
+ function interpolate(template, time) {
863
+ return template.replace("{time}", time);
864
+ }
865
+
866
+ // src/styles.ts
867
+ var PREFIX = "zrl";
868
+ var cx = (name) => `${PREFIX}-${name}`;
869
+ var STYLE_ELEMENT_ID = "zoreal-pairing-styles";
870
+ var LIGHT = `
871
+ --zrl-scrim: rgba(16, 18, 27, 0.45);
872
+ --zrl-surface: #ffffff;
873
+ --zrl-surface-sunken: #f6f7f9;
874
+ --zrl-ink: #16181c;
875
+ --zrl-ink-soft: #4a4f57;
876
+ --zrl-ink-mute: #6b7078;
877
+ --zrl-line: #e4e6ea;
878
+ --zrl-line-soft: #eef0f3;
879
+ --zrl-accent: #00b4d9;
880
+ --zrl-accent-soft: #dcf3fa;
881
+ --zrl-accent-ink: #04698a;
882
+ --zrl-urgent: #b4761a;
883
+ --zrl-qr-bg: #ffffff;
884
+ --zrl-shadow: 0 1px 2px rgba(16, 18, 27, 0.06), 0 20px 50px -12px rgba(16, 18, 27, 0.3);
885
+ --zrl-ring: rgba(16, 18, 27, 0.07);
886
+ `;
887
+ var DARK = `
888
+ --zrl-scrim: rgba(0, 0, 0, 0.62);
889
+ --zrl-surface: #17191d;
890
+ --zrl-surface-sunken: #1f2226;
891
+ --zrl-ink: #f4f5f7;
892
+ --zrl-ink-soft: #b3b8c0;
893
+ --zrl-ink-mute: #8b9199;
894
+ --zrl-line: #2c3036;
895
+ --zrl-line-soft: #24272c;
896
+ --zrl-accent: #34c9e8;
897
+ --zrl-accent-soft: #0d3b47;
898
+ --zrl-accent-ink: #7fdcf0;
899
+ --zrl-urgent: #e0a952;
900
+ /* The QR well stays white in dark mode on purpose: a scanner needs the
901
+ quiet-zone contrast, and an inverted QR fails on a good number of phone
902
+ cameras. It reads as a deliberate light panel, not a theming miss. */
903
+ --zrl-qr-bg: #ffffff;
904
+ --zrl-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 20px 50px -12px rgba(0, 0, 0, 0.65);
905
+ --zrl-ring: rgba(255, 255, 255, 0.1);
906
+ `;
907
+ var CSS = `
908
+ .${PREFIX}-root { ${LIGHT} }
909
+ .${PREFIX}-root[data-theme="dark"] { ${DARK} }
910
+ @media (prefers-color-scheme: dark) {
911
+ .${PREFIX}-root[data-theme="auto"] { ${DARK} }
912
+ }
913
+
914
+ .${PREFIX}-scrim {
915
+ position: fixed;
916
+ inset: 0;
917
+ z-index: 2147483000;
918
+ display: grid;
919
+ place-items: center;
920
+ overflow-y: auto;
921
+ padding: 16px;
922
+ background: var(--zrl-scrim);
923
+ backdrop-filter: blur(3px);
924
+ -webkit-backdrop-filter: blur(3px);
925
+ font-family: inherit;
926
+ animation: ${PREFIX}-fade 200ms ease-out both;
927
+ }
928
+
929
+ .${PREFIX}-card {
930
+ position: relative;
931
+ box-sizing: border-box;
932
+ width: 100%;
933
+ max-width: 380px;
934
+ border-radius: 16px;
935
+ background: var(--zrl-surface);
936
+ color: var(--zrl-ink);
937
+ box-shadow: var(--zrl-shadow);
938
+ outline: 1px solid var(--zrl-ring);
939
+ outline-offset: -1px;
940
+ text-align: center;
941
+ animation: ${PREFIX}-rise 300ms cubic-bezier(0.23, 1, 0.32, 1) both;
942
+ }
943
+
944
+ .${PREFIX}-body { padding: 28px 24px 20px; }
945
+
946
+ .${PREFIX}-lockup { display: block; margin: 0 auto; color: var(--zrl-ink); }
947
+
948
+ .${PREFIX}-title {
949
+ margin: 18px 0 0;
950
+ font-size: 18px;
951
+ font-weight: 600;
952
+ letter-spacing: -0.01em;
953
+ line-height: 1.3;
954
+ color: var(--zrl-ink);
955
+ }
956
+
957
+ .${PREFIX}-body-text {
958
+ margin: 6px auto 0;
959
+ max-width: 30ch;
960
+ font-size: 14px;
961
+ line-height: 1.55;
962
+ color: var(--zrl-ink-soft);
963
+ }
964
+
965
+ .${PREFIX}-qr-well {
966
+ position: relative;
967
+ display: grid;
968
+ place-items: center;
969
+ box-sizing: border-box;
970
+ width: 204px;
971
+ height: 204px;
972
+ margin: 20px auto 0;
973
+ padding: 12px;
974
+ border: 1px solid var(--zrl-line);
975
+ border-radius: 16px;
976
+ background: var(--zrl-qr-bg);
977
+ }
978
+
979
+ .${PREFIX}-qr {
980
+ display: block;
981
+ width: 100%;
982
+ height: 100%;
983
+ border-radius: 8px;
984
+ transition: filter 300ms cubic-bezier(0.23, 1, 0.32, 1),
985
+ opacity 300ms cubic-bezier(0.23, 1, 0.32, 1),
986
+ transform 300ms cubic-bezier(0.23, 1, 0.32, 1);
987
+ }
988
+
989
+ /* Once the code is claimed the QR is spent. Blurring it out rather than
990
+ swapping it keeps one object on screen through the state change, so the eye
991
+ reads a transformation instead of two things trading places. */
992
+ .${PREFIX}-qr[data-spent="true"] { opacity: 0.2; filter: blur(3px); transform: scale(0.96); }
993
+
994
+ .${PREFIX}-qr-overlay {
995
+ position: absolute;
996
+ inset: 0;
997
+ display: grid;
998
+ place-items: center;
999
+ animation: ${PREFIX}-fade 200ms ease-out both;
1000
+ }
1001
+
1002
+ .${PREFIX}-qr-badge {
1003
+ display: grid;
1004
+ place-items: center;
1005
+ width: 56px;
1006
+ height: 56px;
1007
+ border-radius: 999px;
1008
+ background: var(--zrl-accent-soft);
1009
+ color: var(--zrl-accent-ink);
1010
+ }
1011
+
1012
+ .${PREFIX}-status {
1013
+ display: flex;
1014
+ align-items: center;
1015
+ justify-content: center;
1016
+ gap: 8px;
1017
+ margin-top: 20px;
1018
+ font-size: 14px;
1019
+ font-weight: 500;
1020
+ color: var(--zrl-ink);
1021
+ }
1022
+
1023
+ .${PREFIX}-dot { position: relative; display: grid; place-items: center; width: 8px; height: 8px; }
1024
+ .${PREFIX}-dot i {
1025
+ position: absolute;
1026
+ width: 8px;
1027
+ height: 8px;
1028
+ border-radius: 999px;
1029
+ background: var(--zrl-accent);
1030
+ font-style: normal;
1031
+ }
1032
+ .${PREFIX}-dot i:first-child { animation: ${PREFIX}-ping 1.8s cubic-bezier(0.23, 1, 0.32, 1) infinite; }
1033
+
1034
+ .${PREFIX}-timer {
1035
+ margin: 4px 0 0;
1036
+ font-size: 12px;
1037
+ font-variant-numeric: tabular-nums;
1038
+ color: var(--zrl-ink-mute);
1039
+ transition: color 200ms ease-out;
1040
+ }
1041
+ .${PREFIX}-timer[data-urgent="true"] { color: var(--zrl-urgent); }
1042
+
1043
+ .${PREFIX}-help {
1044
+ padding: 14px 24px;
1045
+ border-top: 1px solid var(--zrl-line-soft);
1046
+ background: var(--zrl-surface-sunken);
1047
+ border-radius: 0;
1048
+ }
1049
+ .${PREFIX}-help-title { margin: 0; font-size: 12px; font-weight: 600; color: var(--zrl-ink); }
1050
+ .${PREFIX}-help-body {
1051
+ margin: 4px auto 0;
1052
+ max-width: 34ch;
1053
+ font-size: 12px;
1054
+ line-height: 1.55;
1055
+ color: var(--zrl-ink-soft);
1056
+ }
1057
+
1058
+ .${PREFIX}-footer { padding: 12px; border-top: 1px solid var(--zrl-line-soft); }
1059
+
1060
+ .${PREFIX}-cancel {
1061
+ display: block;
1062
+ width: 100%;
1063
+ padding: 10px;
1064
+ border: 0;
1065
+ border-radius: 12px;
1066
+ background: transparent;
1067
+ font: inherit;
1068
+ font-size: 14px;
1069
+ font-weight: 500;
1070
+ color: var(--zrl-ink-soft);
1071
+ cursor: pointer;
1072
+ transition: background-color 150ms ease-out, color 150ms ease-out, transform 150ms ease-out;
1073
+ }
1074
+ .${PREFIX}-cancel:hover { background: var(--zrl-surface-sunken); color: var(--zrl-ink); }
1075
+ .${PREFIX}-cancel:active { transform: scale(0.99); }
1076
+
1077
+ .${PREFIX}-secured {
1078
+ display: flex;
1079
+ align-items: center;
1080
+ justify-content: center;
1081
+ gap: 6px;
1082
+ margin: 6px 0 0;
1083
+ font-size: 12px;
1084
+ color: var(--zrl-ink-mute);
1085
+ }
1086
+
1087
+ .${PREFIX}-close {
1088
+ position: absolute;
1089
+ top: 12px;
1090
+ inset-inline-end: 12px;
1091
+ display: grid;
1092
+ place-items: center;
1093
+ width: 32px;
1094
+ height: 32px;
1095
+ padding: 0;
1096
+ border: 0;
1097
+ border-radius: 8px;
1098
+ background: transparent;
1099
+ color: var(--zrl-ink-mute);
1100
+ cursor: pointer;
1101
+ transition: background-color 150ms ease-out, color 150ms ease-out, transform 150ms ease-out;
1102
+ }
1103
+ .${PREFIX}-close:hover { background: var(--zrl-surface-sunken); color: var(--zrl-ink); }
1104
+ .${PREFIX}-close:active { transform: scale(0.95); }
1105
+
1106
+ .${PREFIX}-card :focus-visible {
1107
+ outline: 2px solid var(--zrl-accent);
1108
+ outline-offset: 2px;
1109
+ }
1110
+
1111
+ @keyframes ${PREFIX}-fade { from { opacity: 0 } to { opacity: 1 } }
1112
+ @keyframes ${PREFIX}-rise {
1113
+ from { opacity: 0; transform: translateY(10px) scale(0.98) }
1114
+ to { opacity: 1; transform: none }
1115
+ }
1116
+ @keyframes ${PREFIX}-ping {
1117
+ 0% { transform: scale(1); opacity: 0.5 }
1118
+ 70%, 100% { transform: scale(2.6); opacity: 0 }
1119
+ }
1120
+
1121
+ @media (prefers-reduced-motion: reduce) {
1122
+ .${PREFIX}-scrim,
1123
+ .${PREFIX}-card,
1124
+ .${PREFIX}-qr-overlay { animation: none }
1125
+ .${PREFIX}-dot i:first-child { animation: none; opacity: 0.35 }
1126
+ .${PREFIX}-qr,
1127
+ .${PREFIX}-cancel,
1128
+ .${PREFIX}-close,
1129
+ .${PREFIX}-timer { transition: none }
1130
+ }
1131
+ `;
1132
+ function ensureStyles() {
1133
+ if (typeof document === "undefined") return;
1134
+ if (document.getElementById(STYLE_ELEMENT_ID)) return;
1135
+ const el2 = document.createElement("style");
1136
+ el2.id = STYLE_ELEMENT_ID;
1137
+ el2.textContent = CSS;
1138
+ document.head.appendChild(el2);
1139
+ }
1140
+
1141
+ // src/modal.ts
1142
+ var DEFAULT_PAIRING_TIMEOUT_MS = 12e4;
1143
+ var URGENT_SECONDS = 20;
1144
+ function mmss(totalSeconds) {
1145
+ const m = Math.floor(totalSeconds / 60);
1146
+ const s = totalSeconds % 60;
1147
+ return `${m}:${String(s).padStart(2, "0")}`;
1148
+ }
1149
+ function el(tag, className, text) {
1150
+ const node = document.createElement(tag);
1151
+ if (className) node.className = className;
1152
+ if (text !== void 0) node.textContent = text;
1153
+ return node;
1154
+ }
1155
+ var SVG_NS = "http://www.w3.org/2000/svg";
1156
+ function svg(viewBox, attrs = {}) {
1157
+ const node = document.createElementNS(SVG_NS, "svg");
1158
+ node.setAttribute("viewBox", viewBox);
1159
+ node.setAttribute("focusable", "false");
1160
+ node.setAttribute("aria-hidden", "true");
1161
+ for (const [k, v] of Object.entries(attrs)) node.setAttribute(k, v);
1162
+ return node;
1163
+ }
1164
+ function path(d, attrs = {}) {
1165
+ const node = document.createElementNS(SVG_NS, "path");
1166
+ node.setAttribute("d", d);
1167
+ for (const [k, v] of Object.entries(attrs)) node.setAttribute(k, v);
1168
+ return node;
1169
+ }
1170
+ function strokeIcon(size, ds, width = "2") {
1171
+ const node = svg("0 0 24 24", {
1172
+ width: String(size),
1173
+ height: String(size),
1174
+ fill: "none",
1175
+ stroke: "currentColor",
1176
+ "stroke-width": width,
1177
+ "stroke-linecap": "round",
1178
+ "stroke-linejoin": "round"
1179
+ });
1180
+ for (const d of ds) node.appendChild(path(d));
1181
+ return node;
1182
+ }
1183
+ var ZOREAL_BLUE = "#00b4d9";
1184
+ var WORDMARK = "M205,40.5h15.3v-3.5h-11.5v-18.4h-3.8v21.8ZM157,22.2v5.6h10.9v3.5h-10.9v5.8h12.5v3.5h-16.3v-21.8h16.2v3.5h-12.4ZM141.4,25.8c0,1.1-.4,2-1.2,2.7-.8.7-1.9,1-3.3,1h-5.6v-7.3h5.6c1.4,0,2.6.3,3.4.9.8.6,1.2,1.5,1.2,2.7ZM146,40.5l-5.9-8.3c.8-.2,1.4-.5,2.1-.9s1.2-.9,1.7-1.4c.4-.5.8-1.2,1.1-1.9s.4-1.5.4-2.4-.1-2-.5-2.9c-.4-.9-.9-1.6-1.7-2.2-.6-.6-1.5-1-2.5-1.4-1-.3-2.2-.4-3.4-.4h-9.8v21.8h3.8v-7.6h4.8l5.4,7.6h4.5ZM115.7,29.7c0,1.1-.1,2.1-.5,3s-.9,1.7-1.5,2.4-1.4,1.2-2.4,1.7c-.9.4-1.9.6-3,.6s-2.1-.1-3-.6-1.7-1-2.4-1.7-1.2-1.5-1.5-2.4-.5-1.9-.5-3,.1-2.1.5-3,.9-1.7,1.5-2.4,1.4-1.2,2.4-1.7c.9-.4,1.9-.6,3-.6s2.1.2,3,.6c.9.4,1.7,1,2.3,1.7.6.6,1.2,1.5,1.6,2.4s.5,1.9.5,3ZM119.7,29.6c0-1.5-.3-3-.8-4.4-.6-1.4-1.4-2.5-2.4-3.6-1-1-2.2-1.8-3.6-2.4-1.4-.6-3-.9-4.6-.9s-3.2.4-4.6.9c-1.4.6-2.7,1.4-3.7,2.4s-1.8,2.2-2.4,3.6c-.5,1.4-.8,2.8-.8,4.4s.3,3,.8,4.4c.6,1.4,1.4,2.5,2.4,3.6,1,1,2.2,1.8,3.6,2.4,1.4.6,3,.9,4.6.9s3.2-.4,4.6-.9c1.4-.6,2.6-1.4,3.7-2.4,1-1,1.8-2.2,2.4-3.6.5-1.4.8-2.9.8-4.4ZM86.1,22.1l-13,15.6v2.8h17.9v-3.4h-12.9l12.9-15.6v-2.8h-17.5v3.4h12.5ZM188.5,18.5h-3.5l-9.6,22h4c3.7-8.8,3.4-8,7.4-17.4,3.7,8.8,3.9,9.1,7.4,17.4h4l-9.6-22Z";
1185
+ var MARK_PATHS = [
1186
+ "M52,25.7c.4-2-.5-4.2-2.5-5.4l-11.8-6.8,3.4-2,10.1,5.9c3.6,2,5.1,6.3,3.8,10.1-.2.5-.4,1-.7,1.6-.3.5-.6.9-1,1.4-.9.9-1.9,1.7-3,2.2-2.4,1-5.2.9-7.6-.5l-5.9-3.4c-1.9-1.1-4.3-.9-5.9.5-.4.4-.8.8-1.1,1.3-.3.5-.5,1.1-.6,1.7-.4,2,.6,4.2,2.5,5.4l11.8,6.8-3.4,2-10.1-5.9c-3.6-2-5.1-6.3-3.8-10.1.1-.5.4-1,.7-1.6.3-.5.7-.9,1-1.4.9-.9,1.9-1.7,3.1-2.2,2.4-1,5.2-.9,7.6.4l5.9,3.4c1.9,1.1,4.3.9,5.9-.5.4-.4.8-.8,1.1-1.3.3-.5.5-1.1.6-1.7Z",
1187
+ "M60.3,33.1c-.5.8-1.5,1.1-2.3.6-.9-.5-1.1-1.5-.7-2.3.5-.9,1.5-1.1,2.3-.7.9.5,1.1,1.5.7,2.4Z",
1188
+ "M31.9,18c3.4-.5,6.9,0,10,1.9l.8.5h0c.8.5,1,1.5.6,2.3s-1.5,1.1-2.3.6l-.8-.5c-2.8-1.6-6-1.9-8.9-1.2-1,.3-2,.7-3,1.2h0c-.8.5-1.8.2-2.3-.7-.5-.8-.2-1.8.6-2.3,0,0,0,0,.2,0,.2,0,.4-.2.7-.3,1.4-.7,2.9-1.1,4.4-1.4Z",
1189
+ "M21.4,24.9c.5-.8,1.6-1,2.3-.5.8.5,1,1.6.5,2.3-.5.8-1.6,1-2.4.5-.8-.5-1-1.6-.5-2.3Z",
1190
+ "M45.5,23.9c.5-.9,1.5-1.1,2.3-.7.8.5,1.1,1.5.6,2.4-.5.8-1.5,1.1-2.3.6s-1.1-1.5-.6-2.3Z",
1191
+ "M49.4,39.9c-3.3.6-6.9,0-10-1.8l-.8-.5h0c-.8-.5-1.1-1.5-.6-2.3s1.5-1.1,2.3-.6l.8.5c2.8,1.6,6,1.9,9,1.2,1-.3,2-.7,3-1.2h0c.8-.5,1.8-.2,2.3.6.5.9.2,1.9-.6,2.4,0,0-.1,0-.2,0-.2.1-.5.3-.7.4-1.4.7-2.8,1.1-4.4,1.4Z",
1192
+ "M35.8,34c-.5.8-1.5,1.1-2.3.6s-1.1-1.5-.6-2.3,1.5-1.1,2.3-.6,1.1,1.5.6,2.3Z"
1193
+ ];
1194
+ function lockup(height) {
1195
+ const node = svg("0 0 240 58.5", {
1196
+ height: String(height),
1197
+ width: String(Math.round(height * (240 / 58.5)))
1198
+ });
1199
+ node.removeAttribute("aria-hidden");
1200
+ node.setAttribute("role", "img");
1201
+ node.setAttribute("aria-label", "ZOREAL");
1202
+ node.appendChild(path(WORDMARK, { fill: "currentColor" }));
1203
+ const g = document.createElementNS(SVG_NS, "g");
1204
+ g.setAttribute("fill", ZOREAL_BLUE);
1205
+ g.setAttribute("fill-rule", "evenodd");
1206
+ for (const d of MARK_PATHS) g.appendChild(path(d));
1207
+ node.appendChild(g);
1208
+ return node;
1209
+ }
1210
+ function mountPairingModal(state, options) {
1211
+ if (typeof document === "undefined") return null;
1212
+ ensureStyles();
1213
+ const t = strings(options.locale);
1214
+ const timeoutMs = options.timeoutMs ?? DEFAULT_PAIRING_TIMEOUT_MS;
1215
+ let closed = false;
1216
+ const scrim = el("div", `${cx("root")} ${cx("scrim")}`);
1217
+ scrim.dataset.theme = options.theme ?? "auto";
1218
+ const card = el("div", cx("card"));
1219
+ card.setAttribute("role", "dialog");
1220
+ card.setAttribute("aria-modal", "true");
1221
+ card.dir = isRtl(options.locale) ? "rtl" : "ltr";
1222
+ const titleId = `zrl-title-${Math.random().toString(36).slice(2, 9)}`;
1223
+ card.setAttribute("aria-labelledby", titleId);
1224
+ const closeBtn = el("button", cx("close"));
1225
+ closeBtn.type = "button";
1226
+ closeBtn.setAttribute("aria-label", t.close);
1227
+ closeBtn.appendChild(strokeIcon(16, ["M18 6 6 18M6 6l12 12"]));
1228
+ const body = el("div", cx("body"));
1229
+ const mark = lockup(44);
1230
+ mark.classList.add(cx("lockup"));
1231
+ const title = el("h2", cx("title"));
1232
+ title.id = titleId;
1233
+ const bodyText = el("p", cx("body-text"));
1234
+ const well = el("div", cx("qr-well"));
1235
+ const qr = el("img", cx("qr"));
1236
+ qr.alt = t.qrAlt;
1237
+ qr.width = 180;
1238
+ qr.height = 180;
1239
+ if (state.qrUrl) qr.src = state.qrUrl;
1240
+ const overlay = el("span", cx("qr-overlay"));
1241
+ const badge = el("span", cx("qr-badge"));
1242
+ badge.appendChild(strokeIcon(24, ["M8.5 2h7a2.5 2.5 0 0 1 2.5 2.5v15a2.5 2.5 0 0 1-2.5 2.5h-7A2.5 2.5 0 0 1 6 19.5v-15A2.5 2.5 0 0 1 8.5 2Z", "M11 18.5h2"], "1.8"));
1243
+ overlay.appendChild(badge);
1244
+ well.append(qr, overlay);
1245
+ const status = el("div", cx("status"));
1246
+ const dot = el("span", cx("dot"));
1247
+ dot.append(el("i"), el("i"));
1248
+ const statusLabel = el("span");
1249
+ status.append(dot, statusLabel);
1250
+ const timer = el("p", cx("timer"));
1251
+ body.append(mark, title, bodyText, well, status, timer);
1252
+ const help = el("div", cx("help"));
1253
+ help.append(el("p", cx("help-title"), t.noIdTitle), el("p", cx("help-body"), t.noIdBody));
1254
+ const footer = el("div", cx("footer"));
1255
+ const cancelBtn = el("button", cx("cancel"), t.cancel);
1256
+ cancelBtn.type = "button";
1257
+ const secured = el("p", cx("secured"));
1258
+ secured.append(strokeIcon(13, ["M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z", "m9 12 2 2 4-4"]), document.createTextNode(t.secured));
1259
+ footer.append(cancelBtn, secured);
1260
+ card.append(closeBtn, body, help, footer);
1261
+ scrim.appendChild(card);
1262
+ const serverMs = typeof state.expiresIn === "number" ? state.expiresIn * 1e3 : Infinity;
1263
+ const deadline = Date.now() + Math.min(timeoutMs, serverMs);
1264
+ const paint = (s) => {
1265
+ const settled = s.status === "claimed" || s.status === "enrolling";
1266
+ title.textContent = settled ? t.titleApprove : t.title;
1267
+ bodyText.textContent = s.status === "enrolling" ? t.bodyEnrolling : settled ? t.bodyApprove : t.bodyScan;
1268
+ statusLabel.textContent = settled ? t.waitingApproval : t.waiting;
1269
+ qr.dataset.spent = String(settled);
1270
+ overlay.style.display = settled ? "" : "none";
1271
+ if (s.qrUrl && qr.src !== s.qrUrl) qr.src = s.qrUrl;
1272
+ };
1273
+ const tick = () => {
1274
+ const left = Math.max(0, Math.ceil((deadline - Date.now()) / 1e3));
1275
+ timer.textContent = interpolate(t.expiresIn, mmss(left));
1276
+ timer.dataset.urgent = String(left <= URGENT_SECONDS);
1277
+ if (left === 0) {
1278
+ window.clearInterval(interval);
1279
+ options.onCancel();
1280
+ }
1281
+ };
1282
+ const onKey = (e) => {
1283
+ if (e.key === "Escape") options.onCancel();
1284
+ };
1285
+ const close = () => {
1286
+ if (closed) return;
1287
+ closed = true;
1288
+ window.clearInterval(interval);
1289
+ document.removeEventListener("keydown", onKey);
1290
+ document.body.style.overflow = previousOverflow;
1291
+ scrim.remove();
1292
+ };
1293
+ closeBtn.addEventListener("click", options.onCancel);
1294
+ cancelBtn.addEventListener("click", options.onCancel);
1295
+ scrim.addEventListener("click", (e) => {
1296
+ if (e.target === scrim) options.onCancel();
1297
+ });
1298
+ document.addEventListener("keydown", onKey);
1299
+ const previousOverflow = document.body.style.overflow;
1300
+ document.body.style.overflow = "hidden";
1301
+ paint(state);
1302
+ tick();
1303
+ const interval = window.setInterval(tick, 1e3);
1304
+ document.body.appendChild(scrim);
1305
+ closeBtn.focus();
1306
+ return { update: paint, close };
1307
+ }
1308
+
141
1309
  // src/pkce.ts
142
1310
  var VERIFIER_BYTES = 32;
143
1311
  var base64url = (bytes) => btoa(String.fromCharCode(...bytes)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
@@ -168,6 +1336,11 @@ function startLogin(options) {
168
1336
  const controller = new AbortController();
169
1337
  const surface = {};
170
1338
  const cancel = () => controller.abort();
1339
+ let modal = null;
1340
+ const closeModal = () => {
1341
+ modal?.close();
1342
+ modal = null;
1343
+ };
171
1344
  const run = async () => {
172
1345
  const verifier = generateVerifier();
173
1346
  const state = generateState();
@@ -207,17 +1380,31 @@ function startLogin(options) {
207
1380
  appLink: useAppLink,
208
1381
  cancel
209
1382
  };
210
- options.onState?.({ status: "pending", expiresIn: started.expires_in, ...stateSurface });
1383
+ const initial = { status: "pending", expiresIn: started.expires_in, ...stateSurface };
1384
+ options.onState?.(initial);
1385
+ if ((options.pairingUI ?? "modal") === "modal" && !useAppLink) {
1386
+ modal = mountPairingModal(initial, {
1387
+ onCancel: cancel,
1388
+ locale: options.locale,
1389
+ theme: options.theme,
1390
+ timeoutMs: options.pairingTimeoutMs
1391
+ });
1392
+ }
211
1393
  if (useAppLink && typeof window !== "undefined") {
212
1394
  window.location.assign(started.pair_url);
213
1395
  }
214
1396
  code = await pollUntilApproved(
215
1397
  issuer,
216
1398
  started.request_id,
217
- (s) => options.onState?.({ ...s, ...stateSurface }),
1399
+ (s) => {
1400
+ const next = { ...s, ...stateSurface };
1401
+ modal?.update(next);
1402
+ options.onState?.(next);
1403
+ },
218
1404
  controller.signal
219
1405
  );
220
1406
  }
1407
+ closeModal();
221
1408
  if (flow === "auth-code") {
222
1409
  const response2 = {
223
1410
  code,
@@ -242,6 +1429,7 @@ function startLogin(options) {
242
1429
  };
243
1430
  return response;
244
1431
  } catch (e) {
1432
+ closeModal();
245
1433
  if (e instanceof DOMException && e.name === "AbortError") throw e;
246
1434
  if (e instanceof OAuthFlowError || e instanceof FlowAbandonedError) throw e;
247
1435
  throw new FlowAbandonedError({
@@ -272,6 +1460,7 @@ function startLogin(options) {
272
1460
  }
273
1461
  export {
274
1462
  DEFAULT_ISSUER,
1463
+ DEFAULT_PAIRING_TIMEOUT_MS,
275
1464
  FlowAbandonedError,
276
1465
  OAuthFlowError,
277
1466
  POLL_INTERVAL_ENROLLING_MS,
@@ -284,6 +1473,7 @@ export {
284
1473
  generateState,
285
1474
  generateVerifier,
286
1475
  isMobileUserAgent,
1476
+ mountPairingModal,
287
1477
  pollUntilApproved,
288
1478
  startLogin,
289
1479
  startPairing,