@bitgo-beta/key-card 0.0.1-beta.1911 → 0.0.1-beta.1912

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.
@@ -0,0 +1,16 @@
1
+ import { KeycardEntry } from './parseKeycard';
2
+ /**
3
+ * Extracts keycard entries from a PDF file (browser only).
4
+ *
5
+ * Before calling this function, configure the pdfjs worker:
6
+ * import { GlobalWorkerOptions } from 'pdfjs-dist';
7
+ * GlobalWorkerOptions.workerSrc = '<url to pdf.worker.min.js>';
8
+ *
9
+ * pdfjs-dist is loaded via dynamic import so this module can be safely
10
+ * imported in Node.js environments without triggering browser-only globals.
11
+ */
12
+ export declare function extractKeycardEntriesFromPDF(file: File): Promise<{
13
+ lines: string[];
14
+ entries: KeycardEntry[];
15
+ }>;
16
+ //# sourceMappingURL=extractKeycardFromPDF.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractKeycardFromPDF.d.ts","sourceRoot":"","sources":["../../src/extractKeycardFromPDF.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,YAAY,EAAsC,MAAM,gBAAgB,CAAC;AAE1G;;;;;;;;;GASG;AACH,wBAAsB,4BAA4B,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;IACtE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB,CAAC,CAkCD"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.extractKeycardEntriesFromPDF = extractKeycardEntriesFromPDF;
37
+ const parseKeycard_1 = require("./parseKeycard");
38
+ /**
39
+ * Extracts keycard entries from a PDF file (browser only).
40
+ *
41
+ * Before calling this function, configure the pdfjs worker:
42
+ * import { GlobalWorkerOptions } from 'pdfjs-dist';
43
+ * GlobalWorkerOptions.workerSrc = '<url to pdf.worker.min.js>';
44
+ *
45
+ * pdfjs-dist is loaded via dynamic import so this module can be safely
46
+ * imported in Node.js environments without triggering browser-only globals.
47
+ */
48
+ async function extractKeycardEntriesFromPDF(file) {
49
+ const pdfjsLib = await Promise.resolve().then(() => __importStar(require('pdfjs-dist')));
50
+ const arrayBuffer = await file.arrayBuffer();
51
+ const loadingTask = pdfjsLib.getDocument({ data: arrayBuffer });
52
+ const pdfDocument = await loadingTask.promise;
53
+ const nodes = [];
54
+ for (let pageNumber = 1; pageNumber <= pdfDocument.numPages; pageNumber++) {
55
+ const page = await pdfDocument.getPage(pageNumber);
56
+ const textContent = await page.getTextContent();
57
+ for (const item of textContent.items) {
58
+ if (!('str' in item) || !Array.isArray(item.transform)) {
59
+ continue;
60
+ }
61
+ const text = item.str.replace(/\s+/g, ' ').trim();
62
+ if (!text) {
63
+ continue;
64
+ }
65
+ const x = Number(item.transform[4] ?? 0);
66
+ const y = Number(item.transform[5] ?? 0);
67
+ const width = 'width' in item ? Number(item.width ?? 0) : 0;
68
+ nodes.push({ text, x, y, page: pageNumber, width });
69
+ }
70
+ }
71
+ const lines = (0, parseKeycard_1.buildLinesFromPDFNodes)(nodes);
72
+ return {
73
+ lines,
74
+ entries: (0, parseKeycard_1.parseKeycardFromLines)(lines),
75
+ };
76
+ }
77
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0cmFjdEtleWNhcmRGcm9tUERGLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2V4dHJhY3RLZXljYXJkRnJvbVBERi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQVlBLG9FQXFDQztBQWpERCxpREFBMEc7QUFFMUc7Ozs7Ozs7OztHQVNHO0FBQ0ksS0FBSyxVQUFVLDRCQUE0QixDQUFDLElBQVU7SUFJM0QsTUFBTSxRQUFRLEdBQUcsd0RBQWEsWUFBWSxHQUFDLENBQUM7SUFDNUMsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDN0MsTUFBTSxXQUFXLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQ2hFLE1BQU0sV0FBVyxHQUFHLE1BQU0sV0FBVyxDQUFDLE9BQU8sQ0FBQztJQUM5QyxNQUFNLEtBQUssR0FBa0IsRUFBRSxDQUFDO0lBRWhDLEtBQUssSUFBSSxVQUFVLEdBQUcsQ0FBQyxFQUFFLFVBQVUsSUFBSSxXQUFXLENBQUMsUUFBUSxFQUFFLFVBQVUsRUFBRSxFQUFFLENBQUM7UUFDMUUsTUFBTSxJQUFJLEdBQUcsTUFBTSxXQUFXLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ25ELE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBRWhELEtBQUssTUFBTSxJQUFJLElBQUksV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3JDLElBQUksQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZELFNBQVM7WUFDWCxDQUFDO1lBRUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2xELElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDVixTQUFTO1lBQ1gsQ0FBQztZQUVELE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ3pDLE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ3pDLE1BQU0sS0FBSyxHQUFHLE9BQU8sSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFNUQsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUN0RCxDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sS0FBSyxHQUFHLElBQUEscUNBQXNCLEVBQUMsS0FBSyxDQUFDLENBQUM7SUFDNUMsT0FBTztRQUNMLEtBQUs7UUFDTCxPQUFPLEVBQUUsSUFBQSxvQ0FBcUIsRUFBQyxLQUFLLENBQUM7S0FDdEMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBidWlsZExpbmVzRnJvbVBERk5vZGVzLCBLZXljYXJkRW50cnksIHBhcnNlS2V5Y2FyZEZyb21MaW5lcywgUERGVGV4dE5vZGUgfSBmcm9tICcuL3BhcnNlS2V5Y2FyZCc7XG5cbi8qKlxuICogRXh0cmFjdHMga2V5Y2FyZCBlbnRyaWVzIGZyb20gYSBQREYgZmlsZSAoYnJvd3NlciBvbmx5KS5cbiAqXG4gKiBCZWZvcmUgY2FsbGluZyB0aGlzIGZ1bmN0aW9uLCBjb25maWd1cmUgdGhlIHBkZmpzIHdvcmtlcjpcbiAqICAgaW1wb3J0IHsgR2xvYmFsV29ya2VyT3B0aW9ucyB9IGZyb20gJ3BkZmpzLWRpc3QnO1xuICogICBHbG9iYWxXb3JrZXJPcHRpb25zLndvcmtlclNyYyA9ICc8dXJsIHRvIHBkZi53b3JrZXIubWluLmpzPic7XG4gKlxuICogcGRmanMtZGlzdCBpcyBsb2FkZWQgdmlhIGR5bmFtaWMgaW1wb3J0IHNvIHRoaXMgbW9kdWxlIGNhbiBiZSBzYWZlbHlcbiAqIGltcG9ydGVkIGluIE5vZGUuanMgZW52aXJvbm1lbnRzIHdpdGhvdXQgdHJpZ2dlcmluZyBicm93c2VyLW9ubHkgZ2xvYmFscy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGV4dHJhY3RLZXljYXJkRW50cmllc0Zyb21QREYoZmlsZTogRmlsZSk6IFByb21pc2U8e1xuICBsaW5lczogc3RyaW5nW107XG4gIGVudHJpZXM6IEtleWNhcmRFbnRyeVtdO1xufT4ge1xuICBjb25zdCBwZGZqc0xpYiA9IGF3YWl0IGltcG9ydCgncGRmanMtZGlzdCcpO1xuICBjb25zdCBhcnJheUJ1ZmZlciA9IGF3YWl0IGZpbGUuYXJyYXlCdWZmZXIoKTtcbiAgY29uc3QgbG9hZGluZ1Rhc2sgPSBwZGZqc0xpYi5nZXREb2N1bWVudCh7IGRhdGE6IGFycmF5QnVmZmVyIH0pO1xuICBjb25zdCBwZGZEb2N1bWVudCA9IGF3YWl0IGxvYWRpbmdUYXNrLnByb21pc2U7XG4gIGNvbnN0IG5vZGVzOiBQREZUZXh0Tm9kZVtdID0gW107XG5cbiAgZm9yIChsZXQgcGFnZU51bWJlciA9IDE7IHBhZ2VOdW1iZXIgPD0gcGRmRG9jdW1lbnQubnVtUGFnZXM7IHBhZ2VOdW1iZXIrKykge1xuICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCBwZGZEb2N1bWVudC5nZXRQYWdlKHBhZ2VOdW1iZXIpO1xuICAgIGNvbnN0IHRleHRDb250ZW50ID0gYXdhaXQgcGFnZS5nZXRUZXh0Q29udGVudCgpO1xuXG4gICAgZm9yIChjb25zdCBpdGVtIG9mIHRleHRDb250ZW50Lml0ZW1zKSB7XG4gICAgICBpZiAoISgnc3RyJyBpbiBpdGVtKSB8fCAhQXJyYXkuaXNBcnJheShpdGVtLnRyYW5zZm9ybSkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRleHQgPSBpdGVtLnN0ci5yZXBsYWNlKC9cXHMrL2csICcgJykudHJpbSgpO1xuICAgICAgaWYgKCF0ZXh0KSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB4ID0gTnVtYmVyKGl0ZW0udHJhbnNmb3JtWzRdID8/IDApO1xuICAgICAgY29uc3QgeSA9IE51bWJlcihpdGVtLnRyYW5zZm9ybVs1XSA/PyAwKTtcbiAgICAgIGNvbnN0IHdpZHRoID0gJ3dpZHRoJyBpbiBpdGVtID8gTnVtYmVyKGl0ZW0ud2lkdGggPz8gMCkgOiAwO1xuXG4gICAgICBub2Rlcy5wdXNoKHsgdGV4dCwgeCwgeSwgcGFnZTogcGFnZU51bWJlciwgd2lkdGggfSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgbGluZXMgPSBidWlsZExpbmVzRnJvbVBERk5vZGVzKG5vZGVzKTtcbiAgcmV0dXJuIHtcbiAgICBsaW5lcyxcbiAgICBlbnRyaWVzOiBwYXJzZUtleWNhcmRGcm9tTGluZXMobGluZXMpLFxuICB9O1xufVxuIl19
@@ -1,7 +1,9 @@
1
1
  import { GenerateKeycardParams, GenerateLightningQrDataParams, GenerateQrDataBaseParams } from './types';
2
2
  export * from './drawKeycard';
3
+ export * from './extractKeycardFromPDF';
3
4
  export * from './faq';
4
5
  export * from './generateQrData';
6
+ export * from './parseKeycard';
5
7
  export * from './utils';
6
8
  export * from './types';
7
9
  export declare function generateKeycard(params: GenerateKeycardParams): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAEzG,cAAc,eAAe,CAAC;AAC9B,cAAc,OAAO,CAAC;AACtB,cAAc,kBAAkB,CAAC;AACjC,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AAExB,wBAAsB,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBlF;AAED,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,wBAAwB,GAAG,6BAA6B,GAC/D,OAAO,CAAC,IAAI,CAAC,CAMf"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAEzG,cAAc,eAAe,CAAC;AAC9B,cAAc,yBAAyB,CAAC;AACxC,cAAc,OAAO,CAAC;AACtB,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AAExB,wBAAsB,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBlF;AAED,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,wBAAwB,GAAG,6BAA6B,GAC/D,OAAO,CAAC,IAAI,CAAC,CAMf"}
package/dist/src/index.js CHANGED
@@ -21,8 +21,10 @@ const faq_1 = require("./faq");
21
21
  const drawKeycard_1 = require("./drawKeycard");
22
22
  const generateParamsForKeyCreation_1 = require("./generateParamsForKeyCreation");
23
23
  __exportStar(require("./drawKeycard"), exports);
24
+ __exportStar(require("./extractKeycardFromPDF"), exports);
24
25
  __exportStar(require("./faq"), exports);
25
26
  __exportStar(require("./generateQrData"), exports);
27
+ __exportStar(require("./parseKeycard"), exports);
26
28
  __exportStar(require("./utils"), exports);
27
29
  __exportStar(require("./types"), exports);
28
30
  async function generateKeycard(params) {
@@ -57,4 +59,4 @@ async function generateLightningKeycard(params) {
57
59
  const label = params.walletLabel || params.coin.fullName;
58
60
  keycard.save(`BitGo Keycard for ${label}.pdf`);
59
61
  }
60
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQVlBLDBDQXFCQztBQUVELDREQVFDO0FBM0NELHFEQUFxRjtBQUNyRiwrQkFBMEQ7QUFDMUQsK0NBQTRDO0FBQzVDLGlGQUE4RTtBQUc5RSxnREFBOEI7QUFDOUIsd0NBQXNCO0FBQ3RCLG1EQUFpQztBQUNqQywwQ0FBd0I7QUFDeEIsMENBQXdCO0FBRWpCLEtBQUssVUFBVSxlQUFlLENBQUMsTUFBNkI7SUFDakUsSUFBSSxrQkFBa0IsSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUNqQyxNQUFNLFNBQVMsR0FBRyxJQUFBLDBCQUFvQixFQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDN0QsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFBLDZDQUE0QixFQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzFELE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBQSx5QkFBVyxFQUFDLEVBQUUsR0FBRyxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDcEUsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLFdBQVcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQztRQUN6RCxPQUFPLENBQUMsSUFBSSxDQUFDLHFCQUFxQixLQUFLLE1BQU0sQ0FBQyxDQUFDO0lBQ2pELENBQUM7U0FBTSxJQUFJLE1BQU0sSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUM1QixNQUFNLFNBQVMsR0FBRyxJQUFBLGlCQUFXLEVBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNwRCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUEsb0NBQW1CLEVBQUMsTUFBTSxDQUFDLENBQUM7UUFDakQsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFBLHlCQUFXLEVBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUNwRSxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsV0FBVyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQ3pELE9BQU8sQ0FBQyxJQUFJLENBQUMscUJBQXFCLEtBQUssTUFBTSxDQUFDLENBQUM7SUFDakQsQ0FBQztTQUFNLElBQUksT0FBTyxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQzdCLE1BQU0sSUFBSSxHQUFHLElBQUEsMkRBQTRCLEVBQUMsTUFBTSxDQUFDLENBQUM7UUFDbEQsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFBLHlCQUFXLEVBQUMsSUFBSSxDQUFDLENBQUM7UUFDeEMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLFdBQVcsSUFBSSxNQUFNLENBQUMsS0FBSyxDQUFDO1FBQ2pELE9BQU8sQ0FBQyxJQUFJLENBQUMscUJBQXFCLEtBQUssTUFBTSxDQUFDLENBQUM7SUFDakQsQ0FBQztTQUFNLENBQUM7UUFDTixNQUFNLElBQUksS0FBSyxDQUFDLHVDQUF1QyxDQUFDLENBQUM7SUFDM0QsQ0FBQztBQUNILENBQUM7QUFFTSxLQUFLLFVBQVUsd0JBQXdCLENBQzVDLE1BQWdFO0lBRWhFLE1BQU0sU0FBUyxHQUFHLElBQUEsMEJBQW9CLEVBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM3RCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUEsNkNBQTRCLEVBQUMsTUFBTSxDQUFDLENBQUM7SUFDMUQsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFBLHlCQUFXLEVBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUNwRSxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsV0FBVyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3pELE9BQU8sQ0FBQyxJQUFJLENBQUMscUJBQXFCLEtBQUssTUFBTSxDQUFDLENBQUM7QUFDakQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGdlbmVyYXRlTGlnaHRuaW5nUXJEYXRhQXN5bmMsIGdlbmVyYXRlUXJEYXRhQXN5bmMgfSBmcm9tICcuL2dlbmVyYXRlUXJEYXRhJztcbmltcG9ydCB7IGdlbmVyYXRlRmFxLCBnZW5lcmF0ZUxpZ2h0bmluZ0ZhcSB9IGZyb20gJy4vZmFxJztcbmltcG9ydCB7IGRyYXdLZXljYXJkIH0gZnJvbSAnLi9kcmF3S2V5Y2FyZCc7XG5pbXBvcnQgeyBnZW5lcmF0ZVBhcmFtc0ZvcktleUNyZWF0aW9uIH0gZnJvbSAnLi9nZW5lcmF0ZVBhcmFtc0ZvcktleUNyZWF0aW9uJztcbmltcG9ydCB7IEdlbmVyYXRlS2V5Y2FyZFBhcmFtcywgR2VuZXJhdGVMaWdodG5pbmdRckRhdGFQYXJhbXMsIEdlbmVyYXRlUXJEYXRhQmFzZVBhcmFtcyB9IGZyb20gJy4vdHlwZXMnO1xuXG5leHBvcnQgKiBmcm9tICcuL2RyYXdLZXljYXJkJztcbmV4cG9ydCAqIGZyb20gJy4vZmFxJztcbmV4cG9ydCAqIGZyb20gJy4vZ2VuZXJhdGVRckRhdGEnO1xuZXhwb3J0ICogZnJvbSAnLi91dGlscyc7XG5leHBvcnQgKiBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlS2V5Y2FyZChwYXJhbXM6IEdlbmVyYXRlS2V5Y2FyZFBhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoJ3VzZXJBdXRoS2V5Y2hhaW4nIGluIHBhcmFtcykge1xuICAgIGNvbnN0IHF1ZXN0aW9ucyA9IGdlbmVyYXRlTGlnaHRuaW5nRmFxKHBhcmFtcy5jb2luLmZ1bGxOYW1lKTtcbiAgICBjb25zdCBxckRhdGEgPSBhd2FpdCBnZW5lcmF0ZUxpZ2h0bmluZ1FyRGF0YUFzeW5jKHBhcmFtcyk7XG4gICAgY29uc3Qga2V5Y2FyZCA9IGF3YWl0IGRyYXdLZXljYXJkKHsgLi4ucGFyYW1zLCBxdWVzdGlvbnMsIHFyRGF0YSB9KTtcbiAgICBjb25zdCBsYWJlbCA9IHBhcmFtcy53YWxsZXRMYWJlbCB8fCBwYXJhbXMuY29pbi5mdWxsTmFtZTtcbiAgICBrZXljYXJkLnNhdmUoYEJpdEdvIEtleWNhcmQgZm9yICR7bGFiZWx9LnBkZmApO1xuICB9IGVsc2UgaWYgKCdjb2luJyBpbiBwYXJhbXMpIHtcbiAgICBjb25zdCBxdWVzdGlvbnMgPSBnZW5lcmF0ZUZhcShwYXJhbXMuY29pbi5mdWxsTmFtZSk7XG4gICAgY29uc3QgcXJEYXRhID0gYXdhaXQgZ2VuZXJhdGVRckRhdGFBc3luYyhwYXJhbXMpO1xuICAgIGNvbnN0IGtleWNhcmQgPSBhd2FpdCBkcmF3S2V5Y2FyZCh7IC4uLnBhcmFtcywgcXVlc3Rpb25zLCBxckRhdGEgfSk7XG4gICAgY29uc3QgbGFiZWwgPSBwYXJhbXMud2FsbGV0TGFiZWwgfHwgcGFyYW1zLmNvaW4uZnVsbE5hbWU7XG4gICAga2V5Y2FyZC5zYXZlKGBCaXRHbyBLZXljYXJkIGZvciAke2xhYmVsfS5wZGZgKTtcbiAgfSBlbHNlIGlmICgnY3VydmUnIGluIHBhcmFtcykge1xuICAgIGNvbnN0IGRhdGEgPSBnZW5lcmF0ZVBhcmFtc0ZvcktleUNyZWF0aW9uKHBhcmFtcyk7XG4gICAgY29uc3Qga2V5Y2FyZCA9IGF3YWl0IGRyYXdLZXljYXJkKGRhdGEpO1xuICAgIGNvbnN0IGxhYmVsID0gcGFyYW1zLndhbGxldExhYmVsIHx8IHBhcmFtcy5jdXJ2ZTtcbiAgICBrZXljYXJkLnNhdmUoYEJpdEdvIEtleWNhcmQgZm9yICR7bGFiZWx9LnBkZmApO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignRWl0aGVyIGN1cnZlIG9yIGNvaW4gbXVzdCBiZSBwcm92aWRlZCcpO1xuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUxpZ2h0bmluZ0tleWNhcmQoXG4gIHBhcmFtczogR2VuZXJhdGVRckRhdGFCYXNlUGFyYW1zICYgR2VuZXJhdGVMaWdodG5pbmdRckRhdGFQYXJhbXNcbik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBxdWVzdGlvbnMgPSBnZW5lcmF0ZUxpZ2h0bmluZ0ZhcShwYXJhbXMuY29pbi5mdWxsTmFtZSk7XG4gIGNvbnN0IHFyRGF0YSA9IGF3YWl0IGdlbmVyYXRlTGlnaHRuaW5nUXJEYXRhQXN5bmMocGFyYW1zKTtcbiAgY29uc3Qga2V5Y2FyZCA9IGF3YWl0IGRyYXdLZXljYXJkKHsgLi4ucGFyYW1zLCBxdWVzdGlvbnMsIHFyRGF0YSB9KTtcbiAgY29uc3QgbGFiZWwgPSBwYXJhbXMud2FsbGV0TGFiZWwgfHwgcGFyYW1zLmNvaW4uZnVsbE5hbWU7XG4gIGtleWNhcmQuc2F2ZShgQml0R28gS2V5Y2FyZCBmb3IgJHtsYWJlbH0ucGRmYCk7XG59XG4iXX0=
62
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQWNBLDBDQXFCQztBQUVELDREQVFDO0FBN0NELHFEQUFxRjtBQUNyRiwrQkFBMEQ7QUFDMUQsK0NBQTRDO0FBQzVDLGlGQUE4RTtBQUc5RSxnREFBOEI7QUFDOUIsMERBQXdDO0FBQ3hDLHdDQUFzQjtBQUN0QixtREFBaUM7QUFDakMsaURBQStCO0FBQy9CLDBDQUF3QjtBQUN4QiwwQ0FBd0I7QUFFakIsS0FBSyxVQUFVLGVBQWUsQ0FBQyxNQUE2QjtJQUNqRSxJQUFJLGtCQUFrQixJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQ2pDLE1BQU0sU0FBUyxHQUFHLElBQUEsMEJBQW9CLEVBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM3RCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUEsNkNBQTRCLEVBQUMsTUFBTSxDQUFDLENBQUM7UUFDMUQsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFBLHlCQUFXLEVBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUNwRSxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsV0FBVyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQ3pELE9BQU8sQ0FBQyxJQUFJLENBQUMscUJBQXFCLEtBQUssTUFBTSxDQUFDLENBQUM7SUFDakQsQ0FBQztTQUFNLElBQUksTUFBTSxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQzVCLE1BQU0sU0FBUyxHQUFHLElBQUEsaUJBQVcsRUFBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3BELE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBQSxvQ0FBbUIsRUFBQyxNQUFNLENBQUMsQ0FBQztRQUNqRCxNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUEseUJBQVcsRUFBQyxFQUFFLEdBQUcsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3BFLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxXQUFXLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDekQsT0FBTyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsS0FBSyxNQUFNLENBQUMsQ0FBQztJQUNqRCxDQUFDO1NBQU0sSUFBSSxPQUFPLElBQUksTUFBTSxFQUFFLENBQUM7UUFDN0IsTUFBTSxJQUFJLEdBQUcsSUFBQSwyREFBNEIsRUFBQyxNQUFNLENBQUMsQ0FBQztRQUNsRCxNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUEseUJBQVcsRUFBQyxJQUFJLENBQUMsQ0FBQztRQUN4QyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsV0FBVyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUM7UUFDakQsT0FBTyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsS0FBSyxNQUFNLENBQUMsQ0FBQztJQUNqRCxDQUFDO1NBQU0sQ0FBQztRQUNOLE1BQU0sSUFBSSxLQUFLLENBQUMsdUNBQXVDLENBQUMsQ0FBQztJQUMzRCxDQUFDO0FBQ0gsQ0FBQztBQUVNLEtBQUssVUFBVSx3QkFBd0IsQ0FDNUMsTUFBZ0U7SUFFaEUsTUFBTSxTQUFTLEdBQUcsSUFBQSwwQkFBb0IsRUFBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzdELE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBQSw2Q0FBNEIsRUFBQyxNQUFNLENBQUMsQ0FBQztJQUMxRCxNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUEseUJBQVcsRUFBQyxFQUFFLEdBQUcsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQ3BFLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxXQUFXLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDekQsT0FBTyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsS0FBSyxNQUFNLENBQUMsQ0FBQztBQUNqRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZ2VuZXJhdGVMaWdodG5pbmdRckRhdGFBc3luYywgZ2VuZXJhdGVRckRhdGFBc3luYyB9IGZyb20gJy4vZ2VuZXJhdGVRckRhdGEnO1xuaW1wb3J0IHsgZ2VuZXJhdGVGYXEsIGdlbmVyYXRlTGlnaHRuaW5nRmFxIH0gZnJvbSAnLi9mYXEnO1xuaW1wb3J0IHsgZHJhd0tleWNhcmQgfSBmcm9tICcuL2RyYXdLZXljYXJkJztcbmltcG9ydCB7IGdlbmVyYXRlUGFyYW1zRm9yS2V5Q3JlYXRpb24gfSBmcm9tICcuL2dlbmVyYXRlUGFyYW1zRm9yS2V5Q3JlYXRpb24nO1xuaW1wb3J0IHsgR2VuZXJhdGVLZXljYXJkUGFyYW1zLCBHZW5lcmF0ZUxpZ2h0bmluZ1FyRGF0YVBhcmFtcywgR2VuZXJhdGVRckRhdGFCYXNlUGFyYW1zIH0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCAqIGZyb20gJy4vZHJhd0tleWNhcmQnO1xuZXhwb3J0ICogZnJvbSAnLi9leHRyYWN0S2V5Y2FyZEZyb21QREYnO1xuZXhwb3J0ICogZnJvbSAnLi9mYXEnO1xuZXhwb3J0ICogZnJvbSAnLi9nZW5lcmF0ZVFyRGF0YSc7XG5leHBvcnQgKiBmcm9tICcuL3BhcnNlS2V5Y2FyZCc7XG5leHBvcnQgKiBmcm9tICcuL3V0aWxzJztcbmV4cG9ydCAqIGZyb20gJy4vdHlwZXMnO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVLZXljYXJkKHBhcmFtczogR2VuZXJhdGVLZXljYXJkUGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmICgndXNlckF1dGhLZXljaGFpbicgaW4gcGFyYW1zKSB7XG4gICAgY29uc3QgcXVlc3Rpb25zID0gZ2VuZXJhdGVMaWdodG5pbmdGYXEocGFyYW1zLmNvaW4uZnVsbE5hbWUpO1xuICAgIGNvbnN0IHFyRGF0YSA9IGF3YWl0IGdlbmVyYXRlTGlnaHRuaW5nUXJEYXRhQXN5bmMocGFyYW1zKTtcbiAgICBjb25zdCBrZXljYXJkID0gYXdhaXQgZHJhd0tleWNhcmQoeyAuLi5wYXJhbXMsIHF1ZXN0aW9ucywgcXJEYXRhIH0pO1xuICAgIGNvbnN0IGxhYmVsID0gcGFyYW1zLndhbGxldExhYmVsIHx8IHBhcmFtcy5jb2luLmZ1bGxOYW1lO1xuICAgIGtleWNhcmQuc2F2ZShgQml0R28gS2V5Y2FyZCBmb3IgJHtsYWJlbH0ucGRmYCk7XG4gIH0gZWxzZSBpZiAoJ2NvaW4nIGluIHBhcmFtcykge1xuICAgIGNvbnN0IHF1ZXN0aW9ucyA9IGdlbmVyYXRlRmFxKHBhcmFtcy5jb2luLmZ1bGxOYW1lKTtcbiAgICBjb25zdCBxckRhdGEgPSBhd2FpdCBnZW5lcmF0ZVFyRGF0YUFzeW5jKHBhcmFtcyk7XG4gICAgY29uc3Qga2V5Y2FyZCA9IGF3YWl0IGRyYXdLZXljYXJkKHsgLi4ucGFyYW1zLCBxdWVzdGlvbnMsIHFyRGF0YSB9KTtcbiAgICBjb25zdCBsYWJlbCA9IHBhcmFtcy53YWxsZXRMYWJlbCB8fCBwYXJhbXMuY29pbi5mdWxsTmFtZTtcbiAgICBrZXljYXJkLnNhdmUoYEJpdEdvIEtleWNhcmQgZm9yICR7bGFiZWx9LnBkZmApO1xuICB9IGVsc2UgaWYgKCdjdXJ2ZScgaW4gcGFyYW1zKSB7XG4gICAgY29uc3QgZGF0YSA9IGdlbmVyYXRlUGFyYW1zRm9yS2V5Q3JlYXRpb24ocGFyYW1zKTtcbiAgICBjb25zdCBrZXljYXJkID0gYXdhaXQgZHJhd0tleWNhcmQoZGF0YSk7XG4gICAgY29uc3QgbGFiZWwgPSBwYXJhbXMud2FsbGV0TGFiZWwgfHwgcGFyYW1zLmN1cnZlO1xuICAgIGtleWNhcmQuc2F2ZShgQml0R28gS2V5Y2FyZCBmb3IgJHtsYWJlbH0ucGRmYCk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdFaXRoZXIgY3VydmUgb3IgY29pbiBtdXN0IGJlIHByb3ZpZGVkJyk7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlTGlnaHRuaW5nS2V5Y2FyZChcbiAgcGFyYW1zOiBHZW5lcmF0ZVFyRGF0YUJhc2VQYXJhbXMgJiBHZW5lcmF0ZUxpZ2h0bmluZ1FyRGF0YVBhcmFtc1xuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHF1ZXN0aW9ucyA9IGdlbmVyYXRlTGlnaHRuaW5nRmFxKHBhcmFtcy5jb2luLmZ1bGxOYW1lKTtcbiAgY29uc3QgcXJEYXRhID0gYXdhaXQgZ2VuZXJhdGVMaWdodG5pbmdRckRhdGFBc3luYyhwYXJhbXMpO1xuICBjb25zdCBrZXljYXJkID0gYXdhaXQgZHJhd0tleWNhcmQoeyAuLi5wYXJhbXMsIHF1ZXN0aW9ucywgcXJEYXRhIH0pO1xuICBjb25zdCBsYWJlbCA9IHBhcmFtcy53YWxsZXRMYWJlbCB8fCBwYXJhbXMuY29pbi5mdWxsTmFtZTtcbiAga2V5Y2FyZC5zYXZlKGBCaXRHbyBLZXljYXJkIGZvciAke2xhYmVsfS5wZGZgKTtcbn1cbiJdfQ==
@@ -0,0 +1,23 @@
1
+ export type PDFTextNode = {
2
+ text: string;
3
+ x: number;
4
+ y: number;
5
+ page: number;
6
+ width: number;
7
+ };
8
+ export type KeycardEntry = {
9
+ label: string;
10
+ value: string;
11
+ };
12
+ /**
13
+ * Reconstructs logical text lines from an unordered set of PDF text nodes.
14
+ *
15
+ * PDF text extraction returns individual positioned fragments. This function
16
+ * sorts them by page then Y-coordinate (top-to-bottom), groups fragments
17
+ * within PDF_LINE_Y_TOLERANCE points of each other onto the same line, and
18
+ * inserts a space between fragments that are separated by more than
19
+ * PDF_NODE_GAP_THRESHOLD points horizontally.
20
+ */
21
+ export declare function buildLinesFromPDFNodes(nodes: PDFTextNode[]): string[];
22
+ export declare function parseKeycardFromLines(lines: string[]): KeycardEntry[];
23
+ //# sourceMappingURL=parseKeycard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseKeycard.d.ts","sourceRoot":"","sources":["../../src/parseKeycard.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAwCF;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,EAAE,CA4DrE;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAyErE"}
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildLinesFromPDFNodes = buildLinesFromPDFNodes;
4
+ exports.parseKeycardFromLines = parseKeycardFromLines;
5
+ const sectionHeaderRegex = /^([A-D])\s*[:.)-]\s*(.+?)\s*$/i;
6
+ const dataLineRegex = /^data\s*:\s*(.*)$/i;
7
+ const faqHeaderRegex = /^BitGo\s+KeyCard\s+FAQ$/i;
8
+ // PDF coordinate tolerance in points. Nodes within this distance on the Y-axis
9
+ // are treated as belonging to the same line; nodes further apart are separate lines.
10
+ const PDF_LINE_Y_TOLERANCE = 2;
11
+ // Horizontal gap in points above which a space is inserted between adjacent nodes.
12
+ const PDF_NODE_GAP_THRESHOLD = 2;
13
+ function sanitizeText(input) {
14
+ return input.replace(/\s+/g, ' ').trim();
15
+ }
16
+ function normalizeSectionValue(rawValue) {
17
+ // Two-pass removal of "Part N" page-continuation labels:
18
+ // 1. Line filter: removes labels that appear as standalone lines.
19
+ // 2. Regex replace: removes labels embedded mid-line when
20
+ // buildLinesFromPDFNodes merges them with adjacent content at the same
21
+ // y-coordinate (e.g. "...X88bPart 2 lFPMd...").
22
+ // join('') intentionally uses no separator — section values are continuous
23
+ // strings (base64 / xpub) that wrap across PDF lines without spaces.
24
+ return rawValue
25
+ .split('\n')
26
+ .filter((line) => !/^Part\s+\d+$/i.test(line.trim()))
27
+ .join('')
28
+ .replace(/\s*Part\s+\d+\s*/gi, '')
29
+ .trim();
30
+ }
31
+ function countChar(input, char) {
32
+ return input.split(char).length - 1;
33
+ }
34
+ function isEncryptedWalletPasswordSectionTitle(title) {
35
+ return title.toLowerCase().includes('encrypted wallet password');
36
+ }
37
+ /**
38
+ * Reconstructs logical text lines from an unordered set of PDF text nodes.
39
+ *
40
+ * PDF text extraction returns individual positioned fragments. This function
41
+ * sorts them by page then Y-coordinate (top-to-bottom), groups fragments
42
+ * within PDF_LINE_Y_TOLERANCE points of each other onto the same line, and
43
+ * inserts a space between fragments that are separated by more than
44
+ * PDF_NODE_GAP_THRESHOLD points horizontally.
45
+ */
46
+ function buildLinesFromPDFNodes(nodes) {
47
+ const sortedNodes = [...nodes].sort((a, b) => {
48
+ if (a.page !== b.page) {
49
+ return a.page - b.page;
50
+ }
51
+ const yDiff = Math.abs(a.y - b.y);
52
+ if (yDiff > PDF_LINE_Y_TOLERANCE) {
53
+ return b.y - a.y;
54
+ }
55
+ return a.x - b.x;
56
+ });
57
+ const lines = [];
58
+ let currentLineNodes = [];
59
+ let currentPage = -1;
60
+ let currentY = Number.NaN;
61
+ function flushLine() {
62
+ if (currentLineNodes.length === 0) {
63
+ return;
64
+ }
65
+ const sortedLineNodes = [...currentLineNodes].sort((a, b) => a.x - b.x);
66
+ let line = '';
67
+ let previousRightEdge = null;
68
+ for (const node of sortedLineNodes) {
69
+ const piece = sanitizeText(node.text);
70
+ if (!piece) {
71
+ continue;
72
+ }
73
+ if (previousRightEdge !== null && node.x - previousRightEdge > PDF_NODE_GAP_THRESHOLD) {
74
+ line += ' ';
75
+ }
76
+ line += piece;
77
+ previousRightEdge = node.x + node.width;
78
+ }
79
+ const normalizedLine = line.trim();
80
+ if (normalizedLine) {
81
+ lines.push(normalizedLine);
82
+ }
83
+ }
84
+ for (const node of sortedNodes) {
85
+ const pageChanged = node.page !== currentPage;
86
+ const lineChanged = Number.isNaN(currentY) || Math.abs(node.y - currentY) > PDF_LINE_Y_TOLERANCE;
87
+ if (pageChanged || lineChanged) {
88
+ flushLine();
89
+ currentLineNodes = [node];
90
+ currentPage = node.page;
91
+ currentY = node.y;
92
+ continue;
93
+ }
94
+ currentLineNodes.push(node);
95
+ }
96
+ flushLine();
97
+ return lines;
98
+ }
99
+ function parseKeycardFromLines(lines) {
100
+ const sections = [];
101
+ let currentSectionIndex = -1;
102
+ for (const line of lines) {
103
+ const labelMatch = line.match(sectionHeaderRegex);
104
+ if (labelMatch) {
105
+ const section = labelMatch[1]?.toUpperCase();
106
+ const title = sanitizeText(labelMatch[2] ?? '');
107
+ if (section && title) {
108
+ sections.push({
109
+ section,
110
+ title,
111
+ values: [],
112
+ isCapturingData: false,
113
+ openCurlyCount: 0,
114
+ });
115
+ currentSectionIndex = sections.length - 1;
116
+ continue;
117
+ }
118
+ }
119
+ if (currentSectionIndex < 0) {
120
+ continue;
121
+ }
122
+ const currentSection = sections[currentSectionIndex];
123
+ if (!currentSection) {
124
+ continue;
125
+ }
126
+ const dataLineMatch = line.match(dataLineRegex);
127
+ if (dataLineMatch) {
128
+ currentSection.isCapturingData = true;
129
+ const inlineValue = sanitizeText(dataLineMatch[1] ?? '');
130
+ if (inlineValue) {
131
+ currentSection.values.push(inlineValue);
132
+ currentSection.openCurlyCount += countChar(inlineValue, '{') - countChar(inlineValue, '}');
133
+ }
134
+ continue;
135
+ }
136
+ if (currentSection.isCapturingData) {
137
+ if (faqHeaderRegex.test(line)) {
138
+ currentSection.isCapturingData = false;
139
+ continue;
140
+ }
141
+ currentSection.values.push(line);
142
+ // For encrypted wallet password, data is a single JSON object. Stop as
143
+ // soon as the object closes so footer/FAQ content is not appended.
144
+ if (isEncryptedWalletPasswordSectionTitle(currentSection.title)) {
145
+ currentSection.openCurlyCount += countChar(line, '{') - countChar(line, '}');
146
+ if (currentSection.values.length > 0 && currentSection.openCurlyCount <= 0) {
147
+ currentSection.isCapturingData = false;
148
+ }
149
+ }
150
+ }
151
+ }
152
+ return sections
153
+ .filter(({ section, values }) => ['A', 'B', 'C', 'D'].includes(section) && values.length > 0)
154
+ .map(({ section, title, values }) => ({
155
+ label: `${section}: ${title}`,
156
+ value: normalizeSectionValue(values.join('\n')),
157
+ }));
158
+ }
159
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2VLZXljYXJkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BhcnNlS2V5Y2FyZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQTREQSx3REE0REM7QUFFRCxzREF5RUM7QUF0TEQsTUFBTSxrQkFBa0IsR0FBRyxnQ0FBZ0MsQ0FBQztBQUM1RCxNQUFNLGFBQWEsR0FBRyxvQkFBb0IsQ0FBQztBQUMzQyxNQUFNLGNBQWMsR0FBRywwQkFBMEIsQ0FBQztBQUVsRCwrRUFBK0U7QUFDL0UscUZBQXFGO0FBQ3JGLE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO0FBQy9CLG1GQUFtRjtBQUNuRixNQUFNLHNCQUFzQixHQUFHLENBQUMsQ0FBQztBQUVqQyxTQUFTLFlBQVksQ0FBQyxLQUFhO0lBQ2pDLE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDM0MsQ0FBQztBQUVELFNBQVMscUJBQXFCLENBQUMsUUFBZ0I7SUFDN0MseURBQXlEO0lBQ3pELGtFQUFrRTtJQUNsRSwwREFBMEQ7SUFDMUQsMEVBQTBFO0lBQzFFLG1EQUFtRDtJQUNuRCwyRUFBMkU7SUFDM0UscUVBQXFFO0lBQ3JFLE9BQU8sUUFBUTtTQUNaLEtBQUssQ0FBQyxJQUFJLENBQUM7U0FDWCxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztTQUNwRCxJQUFJLENBQUMsRUFBRSxDQUFDO1NBQ1IsT0FBTyxDQUFDLG9CQUFvQixFQUFFLEVBQUUsQ0FBQztTQUNqQyxJQUFJLEVBQUUsQ0FBQztBQUNaLENBQUM7QUFFRCxTQUFTLFNBQVMsQ0FBQyxLQUFhLEVBQUUsSUFBWTtJQUM1QyxPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztBQUN0QyxDQUFDO0FBRUQsU0FBUyxxQ0FBcUMsQ0FBQyxLQUFhO0lBQzFELE9BQU8sS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDLFFBQVEsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO0FBQ25FLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQWdCLHNCQUFzQixDQUFDLEtBQW9CO0lBQ3pELE1BQU0sV0FBVyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDM0MsSUFBSSxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN0QixPQUFPLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUN6QixDQUFDO1FBQ0QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQyxJQUFJLEtBQUssR0FBRyxvQkFBb0IsRUFBRSxDQUFDO1lBQ2pDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25CLENBQUM7UUFDRCxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNuQixDQUFDLENBQUMsQ0FBQztJQUVILE1BQU0sS0FBSyxHQUFhLEVBQUUsQ0FBQztJQUMzQixJQUFJLGdCQUFnQixHQUFrQixFQUFFLENBQUM7SUFDekMsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDckIsSUFBSSxRQUFRLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQztJQUUxQixTQUFTLFNBQVM7UUFDaEIsSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDbEMsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLGVBQWUsR0FBRyxDQUFDLEdBQUcsZ0JBQWdCLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4RSxJQUFJLElBQUksR0FBRyxFQUFFLENBQUM7UUFDZCxJQUFJLGlCQUFpQixHQUFrQixJQUFJLENBQUM7UUFDNUMsS0FBSyxNQUFNLElBQUksSUFBSSxlQUFlLEVBQUUsQ0FBQztZQUNuQyxNQUFNLEtBQUssR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3RDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDWCxTQUFTO1lBQ1gsQ0FBQztZQUVELElBQUksaUJBQWlCLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyxDQUFDLEdBQUcsaUJBQWlCLEdBQUcsc0JBQXNCLEVBQUUsQ0FBQztnQkFDdEYsSUFBSSxJQUFJLEdBQUcsQ0FBQztZQUNkLENBQUM7WUFDRCxJQUFJLElBQUksS0FBSyxDQUFDO1lBQ2QsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQzFDLENBQUM7UUFFRCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDbkMsSUFBSSxjQUFjLEVBQUUsQ0FBQztZQUNuQixLQUFLLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzdCLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxNQUFNLElBQUksSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUMvQixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsSUFBSSxLQUFLLFdBQVcsQ0FBQztRQUM5QyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsR0FBRyxvQkFBb0IsQ0FBQztRQUNqRyxJQUFJLFdBQVcsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUMvQixTQUFTLEVBQUUsQ0FBQztZQUNaLGdCQUFnQixHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDMUIsV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDeEIsUUFBUSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDbEIsU0FBUztRQUNYLENBQUM7UUFFRCxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQUVELFNBQVMsRUFBRSxDQUFDO0lBQ1osT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBRUQsU0FBZ0IscUJBQXFCLENBQUMsS0FBZTtJQUNuRCxNQUFNLFFBQVEsR0FNVCxFQUFFLENBQUM7SUFDUixJQUFJLG1CQUFtQixHQUFHLENBQUMsQ0FBQyxDQUFDO0lBRTdCLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7UUFDekIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ2xELElBQUksVUFBVSxFQUFFLENBQUM7WUFDZixNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLENBQUM7WUFDN0MsTUFBTSxLQUFLLEdBQUcsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUNoRCxJQUFJLE9BQU8sSUFBSSxLQUFLLEVBQUUsQ0FBQztnQkFDckIsUUFBUSxDQUFDLElBQUksQ0FBQztvQkFDWixPQUFPO29CQUNQLEtBQUs7b0JBQ0wsTUFBTSxFQUFFLEVBQUU7b0JBQ1YsZUFBZSxFQUFFLEtBQUs7b0JBQ3RCLGNBQWMsRUFBRSxDQUFDO2lCQUNsQixDQUFDLENBQUM7Z0JBQ0gsbUJBQW1CLEdBQUcsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7Z0JBQzFDLFNBQVM7WUFDWCxDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksbUJBQW1CLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDNUIsU0FBUztRQUNYLENBQUM7UUFFRCxNQUFNLGNBQWMsR0FBRyxRQUFRLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUNyRCxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDcEIsU0FBUztRQUNYLENBQUM7UUFFRCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ2hELElBQUksYUFBYSxFQUFFLENBQUM7WUFDbEIsY0FBYyxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7WUFDdEMsTUFBTSxXQUFXLEdBQUcsWUFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUN6RCxJQUFJLFdBQVcsRUFBRSxDQUFDO2dCQUNoQixjQUFjLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDeEMsY0FBYyxDQUFDLGNBQWMsSUFBSSxTQUFTLENBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxXQUFXLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDN0YsQ0FBQztZQUNELFNBQVM7UUFDWCxDQUFDO1FBRUQsSUFBSSxjQUFjLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDbkMsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQzlCLGNBQWMsQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO2dCQUN2QyxTQUFTO1lBQ1gsQ0FBQztZQUVELGNBQWMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRWpDLHVFQUF1RTtZQUN2RSxtRUFBbUU7WUFDbkUsSUFBSSxxQ0FBcUMsQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDaEUsY0FBYyxDQUFDLGNBQWMsSUFBSSxTQUFTLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQzdFLElBQUksY0FBYyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLGNBQWMsQ0FBQyxjQUFjLElBQUksQ0FBQyxFQUFFLENBQUM7b0JBQzNFLGNBQWMsQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO2dCQUN6QyxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxRQUFRO1NBQ1osTUFBTSxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1NBQzVGLEdBQUcsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNwQyxLQUFLLEVBQUUsR0FBRyxPQUFPLEtBQUssS0FBSyxFQUFFO1FBQzdCLEtBQUssRUFBRSxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0tBQ2hELENBQUMsQ0FBQyxDQUFDO0FBQ1IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB0eXBlIFBERlRleHROb2RlID0ge1xuICB0ZXh0OiBzdHJpbmc7XG4gIHg6IG51bWJlcjtcbiAgeTogbnVtYmVyO1xuICBwYWdlOiBudW1iZXI7XG4gIHdpZHRoOiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBLZXljYXJkRW50cnkgPSB7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIHZhbHVlOiBzdHJpbmc7XG59O1xuXG5jb25zdCBzZWN0aW9uSGVhZGVyUmVnZXggPSAvXihbQS1EXSlcXHMqWzouKS1dXFxzKiguKz8pXFxzKiQvaTtcbmNvbnN0IGRhdGFMaW5lUmVnZXggPSAvXmRhdGFcXHMqOlxccyooLiopJC9pO1xuY29uc3QgZmFxSGVhZGVyUmVnZXggPSAvXkJpdEdvXFxzK0tleUNhcmRcXHMrRkFRJC9pO1xuXG4vLyBQREYgY29vcmRpbmF0ZSB0b2xlcmFuY2UgaW4gcG9pbnRzLiBOb2RlcyB3aXRoaW4gdGhpcyBkaXN0YW5jZSBvbiB0aGUgWS1heGlzXG4vLyBhcmUgdHJlYXRlZCBhcyBiZWxvbmdpbmcgdG8gdGhlIHNhbWUgbGluZTsgbm9kZXMgZnVydGhlciBhcGFydCBhcmUgc2VwYXJhdGUgbGluZXMuXG5jb25zdCBQREZfTElORV9ZX1RPTEVSQU5DRSA9IDI7XG4vLyBIb3Jpem9udGFsIGdhcCBpbiBwb2ludHMgYWJvdmUgd2hpY2ggYSBzcGFjZSBpcyBpbnNlcnRlZCBiZXR3ZWVuIGFkamFjZW50IG5vZGVzLlxuY29uc3QgUERGX05PREVfR0FQX1RIUkVTSE9MRCA9IDI7XG5cbmZ1bmN0aW9uIHNhbml0aXplVGV4dChpbnB1dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGlucHV0LnJlcGxhY2UoL1xccysvZywgJyAnKS50cmltKCk7XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVNlY3Rpb25WYWx1ZShyYXdWYWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgLy8gVHdvLXBhc3MgcmVtb3ZhbCBvZiBcIlBhcnQgTlwiIHBhZ2UtY29udGludWF0aW9uIGxhYmVsczpcbiAgLy8gMS4gTGluZSBmaWx0ZXI6IHJlbW92ZXMgbGFiZWxzIHRoYXQgYXBwZWFyIGFzIHN0YW5kYWxvbmUgbGluZXMuXG4gIC8vIDIuIFJlZ2V4IHJlcGxhY2U6IHJlbW92ZXMgbGFiZWxzIGVtYmVkZGVkIG1pZC1saW5lIHdoZW5cbiAgLy8gICAgYnVpbGRMaW5lc0Zyb21QREZOb2RlcyBtZXJnZXMgdGhlbSB3aXRoIGFkamFjZW50IGNvbnRlbnQgYXQgdGhlIHNhbWVcbiAgLy8gICAgeS1jb29yZGluYXRlIChlLmcuIFwiLi4uWDg4YlBhcnQgMiBsRlBNZC4uLlwiKS5cbiAgLy8gam9pbignJykgaW50ZW50aW9uYWxseSB1c2VzIG5vIHNlcGFyYXRvciDigJQgc2VjdGlvbiB2YWx1ZXMgYXJlIGNvbnRpbnVvdXNcbiAgLy8gc3RyaW5ncyAoYmFzZTY0IC8geHB1YikgdGhhdCB3cmFwIGFjcm9zcyBQREYgbGluZXMgd2l0aG91dCBzcGFjZXMuXG4gIHJldHVybiByYXdWYWx1ZVxuICAgIC5zcGxpdCgnXFxuJylcbiAgICAuZmlsdGVyKChsaW5lKSA9PiAhL15QYXJ0XFxzK1xcZCskL2kudGVzdChsaW5lLnRyaW0oKSkpXG4gICAgLmpvaW4oJycpXG4gICAgLnJlcGxhY2UoL1xccypQYXJ0XFxzK1xcZCtcXHMqL2dpLCAnJylcbiAgICAudHJpbSgpO1xufVxuXG5mdW5jdGlvbiBjb3VudENoYXIoaW5wdXQ6IHN0cmluZywgY2hhcjogc3RyaW5nKTogbnVtYmVyIHtcbiAgcmV0dXJuIGlucHV0LnNwbGl0KGNoYXIpLmxlbmd0aCAtIDE7XG59XG5cbmZ1bmN0aW9uIGlzRW5jcnlwdGVkV2FsbGV0UGFzc3dvcmRTZWN0aW9uVGl0bGUodGl0bGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gdGl0bGUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnZW5jcnlwdGVkIHdhbGxldCBwYXNzd29yZCcpO1xufVxuXG4vKipcbiAqIFJlY29uc3RydWN0cyBsb2dpY2FsIHRleHQgbGluZXMgZnJvbSBhbiB1bm9yZGVyZWQgc2V0IG9mIFBERiB0ZXh0IG5vZGVzLlxuICpcbiAqIFBERiB0ZXh0IGV4dHJhY3Rpb24gcmV0dXJucyBpbmRpdmlkdWFsIHBvc2l0aW9uZWQgZnJhZ21lbnRzLiBUaGlzIGZ1bmN0aW9uXG4gKiBzb3J0cyB0aGVtIGJ5IHBhZ2UgdGhlbiBZLWNvb3JkaW5hdGUgKHRvcC10by1ib3R0b20pLCBncm91cHMgZnJhZ21lbnRzXG4gKiB3aXRoaW4gUERGX0xJTkVfWV9UT0xFUkFOQ0UgcG9pbnRzIG9mIGVhY2ggb3RoZXIgb250byB0aGUgc2FtZSBsaW5lLCBhbmRcbiAqIGluc2VydHMgYSBzcGFjZSBiZXR3ZWVuIGZyYWdtZW50cyB0aGF0IGFyZSBzZXBhcmF0ZWQgYnkgbW9yZSB0aGFuXG4gKiBQREZfTk9ERV9HQVBfVEhSRVNIT0xEIHBvaW50cyBob3Jpem9udGFsbHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZExpbmVzRnJvbVBERk5vZGVzKG5vZGVzOiBQREZUZXh0Tm9kZVtdKTogc3RyaW5nW10ge1xuICBjb25zdCBzb3J0ZWROb2RlcyA9IFsuLi5ub2Rlc10uc29ydCgoYSwgYikgPT4ge1xuICAgIGlmIChhLnBhZ2UgIT09IGIucGFnZSkge1xuICAgICAgcmV0dXJuIGEucGFnZSAtIGIucGFnZTtcbiAgICB9XG4gICAgY29uc3QgeURpZmYgPSBNYXRoLmFicyhhLnkgLSBiLnkpO1xuICAgIGlmICh5RGlmZiA+IFBERl9MSU5FX1lfVE9MRVJBTkNFKSB7XG4gICAgICByZXR1cm4gYi55IC0gYS55O1xuICAgIH1cbiAgICByZXR1cm4gYS54IC0gYi54O1xuICB9KTtcblxuICBjb25zdCBsaW5lczogc3RyaW5nW10gPSBbXTtcbiAgbGV0IGN1cnJlbnRMaW5lTm9kZXM6IFBERlRleHROb2RlW10gPSBbXTtcbiAgbGV0IGN1cnJlbnRQYWdlID0gLTE7XG4gIGxldCBjdXJyZW50WSA9IE51bWJlci5OYU47XG5cbiAgZnVuY3Rpb24gZmx1c2hMaW5lKCkge1xuICAgIGlmIChjdXJyZW50TGluZU5vZGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHNvcnRlZExpbmVOb2RlcyA9IFsuLi5jdXJyZW50TGluZU5vZGVzXS5zb3J0KChhLCBiKSA9PiBhLnggLSBiLngpO1xuICAgIGxldCBsaW5lID0gJyc7XG4gICAgbGV0IHByZXZpb3VzUmlnaHRFZGdlOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgICBmb3IgKGNvbnN0IG5vZGUgb2Ygc29ydGVkTGluZU5vZGVzKSB7XG4gICAgICBjb25zdCBwaWVjZSA9IHNhbml0aXplVGV4dChub2RlLnRleHQpO1xuICAgICAgaWYgKCFwaWVjZSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHByZXZpb3VzUmlnaHRFZGdlICE9PSBudWxsICYmIG5vZGUueCAtIHByZXZpb3VzUmlnaHRFZGdlID4gUERGX05PREVfR0FQX1RIUkVTSE9MRCkge1xuICAgICAgICBsaW5lICs9ICcgJztcbiAgICAgIH1cbiAgICAgIGxpbmUgKz0gcGllY2U7XG4gICAgICBwcmV2aW91c1JpZ2h0RWRnZSA9IG5vZGUueCArIG5vZGUud2lkdGg7XG4gICAgfVxuXG4gICAgY29uc3Qgbm9ybWFsaXplZExpbmUgPSBsaW5lLnRyaW0oKTtcbiAgICBpZiAobm9ybWFsaXplZExpbmUpIHtcbiAgICAgIGxpbmVzLnB1c2gobm9ybWFsaXplZExpbmUpO1xuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3Qgbm9kZSBvZiBzb3J0ZWROb2Rlcykge1xuICAgIGNvbnN0IHBhZ2VDaGFuZ2VkID0gbm9kZS5wYWdlICE9PSBjdXJyZW50UGFnZTtcbiAgICBjb25zdCBsaW5lQ2hhbmdlZCA9IE51bWJlci5pc05hTihjdXJyZW50WSkgfHwgTWF0aC5hYnMobm9kZS55IC0gY3VycmVudFkpID4gUERGX0xJTkVfWV9UT0xFUkFOQ0U7XG4gICAgaWYgKHBhZ2VDaGFuZ2VkIHx8IGxpbmVDaGFuZ2VkKSB7XG4gICAgICBmbHVzaExpbmUoKTtcbiAgICAgIGN1cnJlbnRMaW5lTm9kZXMgPSBbbm9kZV07XG4gICAgICBjdXJyZW50UGFnZSA9IG5vZGUucGFnZTtcbiAgICAgIGN1cnJlbnRZID0gbm9kZS55O1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgY3VycmVudExpbmVOb2Rlcy5wdXNoKG5vZGUpO1xuICB9XG5cbiAgZmx1c2hMaW5lKCk7XG4gIHJldHVybiBsaW5lcztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlS2V5Y2FyZEZyb21MaW5lcyhsaW5lczogc3RyaW5nW10pOiBLZXljYXJkRW50cnlbXSB7XG4gIGNvbnN0IHNlY3Rpb25zOiBBcnJheTx7XG4gICAgc2VjdGlvbjogc3RyaW5nO1xuICAgIHRpdGxlOiBzdHJpbmc7XG4gICAgdmFsdWVzOiBzdHJpbmdbXTtcbiAgICBpc0NhcHR1cmluZ0RhdGE6IGJvb2xlYW47XG4gICAgb3BlbkN1cmx5Q291bnQ6IG51bWJlcjtcbiAgfT4gPSBbXTtcbiAgbGV0IGN1cnJlbnRTZWN0aW9uSW5kZXggPSAtMTtcblxuICBmb3IgKGNvbnN0IGxpbmUgb2YgbGluZXMpIHtcbiAgICBjb25zdCBsYWJlbE1hdGNoID0gbGluZS5tYXRjaChzZWN0aW9uSGVhZGVyUmVnZXgpO1xuICAgIGlmIChsYWJlbE1hdGNoKSB7XG4gICAgICBjb25zdCBzZWN0aW9uID0gbGFiZWxNYXRjaFsxXT8udG9VcHBlckNhc2UoKTtcbiAgICAgIGNvbnN0IHRpdGxlID0gc2FuaXRpemVUZXh0KGxhYmVsTWF0Y2hbMl0gPz8gJycpO1xuICAgICAgaWYgKHNlY3Rpb24gJiYgdGl0bGUpIHtcbiAgICAgICAgc2VjdGlvbnMucHVzaCh7XG4gICAgICAgICAgc2VjdGlvbixcbiAgICAgICAgICB0aXRsZSxcbiAgICAgICAgICB2YWx1ZXM6IFtdLFxuICAgICAgICAgIGlzQ2FwdHVyaW5nRGF0YTogZmFsc2UsXG4gICAgICAgICAgb3BlbkN1cmx5Q291bnQ6IDAsXG4gICAgICAgIH0pO1xuICAgICAgICBjdXJyZW50U2VjdGlvbkluZGV4ID0gc2VjdGlvbnMubGVuZ3RoIC0gMTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGN1cnJlbnRTZWN0aW9uSW5kZXggPCAwKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50U2VjdGlvbiA9IHNlY3Rpb25zW2N1cnJlbnRTZWN0aW9uSW5kZXhdO1xuICAgIGlmICghY3VycmVudFNlY3Rpb24pIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGFMaW5lTWF0Y2ggPSBsaW5lLm1hdGNoKGRhdGFMaW5lUmVnZXgpO1xuICAgIGlmIChkYXRhTGluZU1hdGNoKSB7XG4gICAgICBjdXJyZW50U2VjdGlvbi5pc0NhcHR1cmluZ0RhdGEgPSB0cnVlO1xuICAgICAgY29uc3QgaW5saW5lVmFsdWUgPSBzYW5pdGl6ZVRleHQoZGF0YUxpbmVNYXRjaFsxXSA/PyAnJyk7XG4gICAgICBpZiAoaW5saW5lVmFsdWUpIHtcbiAgICAgICAgY3VycmVudFNlY3Rpb24udmFsdWVzLnB1c2goaW5saW5lVmFsdWUpO1xuICAgICAgICBjdXJyZW50U2VjdGlvbi5vcGVuQ3VybHlDb3VudCArPSBjb3VudENoYXIoaW5saW5lVmFsdWUsICd7JykgLSBjb3VudENoYXIoaW5saW5lVmFsdWUsICd9Jyk7XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoY3VycmVudFNlY3Rpb24uaXNDYXB0dXJpbmdEYXRhKSB7XG4gICAgICBpZiAoZmFxSGVhZGVyUmVnZXgudGVzdChsaW5lKSkge1xuICAgICAgICBjdXJyZW50U2VjdGlvbi5pc0NhcHR1cmluZ0RhdGEgPSBmYWxzZTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGN1cnJlbnRTZWN0aW9uLnZhbHVlcy5wdXNoKGxpbmUpO1xuXG4gICAgICAvLyBGb3IgZW5jcnlwdGVkIHdhbGxldCBwYXNzd29yZCwgZGF0YSBpcyBhIHNpbmdsZSBKU09OIG9iamVjdC4gU3RvcCBhc1xuICAgICAgLy8gc29vbiBhcyB0aGUgb2JqZWN0IGNsb3NlcyBzbyBmb290ZXIvRkFRIGNvbnRlbnQgaXMgbm90IGFwcGVuZGVkLlxuICAgICAgaWYgKGlzRW5jcnlwdGVkV2FsbGV0UGFzc3dvcmRTZWN0aW9uVGl0bGUoY3VycmVudFNlY3Rpb24udGl0bGUpKSB7XG4gICAgICAgIGN1cnJlbnRTZWN0aW9uLm9wZW5DdXJseUNvdW50ICs9IGNvdW50Q2hhcihsaW5lLCAneycpIC0gY291bnRDaGFyKGxpbmUsICd9Jyk7XG4gICAgICAgIGlmIChjdXJyZW50U2VjdGlvbi52YWx1ZXMubGVuZ3RoID4gMCAmJiBjdXJyZW50U2VjdGlvbi5vcGVuQ3VybHlDb3VudCA8PSAwKSB7XG4gICAgICAgICAgY3VycmVudFNlY3Rpb24uaXNDYXB0dXJpbmdEYXRhID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gc2VjdGlvbnNcbiAgICAuZmlsdGVyKCh7IHNlY3Rpb24sIHZhbHVlcyB9KSA9PiBbJ0EnLCAnQicsICdDJywgJ0QnXS5pbmNsdWRlcyhzZWN0aW9uKSAmJiB2YWx1ZXMubGVuZ3RoID4gMClcbiAgICAubWFwKCh7IHNlY3Rpb24sIHRpdGxlLCB2YWx1ZXMgfSkgPT4gKHtcbiAgICAgIGxhYmVsOiBgJHtzZWN0aW9ufTogJHt0aXRsZX1gLFxuICAgICAgdmFsdWU6IG5vcm1hbGl6ZVNlY3Rpb25WYWx1ZSh2YWx1ZXMuam9pbignXFxuJykpLFxuICAgIH0pKTtcbn1cbiJdfQ==