@aibrains/pdf-renderer 0.2.0 → 0.3.0

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.
Files changed (61) hide show
  1. package/dist/components/KeyValueTable.d.ts +23 -0
  2. package/dist/components/KeyValueTable.d.ts.map +1 -0
  3. package/dist/components/KeyValueTable.js +37 -0
  4. package/dist/components/KeyValueTable.js.map +1 -0
  5. package/dist/components/LineItemTable.d.ts +53 -0
  6. package/dist/components/LineItemTable.d.ts.map +1 -0
  7. package/dist/components/LineItemTable.js +99 -0
  8. package/dist/components/LineItemTable.js.map +1 -0
  9. package/dist/components/SignatureLine.d.ts +24 -0
  10. package/dist/components/SignatureLine.d.ts.map +1 -0
  11. package/dist/components/SignatureLine.js +34 -0
  12. package/dist/components/SignatureLine.js.map +1 -0
  13. package/dist/components/TotalsBlock.d.ts +41 -0
  14. package/dist/components/TotalsBlock.d.ts.map +1 -0
  15. package/dist/components/TotalsBlock.js +59 -0
  16. package/dist/components/TotalsBlock.js.map +1 -0
  17. package/dist/components/index.d.ts +20 -0
  18. package/dist/components/index.d.ts.map +1 -0
  19. package/dist/components/index.js +23 -0
  20. package/dist/components/index.js.map +1 -0
  21. package/dist/core/fonts.d.ts +87 -0
  22. package/dist/core/fonts.d.ts.map +1 -0
  23. package/dist/core/fonts.js +159 -0
  24. package/dist/core/fonts.js.map +1 -0
  25. package/dist/core/index.d.ts +2 -0
  26. package/dist/core/index.d.ts.map +1 -1
  27. package/dist/core/index.js +6 -1
  28. package/dist/core/index.js.map +1 -1
  29. package/dist/index.d.ts +3 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +4 -2
  32. package/dist/index.js.map +1 -1
  33. package/dist/primitives/BrandedFooter.d.ts +18 -0
  34. package/dist/primitives/BrandedFooter.d.ts.map +1 -0
  35. package/dist/primitives/BrandedFooter.js +35 -0
  36. package/dist/primitives/BrandedFooter.js.map +1 -0
  37. package/dist/primitives/BrandedHeader.d.ts +41 -0
  38. package/dist/primitives/BrandedHeader.d.ts.map +1 -0
  39. package/dist/primitives/BrandedHeader.js +52 -0
  40. package/dist/primitives/BrandedHeader.js.map +1 -0
  41. package/dist/primitives/Document.d.ts +21 -0
  42. package/dist/primitives/Document.d.ts.map +1 -0
  43. package/dist/primitives/Document.js +19 -0
  44. package/dist/primitives/Document.js.map +1 -0
  45. package/dist/primitives/Page.d.ts +27 -0
  46. package/dist/primitives/Page.d.ts.map +1 -0
  47. package/dist/primitives/Page.js +32 -0
  48. package/dist/primitives/Page.js.map +1 -0
  49. package/dist/primitives/Watermark.d.ts +25 -0
  50. package/dist/primitives/Watermark.d.ts.map +1 -0
  51. package/dist/primitives/Watermark.js +35 -0
  52. package/dist/primitives/Watermark.js.map +1 -0
  53. package/dist/primitives/index.d.ts +21 -0
  54. package/dist/primitives/index.d.ts.map +1 -0
  55. package/dist/primitives/index.js +24 -0
  56. package/dist/primitives/index.js.map +1 -0
  57. package/fonts/NotoSans-Bold.woff +0 -0
  58. package/fonts/NotoSans-Regular.woff +0 -0
  59. package/fonts/NotoSansDevanagari-Bold.woff +0 -0
  60. package/fonts/NotoSansDevanagari-Regular.woff +0 -0
  61. package/package.json +26 -5
@@ -0,0 +1,23 @@
1
+ /**
2
+ * KeyValueTable — two-column label/value grid.
3
+ *
4
+ * Used for invoice/receipt metadata blocks (student name, due date, invoice
5
+ * number, etc.) and for student-info on report cards and admit cards.
6
+ *
7
+ * Caller passes a flat `entries` array. Empty values are skipped automatically
8
+ * (so a missing email doesn't render a blank row).
9
+ */
10
+ import * as React from 'react';
11
+ export interface KeyValueEntry {
12
+ label: string;
13
+ value: string | number | null | undefined;
14
+ }
15
+ export interface KeyValueTableProps {
16
+ entries: KeyValueEntry[];
17
+ /** Column widths as Flex ratios. Defaults to [1, 2] (label gets 1/3 of width). */
18
+ columnRatios?: [number, number];
19
+ /** Hide empty / null / undefined values rather than rendering blank rows. Default true. */
20
+ skipEmpty?: boolean;
21
+ }
22
+ export declare const KeyValueTable: React.FC<KeyValueTableProps>;
23
+ //# sourceMappingURL=KeyValueTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KeyValueTable.d.ts","sourceRoot":"","sources":["../../src/components/KeyValueTable.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAC3C;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,kFAAkF;IAClF,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,2FAA2F;IAC3F,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAyBD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA0BtD,CAAC"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KeyValueTable = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const renderer_1 = require("@react-pdf/renderer");
6
+ const theme_1 = require("../core/theme");
7
+ const fonts_1 = require("../core/fonts");
8
+ const styles = renderer_1.StyleSheet.create({
9
+ container: {
10
+ flexDirection: 'column',
11
+ marginBottom: theme_1.DEFAULT_SPACING.md,
12
+ },
13
+ row: {
14
+ flexDirection: 'row',
15
+ paddingVertical: 2,
16
+ },
17
+ label: {
18
+ fontSize: theme_1.DEFAULT_FONT_SIZE.sm,
19
+ color: theme_1.DEFAULT_COLORS.textMuted,
20
+ fontWeight: 'bold',
21
+ },
22
+ value: {
23
+ fontSize: theme_1.DEFAULT_FONT_SIZE.sm,
24
+ color: theme_1.DEFAULT_COLORS.text,
25
+ },
26
+ });
27
+ const isEmpty = (v) => v === null || v === undefined || (typeof v === 'string' && v.trim() === '');
28
+ const KeyValueTable = ({ entries, columnRatios = [1, 2], skipEmpty = true, }) => {
29
+ const visible = skipEmpty ? entries.filter((e) => !isEmpty(e.value)) : entries;
30
+ const [labelFlex, valueFlex] = columnRatios;
31
+ return ((0, jsx_runtime_1.jsx)(renderer_1.View, { style: styles.container, children: visible.map((entry, idx) => {
32
+ const valueStr = entry.value === null || entry.value === undefined ? '' : String(entry.value);
33
+ return ((0, jsx_runtime_1.jsxs)(renderer_1.View, { style: styles.row, children: [(0, jsx_runtime_1.jsx)(renderer_1.Text, { style: [styles.label, { flex: labelFlex, fontFamily: (0, fonts_1.pickFontFamily)(entry.label) }], children: entry.label }), (0, jsx_runtime_1.jsx)(renderer_1.Text, { style: [styles.value, { flex: valueFlex, fontFamily: (0, fonts_1.pickFontFamily)(valueStr) }], children: valueStr })] }, idx));
34
+ }) }));
35
+ };
36
+ exports.KeyValueTable = KeyValueTable;
37
+ //# sourceMappingURL=KeyValueTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KeyValueTable.js","sourceRoot":"","sources":["../../src/components/KeyValueTable.tsx"],"names":[],"mappings":";;;;AAWA,kDAA6D;AAC7D,yCAAmF;AACnF,yCAA+C;AAe/C,MAAM,MAAM,GAAG,qBAAU,CAAC,MAAM,CAAC;IAC/B,SAAS,EAAE;QACT,aAAa,EAAE,QAAQ;QACvB,YAAY,EAAE,uBAAe,CAAC,EAAE;KACjC;IACD,GAAG,EAAE;QACH,aAAa,EAAE,KAAK;QACpB,eAAe,EAAE,CAAC;KACnB;IACD,KAAK,EAAE;QACL,QAAQ,EAAE,yBAAiB,CAAC,EAAE;QAC9B,KAAK,EAAE,sBAAc,CAAC,SAAS;QAC/B,UAAU,EAAE,MAAM;KACnB;IACD,KAAK,EAAE;QACL,QAAQ,EAAE,yBAAiB,CAAC,EAAE;QAC9B,KAAK,EAAE,sBAAc,CAAC,IAAI;KAC3B;CACF,CAAC,CAAC;AAEH,MAAM,OAAO,GAAG,CAAC,CAAyB,EAAW,EAAE,CACrD,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAEvE,MAAM,aAAa,GAAiC,CAAC,EAC1D,OAAO,EACP,YAAY,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EACrB,SAAS,GAAG,IAAI,GACjB,EAAE,EAAE;IACH,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC/E,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG,YAAY,CAAC;IAE5C,OAAO,CACL,uBAAC,eAAI,IAAC,KAAK,EAAE,MAAM,CAAC,SAAS,YAC1B,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YAC1B,MAAM,QAAQ,GACZ,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC/E,OAAO,CACL,wBAAC,eAAI,IAAW,KAAK,EAAE,MAAM,CAAC,GAAG,aAC/B,uBAAC,eAAI,IAAC,KAAK,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,IAAA,sBAAc,EAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,YACtF,KAAK,CAAC,KAAK,GACP,EACP,uBAAC,eAAI,IAAC,KAAK,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,IAAA,sBAAc,EAAC,QAAQ,CAAC,EAAE,CAAC,YACnF,QAAQ,GACJ,KANE,GAAG,CAOP,CACR,CAAC;QACJ,CAAC,CAAC,GACG,CACR,CAAC;AACJ,CAAC,CAAC;AA1BW,QAAA,aAAa,iBA0BxB"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * LineItemTable — configurable-column tabular block.
3
+ *
4
+ * The columns visible in any render are driven by template config. The full
5
+ * set: description / quantity / amount / discount / taxRate / taxAmount / total.
6
+ * Description, amount, and total are always shown (per design § 2.1 invariant);
7
+ * the rest toggle.
8
+ *
9
+ * Used by Invoice, Receipt, and (post-V1) Fee Statement.
10
+ */
11
+ import * as React from 'react';
12
+ export interface LineItem {
13
+ description: string;
14
+ quantity?: number;
15
+ amount: number;
16
+ discount?: number;
17
+ taxRate?: number;
18
+ taxAmount?: number;
19
+ total: number;
20
+ }
21
+ export interface LineItemColumns {
22
+ /**
23
+ * Required column. The runtime always includes description regardless of this
24
+ * field's value — kept in the type only so the interface enumerates every column.
25
+ */
26
+ description: boolean;
27
+ quantity: boolean;
28
+ /** Required column — see `description`. */
29
+ amount: boolean;
30
+ discount: boolean;
31
+ taxRate: boolean;
32
+ taxAmount: boolean;
33
+ /** Required column — see `description`. */
34
+ total: boolean;
35
+ }
36
+ export interface LineItemTableProps {
37
+ items: LineItem[];
38
+ columns: LineItemColumns;
39
+ /** Map of header-label keys to display strings. Caller passes localized values. */
40
+ headers: {
41
+ description: string;
42
+ quantity: string;
43
+ amount: string;
44
+ discount: string;
45
+ taxRate: string;
46
+ taxAmount: string;
47
+ total: string;
48
+ };
49
+ /** Render numeric values. Caller passes `formatNumber` or `formatCurrency` bound function. */
50
+ renderNumber: (value: number | undefined) => string;
51
+ }
52
+ export declare const LineItemTable: React.FC<LineItemTableProps>;
53
+ //# sourceMappingURL=LineItemTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LineItemTable.d.ts","sourceRoot":"","sources":["../../src/components/LineItemTable.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,MAAM,WAAW,QAAQ;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,2CAA2C;IAC3C,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,2CAA2C;IAC3C,KAAK,EAAE,OAAO,CAAC;CAChB;AAmBD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,OAAO,EAAE,eAAe,CAAC;IACzB,mFAAmF;IACnF,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,8FAA8F;IAC9F,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,MAAM,CAAC;CACrD;AA+CD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAqEtD,CAAC"}
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LineItemTable = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const renderer_1 = require("@react-pdf/renderer");
6
+ const theme_1 = require("../core/theme");
7
+ const fonts_1 = require("../core/fonts");
8
+ /**
9
+ * Render order is fixed by this array, not by `Object.keys(columns)`. Required
10
+ * columns (`description`, `amount`, `total`) are always emitted; optional
11
+ * columns appear iff `columns[key]` is truthy.
12
+ */
13
+ const COLUMN_RENDER_ORDER = [
14
+ 'description',
15
+ 'quantity',
16
+ 'amount',
17
+ 'discount',
18
+ 'taxRate',
19
+ 'taxAmount',
20
+ 'total',
21
+ ];
22
+ const REQUIRED_COLUMNS = new Set(['description', 'amount', 'total']);
23
+ const styles = renderer_1.StyleSheet.create({
24
+ table: {
25
+ flexDirection: 'column',
26
+ marginBottom: theme_1.DEFAULT_SPACING.md,
27
+ },
28
+ headerRow: {
29
+ flexDirection: 'row',
30
+ backgroundColor: theme_1.DEFAULT_COLORS.border,
31
+ paddingVertical: theme_1.DEFAULT_SPACING.xs,
32
+ paddingHorizontal: theme_1.DEFAULT_SPACING.sm,
33
+ borderBottomWidth: 1,
34
+ borderBottomColor: theme_1.DEFAULT_COLORS.textMuted,
35
+ },
36
+ row: {
37
+ flexDirection: 'row',
38
+ paddingVertical: theme_1.DEFAULT_SPACING.xs,
39
+ paddingHorizontal: theme_1.DEFAULT_SPACING.sm,
40
+ borderBottomWidth: 1,
41
+ borderBottomColor: theme_1.DEFAULT_COLORS.border,
42
+ },
43
+ headerCell: {
44
+ fontSize: theme_1.DEFAULT_FONT_SIZE.sm,
45
+ fontWeight: 'bold',
46
+ color: theme_1.DEFAULT_COLORS.text,
47
+ },
48
+ cell: {
49
+ fontSize: theme_1.DEFAULT_FONT_SIZE.sm,
50
+ color: theme_1.DEFAULT_COLORS.text,
51
+ },
52
+ numericCell: {
53
+ textAlign: 'right',
54
+ },
55
+ });
56
+ // Each column has a flex ratio when visible. Description gets the biggest share.
57
+ const COLUMN_FLEX = {
58
+ description: 4,
59
+ quantity: 1,
60
+ amount: 2,
61
+ discount: 1.5,
62
+ taxRate: 1,
63
+ taxAmount: 1.5,
64
+ total: 2,
65
+ };
66
+ const LineItemTable = ({ items, columns, headers, renderNumber, }) => {
67
+ // Deterministic render order: filter by COLUMN_RENDER_ORDER, force-include
68
+ // REQUIRED_COLUMNS regardless of the caller's columns[key] value.
69
+ const visibleKeys = COLUMN_RENDER_ORDER.filter((k) => REQUIRED_COLUMNS.has(k) || columns[k]);
70
+ return ((0, jsx_runtime_1.jsxs)(renderer_1.View, { style: styles.table, children: [(0, jsx_runtime_1.jsx)(renderer_1.View, { style: styles.headerRow, children: visibleKeys.map((key) => ((0, jsx_runtime_1.jsx)(renderer_1.Text, { style: [
71
+ styles.headerCell,
72
+ { flex: COLUMN_FLEX[key], fontFamily: (0, fonts_1.pickFontFamily)(headers[key]) },
73
+ key !== 'description' ? styles.numericCell : {},
74
+ ], children: headers[key] }, key))) }), items.map((item, idx) => ((0, jsx_runtime_1.jsx)(renderer_1.View, { style: styles.row, children: visibleKeys.map((key) => {
75
+ const flex = COLUMN_FLEX[key];
76
+ if (key === 'description') {
77
+ return ((0, jsx_runtime_1.jsx)(renderer_1.Text, { style: [styles.cell, { flex, fontFamily: (0, fonts_1.pickFontFamily)(item.description) }], children: item.description }, key));
78
+ }
79
+ const rawValue = key === 'quantity'
80
+ ? item.quantity
81
+ : key === 'amount'
82
+ ? item.amount
83
+ : key === 'discount'
84
+ ? item.discount
85
+ : key === 'taxRate'
86
+ ? item.taxRate
87
+ : key === 'taxAmount'
88
+ ? item.taxAmount
89
+ : item.total;
90
+ const display = key === 'taxRate' && rawValue !== undefined
91
+ ? `${rawValue}%`
92
+ : renderNumber(rawValue);
93
+ // Numeric cells use Latin family for digits (Latin Arabic numerals
94
+ // render fine in either font, but Latin is the canonical home).
95
+ return ((0, jsx_runtime_1.jsx)(renderer_1.Text, { style: [styles.cell, styles.numericCell, { flex }], children: display }, key));
96
+ }) }, idx)))] }));
97
+ };
98
+ exports.LineItemTable = LineItemTable;
99
+ //# sourceMappingURL=LineItemTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LineItemTable.js","sourceRoot":"","sources":["../../src/components/LineItemTable.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * SignatureLine — a horizontal rule with a caption underneath.
3
+ *
4
+ * Used at the bottom of receipts, certificates, admit cards. Caller supplies
5
+ * the caption (localized) — the component is layout-only. Optional
6
+ * pre-rendered signature image source rendered above the line.
7
+ */
8
+ import * as React from 'react';
9
+ import { type ImageSource } from '../core/fonts';
10
+ export interface SignatureLineProps {
11
+ caption: string;
12
+ /**
13
+ * Optional signature image rendered above the line. Accepts URL string,
14
+ * Buffer, or react-pdf SourceObject literal — see `ImageSource` in
15
+ * `core/fonts.ts`.
16
+ */
17
+ signatureSrc?: ImageSource;
18
+ /** Width of the signature block as % of container. Defaults to 40%. */
19
+ width?: string;
20
+ /** Stack alignment. Defaults to left. */
21
+ align?: 'left' | 'right';
22
+ }
23
+ export declare const SignatureLine: React.FC<SignatureLineProps>;
24
+ //# sourceMappingURL=SignatureLine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignatureLine.d.ts","sourceRoot":"","sources":["../../src/components/SignatureLine.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjE,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAyBD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAatD,CAAC"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SignatureLine = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const renderer_1 = require("@react-pdf/renderer");
6
+ const theme_1 = require("../core/theme");
7
+ const fonts_1 = require("../core/fonts");
8
+ const styles = renderer_1.StyleSheet.create({
9
+ container: {
10
+ flexDirection: 'column',
11
+ marginTop: theme_1.DEFAULT_SPACING.lg,
12
+ },
13
+ signature: {
14
+ height: 32,
15
+ objectFit: 'contain',
16
+ marginBottom: 2,
17
+ },
18
+ line: {
19
+ borderBottomWidth: 1,
20
+ borderBottomColor: theme_1.DEFAULT_COLORS.text,
21
+ marginBottom: 2,
22
+ minHeight: 24,
23
+ },
24
+ caption: {
25
+ fontSize: theme_1.DEFAULT_FONT_SIZE.xs,
26
+ color: theme_1.DEFAULT_COLORS.textMuted,
27
+ textAlign: 'center',
28
+ },
29
+ });
30
+ const SignatureLine = ({ caption, signatureSrc, width = '40%', align = 'left', }) => {
31
+ return ((0, jsx_runtime_1.jsxs)(renderer_1.View, { style: [styles.container, { width, alignSelf: align === 'right' ? 'flex-end' : 'flex-start' }], children: [signatureSrc && (0, jsx_runtime_1.jsx)(renderer_1.Image, { style: styles.signature, src: signatureSrc }), (0, jsx_runtime_1.jsx)(renderer_1.View, { style: styles.line }), (0, jsx_runtime_1.jsx)(renderer_1.Text, { style: [styles.caption, { fontFamily: (0, fonts_1.pickFontFamily)(caption) }], children: caption })] }));
32
+ };
33
+ exports.SignatureLine = SignatureLine;
34
+ //# sourceMappingURL=SignatureLine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignatureLine.js","sourceRoot":"","sources":["../../src/components/SignatureLine.tsx"],"names":[],"mappings":";;;;AASA,kDAAoE;AACpE,yCAAmF;AACnF,yCAAiE;AAgBjE,MAAM,MAAM,GAAG,qBAAU,CAAC,MAAM,CAAC;IAC/B,SAAS,EAAE;QACT,aAAa,EAAE,QAAQ;QACvB,SAAS,EAAE,uBAAe,CAAC,EAAE;KAC9B;IACD,SAAS,EAAE;QACT,MAAM,EAAE,EAAE;QACV,SAAS,EAAE,SAAS;QACpB,YAAY,EAAE,CAAC;KAChB;IACD,IAAI,EAAE;QACJ,iBAAiB,EAAE,CAAC;QACpB,iBAAiB,EAAE,sBAAc,CAAC,IAAI;QACtC,YAAY,EAAE,CAAC;QACf,SAAS,EAAE,EAAE;KACd;IACD,OAAO,EAAE;QACP,QAAQ,EAAE,yBAAiB,CAAC,EAAE;QAC9B,KAAK,EAAE,sBAAc,CAAC,SAAS;QAC/B,SAAS,EAAE,QAAQ;KACpB;CACF,CAAC,CAAC;AAEI,MAAM,aAAa,GAAiC,CAAC,EAC1D,OAAO,EACP,YAAY,EACZ,KAAK,GAAG,KAAK,EACb,KAAK,GAAG,MAAM,GACf,EAAE,EAAE;IACH,OAAO,CACL,wBAAC,eAAI,IAAC,KAAK,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,aACjG,YAAY,IAAI,uBAAC,gBAAK,IAAC,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE,YAAY,GAAI,EACtE,uBAAC,eAAI,IAAC,KAAK,EAAE,MAAM,CAAC,IAAI,GAAI,EAC5B,uBAAC,eAAI,IAAC,KAAK,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,IAAA,sBAAc,EAAC,OAAO,CAAC,EAAE,CAAC,YAAG,OAAO,GAAQ,IACnF,CACR,CAAC;AACJ,CAAC,CAAC;AAbW,QAAA,aAAa,iBAaxB"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * TotalsBlock — right-aligned summary block stacking subtotal / tax / discount
3
+ * / grand total / amount paid / amount due.
4
+ *
5
+ * Lines are conditional via the template's `totalsSection` config — same
6
+ * pattern as LineItemTable columns. The grand-total row gets visual emphasis
7
+ * (bold + larger font) to anchor the eye.
8
+ */
9
+ import * as React from 'react';
10
+ export interface TotalsBlockEntries {
11
+ subtotal?: number;
12
+ taxTotal?: number;
13
+ discountTotal?: number;
14
+ grandTotal: number;
15
+ amountPaid?: number;
16
+ amountDue?: number;
17
+ }
18
+ export interface TotalsBlockVisibility {
19
+ showSubtotal?: boolean;
20
+ showTaxTotal?: boolean;
21
+ showDiscountTotal?: boolean;
22
+ showAmountPaid?: boolean;
23
+ showAmountDue?: boolean;
24
+ }
25
+ export interface TotalsBlockLabels {
26
+ subtotal: string;
27
+ taxTotal: string;
28
+ discountTotal: string;
29
+ grandTotal: string;
30
+ amountPaid: string;
31
+ amountDue: string;
32
+ }
33
+ export interface TotalsBlockProps {
34
+ entries: TotalsBlockEntries;
35
+ visibility?: TotalsBlockVisibility;
36
+ labels: TotalsBlockLabels;
37
+ /** Caller-provided currency formatter; the block is currency-agnostic. */
38
+ renderCurrency: (value: number) => string;
39
+ }
40
+ export declare const TotalsBlock: React.FC<TotalsBlockProps>;
41
+ //# sourceMappingURL=TotalsBlock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TotalsBlock.d.ts","sourceRoot":"","sources":["../../src/components/TotalsBlock.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,0EAA0E;IAC1E,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CAC3C;AA+CD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA2DlD,CAAC"}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TotalsBlock = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const renderer_1 = require("@react-pdf/renderer");
6
+ const theme_1 = require("../core/theme");
7
+ const fonts_1 = require("../core/fonts");
8
+ const styles = renderer_1.StyleSheet.create({
9
+ container: {
10
+ flexDirection: 'column',
11
+ alignSelf: 'flex-end',
12
+ width: '50%',
13
+ marginBottom: theme_1.DEFAULT_SPACING.md,
14
+ },
15
+ row: {
16
+ flexDirection: 'row',
17
+ justifyContent: 'space-between',
18
+ paddingVertical: 2,
19
+ borderBottomWidth: 0.5,
20
+ borderBottomColor: theme_1.DEFAULT_COLORS.border,
21
+ },
22
+ rowGrand: {
23
+ paddingVertical: 4,
24
+ borderTopWidth: 1,
25
+ borderTopColor: theme_1.DEFAULT_COLORS.text,
26
+ borderBottomWidth: 1,
27
+ borderBottomColor: theme_1.DEFAULT_COLORS.text,
28
+ marginTop: theme_1.DEFAULT_SPACING.xs,
29
+ },
30
+ label: {
31
+ fontSize: theme_1.DEFAULT_FONT_SIZE.sm,
32
+ color: theme_1.DEFAULT_COLORS.textMuted,
33
+ },
34
+ labelGrand: {
35
+ fontSize: theme_1.DEFAULT_FONT_SIZE.md,
36
+ fontWeight: 'bold',
37
+ color: theme_1.DEFAULT_COLORS.text,
38
+ },
39
+ value: {
40
+ fontSize: theme_1.DEFAULT_FONT_SIZE.sm,
41
+ color: theme_1.DEFAULT_COLORS.text,
42
+ },
43
+ valueGrand: {
44
+ fontSize: theme_1.DEFAULT_FONT_SIZE.md,
45
+ fontWeight: 'bold',
46
+ color: theme_1.DEFAULT_COLORS.text,
47
+ },
48
+ valueDanger: {
49
+ color: theme_1.DEFAULT_COLORS.danger,
50
+ },
51
+ });
52
+ const TotalsBlock = ({ entries, visibility = {}, labels, renderCurrency, }) => {
53
+ const { showSubtotal = true, showTaxTotal = true, showDiscountTotal = true, showAmountPaid = true, showAmountDue = true, } = visibility;
54
+ // Labels are localized strings — pick family per label.
55
+ // Values come from the caller's currency formatter; assume Latin numerals.
56
+ return ((0, jsx_runtime_1.jsxs)(renderer_1.View, { style: styles.container, children: [showSubtotal && entries.subtotal !== undefined && ((0, jsx_runtime_1.jsxs)(renderer_1.View, { style: styles.row, children: [(0, jsx_runtime_1.jsx)(renderer_1.Text, { style: [styles.label, { fontFamily: (0, fonts_1.pickFontFamily)(labels.subtotal) }], children: labels.subtotal }), (0, jsx_runtime_1.jsx)(renderer_1.Text, { style: styles.value, children: renderCurrency(entries.subtotal) })] })), showDiscountTotal && entries.discountTotal !== undefined && entries.discountTotal > 0 && ((0, jsx_runtime_1.jsxs)(renderer_1.View, { style: styles.row, children: [(0, jsx_runtime_1.jsx)(renderer_1.Text, { style: [styles.label, { fontFamily: (0, fonts_1.pickFontFamily)(labels.discountTotal) }], children: labels.discountTotal }), (0, jsx_runtime_1.jsxs)(renderer_1.Text, { style: styles.value, children: ["\u2212", renderCurrency(entries.discountTotal)] })] })), showTaxTotal && entries.taxTotal !== undefined && entries.taxTotal > 0 && ((0, jsx_runtime_1.jsxs)(renderer_1.View, { style: styles.row, children: [(0, jsx_runtime_1.jsx)(renderer_1.Text, { style: [styles.label, { fontFamily: (0, fonts_1.pickFontFamily)(labels.taxTotal) }], children: labels.taxTotal }), (0, jsx_runtime_1.jsx)(renderer_1.Text, { style: styles.value, children: renderCurrency(entries.taxTotal) })] })), (0, jsx_runtime_1.jsxs)(renderer_1.View, { style: [styles.row, styles.rowGrand], children: [(0, jsx_runtime_1.jsx)(renderer_1.Text, { style: [styles.labelGrand, { fontFamily: (0, fonts_1.pickFontFamily)(labels.grandTotal) }], children: labels.grandTotal }), (0, jsx_runtime_1.jsx)(renderer_1.Text, { style: styles.valueGrand, children: renderCurrency(entries.grandTotal) })] }), showAmountPaid && entries.amountPaid !== undefined && ((0, jsx_runtime_1.jsxs)(renderer_1.View, { style: styles.row, children: [(0, jsx_runtime_1.jsx)(renderer_1.Text, { style: [styles.label, { fontFamily: (0, fonts_1.pickFontFamily)(labels.amountPaid) }], children: labels.amountPaid }), (0, jsx_runtime_1.jsx)(renderer_1.Text, { style: styles.value, children: renderCurrency(entries.amountPaid) })] })), showAmountDue && entries.amountDue !== undefined && ((0, jsx_runtime_1.jsxs)(renderer_1.View, { style: styles.row, children: [(0, jsx_runtime_1.jsx)(renderer_1.Text, { style: [styles.label, { fontFamily: (0, fonts_1.pickFontFamily)(labels.amountDue) }], children: labels.amountDue }), (0, jsx_runtime_1.jsx)(renderer_1.Text, { style: [styles.value, entries.amountDue > 0 ? styles.valueDanger : {}], children: renderCurrency(entries.amountDue) })] }))] }));
57
+ };
58
+ exports.TotalsBlock = TotalsBlock;
59
+ //# sourceMappingURL=TotalsBlock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TotalsBlock.js","sourceRoot":"","sources":["../../src/components/TotalsBlock.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Reusable components — composed from primitives, consumed by documents.
3
+ *
4
+ * Sprint C.0.3:
5
+ * - KeyValueTable — 2-col label/value grid (invoice metadata, student info)
6
+ * - LineItemTable — configurable-column tabular block (invoice line items)
7
+ * - TotalsBlock — right-aligned subtotal/tax/grand-total/paid/due stack
8
+ * - SignatureLine — horizontal rule + caption (signed-by markers)
9
+ *
10
+ * GradeTable / StudentPhotoFrame / BarcodeQR ship later (C.3 / C.5).
11
+ */
12
+ export { KeyValueTable } from './KeyValueTable';
13
+ export type { KeyValueTableProps, KeyValueEntry } from './KeyValueTable';
14
+ export { LineItemTable } from './LineItemTable';
15
+ export type { LineItemTableProps, LineItem, LineItemColumns, } from './LineItemTable';
16
+ export { TotalsBlock } from './TotalsBlock';
17
+ export type { TotalsBlockProps, TotalsBlockEntries, TotalsBlockVisibility, TotalsBlockLabels, } from './TotalsBlock';
18
+ export { SignatureLine } from './SignatureLine';
19
+ export type { SignatureLineProps } from './SignatureLine';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEzE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EACV,kBAAkB,EAClB,QAAQ,EACR,eAAe,GAChB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ /**
3
+ * Reusable components — composed from primitives, consumed by documents.
4
+ *
5
+ * Sprint C.0.3:
6
+ * - KeyValueTable — 2-col label/value grid (invoice metadata, student info)
7
+ * - LineItemTable — configurable-column tabular block (invoice line items)
8
+ * - TotalsBlock — right-aligned subtotal/tax/grand-total/paid/due stack
9
+ * - SignatureLine — horizontal rule + caption (signed-by markers)
10
+ *
11
+ * GradeTable / StudentPhotoFrame / BarcodeQR ship later (C.3 / C.5).
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.SignatureLine = exports.TotalsBlock = exports.LineItemTable = exports.KeyValueTable = void 0;
15
+ var KeyValueTable_1 = require("./KeyValueTable");
16
+ Object.defineProperty(exports, "KeyValueTable", { enumerable: true, get: function () { return KeyValueTable_1.KeyValueTable; } });
17
+ var LineItemTable_1 = require("./LineItemTable");
18
+ Object.defineProperty(exports, "LineItemTable", { enumerable: true, get: function () { return LineItemTable_1.LineItemTable; } });
19
+ var TotalsBlock_1 = require("./TotalsBlock");
20
+ Object.defineProperty(exports, "TotalsBlock", { enumerable: true, get: function () { return TotalsBlock_1.TotalsBlock; } });
21
+ var SignatureLine_1 = require("./SignatureLine");
22
+ Object.defineProperty(exports, "SignatureLine", { enumerable: true, get: function () { return SignatureLine_1.SignatureLine; } });
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AAEH,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AAGtB,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AAOtB,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AAQpB,iDAAgD;AAAvC,8GAAA,aAAa,OAAA"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Font registration for @aibrains/pdf-renderer.
3
+ *
4
+ * Two font families ship with the package:
5
+ * - `Noto Sans` — Latin script (Regular + Bold)
6
+ * - `Noto Sans Devanagari` — Devanagari script for Nepali (Regular + Bold)
7
+ *
8
+ * Both are sourced from @fontsource/* at build time and copied to ./fonts/ at the
9
+ * package root (see scripts/copy-fonts.js). At runtime, paths resolve identically
10
+ * from `src/core/fonts.ts` and `dist/core/fonts.js` because both live two
11
+ * directories below the package root (../../fonts/).
12
+ *
13
+ * Devanagari rendering uses Yoga + Fontkit + Harfbuzz inside @react-pdf/renderer v4
14
+ * to handle complex script shaping (conjuncts, vowel marks). This is the canary for
15
+ * Risk R45 (Devanagari shaping defects in production); snapshot tests in the
16
+ * primitives + components directories exercise the pipeline.
17
+ *
18
+ * Call `registerFonts()` exactly once per process before the first render. The
19
+ * `Document` primitive (in `primitives/Document.tsx`) does this automatically.
20
+ *
21
+ * For browser consumers (Shell live-preview via `<PDFViewer>`), the same fonts
22
+ * are bundled in the published tarball; consumers' bundlers (Rsbuild, Webpack)
23
+ * pick them up via the relative path. URL-based registration for CDN deployments
24
+ * is a Sprint C.2 concern.
25
+ */
26
+ /** Latin font family registered by `registerFonts()`. */
27
+ export declare const FONT_FAMILY_LATIN: "Noto Sans";
28
+ /** Devanagari (Nepali) font family registered by `registerFonts()`. */
29
+ export declare const FONT_FAMILY_DEVANAGARI: "Noto Sans Devanagari";
30
+ /**
31
+ * Pick the correct font family for a text run.
32
+ *
33
+ * `@react-pdf/renderer` does NOT support CSS-style font-fallback chains —
34
+ * each text run uses exactly one font family. For mixed-script content
35
+ * (e.g., dual-language labels "Invoice / बिल"), components must split into
36
+ * separate `<Text>` elements and call this helper per segment.
37
+ *
38
+ * Detection rule: **any-Devanagari-wins**. The implementation tests
39
+ * `DEVANAGARI_RANGE.test(str)`, which returns true if ANY codepoint in the
40
+ * string falls in the Devanagari block — regardless of position. So
41
+ * `pickFontFamily('Invoice / बिल')` returns `FONT_FAMILY_DEVANAGARI` even
42
+ * though Latin appears first. This is intentional for V1: when a Devanagari
43
+ * character is present, we always need its font to render correctly; the
44
+ * Latin characters in `Noto Sans Devanagari` render acceptably (the font
45
+ * includes Basic Latin glyphs). If first-script-wins semantics are ever
46
+ * needed, change `DEVANAGARI_RANGE.test(str)` to scan only the first script
47
+ * cluster.
48
+ *
49
+ * @example
50
+ * pickFontFamily('Subtotal') // 'Noto Sans'
51
+ * pickFontFamily('उप-योग') // 'Noto Sans Devanagari'
52
+ * pickFontFamily('Invoice / बिल') // 'Noto Sans Devanagari' (any-Devanagari-wins)
53
+ * pickFontFamily('बिल / Invoice') // 'Noto Sans Devanagari'
54
+ * pickFontFamily('') // 'Noto Sans' (default for empty / null / undefined)
55
+ */
56
+ export declare function pickFontFamily(text: string | number | null | undefined): typeof FONT_FAMILY_LATIN | typeof FONT_FAMILY_DEVANAGARI;
57
+ /**
58
+ * Image source type accepted by `<Image>` components in this library.
59
+ *
60
+ * Narrowed subset of `@react-pdf/renderer`'s `SourceObject`:
61
+ * - `string` — URL (absolute http(s)) or absolute filesystem path
62
+ * - `Buffer` — Node Buffer (Lambda / server-side use)
63
+ *
64
+ * V1 deliberately excludes:
65
+ * - `SourceURLObject` literal (`{uri, method, body, headers}`) — the
66
+ * `method` field is typed as a narrow `HTTPMethod` enum upstream and
67
+ * callers rarely need request-shaping; if a future use case demands
68
+ * authenticated HTTP fetches, callers can cast at the site.
69
+ * - Factory + async variants — generating PDFs from dynamic factories
70
+ * isn't a V1 use case.
71
+ *
72
+ * Compatible at the value level with everything react-pdf's Image accepts
73
+ * for these two forms.
74
+ */
75
+ export type ImageSource = string | Buffer;
76
+ /**
77
+ * Register the bundled fonts with `@react-pdf/renderer`. Idempotent — safe to
78
+ * call multiple times; subsequent calls short-circuit.
79
+ *
80
+ * Throws if the font files are not on disk (which means `npm run build` was
81
+ * never run after installation). Surfaces a clear error rather than silently
82
+ * rendering with the default font.
83
+ */
84
+ export declare function registerFonts(): void;
85
+ /** Test-only escape hatch — resets the registration guard so a test can re-register. */
86
+ export declare function _resetFontsForTest(): void;
87
+ //# sourceMappingURL=fonts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../../src/core/fonts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAQH,yDAAyD;AACzD,eAAO,MAAM,iBAAiB,EAAG,WAAoB,CAAC;AACtD,uEAAuE;AACvE,eAAO,MAAM,sBAAsB,EAAG,sBAA+B,CAAC;AAStE;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GACvC,OAAO,iBAAiB,GAAG,OAAO,sBAAsB,CAI1D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;AAI1C;;;;;;;GAOG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAoCpC;AAED,wFAAwF;AACxF,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}