@gerege-systems/eid-mongolia-sdk 0.13.0 → 0.14.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/button.js ADDED
@@ -0,0 +1,975 @@
1
+ // src/devicelink.ts
2
+ function isMobileUserAgent(nav) {
3
+ const n = nav ?? globalThis.navigator;
4
+ if (!n) return false;
5
+ if (n.userAgentData?.mobile === true) return true;
6
+ const ua = n.userAgent ?? "";
7
+ if (/Android|iPhone|iPod|iPad/i.test(ua)) return true;
8
+ return /Macintosh/.test(ua) && (n.maxTouchPoints ?? 0) > 1;
9
+ }
10
+
11
+ // src/logo.ts
12
+ var EID_LOGO_DATA_URI = "data:image/png;base64,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";
13
+
14
+ // src/qr.ts
15
+ var ECC_PER_BLOCK_M = [
16
+ -1,
17
+ 10,
18
+ 16,
19
+ 26,
20
+ 18,
21
+ 24,
22
+ 16,
23
+ 18,
24
+ 22,
25
+ 22,
26
+ 26,
27
+ 30,
28
+ 22,
29
+ 22,
30
+ 24,
31
+ 24,
32
+ 28,
33
+ 28,
34
+ 26,
35
+ 26,
36
+ 26,
37
+ 26,
38
+ 28,
39
+ 28,
40
+ 28,
41
+ 28,
42
+ 28,
43
+ 28,
44
+ 28,
45
+ 28,
46
+ 28,
47
+ 28,
48
+ 28,
49
+ 28,
50
+ 28,
51
+ 28,
52
+ 28,
53
+ 28,
54
+ 28,
55
+ 28,
56
+ 28
57
+ ];
58
+ var BLOCKS_M = [
59
+ -1,
60
+ 1,
61
+ 1,
62
+ 1,
63
+ 2,
64
+ 2,
65
+ 4,
66
+ 4,
67
+ 4,
68
+ 5,
69
+ 5,
70
+ 5,
71
+ 8,
72
+ 9,
73
+ 9,
74
+ 10,
75
+ 10,
76
+ 11,
77
+ 13,
78
+ 14,
79
+ 16,
80
+ 17,
81
+ 17,
82
+ 18,
83
+ 20,
84
+ 21,
85
+ 23,
86
+ 25,
87
+ 26,
88
+ 28,
89
+ 29,
90
+ 31,
91
+ 33,
92
+ 35,
93
+ 37,
94
+ 38,
95
+ 40,
96
+ 43,
97
+ 45,
98
+ 47,
99
+ 49
100
+ ];
101
+ var FORMAT_BITS_M = 0;
102
+ function rawModules(ver) {
103
+ let r = (16 * ver + 128) * ver + 64;
104
+ if (ver >= 2) {
105
+ const n = Math.floor(ver / 7) + 2;
106
+ r -= (25 * n - 10) * n - 55;
107
+ if (ver >= 7) r -= 36;
108
+ }
109
+ return r;
110
+ }
111
+ function dataCodewords(ver) {
112
+ return Math.floor(rawModules(ver) / 8) - ECC_PER_BLOCK_M[ver] * BLOCKS_M[ver];
113
+ }
114
+ function gfMul(x, y) {
115
+ let z = 0;
116
+ for (let i = 7; i >= 0; i--) {
117
+ z = z << 1 ^ (z >>> 7) * 285;
118
+ z ^= (y >>> i & 1) * x;
119
+ }
120
+ return z;
121
+ }
122
+ function rsDivisor(degree) {
123
+ const r = new Array(degree).fill(0);
124
+ r[degree - 1] = 1;
125
+ let root = 1;
126
+ for (let i = 0; i < degree; i++) {
127
+ for (let j = 0; j < r.length; j++) {
128
+ r[j] = gfMul(r[j], root);
129
+ if (j + 1 < r.length) r[j] ^= r[j + 1];
130
+ }
131
+ root = gfMul(root, 2);
132
+ }
133
+ return r;
134
+ }
135
+ function rsRemainder(data, divisor) {
136
+ const r = divisor.map(() => 0);
137
+ for (const b of data) {
138
+ const f = b ^ r.shift();
139
+ r.push(0);
140
+ divisor.forEach((c, i) => r[i] ^= gfMul(c, f));
141
+ }
142
+ return r;
143
+ }
144
+ function encodeQr(text) {
145
+ const bytes = Array.from(new TextEncoder().encode(text));
146
+ let ver = 1;
147
+ for (; ; ver++) {
148
+ if (ver > 40) throw new Error("qr: \u04E9\u0433\u04E9\u0433\u0434\u04E9\u043B \u0445\u044D\u0442 \u0443\u0440\u0442");
149
+ const bits = 4 + (ver <= 9 ? 8 : 16) + bytes.length * 8;
150
+ if (bits <= dataCodewords(ver) * 8) break;
151
+ }
152
+ const bb = [];
153
+ const put = (v, n) => {
154
+ for (let i2 = n - 1; i2 >= 0; i2--) bb.push(v >>> i2 & 1);
155
+ };
156
+ put(4, 4);
157
+ put(bytes.length, ver <= 9 ? 8 : 16);
158
+ for (const b of bytes) put(b, 8);
159
+ const cap = dataCodewords(ver) * 8;
160
+ put(0, Math.min(4, cap - bb.length));
161
+ put(0, (8 - bb.length % 8) % 8);
162
+ for (let pad = 236; bb.length < cap; pad ^= 236 ^ 17) put(pad, 8);
163
+ const data = [];
164
+ for (let i2 = 0; i2 < bb.length; i2 += 8) data.push(parseInt(bb.slice(i2, i2 + 8).join(""), 2));
165
+ const nBlocks = BLOCKS_M[ver];
166
+ const eccLen = ECC_PER_BLOCK_M[ver];
167
+ const raw = Math.floor(rawModules(ver) / 8);
168
+ const nShort = nBlocks - raw % nBlocks;
169
+ const shortLen = Math.floor(raw / nBlocks);
170
+ const div = rsDivisor(eccLen);
171
+ const blocks = [];
172
+ for (let i2 = 0, k = 0; i2 < nBlocks; i2++) {
173
+ const dat = data.slice(k, k + shortLen - eccLen + (i2 < nShort ? 0 : 1));
174
+ k += dat.length;
175
+ const ecc = rsRemainder(dat, div);
176
+ if (i2 < nShort) dat.push(0);
177
+ blocks.push(dat.concat(ecc));
178
+ }
179
+ const codewords = [];
180
+ for (let i2 = 0; i2 < blocks[0].length; i2++) {
181
+ blocks.forEach((b, j) => {
182
+ if (i2 !== shortLen - eccLen || j >= nShort) codewords.push(b[i2]);
183
+ });
184
+ }
185
+ const size = ver * 4 + 17;
186
+ const mod = Array.from({ length: size }, () => new Array(size).fill(false));
187
+ const fn = Array.from({ length: size }, () => new Array(size).fill(false));
188
+ const set = (x, y, dark) => {
189
+ mod[y][x] = dark;
190
+ fn[y][x] = true;
191
+ };
192
+ for (let i2 = 0; i2 < size; i2++) {
193
+ set(6, i2, i2 % 2 === 0);
194
+ set(i2, 6, i2 % 2 === 0);
195
+ }
196
+ for (const [cx, cy] of [[3, 3], [size - 4, 3], [3, size - 4]]) {
197
+ for (let dy = -4; dy <= 4; dy++) {
198
+ for (let dx = -4; dx <= 4; dx++) {
199
+ const d = Math.max(Math.abs(dx), Math.abs(dy));
200
+ const x = cx + dx;
201
+ const y = cy + dy;
202
+ if (x >= 0 && x < size && y >= 0 && y < size) set(x, y, d !== 2 && d !== 4);
203
+ }
204
+ }
205
+ }
206
+ const align = [];
207
+ if (ver > 1) {
208
+ const n = Math.floor(ver / 7) + 2;
209
+ const step = ver === 32 ? 26 : Math.ceil((ver * 4 + 4) / (n * 2 - 2)) * 2;
210
+ align.push(6);
211
+ for (let p = size - 7; align.length < n; p -= step) align.splice(1, 0, p);
212
+ }
213
+ const na = align.length;
214
+ for (let i2 = 0; i2 < na; i2++) {
215
+ for (let j = 0; j < na; j++) {
216
+ if (i2 === 0 && j === 0 || i2 === 0 && j === na - 1 || i2 === na - 1 && j === 0) continue;
217
+ for (let dy = -2; dy <= 2; dy++) {
218
+ for (let dx = -2; dx <= 2; dx++) set(align[i2] + dx, align[j] + dy, Math.max(Math.abs(dx), Math.abs(dy)) !== 1);
219
+ }
220
+ }
221
+ }
222
+ const bit = (v, i2) => (v >>> i2 & 1) !== 0;
223
+ const drawFormat = (mask) => {
224
+ const d = FORMAT_BITS_M << 3 | mask;
225
+ let rem = d;
226
+ for (let i2 = 0; i2 < 10; i2++) rem = rem << 1 ^ (rem >>> 9) * 1335;
227
+ const bits = (d << 10 | rem) ^ 21522;
228
+ for (let i2 = 0; i2 <= 5; i2++) set(8, i2, bit(bits, i2));
229
+ set(8, 7, bit(bits, 6));
230
+ set(8, 8, bit(bits, 7));
231
+ set(7, 8, bit(bits, 8));
232
+ for (let i2 = 9; i2 < 15; i2++) set(14 - i2, 8, bit(bits, i2));
233
+ for (let i2 = 0; i2 < 8; i2++) set(size - 1 - i2, 8, bit(bits, i2));
234
+ for (let i2 = 8; i2 < 15; i2++) set(8, size - 15 + i2, bit(bits, i2));
235
+ set(8, size - 8, true);
236
+ };
237
+ drawFormat(0);
238
+ if (ver >= 7) {
239
+ let rem = ver;
240
+ for (let i2 = 0; i2 < 12; i2++) rem = rem << 1 ^ (rem >>> 11) * 7973;
241
+ const bits = ver << 12 | rem;
242
+ for (let i2 = 0; i2 < 18; i2++) {
243
+ const a = size - 11 + i2 % 3;
244
+ const b = Math.floor(i2 / 3);
245
+ set(a, b, bit(bits, i2));
246
+ set(b, a, bit(bits, i2));
247
+ }
248
+ }
249
+ let i = 0;
250
+ for (let right = size - 1; right >= 1; right -= 2) {
251
+ if (right === 6) right = 5;
252
+ for (let vert = 0; vert < size; vert++) {
253
+ for (let j = 0; j < 2; j++) {
254
+ const x = right - j;
255
+ const y = (right + 1 & 2) === 0 ? size - 1 - vert : vert;
256
+ if (!fn[y][x] && i < codewords.length * 8) {
257
+ mod[y][x] = bit(codewords[i >>> 3], 7 - (i & 7));
258
+ i++;
259
+ }
260
+ }
261
+ }
262
+ }
263
+ const applyMask = (m) => {
264
+ for (let y = 0; y < size; y++) {
265
+ for (let x = 0; x < size; x++) {
266
+ if (fn[y][x]) continue;
267
+ let inv;
268
+ switch (m) {
269
+ case 0:
270
+ inv = (x + y) % 2 === 0;
271
+ break;
272
+ case 1:
273
+ inv = y % 2 === 0;
274
+ break;
275
+ case 2:
276
+ inv = x % 3 === 0;
277
+ break;
278
+ case 3:
279
+ inv = (x + y) % 3 === 0;
280
+ break;
281
+ case 4:
282
+ inv = (Math.floor(x / 3) + Math.floor(y / 2)) % 2 === 0;
283
+ break;
284
+ case 5:
285
+ inv = x * y % 2 + x * y % 3 === 0;
286
+ break;
287
+ case 6:
288
+ inv = (x * y % 2 + x * y % 3) % 2 === 0;
289
+ break;
290
+ default:
291
+ inv = ((x + y) % 2 + x * y % 3) % 2 === 0;
292
+ }
293
+ if (inv) mod[y][x] = !mod[y][x];
294
+ }
295
+ }
296
+ };
297
+ let best = 0;
298
+ let bestScore = Infinity;
299
+ for (let m = 0; m < 8; m++) {
300
+ applyMask(m);
301
+ drawFormat(m);
302
+ const s = penalty(mod, size);
303
+ if (s < bestScore) {
304
+ best = m;
305
+ bestScore = s;
306
+ }
307
+ applyMask(m);
308
+ }
309
+ applyMask(best);
310
+ drawFormat(best);
311
+ return { size, modules: mod };
312
+ }
313
+ function penalty(m, size) {
314
+ let s = 0;
315
+ const at = (x, y, horiz) => horiz ? m[y][x] : m[x][y];
316
+ for (const horiz of [true, false]) {
317
+ for (let a = 0; a < size; a++) {
318
+ let run = 1;
319
+ for (let b = 1; b <= size; b++) {
320
+ if (b < size && at(b, a, horiz) === at(b - 1, a, horiz)) {
321
+ run++;
322
+ } else {
323
+ if (run >= 5) s += run - 2;
324
+ run = 1;
325
+ }
326
+ }
327
+ for (let b = 0; b + 7 <= size; b++) {
328
+ const p = [1, 0, 1, 1, 1, 0, 1].every((v, k) => at(b + k, a, horiz) === (v === 1));
329
+ if (!p) continue;
330
+ const light = (from) => {
331
+ for (let k = from; k < from + 4; k++) if (k >= 0 && k < size && at(k, a, horiz)) return false;
332
+ return true;
333
+ };
334
+ if (light(b - 4) || light(b + 7)) s += 40;
335
+ }
336
+ }
337
+ }
338
+ let dark = 0;
339
+ for (let y = 0; y < size; y++) {
340
+ for (let x = 0; x < size; x++) {
341
+ if (m[y][x]) dark++;
342
+ if (x < size - 1 && y < size - 1) {
343
+ const c = m[y][x];
344
+ if (c === m[y][x + 1] && c === m[y + 1][x] && c === m[y + 1][x + 1]) s += 3;
345
+ }
346
+ }
347
+ }
348
+ const total = size * size;
349
+ s += (Math.ceil(Math.abs(dark * 20 - total * 10) / total) - 1) * 10;
350
+ return s;
351
+ }
352
+ function qrSvgPath(q, border = 4) {
353
+ let d = "";
354
+ for (let y = 0; y < q.size; y++) {
355
+ for (let x = 0; x < q.size; x++) {
356
+ if (q.modules[y][x]) d += `M${x + border},${y + border}h1v1h-1z`;
357
+ }
358
+ }
359
+ return d;
360
+ }
361
+
362
+ // src/button.ts
363
+ var T = {
364
+ mn: {
365
+ button: "eID-\u044D\u044D\u0440 \u043D\u044D\u0432\u0442\u0440\u044D\u0445",
366
+ title: "eID-\u044D\u044D\u0440 \u043D\u044D\u0432\u0442\u0440\u044D\u0445",
367
+ close: "\u0425\u0430\u0430\u0445",
368
+ loading: "\u0410\u0447\u0430\u0430\u043B\u0436 \u0431\u0430\u0439\u043D\u0430",
369
+ qrAlt: "\u041D\u044D\u0432\u0442\u0440\u044D\u0445 QR \u043A\u043E\u0434 \u2014 \u0443\u0442\u0441\u0430\u043D \u0434\u044D\u044D\u0440\u0445 eID Mongolia \u0430\u043F\u043F\u0430\u0430\u0440 \u0443\u043D\u0448\u0443\u0443\u043B\u043D\u0430",
370
+ steps: ["\u0423\u0442\u0441\u0430\u043D \u0434\u044D\u044D\u0440\u0445 eID Mongolia \u0430\u043F\u043F\u044B\u0433 \u043D\u044D\u044D\u043D\u044D", "QR \u043A\u043E\u0434\u044B\u0433 \u0443\u043D\u0448\u0443\u0443\u043B\u043D\u0430", "PIN1 \u043A\u043E\u0434\u043E\u043E \u043E\u0440\u0443\u0443\u043B\u043D\u0430"],
371
+ code: "\u0423\u0442\u0441\u0430\u043D \u0434\u044D\u044D\u0440\u0445 \u043A\u043E\u0434:",
372
+ or: "\u044D\u0441\u0432\u044D\u043B",
373
+ idLabel: "\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0439\u043D \u0434\u0443\u0433\u0430\u0430\u0440",
374
+ idHint: "\u0423\u0442\u0441\u0430\u043D\u0434 \u0442\u0430\u043D\u044C \u043C\u044D\u0434\u044D\u0433\u0434\u044D\u043B \u043E\u0447\u043D\u043E. \u0418\u0440\u0433\u044D\u043D\u0438\u0439 12 \u043E\u0440\u043E\u043D\u0442\u043E\u0439 \u0434\u0443\u0433\u0430\u0430\u0440\u0430\u0430\u0440 \u0447 \u0431\u043E\u043B\u043D\u043E.",
375
+ idEmpty: "\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0439\u043D \u0434\u0443\u0433\u0430\u0430\u0440 \u043E\u0440\u0443\u0443\u043B\u043D\u0430 \u0443\u0443",
376
+ idLatin: "\u04AE\u0441\u0433\u0438\u0439\u0433 \u043A\u0438\u0440\u0438\u043B\u043B\u044D\u044D\u0440 \u0431\u0438\u0447\u043D\u044D \u04AF\u04AF: \u0423\u041112345678",
377
+ idBad: "\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0439\u043D \u0434\u0443\u0433\u0430\u0430\u0440 2 \u04AF\u0441\u044D\u0433, 8 \u0446\u0438\u0444\u0440\u0442\u044D\u0439 \u0431\u0430\u0439\u043D\u0430: \u0423\u041112345678",
378
+ push: "\u041C\u044D\u0434\u044D\u0433\u0434\u044D\u043B \u0438\u043B\u0433\u044D\u044D\u0445",
379
+ pushing: "\u0418\u043B\u0433\u044D\u044D\u0436 \u0431\u0430\u0439\u043D\u0430",
380
+ rateLimited: "\u0425\u044D\u0442 \u043E\u043B\u043E\u043D \u043E\u0440\u043E\u043B\u0434\u043B\u043E\u0433\u043E. \u0422\u04AF\u0440 \u0445\u04AF\u043B\u044D\u044D\u0433\u044D\u044D\u0434 \u0434\u0430\u0445\u0438\u043D \u043E\u0440\u043E\u043B\u0434\u043E\u043D\u043E \u0443\u0443",
381
+ pushFailed: "\u041C\u044D\u0434\u044D\u0433\u0434\u044D\u043B \u0438\u043B\u0433\u044D\u044D\u0436 \u0447\u0430\u0434\u0441\u0430\u043D\u0433\u04AF\u0439. \u0414\u0430\u0445\u0438\u043D \u043E\u0440\u043E\u043B\u0434\u043E\u043D\u043E \u0443\u0443",
382
+ waitText: "\u0423\u0442\u0441\u0430\u043D \u0434\u044D\u044D\u0440\u0445 \u043A\u043E\u0434 \u0438\u0436\u0438\u043B \u0431\u043E\u043B PIN1 \u043E\u0440\u0443\u0443\u043B\u043D\u0430 \u0443\u0443. \u0418\u0436\u0438\u043B \u0431\u0438\u0448 \u0431\u043E\u043B \u0442\u0430\u0442\u0433\u0430\u043B\u0437\u0430\u043D\u0430 \u0443\u0443.",
383
+ waiting: "\u0425\u04AF\u043B\u044D\u044D\u0436 \u0431\u0430\u0439\u043D\u0430",
384
+ back: "\u0411\u0443\u0446\u0430\u0445",
385
+ left: "\u04AE\u043B\u0434\u0441\u044D\u043D \u0445\u0443\u0433\u0430\u0446\u0430\u0430",
386
+ stale: "QR \u043A\u043E\u0434 \u0445\u0443\u0443\u0447\u0438\u0440\u0441\u0430\u043D",
387
+ refresh: "\u0428\u0438\u043D\u044D\u0447\u043B\u044D\u0445",
388
+ offline: "\u0425\u043E\u043B\u0431\u043E\u043B\u0442 \u0442\u0430\u0441\u0430\u0440\u0441\u0430\u043D. \u0418\u043D\u0442\u0435\u0440\u043D\u044D\u0442\u044D\u044D \u0448\u0430\u043B\u0433\u0430\u043D\u0430 \u0443\u0443 \u2014 \u0434\u0430\u0445\u0438\u043D \u0445\u043E\u043B\u0431\u043E\u0433\u0434\u043E\u0445\u044B\u0433 \u043E\u0440\u043E\u043B\u0434\u043E\u0436 \u0431\u0430\u0439\u043D\u0430.",
389
+ expiredTitle: "\u041D\u044D\u0432\u0442\u0440\u044D\u043B\u0442\u0438\u0439\u043D \u0445\u0443\u0433\u0430\u0446\u0430\u0430 \u0434\u0443\u0443\u0441\u0441\u0430\u043D",
390
+ refusedTitle: "\u041D\u044D\u0432\u0442\u0440\u044D\u043B\u0442\u044D\u044D\u0441 \u0442\u0430\u0442\u0433\u0430\u043B\u0437\u0441\u0430\u043D",
391
+ failedTitle: "\u041D\u044D\u0432\u0442\u044D\u0440\u0447 \u0447\u0430\u0434\u0441\u0430\u043D\u0433\u04AF\u0439",
392
+ failedText: "\u0411\u0430\u0442\u0430\u043B\u0433\u0430\u0430\u0436\u0443\u0443\u043B\u0430\u043B\u0442 \u0430\u043C\u0436\u0438\u043B\u0442\u0433\u04AF\u0439 \u0431\u043E\u043B\u043B\u043E\u043E. \u0414\u0430\u0445\u0438\u043D \u043E\u0440\u043E\u043B\u0434\u043E\u043D\u043E \u0443\u0443.",
393
+ unavailable: "eID \u04AF\u0439\u043B\u0447\u0438\u043B\u0433\u044D\u044D\u043D\u0434 \u0445\u043E\u043B\u0431\u043E\u0433\u0434\u043E\u0436 \u0447\u0430\u0434\u0441\u0430\u043D\u0433\u04AF\u0439. \u0422\u04AF\u0440 \u0445\u04AF\u043B\u044D\u044D\u0433\u044D\u044D\u0434 \u0434\u0430\u0445\u0438\u043D \u043E\u0440\u043E\u043B\u0434\u043E\u043D\u043E \u0443\u0443.",
394
+ callbackTitle: "\u0423\u0442\u0441\u0430\u043D \u0434\u044D\u044D\u0440\u0445 \u0445\u04E9\u0442\u0447\u04E9\u04E9\u0440 \u04AF\u0440\u0433\u044D\u043B\u0436\u0438\u043B\u043D\u044D",
395
+ callbackText: "\u0411\u0430\u0442\u0430\u043B\u0433\u0430\u0430\u0436\u0443\u0443\u043B\u0430\u043B\u0442 \u0430\u043C\u0436\u0438\u043B\u0442\u0442\u0430\u0439. \u0410\u043F\u043F\u0430\u0430\u0441 \u043D\u044D\u044D\u0433\u0434\u0441\u044D\u043D \u0445\u04E9\u0442\u0447\u0438\u0439\u043D \u0446\u043E\u043D\u0445\u043E\u043D\u0434 \u043D\u044D\u0432\u0442\u0440\u044D\u043B\u0442 \u04AF\u0440\u0433\u044D\u043B\u0436\u0438\u043B\u043D\u044D.",
396
+ retry: "\u0414\u0430\u0445\u0438\u043D \u043E\u0440\u043E\u043B\u0434\u043E\u0445",
397
+ success: "\u0410\u043C\u0436\u0438\u043B\u0442\u0442\u0430\u0439 \u043D\u044D\u0432\u0442\u044D\u0440\u043B\u044D\u044D",
398
+ sent: (vc) => `\u041C\u044D\u0434\u044D\u0433\u0434\u044D\u043B \u0438\u043B\u0433\u044D\u044D\u043B\u044D\u044D. \u0423\u0442\u0441\u0430\u043D \u0434\u044D\u044D\u0440\u0445 \u043A\u043E\u0434 ${vc.split("").join(" ")}`,
399
+ minute: "1 \u043C\u0438\u043D\u0443\u0442 \u04AF\u043B\u0434\u043B\u044D\u044D"
400
+ },
401
+ en: {
402
+ button: "Log in with eID",
403
+ title: "Log in with eID",
404
+ close: "Close",
405
+ loading: "Loading",
406
+ qrAlt: "Login QR code \u2014 scan it with the eID Mongolia app on your phone",
407
+ steps: ["Open the eID Mongolia app on your phone", "Scan the QR code", "Enter your PIN1"],
408
+ code: "Code on your phone:",
409
+ or: "or",
410
+ idLabel: "Registration number",
411
+ idHint: "A notification will be sent to your phone. The 12-digit civil ID also works.",
412
+ idEmpty: "Enter your registration number",
413
+ idLatin: "Use Cyrillic letters: \u0423\u041112345678",
414
+ idBad: "Registration number is 2 letters and 8 digits: \u0423\u041112345678",
415
+ push: "Send notification",
416
+ pushing: "Sending",
417
+ rateLimited: "Too many attempts. Please wait and try again",
418
+ pushFailed: "Could not send the notification. Please try again",
419
+ waitText: "If the code on your phone matches, enter PIN1. Otherwise decline.",
420
+ waiting: "Waiting",
421
+ back: "Back",
422
+ left: "Time left",
423
+ stale: "QR code expired",
424
+ refresh: "Refresh",
425
+ offline: "Connection lost. Check your internet \u2014 reconnecting.",
426
+ expiredTitle: "Login expired",
427
+ refusedTitle: "Login declined",
428
+ failedTitle: "Login failed",
429
+ failedText: "Verification failed. Please try again.",
430
+ unavailable: "Could not reach the eID service. Please try again shortly.",
431
+ callbackTitle: "Continue in your phone's browser",
432
+ callbackText: "Verified. Login continues in the browser window the app opened.",
433
+ retry: "Try again",
434
+ success: "Logged in",
435
+ sent: (vc) => `Notification sent. Code on your phone ${vc.split("").join(" ")}`,
436
+ minute: "1 minute left"
437
+ }
438
+ };
439
+ var CSS_BASE = `
440
+ :host { display: inline-block;
441
+ --eid-bg: hsl(0 0% 100%); --eid-bg-subtle: hsl(210 40% 98%); --eid-bg-muted: hsl(210 40% 96%);
442
+ --eid-fg: hsl(222 47% 11%); --eid-fg-muted: hsl(215 19% 35%); --eid-fg-subtle: hsl(215 16% 45%);
443
+ --eid-border: hsl(214 32% 91%); --eid-border-strong: hsl(213 27% 84%);
444
+ --eid-accent: oklch(0.534 0.2 259); --eid-accent-fg: #fff; --eid-accent-subtle: oklch(0.97 0.03 259);
445
+ --eid-accent-subtle-fg: oklch(0.474 0.19 259); --eid-ring: oklch(0.604 0.2 259);
446
+ --eid-warning-bg: hsl(48 100% 96%); --eid-warning-border: hsl(45 95% 78%); --eid-warning-fg: hsl(23 75% 33%);
447
+ --eid-danger-fg: hsl(0 74% 42%); --eid-radius: 6px; --eid-radius-lg: 8px; font-family: inherit; color-scheme: light; }
448
+ button, input { font-family: inherit; }
449
+ `;
450
+ var DARK_CSS = `:host { color-scheme: dark;
451
+ --eid-bg: hsl(229 50% 6%); --eid-bg-subtle: hsl(222 47% 9%); --eid-bg-muted: hsl(217 33% 13%);
452
+ --eid-fg: hsl(210 40% 98%); --eid-fg-muted: hsl(213 27% 84%); --eid-fg-subtle: hsl(215 20% 65%);
453
+ --eid-border: hsl(217 33% 17%); --eid-border-strong: hsl(215 25% 27%);
454
+ --eid-accent: oklch(0.64 0.15 259); --eid-accent-fg: hsl(229 50% 6%); --eid-accent-subtle: oklch(0.24 0.06 259);
455
+ --eid-accent-subtle-fg: oklch(0.82 0.1 259); --eid-ring: oklch(0.68 0.15 259);
456
+ --eid-warning-bg: hsl(20 60% 10%); --eid-warning-border: hsl(22 70% 26%); --eid-warning-fg: hsl(40 92% 65%);
457
+ --eid-danger-fg: hsl(0 91% 71%); }
458
+ `;
459
+ var CSS_REST = `
460
+ *, *::before, *::after { box-sizing: border-box; }
461
+ [hidden] { display: none !important; }
462
+ h2, p, ol { margin: 0; }
463
+ :focus-visible { outline: 2px solid var(--eid-ring); outline-offset: 2px; }
464
+ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
465
+ .btn { display: inline-flex; width: 100%; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 0 20px;
466
+ border-radius: var(--eid-radius); font-family: inherit; font-weight: 500; font-size: 1rem; line-height: 1.25; text-decoration: none; border: 1px solid transparent; cursor: pointer;
467
+ transition: background-color 160ms cubic-bezier(0,0,0.2,1); }
468
+ .btn:disabled { opacity: 0.6; cursor: progress; }
469
+ .btn-primary { background: var(--eid-accent); color: var(--eid-accent-fg); }
470
+ .btn-primary:hover { background: color-mix(in oklab, var(--eid-accent) 88%, black); }
471
+ .btn-outline { background: var(--eid-bg); color: var(--eid-fg); border-color: var(--eid-border-strong); }
472
+ .btn-outline:hover { background: var(--eid-bg-muted); }
473
+ .btn-sm { width: auto; min-height: 36px; padding: 0 14px; font-size: 0.8125rem; }
474
+ .trigger { width: auto; }
475
+ .trigger img { width: 20px; height: 20px; border-radius: 4px; }
476
+ .backdrop { position: fixed; inset: 0; z-index: 2147483000; background: hsl(222 47% 11% / 0.5); display: flex; align-items: center;
477
+ justify-content: center; padding: 16px; overflow-y: auto; }
478
+ .dialog { position: relative; width: 100%; max-width: 26rem; max-height: calc(100dvh - 32px); overflow-y: auto; background: var(--eid-bg);
479
+ color: var(--eid-fg); border: 1px solid var(--eid-border); border-radius: var(--eid-radius-lg); padding: 24px; font-size: 0.875rem; line-height: 1.5rem; }
480
+ @media (max-width: 639px) { .dialog { padding: 16px; } }
481
+ .head { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; }
482
+ .head img { width: 28px; height: 28px; border-radius: var(--eid-radius); }
483
+ .head h2 { flex: 1; font-size: 1.125rem; line-height: 1.75rem; font-weight: 600; }
484
+ .x { width: 36px; height: 36px; border: 0; border-radius: var(--eid-radius); background: transparent; color: var(--eid-fg-muted); cursor: pointer; font-size: 1.25rem; line-height: 1; }
485
+ .x:hover { background: var(--eid-bg-muted); color: var(--eid-fg); }
486
+ .qr { position: relative; width: 256px; max-width: 100%; aspect-ratio: 1; margin: 0 auto; border: 1px solid var(--eid-border);
487
+ border-radius: var(--eid-radius-lg); background: #fff; overflow: hidden; }
488
+ .qr svg { display: block; width: 100%; height: 100%; }
489
+ .qr.stale svg { opacity: 0.12; }
490
+ .qr-stale { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
491
+ color: hsl(222 47% 11%); font-weight: 500; }
492
+ .qr-vc { margin-top: 8px; text-align: center; font-size: 0.8125rem; color: var(--eid-fg-subtle); }
493
+ .mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-variant-numeric: tabular-nums; letter-spacing: 0.08em; color: var(--eid-fg-muted); }
494
+ .steps { margin-top: 16px; padding: 0; list-style: none; counter-reset: st; display: grid; gap: 8px; }
495
+ .steps li { counter-increment: st; display: flex; align-items: center; gap: 12px; }
496
+ .steps li::before { content: counter(st); flex: none; width: 24px; height: 24px; border-radius: 9999px; background: var(--eid-accent-subtle);
497
+ color: var(--eid-accent-subtle-fg); display: flex; align-items: center; justify-content: center; font-size: 0.75rem; font-weight: 600; }
498
+ .or { display: flex; align-items: center; gap: 12px; margin: 24px 0; color: var(--eid-fg-subtle); font-size: 0.8125rem; }
499
+ .or::before, .or::after { content: ""; flex: 1; height: 1px; background: var(--eid-border); }
500
+ .field { display: grid; gap: 8px; }
501
+ .field label { font-weight: 500; }
502
+ .field input { width: 100%; height: 44px; padding: 0 12px; border: 1px solid var(--eid-border-strong); border-radius: var(--eid-radius);
503
+ background: var(--eid-bg); color: var(--eid-fg); font-family: inherit; font-size: 1rem; line-height: 1.5rem; letter-spacing: 0.02em; text-transform: uppercase; }
504
+ .field input::placeholder { color: var(--eid-fg-subtle); text-transform: none; }
505
+ .field input[aria-invalid="true"] { border-color: var(--eid-danger-fg); }
506
+ .hint { font-size: 0.8125rem; color: var(--eid-fg-subtle); }
507
+ .err { font-size: 0.8125rem; color: var(--eid-danger-fg); font-weight: 500; }
508
+ .push { margin-top: 16px; }
509
+ .center { text-align: center; }
510
+ .vc { font: 600 2.25rem/2.5rem ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: 0.16em; padding-left: 0.16em; }
511
+ .vc:focus, h2:focus { outline: none; }
512
+ .text { margin-top: 12px; color: var(--eid-fg-muted); }
513
+ .pending { margin-top: 16px; display: inline-flex; align-items: center; gap: 8px; color: var(--eid-fg-muted); }
514
+ .end .btn, .center .btn { margin-top: 24px; }
515
+ .spinner { width: 16px; height: 16px; flex: none; border: 2px solid currentColor; border-right-color: transparent; border-radius: 9999px; animation: spin 0.8s linear infinite; }
516
+ @keyframes spin { to { transform: rotate(360deg); } }
517
+ .netwarn { margin-top: 16px; padding: 8px 12px; border: 1px solid var(--eid-warning-border); border-radius: var(--eid-radius); background: var(--eid-warning-bg);
518
+ color: var(--eid-warning-fg); font-size: 0.8125rem; }
519
+ .meta { margin-top: 16px; font-size: 0.8125rem; color: var(--eid-fg-subtle); }
520
+ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition: none !important; }
521
+ .spinner { animation: none; border-right-color: currentColor; opacity: 0.6; } }
522
+ `;
523
+ var CSS = CSS_BASE + CSS_REST;
524
+ function resolveEidTheme(theme, doc = document) {
525
+ if (theme === "light" || theme === "dark") return theme;
526
+ const html = doc.documentElement;
527
+ const dt = html?.getAttribute("data-theme");
528
+ if (dt === "dark" || dt === "light") return dt;
529
+ if (html?.classList.contains("dark")) return "dark";
530
+ if (html?.classList.contains("light")) return "light";
531
+ const mq = doc.defaultView?.matchMedia?.("(prefers-color-scheme: dark)");
532
+ return mq?.matches ? "dark" : "light";
533
+ }
534
+ var ID_RE = /^([А-ЯЁӨҮ]{2}[0-9]{8}|[0-9]{8,14})$/;
535
+ var FOCUSABLE = 'button:not([disabled]), input:not([disabled]), a[href], [tabindex]:not([tabindex="-1"])';
536
+ function el(tag, attrs = {}, text) {
537
+ const e = document.createElement(tag);
538
+ for (const [k, v] of Object.entries(attrs)) e.setAttribute(k, v);
539
+ if (text != null) e.textContent = text;
540
+ return e;
541
+ }
542
+ var Base = typeof HTMLElement === "undefined" ? class {
543
+ } : HTMLElement;
544
+ var EidLoginButton = class extends Base {
545
+ static observedAttributes = ["lang", "theme"];
546
+ /** Тест/дотоод: гар утас эсэхийг дарж бичих. */
547
+ isMobile = () => isMobileUserAgent();
548
+ /** Тест/дотоод: шилжилт (location.assign). */
549
+ navigate = (url) => location.assign(url);
550
+ root;
551
+ trigger;
552
+ backdrop = null;
553
+ body;
554
+ live;
555
+ timer = 0;
556
+ tick = 0;
557
+ left = -1;
558
+ fails = 0;
559
+ gen = 0;
560
+ // цонх нээх бүрд нэмэгдэнэ — хуучин fetch-ийн хариуг үл тооно
561
+ lastFocus = null;
562
+ darkStyle;
563
+ themeObs = null;
564
+ mq = null;
565
+ onScheme = () => this.applyTheme();
566
+ get t() {
567
+ return T[this.getAttribute("lang") === "en" ? "en" : "mn"];
568
+ }
569
+ attr(name, def = "") {
570
+ return this.getAttribute(name) ?? def;
571
+ }
572
+ connectedCallback() {
573
+ if (!this.root) {
574
+ this.root = this.attachShadow({ mode: "open" });
575
+ const style = el("style");
576
+ style.textContent = CSS;
577
+ this.darkStyle = el("style", { "data-eid-theme": "dark" });
578
+ this.trigger = el("button", { type: "button", class: "btn btn-outline trigger", part: "button", "aria-haspopup": "dialog" });
579
+ this.trigger.append(el("img", { src: EID_LOGO_DATA_URI, alt: "", width: "20", height: "20" }), el("span", {}, this.t.button));
580
+ this.trigger.addEventListener("click", () => this.start());
581
+ this.root.append(style, this.darkStyle, this.trigger);
582
+ }
583
+ this.watchTheme();
584
+ this.applyTheme();
585
+ }
586
+ attributeChangedCallback(name) {
587
+ if (name === "theme") {
588
+ if (this.root) this.applyTheme();
589
+ return;
590
+ }
591
+ const label = this.trigger?.querySelector("span");
592
+ if (label) label.textContent = this.t.button;
593
+ }
594
+ disconnectedCallback() {
595
+ this.close();
596
+ this.themeObs?.disconnect();
597
+ this.themeObs = null;
598
+ this.mq?.removeEventListener?.("change", this.onScheme);
599
+ this.mq = null;
600
+ }
601
+ /** Одоогийн бодит схем (`theme` + auto үед хуудас/OS). */
602
+ get scheme() {
603
+ return resolveEidTheme(this.getAttribute("theme"));
604
+ }
605
+ applyTheme() {
606
+ const css = this.scheme === "dark" ? DARK_CSS : "";
607
+ if (this.darkStyle.textContent !== css) this.darkStyle.textContent = css;
608
+ }
609
+ /** auto үед хуудасны html[data-theme]/class ба OS-ийн схемийн өөрчлөлтийг дагана. */
610
+ watchTheme() {
611
+ if (!this.themeObs && typeof MutationObserver !== "undefined" && document.documentElement) {
612
+ this.themeObs = new MutationObserver(this.onScheme);
613
+ this.themeObs.observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme", "class"] });
614
+ }
615
+ if (!this.mq && typeof matchMedia === "function") {
616
+ this.mq = matchMedia("(prefers-color-scheme: dark)");
617
+ this.mq.addEventListener?.("change", this.onScheme);
618
+ }
619
+ }
620
+ /** Товчны үйлдэл (программаар ч дуудаж болно). */
621
+ start() {
622
+ const mode = this.attr("mode", "auto");
623
+ if (mode === "app" || mode === "auto" && this.isMobile()) {
624
+ const u = new URL(this.attr("start-url"), location.href);
625
+ u.searchParams.set("mode", "web2app");
626
+ u.searchParams.set("lang", this.attr("lang") === "en" ? "en" : "mn");
627
+ this.navigate(u.toString());
628
+ return;
629
+ }
630
+ this.open();
631
+ }
632
+ open() {
633
+ this.close();
634
+ const gen = ++this.gen;
635
+ this.lastFocus = this.getRootNode().activeElement ?? document.activeElement;
636
+ const bd = el("div", { class: "backdrop", part: "backdrop" });
637
+ const dlg = el("div", { class: "dialog", role: "dialog", "aria-modal": "true", "aria-labelledby": "eid-title", part: "dialog" });
638
+ const head = el("div", { class: "head" });
639
+ const x = el("button", { type: "button", class: "x", "aria-label": this.t.close }, "\xD7");
640
+ x.addEventListener("click", () => this.close());
641
+ head.append(el("img", { src: EID_LOGO_DATA_URI, alt: "", width: "28", height: "28" }), el("h2", { id: "eid-title" }, this.t.title), x);
642
+ this.body = el("div");
643
+ this.live = el("p", { class: "sr-only", "aria-live": "polite" });
644
+ dlg.append(head, this.body, this.live);
645
+ bd.append(dlg);
646
+ bd.addEventListener("mousedown", (e) => {
647
+ if (e.target === bd) this.close();
648
+ });
649
+ bd.addEventListener("keydown", (e) => this.onKey(e));
650
+ this.root.append(bd);
651
+ this.backdrop = bd;
652
+ this.showLoading();
653
+ x.focus();
654
+ void this.begin(gen, { mode: "qr" });
655
+ }
656
+ /** Цонхыг хааж poll-ийг зогсооно. */
657
+ close() {
658
+ this.gen++;
659
+ clearTimeout(this.timer);
660
+ clearInterval(this.tick);
661
+ if (!this.backdrop) return;
662
+ this.backdrop.remove();
663
+ this.backdrop = null;
664
+ this.lastFocus?.focus?.();
665
+ if (!this.lastFocus) this.trigger.focus();
666
+ }
667
+ onKey(e) {
668
+ if (e.key === "Escape") {
669
+ e.preventDefault();
670
+ this.close();
671
+ return;
672
+ }
673
+ if (e.key !== "Tab" || !this.backdrop) return;
674
+ const items = Array.from(this.backdrop.querySelectorAll(FOCUSABLE)).filter((n) => !n.closest("[hidden]"));
675
+ if (items.length === 0) return;
676
+ const first = items[0];
677
+ const last = items[items.length - 1];
678
+ const active = this.root.activeElement;
679
+ if (e.shiftKey && active === first) {
680
+ e.preventDefault();
681
+ last.focus();
682
+ } else if (!e.shiftKey && active === last) {
683
+ e.preventDefault();
684
+ first.focus();
685
+ }
686
+ }
687
+ say(text) {
688
+ this.live.textContent = text;
689
+ }
690
+ view(...nodes) {
691
+ this.body.replaceChildren(...nodes);
692
+ }
693
+ showLoading() {
694
+ const p = el("p", { class: "pending", role: "status" });
695
+ p.append(el("span", { class: "spinner", "aria-hidden": "true" }), el("span", {}, this.t.loading));
696
+ const c = el("div", { class: "center" });
697
+ c.append(p);
698
+ this.view(c);
699
+ }
700
+ async begin(gen, body) {
701
+ let r;
702
+ try {
703
+ r = await fetch(this.attr("start-url"), {
704
+ method: "POST",
705
+ credentials: "same-origin",
706
+ cache: "no-store",
707
+ headers: { "Content-Type": "application/json" },
708
+ body: JSON.stringify({ ...body, lang: this.attr("lang") === "en" ? "en" : "mn" })
709
+ });
710
+ } catch {
711
+ if (gen === this.gen && body.mode === "qr") this.end("unavailable");
712
+ return null;
713
+ }
714
+ if (gen !== this.gen) return null;
715
+ if (body.mode === "push") return r;
716
+ if (!r.ok) {
717
+ this.end("unavailable");
718
+ return null;
719
+ }
720
+ const s = await r.json();
721
+ this.showQr(s);
722
+ this.startTimer(s.expiresIn ?? -1);
723
+ this.schedule(gen, 1e3);
724
+ return r;
725
+ }
726
+ qrBox;
727
+ qrStale;
728
+ netwarn;
729
+ drawQr(link) {
730
+ const q = encodeQr(link);
731
+ const n = q.size + 8;
732
+ const NS = "http://www.w3.org/2000/svg";
733
+ const svg = document.createElementNS(NS, "svg");
734
+ svg.setAttribute("viewBox", `0 0 ${n} ${n}`);
735
+ svg.setAttribute("role", "img");
736
+ svg.setAttribute("aria-label", this.t.qrAlt);
737
+ svg.setAttribute("shape-rendering", "crispEdges");
738
+ const path = document.createElementNS(NS, "path");
739
+ path.setAttribute("d", qrSvgPath(q));
740
+ path.setAttribute("fill", "#000");
741
+ svg.append(path);
742
+ this.qrBox.querySelector("svg")?.remove();
743
+ this.qrBox.prepend(svg);
744
+ }
745
+ showQr(s) {
746
+ const t = this.t;
747
+ this.qrBox = el("div", { class: "qr" });
748
+ this.qrStale = el("div", { class: "qr-stale", hidden: "" });
749
+ const refresh = el("button", { type: "button", class: "btn btn-outline btn-sm" }, t.refresh);
750
+ refresh.addEventListener("click", () => this.schedule(this.gen, 0));
751
+ this.qrStale.append(el("p", {}, t.stale), refresh);
752
+ this.qrBox.append(this.qrStale);
753
+ if (s.qr) this.drawQr(s.qr);
754
+ const nodes = [this.qrBox];
755
+ if (s.vc) {
756
+ const vc = el("p", { class: "qr-vc" }, t.code + " ");
757
+ vc.append(el("span", { class: "mono" }, s.vc));
758
+ nodes.push(vc);
759
+ }
760
+ const steps = el("ol", { class: "steps" });
761
+ for (const st of t.steps) steps.append(el("li", {}, st));
762
+ nodes.push(steps, el("div", { class: "or", role: "separator", "aria-label": t.or }, t.or), this.pushForm());
763
+ this.netwarn = el("p", { class: "netwarn", role: "status", hidden: "" }, t.offline);
764
+ nodes.push(this.netwarn, this.meta());
765
+ this.view(...nodes);
766
+ }
767
+ leftEl = null;
768
+ meta() {
769
+ const p = el("p", { class: "meta" }, this.t.left + " ");
770
+ this.leftEl = el("span", { class: "mono", role: "timer", "aria-live": "off" }, "--:--");
771
+ p.append(this.leftEl);
772
+ if (this.left < 0) p.hidden = true;
773
+ return p;
774
+ }
775
+ startTimer(seconds) {
776
+ clearInterval(this.tick);
777
+ this.left = seconds;
778
+ const render = () => {
779
+ if (!this.leftEl || this.left < 0) return;
780
+ this.leftEl.parentElement.hidden = false;
781
+ const m = Math.floor(this.left / 60);
782
+ const s = this.left % 60;
783
+ this.leftEl.textContent = `${m < 10 ? "0" : ""}${m}:${s < 10 ? "0" : ""}${s}`;
784
+ if (this.left === 60) this.say(this.t.minute);
785
+ };
786
+ render();
787
+ if (seconds < 0) return;
788
+ this.tick = setInterval(() => {
789
+ this.left -= 1;
790
+ render();
791
+ if (this.left <= 0) this.end("expired");
792
+ }, 1e3);
793
+ }
794
+ pushForm() {
795
+ const t = this.t;
796
+ const form = el("form", { novalidate: "" });
797
+ const field = el("div", { class: "field" });
798
+ const input = el("input", {
799
+ id: "eid-id",
800
+ name: "idCode",
801
+ type: "text",
802
+ autocapitalize: "characters",
803
+ autocomplete: "off",
804
+ autocorrect: "off",
805
+ spellcheck: "false",
806
+ maxlength: "14",
807
+ placeholder: "\u0423\u041112345678",
808
+ "aria-describedby": "eid-id-hint eid-id-err"
809
+ });
810
+ const err = el("p", { class: "err", id: "eid-id-err", hidden: "" });
811
+ field.append(el("label", { for: "eid-id" }, t.idLabel), input, el("p", { class: "hint", id: "eid-id-hint" }, t.idHint), err);
812
+ const btn = el("button", { type: "submit", class: "btn btn-primary push" });
813
+ const spin = el("span", { class: "spinner", hidden: "", "aria-hidden": "true" });
814
+ const label = el("span", {}, t.push);
815
+ btn.append(spin, label);
816
+ form.append(field, btn);
817
+ const check = () => {
818
+ const v = input.value.replace(/\s+/g, "").toUpperCase();
819
+ if (v === "") return t.idEmpty;
820
+ if (ID_RE.test(v)) return "";
821
+ if (/^[A-Z]{2}[0-9]{8}$/.test(v)) return t.idLatin;
822
+ return t.idBad;
823
+ };
824
+ const setErr = (msg) => {
825
+ err.textContent = msg;
826
+ err.hidden = !msg;
827
+ if (msg) input.setAttribute("aria-invalid", "true");
828
+ else input.removeAttribute("aria-invalid");
829
+ };
830
+ const busy = (on) => {
831
+ btn.disabled = on;
832
+ spin.hidden = !on;
833
+ label.textContent = on ? t.pushing : t.push;
834
+ };
835
+ form.addEventListener("submit", (e) => {
836
+ e.preventDefault();
837
+ if (btn.disabled) return;
838
+ const msg = check();
839
+ setErr(msg);
840
+ if (msg) {
841
+ input.focus();
842
+ return;
843
+ }
844
+ busy(true);
845
+ const gen = this.gen;
846
+ void this.begin(gen, { mode: "push", idCode: input.value.replace(/\s+/g, "").toUpperCase() }).then(async (r) => {
847
+ if (gen !== this.gen) return;
848
+ busy(false);
849
+ if (!r) return setErr(t.pushFailed);
850
+ const b = await r.json().catch(() => ({}));
851
+ if (r.ok && b.vc) return this.showWait(b);
852
+ if (r.status === 429) return setErr(t.rateLimited);
853
+ if (r.status === 400) return setErr(t.idBad);
854
+ setErr(t.pushFailed);
855
+ });
856
+ });
857
+ return form;
858
+ }
859
+ showWait(s) {
860
+ const t = this.t;
861
+ const c = el("div", { class: "center" });
862
+ c.append(el("h2", { class: "sr-only" }, t.waiting));
863
+ const vc = el("p", { class: "vc", tabindex: "-1", "aria-describedby": "eid-wait" }, s.vc ?? "");
864
+ const pending = el("p", { class: "pending" });
865
+ pending.append(el("span", { class: "spinner", "aria-hidden": "true" }), el("span", {}, t.waiting));
866
+ const back = el("button", { type: "button", class: "btn btn-outline" }, t.back);
867
+ back.addEventListener("click", () => this.open());
868
+ this.netwarn = el("p", { class: "netwarn", role: "status", hidden: "" }, t.offline);
869
+ c.append(vc, el("p", { class: "text", id: "eid-wait" }, t.waitText), pending, back, this.netwarn, this.meta());
870
+ this.view(c);
871
+ this.startTimer(s.expiresIn ?? -1);
872
+ vc.focus();
873
+ this.say(t.sent(s.vc ?? ""));
874
+ }
875
+ schedule(gen, ms) {
876
+ clearTimeout(this.timer);
877
+ this.timer = setTimeout(() => void this.poll(gen), ms);
878
+ }
879
+ async poll(gen) {
880
+ if (gen !== this.gen) return;
881
+ let s;
882
+ try {
883
+ const r = await fetch(this.attr("status-url"), { credentials: "same-origin", cache: "no-store" });
884
+ if (!r.ok) throw new Error(`status ${r.status}`);
885
+ s = await r.json();
886
+ } catch {
887
+ if (gen !== this.gen) return;
888
+ this.fails++;
889
+ if (this.fails >= 3) {
890
+ this.netwarn.hidden = false;
891
+ this.qrBox?.classList.add("stale");
892
+ if (this.qrStale) this.qrStale.hidden = false;
893
+ }
894
+ this.schedule(gen, 2e3);
895
+ return;
896
+ }
897
+ if (gen !== this.gen) return;
898
+ this.fails = 0;
899
+ this.netwarn.hidden = true;
900
+ this.qrBox?.classList.remove("stale");
901
+ if (this.qrStale) this.qrStale.hidden = true;
902
+ switch (s.state) {
903
+ case "PENDING":
904
+ if (s.qr && this.qrBox?.isConnected) this.drawQr(s.qr);
905
+ if (typeof s.expiresIn === "number" && Math.abs(s.expiresIn - this.left) > 2) this.startTimer(s.expiresIn);
906
+ this.schedule(gen, 1e3);
907
+ return;
908
+ case "OK":
909
+ return this.succeed(s);
910
+ case "WAIT_CALLBACK":
911
+ return this.end("callback");
912
+ case "EXPIRED":
913
+ return this.end("expired");
914
+ default:
915
+ return this.end(s.error && s.error.startsWith("USER_REFUSED") ? "refused" : s.error === "TIMEOUT" ? "expired" : "failed", s.error);
916
+ }
917
+ }
918
+ succeed(s) {
919
+ clearInterval(this.tick);
920
+ const c = el("div", { class: "center" });
921
+ const h = el("h2", { tabindex: "-1" }, this.t.success);
922
+ c.append(h);
923
+ this.view(c);
924
+ h.focus();
925
+ const ev = new CustomEvent("eid-login-success", { detail: s, bubbles: true, composed: true, cancelable: true });
926
+ const go = this.dispatchEvent(ev);
927
+ const to = s.redirect ?? this.getAttribute("success-url");
928
+ if (go && to) this.navigate(to);
929
+ }
930
+ end(kind, error) {
931
+ clearTimeout(this.timer);
932
+ clearInterval(this.tick);
933
+ this.gen++;
934
+ const t = this.t;
935
+ const titles = { expired: t.expiredTitle, refused: t.refusedTitle, failed: t.failedTitle, unavailable: t.failedTitle, callback: t.callbackTitle };
936
+ const c = el("div", { class: "end", role: "alert" });
937
+ const h = el("h2", { tabindex: "-1" }, titles[kind]);
938
+ c.append(h);
939
+ if (kind === "failed") c.append(el("p", { class: "text" }, t.failedText));
940
+ if (kind === "unavailable") c.append(el("p", { class: "text" }, t.unavailable));
941
+ if (kind === "callback") c.append(el("p", { class: "text" }, t.callbackText));
942
+ if (kind !== "callback") {
943
+ const retry = el("button", { type: "button", class: "btn btn-primary" }, t.retry);
944
+ retry.addEventListener("click", () => this.open());
945
+ c.append(retry);
946
+ this.dispatchEvent(new CustomEvent("eid-login-error", { detail: { error: error ?? kind.toUpperCase() }, bubbles: true, composed: true }));
947
+ }
948
+ this.view(c);
949
+ h.focus();
950
+ }
951
+ };
952
+ function defineEidLoginButton(tag = "eid-login-button") {
953
+ if (typeof customElements !== "undefined" && !customElements.get(tag)) customElements.define(tag, EidLoginButton);
954
+ }
955
+ function mountEidLoginButton(target, opts) {
956
+ defineEidLoginButton();
957
+ const b = document.createElement("eid-login-button");
958
+ b.setAttribute("start-url", opts.startUrl);
959
+ b.setAttribute("status-url", opts.statusUrl);
960
+ b.setAttribute("lang", opts.lang ?? "mn");
961
+ if (opts.mode) b.setAttribute("mode", opts.mode);
962
+ if (opts.theme) b.setAttribute("theme", opts.theme);
963
+ if (opts.successUrl) b.setAttribute("success-url", opts.successUrl);
964
+ if (opts.onSuccess) b.addEventListener("eid-login-success", (e) => opts.onSuccess(e.detail));
965
+ if (opts.onError) b.addEventListener("eid-login-error", (e) => opts.onError(e.detail.error));
966
+ target.append(b);
967
+ return b;
968
+ }
969
+ defineEidLoginButton();
970
+ export {
971
+ EidLoginButton,
972
+ defineEidLoginButton,
973
+ mountEidLoginButton,
974
+ resolveEidTheme
975
+ };