@hidemikimura/receipt-html-to-pdf 0.1.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.
- package/CHANGELOG.md +44 -0
- package/LICENSE +21 -0
- package/README.md +109 -0
- package/dist/receipt-html-to-pdf.min.js +39 -0
- package/dist/receipt-html-to-pdf.min.js.map +7 -0
- package/examples/lit.js +52 -0
- package/examples/react.jsx +56 -0
- package/examples/vanilla.html +55 -0
- package/package.json +82 -0
- package/src/font/cid.js +187 -0
- package/src/font/parse.js +336 -0
- package/src/font/registry.js +168 -0
- package/src/font/subset.js +211 -0
- package/src/index.js +239 -0
- package/src/page.js +429 -0
- package/src/paginate.js +119 -0
- package/src/pdf/compress.js +30 -0
- package/src/pdf/content.js +192 -0
- package/src/pdf/image.js +33 -0
- package/src/pdf/writer.js +253 -0
- package/src/renderer.js +328 -0
- package/src/units.js +127 -0
- package/src/walker/image.js +264 -0
- package/src/walker/text.js +199 -0
- package/src/walker/walk.js +670 -0
- package/types/font/cid.d.ts +40 -0
- package/types/font/parse.d.ts +113 -0
- package/types/font/registry.d.ts +63 -0
- package/types/font/subset.d.ts +26 -0
- package/types/index.d.ts +198 -0
- package/types/page.d.ts +64 -0
- package/types/paginate.d.ts +59 -0
- package/types/pdf/compress.d.ts +13 -0
- package/types/pdf/content.d.ts +65 -0
- package/types/pdf/image.d.ts +9 -0
- package/types/pdf/writer.d.ts +125 -0
- package/types/renderer.d.ts +55 -0
- package/types/units.d.ts +53 -0
- package/types/walker/image.d.ts +72 -0
- package/types/walker/text.d.ts +38 -0
- package/types/walker/walk.d.ts +150 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
設計と経緯の詳細は docs/design.md。
|
|
4
|
+
|
|
5
|
+
## 0.1.0 — 初回公開(2026-09-18)
|
|
6
|
+
|
|
7
|
+
npm への最初の公開バージョン。開発中の内部マイルストーン(下記 0.1〜1.0)をまとめて 0.1.0 として出す。
|
|
8
|
+
API(`registerFont` / `htmlToPdf` / `downloadPdf` / `listFonts` / `version`、`ConvertOptions`)は 1.0.0 までは変更の可能性がある。
|
|
9
|
+
|
|
10
|
+
### 開発マイルストーン(内部、未公開)
|
|
11
|
+
|
|
12
|
+
#### 1.0 相当
|
|
13
|
+
|
|
14
|
+
- npm 公開準備: `private` を外し `publishConfig.access: public`、`repository` / `homepage` / `bugs`、`prepublishOnly`(typecheck → test → types → build --check)、`files` 許可リスト、tarball からのインストール検証
|
|
15
|
+
|
|
16
|
+
- `overflow: hidden` / `clip` / `auto` / `scroll` の要素で子孫を padding-box(角丸込み)にクリップ。完全にはみ出した命令は捨て、抽出テキストにも残らない
|
|
17
|
+
- `<tfoot>` を、表が次ページへ続く各ページの最後の行の直下に繰り返す
|
|
18
|
+
- サンプル(`examples/`: Vanilla JS / React / Lit)、`version` エクスポート、CHANGELOG
|
|
19
|
+
|
|
20
|
+
#### 0.4 相当
|
|
21
|
+
|
|
22
|
+
- Playwright ブラウザテスト(Chromium / Firefox / WebKit): テキスト抽出照合・ページ数・thead の繰り返し・画素差分・エラー/警告
|
|
23
|
+
- esbuild による minify バンドル(`dist/`、`./min` エクスポート)と gzip 40KB 以下の検査(実測 18KB)
|
|
24
|
+
- `docs/css-support.md`、GitHub Actions ワークフロー(3 ブラウザ + qpdf --check)
|
|
25
|
+
- 修正: Desktop Safari プリセットの `deviceScaleFactor: 2` で画素差分が破綻していた
|
|
26
|
+
|
|
27
|
+
#### 0.3 相当
|
|
28
|
+
|
|
29
|
+
- 複数ページ: テキスト行・`tr`・`thead`・`<img>`・`break-inside: avoid` を跨がない分割、`break-before/after: page`
|
|
30
|
+
- `<thead>` を 2 ページ目以降の先頭に繰り返す
|
|
31
|
+
- `header` / `footer` テンプレート(`{{pageNumber}}` `{{totalPages}}`)
|
|
32
|
+
- 明細 60 行のフィクスチャ `fixtures/receipt-invoice-long`
|
|
33
|
+
|
|
34
|
+
#### 0.2 相当
|
|
35
|
+
|
|
36
|
+
- 画像: `<img>`(PNG 透過 → SMask、JPEG → DCTDecode そのまま)、`background-image: url()`、`object-fit` / `background-size` / `position`
|
|
37
|
+
- `border-radius`、2D `transform`(`transform-origin` 込み)、`::before` / `::after` の文字列 content、画像への `opacity`
|
|
38
|
+
- 要素入力時に `<html>` / `<body>` の属性を iframe に写す(`body.reissue .x` などの祖先依存セレクタ)
|
|
39
|
+
|
|
40
|
+
#### 0.1 相当
|
|
41
|
+
|
|
42
|
+
- PDF Writer(xref・FlateDecode・日本語メタデータ)、TrueType パース/サブセット/CIDFontType2 + ToUnicode
|
|
43
|
+
- iframe レンダラー、DOM Walker(テキスト・背景・ボーダー)、単一ページ出力
|
|
44
|
+
- ベースラインはプローブ方式、グリフ位置は 1 文字ずつ実測して `TJ` の調整値に
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Hidemi Kimura
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Receipt html to pdf
|
|
2
|
+
|
|
3
|
+
`@hidemikimura/receipt-html-to-pdf`
|
|
4
|
+
|
|
5
|
+
ブラウザ内だけで HTML/CSS を**テキスト選択・検索可能なベクター PDF** に変換する JavaScript ライブラリ。第一の用途は日本の適格請求書(インボイス)要件を満たす領収証の PDF 出力。
|
|
6
|
+
|
|
7
|
+
- サーバー不要、ランタイム依存ゼロ、素の JavaScript(ESM)+ JSDoc 型
|
|
8
|
+
- レイアウトはブラウザに任せ(非表示 iframe で描画して計測)、描画だけを PDF 命令へ変換
|
|
9
|
+
- 日本語フォントをサブセット化して埋め込み(TrueType `glyf` アウトラインの静的 TTF)
|
|
10
|
+
|
|
11
|
+
> **v0.1.0**(初回公開)— テキスト・背景・ボーダー・画像・角丸・2D transform・擬似要素・`overflow: hidden`・複数ページ(行を跨がない分割、`break-*`、`thead` / `tfoot` の繰り返し、ヘッダー/フッター)に対応。依存ゼロ、minify バンドルは gzip 19KB。
|
|
12
|
+
> Chromium / Firefox / WebKit の 3 ブラウザで Playwright テスト(テキスト抽出・ページ分割・画素差分)に合格。対応 CSS は [docs/css-support.md](docs/css-support.md)、設計と経緯は [docs/design.md](docs/design.md)、変更履歴は [CHANGELOG.md](CHANGELOG.md)。
|
|
13
|
+
|
|
14
|
+
## 使い方
|
|
15
|
+
|
|
16
|
+
```js
|
|
17
|
+
import { registerFont, htmlToPdf, downloadPdf } from '@hidemikimura/receipt-html-to-pdf';
|
|
18
|
+
|
|
19
|
+
await registerFont({ family: 'BIZ UDPGothic', weight: 400, src: '/fonts/BIZUDPGothic-Regular.ttf' });
|
|
20
|
+
await registerFont({ family: 'BIZ UDPGothic', weight: 700, src: '/fonts/BIZUDPGothic-Bold.ttf' });
|
|
21
|
+
|
|
22
|
+
const pdf = await htmlToPdf(document.querySelector('#receipt'), {
|
|
23
|
+
page: { size: 'A4', margin: '15mm' },
|
|
24
|
+
footer: '<div style="text-align:center;font-size:8pt">{{pageNumber}} / {{totalPages}}</div>',
|
|
25
|
+
metadata: { title: '領収証 No. R-2026-000123' },
|
|
26
|
+
onWarning: (w) => console.warn(w),
|
|
27
|
+
});
|
|
28
|
+
downloadPdf(pdf, 'receipt.pdf');
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## API
|
|
32
|
+
|
|
33
|
+
| 関数 | 説明 |
|
|
34
|
+
|---|---|
|
|
35
|
+
| `registerFont({ family, weight?, style?, src })` | フォントを登録する。`src` は URL か `ArrayBuffer`。TrueType(glyf)の静的 TTF のみ。`@font-face` と同じファイルを渡す |
|
|
36
|
+
| `htmlToPdf(input, options?)` | `Element` または HTML 文字列を PDF にする。既定は `Blob` を返す(`output: 'uint8array' \| 'dataurl'`) |
|
|
37
|
+
| `downloadPdf(pdf, filename)` | ブラウザでダウンロードさせる補助 |
|
|
38
|
+
| `listFonts()` / `version` | 登録済みフォントの一覧、ライブラリのバージョン |
|
|
39
|
+
|
|
40
|
+
主なオプション(`ConvertOptions`、型は `types/index.d.ts`): `page: { size, orientation, margin }`、`header` / `footer`(`{{pageNumber}}` `{{totalPages}}`)、`stylesheets: 'inherit' | 'none' | [url または CSS 文字列]`、`mediaPrint`、`fontFallback`、`metadata`、`compress`、`baseUrl`、`onWarning`。
|
|
41
|
+
|
|
42
|
+
サンプル: [`examples/vanilla.html`](examples/vanilla.html)(`npm run dev` 後に `/examples/vanilla.html`)、[`examples/react.jsx`](examples/react.jsx)、[`examples/lit.js`](examples/lit.js)(Shadow DOM では `stylesheets` に CSS を明示的に渡す)。
|
|
43
|
+
|
|
44
|
+
## インストール
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
npm install @hidemikimura/receipt-html-to-pdf
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`import ... from '@hidemikimura/receipt-html-to-pdf'` でソース(ESM)、`'@hidemikimura/receipt-html-to-pdf/min'` で minify 済み単一ファイル(`npm run build` で生成)を読み込める。
|
|
51
|
+
|
|
52
|
+
## 開発
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
npm install
|
|
56
|
+
npm run fonts # 参照フォント(BIZ UDPGothic)を fonts/ に取得
|
|
57
|
+
npm run dev # http://localhost:5173/fixtures/receipt-invoice/ でフィクスチャを表示
|
|
58
|
+
npm run typecheck # JSDoc 型検査
|
|
59
|
+
npm test # 単体テスト(Vitest)
|
|
60
|
+
npm run e2e # Chromium でフィクスチャを PDF 化 → out/*.pdf → pdf.js でテキスト抽出を検証
|
|
61
|
+
npm run test:browser # Playwright: Chromium / Firefox / WebKit で変換・抽出・画素差分(要 npx playwright install)
|
|
62
|
+
npm run build -- --check # dist/ に minify バンドルを生成し gzip 40KB 以下を検査
|
|
63
|
+
npm run types # JSDoc から types/*.d.ts を生成
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
ブラウザテストの初回セットアップ(macOS):
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
npx playwright install chromium firefox webkit # ブラウザ本体を取得(Chromium は headless shell も含む)
|
|
70
|
+
brew install poppler # pdftoppm: 画素差分テストに必要(無ければスキップされる)
|
|
71
|
+
brew install qpdf # 任意: 生成 PDF の構造検査
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
環境変数: `CHROMIUM_PATH=/path/to/chrome` で Playwright 同梱以外の Chromium を使う。`BROWSERS=chromium,webkit` で `test:browser` の対象を絞る。画素差分テストは `pdftoppm`(poppler-utils)が無ければスキップされる。
|
|
75
|
+
|
|
76
|
+
CI(`.github/workflows/ci.yml`)は typecheck → 単体テスト → サイズ検査の後、3 ブラウザ並列でブラウザテストを流し、生成された PDF を `qpdf --check` で検証する。
|
|
77
|
+
|
|
78
|
+
## 対応範囲(v0.1.0)
|
|
79
|
+
|
|
80
|
+
| 対応 | 未対応(onWarning で通知) |
|
|
81
|
+
|---|---|
|
|
82
|
+
| テキスト(日本語・サブセット埋め込み・ToUnicode)、`color`、`opacity`、`text-decoration` | `box-shadow`、`text-shadow`、`filter`、`clip-path`、`outline`、縦書き |
|
|
83
|
+
| `background-color`、`border-*`(solid / dashed / dotted、辺ごと)、`border-collapse`、`border-radius` | 非均一ボーダー + 角丸(直線で近似)、グラデーション、`background-repeat`(1 回描画) |
|
|
84
|
+
| `<img>`(PNG 透過 / JPEG、`object-fit`)、`background-image: url()`(size / position)、`overflow: hidden` のクリップ | SVG のベクター化(画像として埋め込む) |
|
|
85
|
+
| `transform`(2D、`transform-origin`)、`::before` / `::after`(文字列 content) | 3D transform、`counter()` / `url()` content |
|
|
86
|
+
| 複数ページ: 行・`tr`・`thead`・`tfoot`・`<img>`・`break-inside: avoid` を跨がない分割、`break-before/after: page`、`thead` / `tfoot` の各ページ繰り返し、`header` / `footer` テンプレート(`{{pageNumber}}` `{{totalPages}}`) | `break-before/after: avoid`、`orphans` / `widows`、ページ番号による高さ変化 |
|
|
87
|
+
| レイアウト全般(Flexbox / Grid / テーブル / 禁則 / letter-spacing)はブラウザ計算をそのまま利用 | |
|
|
88
|
+
|
|
89
|
+
## フィクスチャ
|
|
90
|
+
|
|
91
|
+
`fixtures/receipt-invoice/` — 適格請求書の記載事項 6 項目(発行者名と登録番号、取引年月日、取引内容と軽減税率対象の旨、税率ごとの対価の額と適用税率、税率ごとの消費税額、交付を受ける事業者名)を含む領収証。角印(透過 PNG)とロゴ(JPEG)は `assets/` にあるサンプル画像。`expected.json` に PDF テキスト抽出で必ず含まれるべき文字列と金額を定義し、`variants.reissue`(`<body class="reissue">` で「再発行」の透かしを表示)も検証する。
|
|
92
|
+
|
|
93
|
+
`fixtures/receipt-invoice-long/` — 同じテンプレートで明細を 60 行にした複数ページ検証用。`npm run fixtures` (`scripts/gen-fixture-long.mjs`) で生成する。A4・余白 15mm・フッター付きで 3 ページになり、`thead` が 2 ページ目以降に繰り返される。
|
|
94
|
+
|
|
95
|
+
紙で交付する場合、税抜 5 万円以上の領収証には収入印紙が必要になる。電子データ(PDF)として交付する場合は印紙税の課税対象外のため、フィクスチャは印紙欄を持たない。
|
|
96
|
+
|
|
97
|
+
## 公開手順(メンテナ向け)
|
|
98
|
+
|
|
99
|
+
1. `CHANGELOG.md` に変更を書き、`package.json` と `src/index.js` の `version` を上げる(不一致はビルドで失敗する)
|
|
100
|
+
2. `npm run pack:check` で tarball の内容を確認する(`files` で許可リスト管理。フォント・フィクスチャ・テストは含まれない)
|
|
101
|
+
3. `npm login`(スコープ `@hidemikimura` の所有者アカウント)
|
|
102
|
+
4. `npm publish` — `prepublishOnly` が typecheck → 単体テスト → `.d.ts` 生成 → minify ビルド + サイズ検査を自動で流す。`publishConfig.access` が `public` なのでスコープ付きでも無料で公開される
|
|
103
|
+
5. `git tag v0.1.0 && git push --tags`
|
|
104
|
+
|
|
105
|
+
初回公開前に `package.json` の `repository` / `homepage` / `bugs` の URL(`github.com/hidemikimura/receipt-html-to-pdf` を仮置き)を実際のリポジトリに合わせること。
|
|
106
|
+
|
|
107
|
+
## ライセンス
|
|
108
|
+
|
|
109
|
+
MIT © 2026 Hidemi Kimura。参照フォント BIZ UDPGothic は SIL Open Font License 1.1。
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/* @hidemikimura/receipt-html-to-pdf v0.1.0 | MIT */
|
|
2
|
+
function kt(e){let t=e instanceof Uint8Array?e:new Uint8Array(e),n=new DataView(t.buffer,t.byteOffset,t.byteLength),s=n.getUint32(0);if(s===1330926671)throw new Error("CFF outlines (OpenType/CFF) are not supported. Use a TrueType (glyf) font.");if(s===2001684038||s===2001684018)throw new Error("WOFF/WOFF2 are not supported. Use a raw .ttf file.");if(s===1953784678)throw new Error("TrueType collections (.ttc) are not supported. Extract a single face first.");if(s!==65536&&s!==1953658213)throw new Error("Not a TrueType font (bad sfnt version)");let o=n.getUint16(4),r=new Map;for(let y=0;y<o;y++){let T=12+y*16,D=String.fromCharCode(t[T]??0,t[T+1]??0,t[T+2]??0,t[T+3]??0);r.set(D,{offset:n.getUint32(T+8),length:n.getUint32(T+12)})}if(r.has("CFF "))throw new Error("CFF outlines are not supported. Use a TrueType (glyf) font.");let i=r.has("fvar");for(let y of["head","hhea","maxp","hmtx","loca","glyf"])if(!r.has(y))throw new Error(`Font is missing required table: ${y}`);let c=y=>r.get(y),a=c("head"),h=n.getUint16(a.offset+18),m=[n.getInt16(a.offset+36),n.getInt16(a.offset+38),n.getInt16(a.offset+40),n.getInt16(a.offset+42)],f=n.getUint16(a.offset+44),d=n.getInt16(a.offset+50),g=c("hhea"),w=n.getInt16(g.offset+4),b=n.getInt16(g.offset+6),C=n.getInt16(g.offset+8),O=n.getUint16(g.offset+34),B=n.getUint16(c("maxp").offset+4),R=c("hmtx"),j=new Uint16Array(B),L=0;for(let y=0;y<B;y++)y<O&&(L=n.getUint16(R.offset+y*4)),j[y]=L;let N=c("loca"),X=new Uint32Array(B+1);for(let y=0;y<=B;y++)X[y]=d===0?n.getUint16(N.offset+y*2)*2:n.getUint32(N.offset+y*4);let et=r.get("cmap"),$=et?ee(n,et.offset):new Map,l=Math.round(w*.7),p=!1,u=w,x=b,S=w,F=-b,P=(f&1)!==0,k=(f&2)!==0,A=r.get("OS/2");if(A){let y=n.getUint16(A.offset),T=n.getUint16(A.offset+62);if(p=(T&128)!==0,P=P||(T&32)!==0,k=k||(T&1)!==0,u=n.getInt16(A.offset+68),x=n.getInt16(A.offset+70),S=n.getUint16(A.offset+74),F=n.getUint16(A.offset+76),y>=2&&A.length>=90){let D=n.getInt16(A.offset+88);D>0&&(l=D)}}let I=0,z=r.get("post");z&&(I=n.getInt32(z.offset+4)/65536);let W=ne(n,t,r.get("name"))??"Embedded";return{data:t,tables:r,unitsPerEm:h,indexToLocFormat:d,bbox:m,ascender:w,descender:b,lineGap:C,numGlyphs:B,advances:j,loca:X,cmap:$,capHeight:l,italicAngle:I,useTypoMetrics:p,typoAscender:u,typoDescender:x,winAscent:S,winDescent:F,postScriptName:W,bold:P,italic:k,variable:i}}function ee(e,t){let n=e.getUint16(t+2),s=-1,o=-1;for(let c=0;c<n;c++){let a=t+4+c*8,h=e.getUint16(a),m=e.getUint16(a+2),f=e.getUint32(a+4),d=e.getUint16(t+f),g=-1;h===3&&m===10&&d===12?g=4:h===0&&(m===4||m===6)&&d===12?g=3:h===3&&m===1&&d===4?g=2:h===0&&d===4&&(g=1),g>o&&(o=g,s=t+f)}if(s<0)throw new Error("Font has no usable Unicode cmap subtable (format 4 or 12)");let r=new Map,i=e.getUint16(s);if(i===4){let c=e.getUint16(s+6),a=c/2,h=s+14,m=h+c+2,f=m+c,d=f+c;for(let g=0;g<a;g++){let w=e.getUint16(h+g*2),b=e.getUint16(m+g*2),C=e.getInt16(f+g*2),O=e.getUint16(d+g*2);if(b!==65535)for(let B=b;B<=w;B++){let R;if(O===0)R=B+C&65535;else{let j=d+g*2+O+(B-b)*2;if(j+2>e.byteLength)continue;R=e.getUint16(j),R!==0&&(R=R+C&65535)}R!==0&&r.set(B,R)}}}else if(i===12){let c=e.getUint32(s+12),a=s+16;for(let h=0;h<c;h++,a+=12){let m=e.getUint32(a),f=e.getUint32(a+4),d=e.getUint32(a+8);for(let g=m;g<=f&&g-m<65536;g++){let w=d+(g-m);w!==0&&r.set(g,w)}}}return r}function ne(e,t,n){if(!n)return null;let s=e.getUint16(n.offset+2),o=e.getUint16(n.offset+4),r=null;for(let i=0;i<s;i++){let c=n.offset+6+i*12,a=e.getUint16(c),h=e.getUint16(c+6),m=e.getUint16(c+8),f=e.getUint16(c+10);if(h!==6)continue;let d=n.offset+o+f;if(a===1)return Ut(String.fromCharCode(...t.subarray(d,d+m)));if(a===3||a===0){let g="";for(let w=0;w+1<m;w+=2)g+=String.fromCharCode(e.getUint16(d+w));r=Ut(g)}}return r}function Ut(e){return e.replace(/[^\x21-\x7e]/g,"").replace(/[\[\]\(\)\{\}<>\/%#]/g,"")||"Embedded"}function yt(e,t){let n=e.tables.get("glyf"),s=e.loca[t]??0,o=e.loca[t+1]??s;return e.data.subarray(n.offset+s,n.offset+o)}function Pt(e){if(e.length<10)return[];let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(t.getInt16(0)>=0)return[];let s=[],o=10;for(;;){let r=t.getUint16(o),i=t.getUint16(o+2);if(s.push(i),o+=4,o+=r&1?4:2,r&8?o+=2:r&64?o+=4:r&128&&(o+=8),!(r&32)||o>=e.length)break}return s}var at=class{constructor(){this.fonts=[]}async register(t){let n=await oe(t.src),s=kt(n),o={family:wt(t.family),displayFamily:t.family,weight:t.weight??400,style:t.style??"normal",parsed:s},r=this.fonts.findIndex(i=>i.family===o.family&&i.weight===o.weight&&i.style===o.style);return r>=0?this.fonts[r]=o:this.fonts.push(o),o}hasFamily(t){let n=wt(t);return this.fonts.some(s=>s.family===n)}match(t,n,s,o){for(let r of t){let i=wt(r),c=this.fonts.filter(a=>a.family===i);if(o!==void 0&&(c=c.filter(a=>a.parsed.cmap.has(o))),!!c.length)return Et(c,n,s)}return null}anyWithGlyph(t,n,s){let o=this.fonts.filter(r=>r.parsed.cmap.has(t));return o.length?Et(o,n,s):null}};function Et(e,t,n){let s=e.filter(h=>h.style===n),o=s.length?s:e,r=o.find(h=>h.weight===t);if(r)return r;let i=[...o].sort((h,m)=>h.weight-m.weight),c=i.filter(h=>h.weight>t),a=i.filter(h=>h.weight<t).reverse();if(t>=400&&t<=500){let h=c.find(m=>m.weight<=500);return h||(a.length?a[0]:c[0])}return t<400?a[0]??c[0]:c[0]??a[0]}function wt(e){return e.trim().replace(/^["']|["']$/g,"").trim().toLowerCase()}function It(e){let t=[],n="",s="";for(let o of e)s?o===s?s="":n+=o:o==='"'||o==="'"?s=o:o===","?(n.trim()&&t.push(n.trim()),n=""):n+=o;return n.trim()&&t.push(n.trim()),t}function Mt(e){if(e==="bold")return 700;if(e==="normal")return 400;let t=parseInt(e,10);return Number.isFinite(t)?t:400}async function oe(e){if(e instanceof Uint8Array)return e;if(e instanceof ArrayBuffer)return new Uint8Array(e);let t=await fetch(e);if(!t.ok)throw new Error(`Failed to fetch font ${e}: ${t.status} ${t.statusText}`);return new Uint8Array(await t.arrayBuffer())}async function xt(e,t){let n=document.createElement("iframe");n.setAttribute("aria-hidden","true"),n.style.cssText=`position:fixed;left:-100000px;top:0;width:${t.widthPx}px;height:1000px;border:0;visibility:hidden;pointer-events:none;`,document.body.appendChild(n);let s=n.contentWindow,o=n.contentDocument;if(!s||!o)throw new Error("Failed to create rendering iframe");let r=se(e,t);o.open(),o.write(r),o.close();let i=()=>{n.style.height=`${Math.max(o.documentElement.scrollHeight,o.body.scrollHeight,100)}px`};return i(),await ie(o),i(),await ae(o),await ce(o),fe(o,t.warn??(()=>{})),i(),o.body.offsetHeight,{iframe:n,doc:o,win:s,root:o.body,destroy:()=>n.remove()}}function se(e,t){let n=t.baseUrl??document.baseURI,s=`<base href="${rt(n)}">`,o="<style data-rhtp-reset>html,body{margin:0;padding:0;background:transparent}html{-webkit-text-size-adjust:100%}</style>";if(typeof e=="string"){if(/<html[\s>]/i.test(e)){let m=e;return m=/<head[^>]*>/i.test(m)?m.replace(/<head[^>]*>/i,f=>`${f}${s}${o}`):m.replace(/<html[^>]*>/i,f=>`${f}<head>${s}${o}</head>`),t.mediaPrint?re(m):m}let h=At(t.stylesheets,t.mediaPrint);return`<!DOCTYPE html><html><head><meta charset="utf-8">${s}${o}${h}</head><body>${e}</body></html>`}let r=At(t.stylesheets,t.mediaPrint),i=Bt(document.documentElement),c=Bt(document.body),a=e===document.body||e===document.documentElement?document.body.innerHTML:e.outerHTML;return`<!DOCTYPE html><html${i}><head><meta charset="utf-8">${s}${o}${r}</head><body${c}>${a}</body></html>`}function At(e,t){if(e==="none")return"";let n=[];if(e==="inherit"){for(let s of document.querySelectorAll('style, link[rel~="stylesheet"]'))if(!s.hasAttribute("data-rhtp-reset"))if(s instanceof HTMLStyleElement){let o=s.textContent??"";n.push(`<style>${t?ct(o):o}</style>`)}else s instanceof HTMLLinkElement&&n.push(`<link rel="stylesheet" href="${rt(s.href)}"${s.media?` media="${rt(s.media)}"`:""}>`);return n.join("")}for(let s of e)/^(https?:)?\/\/|^\.{0,2}\/|\.css(\?|$)/i.test(s)&&!s.includes("{")?n.push(`<link rel="stylesheet" href="${rt(s)}">`):n.push(`<style>${t?ct(s):s}</style>`);return n.join("")}function re(e){return e.replace(/<style([^>]*)>([\s\S]*?)<\/style>/gi,(t,n,s)=>`<style${n}>${ct(s)}</style>`)}function ct(e){let t="",n=0;for(;n<e.length;){let s=/@media\s*([^{]+)\{/g;s.lastIndex=n;let o=s.exec(e);if(!o){t+=e.slice(n);break}t+=e.slice(n,o.index);let r=1,i=s.lastIndex;for(;i<e.length&&r>0;)e[i]==="{"?r++:e[i]==="}"&&r--,i++;let c=o[1].trim(),a=e.slice(s.lastIndex,i-1);/\bprint\b/.test(c)?t+=a:/^\s*(only\s+)?screen\b/.test(c)&&!/\band\b/.test(c)?t+="":t+=e.slice(o.index,i),n=i}return t}function Bt(e){let t="";for(let n of e.attributes)/^on/i.test(n.name)||(t+=` ${n.name}="${rt(n.value)}"`);return t}function rt(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<")}async function ie(e){let t=[...e.querySelectorAll('link[rel~="stylesheet"]')];await Promise.all(t.map(n=>new Promise(s=>{let o=n;if(o.sheet)return s(void 0);o.addEventListener("load",()=>s(void 0),{once:!0}),o.addEventListener("error",()=>s(void 0),{once:!0}),setTimeout(()=>s(void 0),1e4)})))}async function ae(e){if(e.body.offsetHeight,e.fonts){await e.fonts.ready;let t=[...e.fonts].filter(n=>n.status==="loading").map(n=>n.loaded.catch(()=>{}));t.length&&await Promise.all(t),await e.fonts.ready}}async function ce(e){let t=[...e.images];await Promise.all(t.map(n=>n.complete?n.decode().catch(()=>{}):new Promise(s=>{n.addEventListener("load",()=>n.decode().catch(()=>{}).then(s),{once:!0}),n.addEventListener("error",()=>s(void 0),{once:!0}),setTimeout(()=>s(void 0),1e4)})))}function fe(e,t){let n=e.defaultView;if(!n)return;let s=[];for(let r of e.body.querySelectorAll("*"))for(let i of["before","after"]){let c=n.getComputedStyle(r,`::${i}`),a=c.content;if(!a||a==="none"||a==="normal"||c.display==="none")continue;let h=le(a);if(h===null){t({code:"unsupported-css",message:`::${i} content "${a}" is not supported (only quoted strings are); the pseudo-element is skipped`,element:r,property:"content"});continue}let m=[];for(let f=0;f<c.length;f++){let d=c[f];d==="content"||d.startsWith("-webkit-")||d.startsWith("-moz-")||m.push([d,c.getPropertyValue(d)])}s.push({el:r,pseudo:i,text:h,styles:m})}if(!s.length)return;let o=e.createElement("style");o.setAttribute("data-rhtp-pseudo",""),o.textContent='[data-rhtp-pseudo-host~="before"]::before{content:none!important;display:none!important}[data-rhtp-pseudo-host~="after"]::after{content:none!important;display:none!important}',e.head.appendChild(o);for(let r of s){let i=e.createElement("span");i.setAttribute("data-rhtp-pseudo",r.pseudo);for(let[a,h]of r.styles)i.style.setProperty(a,h);i.textContent=r.text;let c=(r.el.getAttribute("data-rhtp-pseudo-host")??"").split(" ").filter(Boolean);c.push(r.pseudo),r.el.setAttribute("data-rhtp-pseudo-host",c.join(" ")),r.pseudo==="before"?r.el.insertBefore(i,r.el.firstChild):r.el.appendChild(i)}}function le(e){let t="",n=0,s=e.trim();for(;n<s.length;){let o=s[n];if(o===" "||o===" "){n++;continue}if(o!=='"'&&o!=="'")return null;let r=o;for(n++;n<s.length&&s[n]!==r;)if(s[n]==="\\"){n++;let i=/^[0-9a-fA-F]{1,6}/.exec(s.slice(n));i?(t+=String.fromCodePoint(parseInt(i[0],16)),n+=i[0].length,s[n]===" "&&n++):(t+=s[n]??"",n++)}else t+=s[n],n++;n++}return t}var _=2.834645669291339,St={A3:{width:297*_,height:420*_},A4:{width:210*_,height:297*_},A5:{width:148*_,height:210*_},B4:{width:257*_,height:364*_},B5:{width:182*_,height:257*_},Letter:{width:612,height:792},Legal:{width:612,height:1008}};function Y(e){if(typeof e=="number")return e*.75;let t=/^\s*(-?[\d.]+)\s*([a-z%]*)\s*$/i.exec(e);if(!t)throw new Error(`Invalid CSS length: ${e}`);let n=parseFloat(t[1]);switch((t[2]??"").toLowerCase()){case"":case"px":return n*.75;case"pt":return n;case"mm":return n*_;case"cm":return n*_*10;case"in":return n*72;case"pc":return n*12;default:throw new Error(`Unsupported CSS unit: ${e}`)}}function H(e){let t=parseFloat(e);return Number.isFinite(t)?t:0}function ot(e){if(!e)return null;let t=e.trim();if(t==="transparent")return{r:0,g:0,b:0,a:0};let n=/^rgba?\(\s*([\d.]+)\s*[, ]\s*([\d.]+)\s*[, ]\s*([\d.]+)\s*(?:[,/]\s*([\d.]+%?)\s*)?\)$/i.exec(t);if(n){let s=n[4]===void 0?1:n[4].endsWith("%")?parseFloat(n[4])/100:parseFloat(n[4]);return{r:tt(parseFloat(n[1])/255),g:tt(parseFloat(n[2])/255),b:tt(parseFloat(n[3])/255),a:tt(s)}}if(n=/^color\(srgb\s+([\d.]+)\s+([\d.]+)\s+([\d.]+)\s*(?:\/\s*([\d.]+%?)\s*)?\)$/i.exec(t),n){let s=n[4]===void 0?1:n[4].endsWith("%")?parseFloat(n[4])/100:parseFloat(n[4]);return{r:tt(parseFloat(n[1])),g:tt(parseFloat(n[2])),b:tt(parseFloat(n[3])),a:tt(s)}}if(n=/^#([0-9a-f]{3,8})$/i.exec(t),n){let s=n[1];(s.length===3||s.length===4)&&(s=s.split("").map(r=>r+r).join(""));let o=parseInt(s.padEnd(8,"f"),16);return{r:(o>>>24&255)/255,g:(o>>>16&255)/255,b:(o>>>8&255)/255,a:(o&255)/255}}return null}function tt(e){return e<0?0:e>1?1:e}function U(e){if(!Number.isFinite(e))return"0";let t=e.toFixed(3),n=t.includes(".")?t.replace(/\.?0+$/,""):t;return n===""||n==="-0"||n==="-"?"0":n}var he=new Set([32,9,10,13,12,160,12288,8194,8195,8201,8202,8239,8287]);function Rt(e,t,n){let s=e.ownerDocument,o=ue(e.data,t.textTransform),r=s.createRange(),i=me(s,t),c=[],a=null,h=NaN,m=new Set;for(let f=0;f<o.length;){let d=o.codePointAt(f),g=d>65535?2:1,w=f+g;r.setStart(e,f),r.setEnd(e,Math.min(w,e.data.length));let b=de(r.getClientRects());if(f=w,!b)continue;let C=pe(d,n,m);if(!C)continue;let{font:O,gid:B,cpForUnicode:R}=C,j=b.top;(!a||a.font!==O||Math.abs(j-h)>.5)&&(a={font:O,baseline:j+i,top:j,bottom:b.bottom,glyphs:[]},h=j,c.push(a)),a.top=Math.min(a.top,j),a.bottom=Math.max(a.bottom,b.bottom);let L=(O.parsed.advances[B]??0)*n.size/O.parsed.unitsPerEm;a.glyphs.push({gid:B,cp:R,x:b.left,advance:L})}return c}function de(e){let t=null;for(let n of e)n.width>.01&&(!t||n.width>t.width)&&(t=n);return t}function pe(e,t,n){let s=(i,c)=>{let a=i?.parsed.cmap.get(c);return i&&a?{font:i,gid:a,cpForUnicode:e}:null};if(he.has(e))return s(t.primary,e)??s(t.primary,32)??s(t.registry.anyWithGlyph(32,t.weight,t.fstyle),32);let o=s(t.primary,e);if(o||(o=s(t.registry.match(t.families,t.weight,t.fstyle,e),e),o)||(o=s(t.registry.match(t.fallback,t.weight,t.fstyle,e),e),o)||(o=s(t.registry.anyWithGlyph(e,t.weight,t.fstyle),e),o))return o;n.has(e)||(n.add(e),t.warn({code:"missing-glyph",message:`No registered font has a glyph for U+${e.toString(16).toUpperCase().padStart(4,"0")} "${String.fromCodePoint(e)}"; substituted with U+25A1`,element:t.element,text:String.fromCodePoint(e)}));let r=s(t.primary,9633)??s(t.registry.anyWithGlyph(9633,t.weight,t.fstyle),9633);return r?{...r,cpForUnicode:e}:null}function ue(e,t){if(!t||t==="none")return e;let n=e;return t.includes("uppercase")?n=e.toUpperCase():t.includes("lowercase")?n=e.toLowerCase():t.includes("capitalize")&&(n=e.replace(new RegExp("(^|\\s)(\\p{L})","gu"),(s,o,r)=>o+r.toUpperCase())),n.length===e.length?n:e}var Dt=new WeakMap;function me(e,t){let n=[t.fontFamily,t.fontSize,t.fontWeight,t.fontStyle,t.fontStretch,t.fontVariant,t.fontFeatureSettings].join("|"),s=Dt.get(e);s||(s=new Map,Dt.set(e,s));let o=s.get(n);if(o!==void 0)return o;let r=e.createElement("div");r.setAttribute("data-rhtp-probe",""),r.style.cssText="position:absolute;left:0;top:0;visibility:hidden;white-space:pre;line-height:normal;margin:0;padding:0;border:0;letter-spacing:0;text-indent:0;",r.style.fontFamily=t.fontFamily,r.style.fontSize=t.fontSize,r.style.fontWeight=t.fontWeight,r.style.fontStyle=t.fontStyle,r.style.fontStretch=t.fontStretch,r.style.fontVariant=t.fontVariant,r.style.fontFeatureSettings=t.fontFeatureSettings;let i=e.createTextNode("Ag\u3042");r.appendChild(i);let c=e.createElement("span");c.style.cssText="display:inline-block;width:0;height:0;vertical-align:baseline;margin:0;padding:0;border:0;",r.appendChild(c),e.body.appendChild(r);let a=e.createRange();a.selectNodeContents(i);let h=a.getBoundingClientRect(),f=c.getBoundingClientRect().bottom-h.top;r.remove();let d=Number.isFinite(f)&&f>0?f:parseFloat(t.fontSize)*.8;return s.set(n,d),d}var Ot=new Map;function Tt(e,t,n){let s=Ot.get(e);return s||(s=ge(e,t,n).catch(o=>(t({code:"image-failed",message:`Failed to load image ${e}: ${o instanceof Error?o.message:String(o)}`,element:n}),null)),Ot.set(e,s)),s}async function ge(e,t,n){let s=null;try{let b=await fetch(e,{mode:"cors",credentials:"same-origin"});b.ok&&(s=new Uint8Array(await b.arrayBuffer()))}catch{s=null}if(s&&s[0]===255&&s[1]===216){let b=be(s);if(b&&b.components===3)return{key:e,width:b.width,height:b.height,jpeg:s,rgb:null,alpha:null}}let o=new Image;o.crossOrigin="anonymous",o.decoding="sync";let r=new Promise((b,C)=>{o.onload=()=>b(void 0),o.onerror=()=>C(new Error("image failed to load"))});if(s){let b=URL.createObjectURL(new Blob([s]));o.src=b;try{await r}finally{URL.revokeObjectURL(b)}}else o.src=e,await r;let i=o.naturalWidth,c=o.naturalHeight;if(!i||!c)throw new Error("image has no intrinsic size");let a=document.createElement("canvas");a.width=i,a.height=c;let h=a.getContext("2d",{willReadFrequently:!0});if(!h)throw new Error("2D canvas unavailable");h.drawImage(o,0,0);let m;try{m=h.getImageData(0,0,i,c)}catch{return t({code:"image-failed",message:`Image ${e} is cross-origin without CORS headers; add crossorigin="anonymous" and Access-Control-Allow-Origin. Skipped.`,element:n}),null}let f=m.data,d=new Uint8Array(i*c*3),g=new Uint8Array(i*c),w=!0;for(let b=0,C=0,O=0;b<f.length;b+=4,C+=3,O++){let B=f[b+3];B===0?d[C]=d[C+1]=d[C+2]=255:(d[C]=f[b],d[C+1]=f[b+1],d[C+2]=f[b+2]),g[O]=B,B!==255&&(w=!1)}return{key:e,width:i,height:c,jpeg:null,rgb:d,alpha:w?null:g}}function be(e){let t=2;for(;t+9<e.length;){if(e[t]!==255){t++;continue}let n=e[t+1];if(n===216||n>=208&&n<=215||n===1||n===255){t+=n===255?1:2;continue}let s=e[t+2]<<8|e[t+3];if(n>=192&&n<=195||n>=197&&n<=199||n>=201&&n<=203||n>=205&&n<=207)return{height:e[t+5]<<8|e[t+6],width:e[t+7]<<8|e[t+8],components:e[t+9]};if(n===218)break;t+=2+s}return null}function Lt(e){if(!e||e==="none")return null;let t=ye(e);if(t.length!==1)return null;let n=/^url\((?:"([^"]*)"|'([^']*)'|([^)]*))\)$/.exec(t[0].trim());return n?n[1]??n[2]??n[3]??null:null}function ye(e){let t=[],n=0,s="";for(let o of e)o==="("?n++:o===")"&&n--,o===","&&n===0?(t.push(s),s=""):s+=o;return s.trim()&&t.push(s),t}function ft(e,t,n,s,o){let r,i,c=s.trim();if(c==="cover"||c==="contain"){let d=c==="cover"?Math.max(e.w/t,e.h/n):Math.min(e.w/t,e.h/n);r=t*d,i=n*d}else{let[d="auto",g="auto"]=c.split(/\s+/),w=vt(d,e.w),b=vt(g,e.h);w===null&&b===null?(r=t,i=n):w===null?(i=b,r=t*i/n):b===null?(r=w,i=n*r/t):(r=w,i=b)}let[a="0%",h="0%"]=o.trim().split(/\s+/),m=e.x+jt(a,e.w-r),f=e.y+jt(h,e.h-i);return{x:m,y:f,w:r,h:i}}function vt(e,t){return e==="auto"?null:e.endsWith("%")?parseFloat(e)/100*t:parseFloat(e)||0}function jt(e,t){return e==="left"||e==="top"?0:e==="center"?t/2:e==="right"||e==="bottom"?t:e.endsWith("%")?parseFloat(e)/100*t:parseFloat(e)||0}function zt(e){switch(e){case"contain":case"scale-down":return"contain";case"cover":return"cover";case"none":return"auto";default:return"100% 100%"}}var we=new Set(["SCRIPT","STYLE","NOSCRIPT","TEMPLATE","HEAD","META","LINK","TITLE","BASE","IFRAME","CANVAS","VIDEO","AUDIO","SVG","OBJECT","EMBED"]),xe=[["boxShadow",e=>e!=="none"],["textShadow",e=>e!=="none"],["filter",e=>e!=="none"],["backdropFilter",e=>e!=="none"&&e!==""],["writingMode",e=>e.startsWith("vertical")],["outlineStyle",e=>e!=="none"],["clipPath",e=>e!=="none"],["mixBlendMode",e=>e!=="normal"]];async function $t(e,t){let n=e.ownerDocument.defaultView,s=n.scrollX,o=n.scrollY,r=[],i=r,c=[],a=[],h=[],m=null,f=0,d=new Set,g=new Set;function w(l,p){d.has(l)||(d.add(l),t.warn(p))}async function b(l,p){if(we.has(l.tagName))return;let u=n.getComputedStyle(l);if(u.display==="none")return;let x=Se(u.transform);if(x&&"style"in l){let S=l,F=S.getBoundingClientRect(),P=S.style.transform;S.style.transform="none",S.offsetWidth;let k=S.getBoundingClientRect(),[A,I]=Te(u.transformOrigin),z={x:k.left+A+s,y:k.top+I+o},W=r;r=[],await O(l,n.getComputedStyle(l),p);let y=r;r=W,S.style.transform=P,S.offsetWidth,r.push({type:"group",matrix:x,origin:z,items:y,top:F.top+o,bottom:F.bottom+o,z:C(u,p.z),seq:f++});return}await O(l,u,p)}function C(l,p){if(l.position!=="static"&&l.zIndex!=="auto"){let u=parseInt(l.zIndex,10);if(Number.isFinite(u))return u}return p}async function O(l,p,u){let x=C(p,u.z),S=parseFloat(p.opacity),F=u.alpha*(Number.isFinite(S)?S:1),P=p.visibility==="visible"&&F>0;if(p.display!=="contents"&&p.display!=="inline"){let E=l.getBoundingClientRect(),q=E.top+o,J=E.bottom+o;if(E.height>0){let V=p.breakBefore||p.pageBreakBefore,te=p.breakAfter||p.pageBreakAfter;/^(page|always|left|right|recto|verso)$/.test(V)&&a.push(q),/^(page|always|left|right|recto|verso)$/.test(te)&&a.push(J);let Ft=p.breakInside||p.pageBreakInside;(Ft==="avoid"||Ft==="avoid-page"||p.display==="table-row"||p.display==="table-header-group"||p.display==="table-footer-group"||l.tagName==="IMG")&&c.push({top:q,bottom:J})}}let k=null;if(p.display==="table"||p.display==="inline-table"){let E=l.getBoundingClientRect();k={top:E.top+o,bottom:E.bottom+o,headTop:0,headBottom:0,headItems:[],footTop:0,footBottom:0,footItems:[]},h.push(k)}let A=m;k&&(m=k);let I=p.display==="table-header-group"&&m&&!m.headItems.length,z=p.display==="table-footer-group"&&m&&!m.footItems.length,W=I||z?r.length:-1,y=p.overflowX!=="visible"||p.overflowY!=="visible",T=null,D=null;if(y&&p.display!=="inline"&&p.display!=="contents"&&l!==e){let E=l.getBoundingClientRect();D=N(E,p,"padding-box",Wt(p,E))}if(P&&p.display!=="contents"){B(l,p);let E=p.display==="inline"?[...l.getClientRects()]:[l.getBoundingClientRect()],q=p.borderCollapse==="collapse"&&/^table/.test(p.display)&&p.display!=="table-caption",J=E.length===1?Wt(p,E[0]):null;for(let V of E)V.width<=0&&V.height<=0||(R(V,p,F,x,J),await j(l,V,p,F,x,J),X(V,p,F,x,q,J));l.tagName==="IMG"&&E[0]&&await L(l,E[0],p,F,x,J)}let v=u.decorations,G=p.textDecorationLine;if(G&&G!=="none"){let E=ot(p.textDecorationColor)??ot(p.color)??{r:0,g:0,b:0,a:1};v=[...v,{line:G,color:E}]}D&&(T=r,r=[]);let Z={z:x,alpha:F,decorations:v};for(let E of[...l.childNodes])E.nodeType===Node.TEXT_NODE?P&&et(E,l,p,Z):E.nodeType===Node.ELEMENT_NODE&&await b(E,Z);if(D&&T){let E=r.filter(q=>$e(q,D));r=T,E.length&&r.push({type:"clip",box:D,items:E,top:D.y,bottom:D.y+D.h,z:x,seq:f++})}if((I||z)&&m&&W>=0){let E=l.getBoundingClientRect(),q=r.slice(W);I?(m.headTop=E.top+o,m.headBottom=E.bottom+o,m.headItems=q):(m.footTop=E.top+o,m.footBottom=E.bottom+o,m.footItems=q)}m=A}function B(l,p){for(let[u,x]of xe){let S=String(p[u]??"");x(S)&&w(`css:${u}`,{code:"unsupported-css",message:`CSS property "${Gt(u)}" is not supported in this version and will be ignored (first seen on <${l.tagName.toLowerCase()}>: ${S})`,element:l,property:Gt(u)})}/^matrix3d/.test(p.transform)&&w("css:transform3d",{code:"unsupported-css",message:"3D transforms are not supported; the element is drawn untransformed",element:l,property:"transform"})}function R(l,p,u,x,S){let F=ot(p.backgroundColor);if(!F||F.a<=0)return;let P={type:"rect",x:l.left+s,y:l.top+o,w:l.width,h:l.height,color:it(F,u),z:x,seq:f++};S&&(P.radius=S),r.push(P)}async function j(l,p,u,x,S,F){if(u.backgroundImage==="none")return;let P=Lt(u.backgroundImage);if(!P){w("css:backgroundImage",{code:"unsupported-css",message:`background-image "${u.backgroundImage}" is not supported (only a single url() is); ignored`,element:l,property:"background-image"});return}let k=await Tt(new URL(P,l.ownerDocument.baseURI).href,t.warn,l);if(!k)return;u.backgroundRepeat!=="no-repeat"&&w("css:backgroundRepeat",{code:"unsupported-css",message:`background-repeat "${u.backgroundRepeat}" is not supported; drawn once as no-repeat`,element:l,property:"background-repeat"});let A=N(p,u,u.backgroundClip||"border-box",F),I=N(p,u,u.backgroundOrigin||"padding-box",null),z=ft(I,k.width,k.height,u.backgroundSize,u.backgroundPosition);r.push({type:"image",...z,image:k,clip:A,alpha:x,z:S,seq:f++})}async function L(l,p,u,x,S,F){let P=l.currentSrc||l.src;if(!P)return;let k=await Tt(P,t.warn,l);if(!k)return;let A=N(p,u,"content-box",F),I=ft(A,k.width,k.height,zt(u.objectFit),u.objectPosition);u.objectFit==="scale-down"&&(I.w>k.width||I.h>k.height)&&Object.assign(I,ft(A,k.width,k.height,"auto",u.objectPosition)),r.push({type:"image",...I,image:k,clip:A,alpha:x,z:S,seq:f++})}function N(l,p,u,x){let S=l.left+s,F=l.top+o,P=l.width,k=l.height;if(u==="padding-box"||u==="content-box"){let I=H(p.borderTopWidth),z=H(p.borderRightWidth),W=H(p.borderBottomWidth),y=H(p.borderLeftWidth);S+=y,F+=I,P-=y+z,k-=I+W,x&&(x=x.map(T=>Math.max(0,T-Math.max(I,z,W,y))))}if(u==="content-box"){let I=H(p.paddingTop),z=H(p.paddingRight),W=H(p.paddingBottom),y=H(p.paddingLeft);S+=y,F+=I,P-=y+z,k-=I+W}let A={x:S,y:F,w:Math.max(0,P),h:Math.max(0,k)};return x&&x.some(I=>I>0)&&(A.radius=x),A}function X(l,p,u,x,S,F){let P=l.left+s,k=l.top+o,A=l.width,I=l.height,y=["Top","Right","Bottom","Left"].map(T=>({side:T,width:H(p[`border${T}Width`]),style:p[`border${T}Style`],color:ot(p[`border${T}Color`])})).filter(T=>T.width>0&&T.style!=="none"&&T.style!=="hidden"&&T.color&&T.color.a>0);if(y.length){if(F&&F.some(T=>T>0)){let T=y[0];if(y.length===4&&y.every(v=>v.width===T.width&&v.style===T.style&&JSON.stringify(v.color)===JSON.stringify(T.color))){let v=T.width;r.push({type:"stroke-rrect",x:P+v/2,y:k+v/2,w:A-v,h:I-v,radius:F.map(G=>Math.max(0,G-v/2)),width:v,color:it(T.color,u),dash:Nt(T.style,v),z:x,seq:f++});return}w("css:borderRadiusNonUniform",{code:"unsupported-css",message:"border-radius with non-uniform borders is approximated with straight borders",property:"border-radius"})}for(let T of y){let D=T.width,v=it(T.color,u),G=T.side==="Top"||T.side==="Bottom",Z=T.side==="Top"||T.side==="Left"?1:-1,E=T.side==="Top"?k:T.side==="Bottom"?k+I:T.side==="Left"?P:P+A,q=Nt(T.style,D);if(q){let V=S?E:E+D/2*Z;r.push({type:"line",x1:G?P:V,y1:G?V:k,x2:G?P+A:V,y2:G?V:k+I,width:D,color:v,dash:q,z:x,seq:f++});continue}let J=S?E-D/2:Z>0?E:E-D;G?r.push({type:"rect",x:P,y:J,w:A,h:D,color:v,z:x,seq:f++}):r.push({type:"rect",x:J,y:k,w:D,h:I,color:v,z:x,seq:f++})}}}function et(l,p,u,x){let S=l.data;if(!S)return;if(!/\S/.test(S)&&!S.includes("\xA0")){let y=l.ownerDocument.createRange();if(y.selectNodeContents(l),![...y.getClientRects()].some(T=>T.width>0))return}let F=it(ot(u.color)??{r:0,g:0,b:0,a:1},x.alpha),P=H(u.fontSize);if(P<=0)return;let k=It(u.fontFamily),A=Mt(u.fontWeight),I=u.fontStyle==="italic"||u.fontStyle==="oblique"?"italic":"normal",z=t.registry.match(k,A,I)??t.registry.match(t.fontFallback,A,I);if(!z){let y=k.join(",");g.has(y)||(g.add(y),t.warn({code:"missing-font",message:`No registered font matches font-family "${u.fontFamily}" and no fallback is available; text will be skipped`,element:p}));return}let W=Rt(l,u,{registry:t.registry,families:k,fallback:t.fontFallback,primary:z,weight:A,fstyle:I,size:P,textMeasure:t.textMeasure,warn:t.warn,element:p});for(let y of W)if(y.glyphs.length){c.push({top:y.top+o,bottom:y.bottom+o}),r.push({type:"text",x:y.glyphs[0]?.x??0,y:y.baseline+o,top:y.top+o,bottom:y.bottom+o,size:P,color:F,font:y.font,glyphs:y.glyphs.map(T=>({...T,x:T.x+s})),z:x.z,seq:f++});for(let T of x.decorations){let D=y.glyphs[0],v=y.glyphs[y.glyphs.length-1];if(!D||!v)continue;let G=D.x+s,Z=v.x+v.advance+s,E=Math.max(1,P/14),q=it(T.color,x.alpha);T.line.includes("underline")&&r.push({type:"rect",x:G,y:y.baseline+o+P*.08,w:Z-G,h:E,color:q,z:x.z,seq:f++}),T.line.includes("line-through")&&r.push({type:"rect",x:G,y:y.baseline+o-P*.3,w:Z-G,h:E,color:q,z:x.z,seq:f++})}}}await b(e,{z:0,alpha:1,decorations:[]}),qt(i);let $=e.getBoundingClientRect().bottom+o;for(let l of i)l.type==="rect"||l.type==="stroke-rrect"||l.type==="image"?$=Math.max($,l.y+l.h):l.type==="line"?$=Math.max($,l.y1,l.y2):(l.type==="text"||l.type==="group"||l.type==="clip")&&($=Math.max($,l.bottom));return{items:i,atoms:c,breaks:a,tables:h,height:$}}function qt(e){e.sort((t,n)=>t.z-n.z||t.seq-n.seq);for(let t of e)(t.type==="group"||t.type==="clip")&&qt(t.items)}function Nt(e,t){return e==="dashed"?[t*3,t*3]:e==="dotted"?[t,t]:null}function Wt(e,t){let n=o=>{let r=o.trim().split(/\s+/)[0]??"0px";return r.endsWith("%")?parseFloat(r)/100*t.width:H(r)},s=[n(e.borderTopLeftRadius),n(e.borderTopRightRadius),n(e.borderBottomRightRadius),n(e.borderBottomLeftRadius)];return s.some(o=>o>0)?s:null}function Se(e){if(!e||e==="none")return null;let t=/^matrix\(([^)]+)\)$/.exec(e.trim());if(!t)return null;let n=t[1].split(",").map(h=>parseFloat(h));if(n.length!==6||n.some(h=>!Number.isFinite(h)))return null;let[s,o,r,i,c,a]=n;return s===1&&o===0&&r===0&&i===1&&c===0&&a===0?null:[s,o,r,i,c,a]}function Te(e){let t=e.trim().split(/\s+/);return[H(t[0]??"0"),H(t[1]??"0")]}function $e(e,t){let n,s,o,r;if(e.type==="rect"||e.type==="stroke-rrect"||e.type==="image")n=e.x,s=e.y,o=e.x+e.w,r=e.y+e.h;else if(e.type==="line")n=Math.min(e.x1,e.x2)-e.width,s=Math.min(e.y1,e.y2)-e.width,o=Math.max(e.x1,e.x2)+e.width,r=Math.max(e.y1,e.y2)+e.width;else if(e.type==="text"){let i=e.glyphs[e.glyphs.length-1];n=e.x,s=e.top,o=i?i.x+i.advance:e.x,r=e.bottom}else if(e.type==="clip")n=e.box.x,s=e.box.y,o=e.box.x+e.box.w,r=e.box.y+e.box.h;else return!0;return o>t.x&&n<t.x+t.w&&r>t.y&&s<t.y+t.h}function it(e,t){return t===1?e:{...e,a:e.a*t}}function Gt(e){return e.replace(/[A-Z]/g,t=>"-"+t.toLowerCase())}function Ce(){return typeof CompressionStream=="function"}async function Ht(e){if(!Ce())return null;try{let t=new CompressionStream("deflate"),n=t.writable.getWriter();n.write(e),n.close();let s=await new Response(t.readable).arrayBuffer();return new Uint8Array(s)}catch{return null}}var lt=class{constructor(t){this.id=t}toString(){return`${this.id} 0 R`}},K=class{constructor(t){this.name=t}toString(){let t="/";for(let n of this.name){let s=n.charCodeAt(0);if(s<33||s>126||"#/%()<>[]{}".includes(n))for(let o of new TextEncoder().encode(n))t+="#"+o.toString(16).padStart(2,"0");else t+=n}return t}},Q=class{constructor(t){this.text=t}toString(){return this.text}};function nt(e){if(/^[\x20-\x7e]*$/.test(e))return new Q("("+e.replace(/[\\()]/g,n=>"\\"+n)+")");let t="FEFF";for(let n=0;n<e.length;n++)t+=e.charCodeAt(n).toString(16).padStart(4,"0");return new Q("<"+t+">")}function Xt(e){let t=i=>String(i).padStart(2,"0"),n=-e.getTimezoneOffset(),s=n>=0?"+":"-",o=t(Math.floor(Math.abs(n)/60)),r=t(Math.abs(n)%60);return new Q(`(D:${e.getFullYear()}${t(e.getMonth()+1)}${t(e.getDate())}${t(e.getHours())}${t(e.getMinutes())}${t(e.getSeconds())}${s}${o}'${r}')`)}function ht(e){if(e===null)return"null";if(typeof e=="number")return U(e);if(typeof e=="boolean")return e?"true":"false";if(typeof e=="string")return new K(e).toString();if(e instanceof lt||e instanceof K||e instanceof Q)return e.toString();if(Array.isArray(e))return"["+e.map(ht).join(" ")+"]";let t=[];for(let[n,s]of Object.entries(e))s!==void 0&&t.push(new K(n).toString()+" "+ht(s));return"<< "+t.join(" ")+" >>"}var dt=class{constructor(t={}){this.objects=[null],this.compress=t.compress??!0,this.version=t.version??"1.7"}reserve(){return this.objects.push({value:null}),new lt(this.objects.length-1)}set(t,n,s){this.objects[t.id]={value:n,stream:s}}add(t){let n=this.reserve();return this.set(n,t),n}async addStream(t,n,s={}){let o=this.reserve();return await this.setStream(o,t,n,s),o}async setStream(t,n,s,o={}){let r=s,i={...n};if((o.compress??this.compress)&&!("Filter"in i)){let a=await Ht(s);a&&a.length<s.length&&(r=a,i.Filter="FlateDecode")}i.Length=r.length,this.set(t,i,r)}build(t,n){let s=new TextEncoder,o=[],r=0,i=f=>{let d=typeof f=="string"?s.encode(f):f;o.push(d),r+=d.length};i(pt([s.encode(`%PDF-${this.version}
|
|
3
|
+
%`),new Uint8Array([226,227,207,211]),s.encode(`
|
|
4
|
+
`)]));let c=[];for(let f=1;f<this.objects.length;f++){let d=this.objects[f];if(!d)throw new Error(`PDF object ${f} was reserved but never set`);c[f]=r,i(`${f} 0 obj
|
|
5
|
+
${ht(d.value)}
|
|
6
|
+
`),d.stream&&(i(`stream
|
|
7
|
+
`),i(d.stream),i(`
|
|
8
|
+
endstream
|
|
9
|
+
`)),i(`endobj
|
|
10
|
+
`)}let a=r,h=`xref
|
|
11
|
+
0 ${this.objects.length}
|
|
12
|
+
0000000000 65535 f
|
|
13
|
+
`;for(let f=1;f<this.objects.length;f++)h+=String(c[f]).padStart(10,"0")+` 00000 n
|
|
14
|
+
`;i(h);let m={Size:this.objects.length,Root:t};return n&&(m.Info=n),i(`trailer
|
|
15
|
+
${ht(m)}
|
|
16
|
+
startxref
|
|
17
|
+
${a}
|
|
18
|
+
%%EOF
|
|
19
|
+
`),pt(o)}};function pt(e){let t=0;for(let o of e)t+=o.length;let n=new Uint8Array(t),s=0;for(let o of e)n.set(o,s),s+=o.length;return n}var ut=class{constructor(){this.ops=[],this.depth=0}save(){return this.ops.push("q"),this.depth++,this}restore(){if(this.depth<=0)throw new Error("ContentStream: unbalanced Q");return this.ops.push("Q"),this.depth--,this}transform(t,n,s,o,r,i){return this.ops.push(`${U(t)} ${U(n)} ${U(s)} ${U(o)} ${U(r)} ${U(i)} cm`),this}setGState(t){return this.ops.push(`/${t} gs`),this}fillColor(t,n,s){return this.ops.push(`${U(t)} ${U(n)} ${U(s)} rg`),this}strokeColor(t,n,s){return this.ops.push(`${U(t)} ${U(n)} ${U(s)} RG`),this}lineWidth(t){return this.ops.push(`${U(t)} w`),this}dash(t,n=0){return this.ops.push(`[${t.map(U).join(" ")}] ${U(n)} d`),this}lineCap(t){return this.ops.push(`${t} J`),this}rect(t,n,s,o){return this.ops.push(`${U(t)} ${U(n)} ${U(s)} ${U(o)} re`),this}moveTo(t,n){return this.ops.push(`${U(t)} ${U(n)} m`),this}lineTo(t,n){return this.ops.push(`${U(t)} ${U(n)} l`),this}curveTo(t,n,s,o,r,i){return this.ops.push(`${U(t)} ${U(n)} ${U(s)} ${U(o)} ${U(r)} ${U(i)} c`),this}closePath(){return this.ops.push("h"),this}roundedRect(t,n,s,o,r){let c=Math.min(s,o)/2,a=b=>Math.max(0,Math.min(b,c)),h=a(r[0]),m=a(r[1]),f=a(r[2]),d=a(r[3]),g=n+o,w=t+s;return this.moveTo(t+h,g),this.lineTo(w-m,g),m&&this.curveTo(w-m+m*.5523,g,w,g-m+m*.5523,w,g-m),this.lineTo(w,n+f),f&&this.curveTo(w,n+f-f*.5523,w-f+f*.5523,n,w-f,n),this.lineTo(t+d,n),d&&this.curveTo(t+d-d*.5523,n,t,n+d-d*.5523,t,n+d),this.lineTo(t,g-h),h&&this.curveTo(t,g-h+h*.5523,t+h-h*.5523,g,t+h,g),this.closePath()}image(t,n,s,o,r){return this.ops.push(`q ${U(o)} 0 0 ${U(r)} ${U(n)} ${U(s)} cm /${t} Do Q`),this}fill(){return this.ops.push("f"),this}stroke(){return this.ops.push("S"),this}clip(){return this.ops.push("W n"),this}fillRect(t,n,s,o){return this.rect(t,n,s,o).fill()}text(t,n,s,o,r,i={}){let c=[];for(let a of r)typeof a=="string"?a.length&&c.push(`<${a}>`):a!==0&&c.push(U(a));return c.length?(this.ops.push("BT"),this.ops.push(`/${t} ${U(n)} Tf`),i.charSpacing&&this.ops.push(`${U(i.charSpacing)} Tc`),i.rise&&this.ops.push(`${U(i.rise)} Ts`),this.ops.push(`1 0 0 1 ${U(s)} ${U(o)} Tm`),this.ops.push(`[${c.join(" ")}] TJ`),this.ops.push("ET"),this):this}toBytes(){if(this.depth!==0)throw new Error(`ContentStream: ${this.depth} unclosed q`);return new TextEncoder().encode(this.ops.join(`
|
|
20
|
+
`)+`
|
|
21
|
+
`)}};function _t(e,t){let n=new Set([0]),s=[...t];for(;s.length;){let $=s.pop();if(!($<0||$>=e.numGlyphs||n.has($))){n.add($);for(let l of Pt(yt(e,$)))n.has(l)||s.push(l)}}let o=[...n].sort(($,l)=>$-l),r=new Map;o.forEach(($,l)=>r.set($,l));let i=o.length,c=[],a=new Uint32Array(i+1),h=0;for(let $=0;$<i;$++){let l=yt(e,o[$]);l.length&&new DataView(l.buffer,l.byteOffset,l.byteLength).getInt16(0)<0&&(l=Fe(l,r)),a[$]=h,c.push(l),h+=l.length;let p=(4-h%4)%4;p&&(c.push(new Uint8Array(p)),h+=p)}a[i]=h;let m=pt(c),f=new Uint8Array(a.length*4),d=new DataView(f.buffer);a.forEach(($,l)=>d.setUint32(l*4,$));let g=e.tables.get("hmtx"),w=e.tables.get("hhea"),b=new DataView(e.data.buffer,e.data.byteOffset,e.data.byteLength),C=b.getUint16(w.offset+34),O=new Uint8Array(i*4),B=new DataView(O.buffer);for(let $=0;$<i;$++){let l=o[$],p=l<C?g.offset+l*4+2:g.offset+C*4+(l-C)*2;B.setUint16($*4,e.advances[l]??0),B.setInt16($*4+2,p+2<=e.data.byteLength?b.getInt16(p):0)}let R=mt(e,"head"),j=new DataView(R.buffer);j.setUint32(8,0),j.setInt16(50,1);let L=mt(e,"hhea");new DataView(L.buffer).setUint16(34,i);let N=mt(e,"maxp");new DataView(N.buffer).setUint16(4,i);let X=[["glyf",m],["head",R],["hhea",L],["hmtx",O],["loca",f],["maxp",N]];for(let $ of["cvt ","fpgm","prep"])e.tables.has($)&&X.push([$,mt(e,$)]);return X.sort(($,l)=>$[0]<l[0]?-1:1),{data:Ue(X),gidMap:r,oldGids:o}}function mt(e,t){let n=e.tables.get(t);if(!n)throw new Error(`missing table ${t}`);return new Uint8Array(e.data.subarray(n.offset,n.offset+n.length))}function Fe(e,t){let n=new Uint8Array(e),s=new DataView(n.buffer),o=10;for(;;){let r=s.getUint16(o),i=s.getUint16(o+2);if(s.setUint16(o+2,t.get(i)??0),o+=4,o+=r&1?4:2,r&8?o+=2:r&64?o+=4:r&128&&(o+=8),!(r&32)||o>=n.length)break}return n}function Ue(e){let t=e.length,n=0;for(;1<<n+1<=t;)n++;let s=(1<<n)*16,o=t*16-s,i=12+t*16,c=[];for(let[f,d]of e)c.push({tag:f,data:d,offset:i,checksum:Vt(d)}),i+=d.length+3&-4;let a=new Uint8Array(i),h=new DataView(a.buffer);h.setUint32(0,65536),h.setUint16(4,t),h.setUint16(6,s),h.setUint16(8,n),h.setUint16(10,o),c.forEach((f,d)=>{let g=12+d*16;for(let w=0;w<4;w++)a[g+w]=f.tag.charCodeAt(w);h.setUint32(g+4,f.checksum),h.setUint32(g+8,f.offset),h.setUint32(g+12,f.data.length),a.set(f.data,f.offset)});let m=c.find(f=>f.tag==="head");if(m){let f=Vt(a);h.setUint32(m.offset+8,2981146554-f>>>0)}return a}function Vt(e){let t=0,n=e.length;for(let s=0;s<n;s+=4){let o=e[s]??0,r=e[s+1]??0,i=e[s+2]??0,c=e[s+3]??0;t=t+((o<<24|r<<16|i<<8|c)>>>0)>>>0}return t}var gt=class{constructor(t,n){this.font=t,this.resourceName=n,this.usedGids=new Map,this.subset=null}addGlyph(t,n){this.usedGids.has(t)||this.usedGids.set(t,n)}cid(t){if(!this.subset)throw new Error("EmbeddedFont: embed() must be called before cid()");return this.subset.gidMap.get(t)??0}finalize(){return this.subset||(this.subset=_t(this.font,this.usedGids.keys())),this.subset}async embed(t){let n=this.finalize(),s=this.font,o=1e3/s.unitsPerEm,i=`${ke(this.usedGids)}+${s.postScriptName}`,c=await t.addStream({Length1:n.data.length},n.data),a=4;s.italic&&(a|=64),s.bold&&(a|=1<<18);let h=t.add({Type:"FontDescriptor",FontName:i,Flags:a,FontBBox:s.bbox.map(b=>Math.round(b*o)),ItalicAngle:s.italicAngle,Ascent:Math.round(s.ascender*o),Descent:Math.round(s.descender*o),CapHeight:Math.round(s.capHeight*o),StemV:s.bold?120:80,FontFile2:c}),m=[],f=n.oldGids.map(b=>Math.round((s.advances[b]??0)*o)),d=0;for(;d<f.length;){let b=d;for(;b+1<f.length&&b-d<100;)b++;m.push(d,f.slice(d,b+1)),d=b+1}let g=t.add({Type:"Font",Subtype:"CIDFontType2",BaseFont:i,CIDSystemInfo:{Registry:new Q("(Adobe)"),Ordering:new Q("(Identity)"),Supplement:0},FontDescriptor:h,DW:1e3,W:m,CIDToGIDMap:"Identity"}),w=await t.addStream({},Pe(n,this.usedGids));return t.add({Type:"Font",Subtype:"Type0",BaseFont:i,Encoding:"Identity-H",DescendantFonts:[g],ToUnicode:w})}};function ke(e){let t=2166136261;for(let s of e.keys())t^=s,t=Math.imul(t,16777619)>>>0;let n="";for(let s=0;s<6;s++)n+=String.fromCharCode(65+t%26),t=Math.floor(t/26);return n}function Pe(e,t){let n=[];e.oldGids.forEach((r,i)=>{let c=t.get(r);c!==void 0&&n.push(`<${st(i)}> <${Ee(c)}>`)});let s="";for(let r=0;r<n.length;r+=100){let i=n.slice(r,r+100);s+=`${i.length} beginbfchar
|
|
22
|
+
${i.join(`
|
|
23
|
+
`)}
|
|
24
|
+
endbfchar
|
|
25
|
+
`}let o=`/CIDInit /ProcSet findresource begin
|
|
26
|
+
12 dict begin
|
|
27
|
+
begincmap
|
|
28
|
+
/CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def
|
|
29
|
+
/CMapName /Adobe-Identity-UCS def
|
|
30
|
+
/CMapType 2 def
|
|
31
|
+
1 begincodespacerange
|
|
32
|
+
<0000> <FFFF>
|
|
33
|
+
endcodespacerange
|
|
34
|
+
`+s+`endcmap
|
|
35
|
+
CMapName currentdict /CMap defineresource pop
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
`;return new TextEncoder().encode(o)}function st(e){return e.toString(16).toUpperCase().padStart(4,"0")}function Ee(e){if(e<=65535)return st(e);let t=e-65536;return st(55296+(t>>10))+st(56320+(t&1023))}async function Yt(e,t){let n={Type:"XObject",Subtype:"Image",Width:t.width,Height:t.height,ColorSpace:"DeviceRGB",BitsPerComponent:8};if(t.jpeg)return n.Filter="DCTDecode",e.addStream(n,t.jpeg,{compress:!1});if(!t.rgb)throw new Error("embedImage: image has no pixel data");return t.alpha&&(n.SMask=await e.addStream({Type:"XObject",Subtype:"Image",Width:t.width,Height:t.height,ColorSpace:"DeviceGray",BitsPerComponent:8},t.alpha)),e.addStream(n,t.rgb)}function Jt(e,t){let n=t,s=e.height,o=[...e.atoms].sort((f,d)=>f.top-d.top),r=[...new Set(e.breaks)].sort((f,d)=>f-d),i=.01,c=[],a=0,h=0;for(;a<s-i&&h++<1e4;){let f=[],d=0;for(let C of e.tables)C.headItems.length&&C.headBottom<=a+i&&a<C.bottom-i&&(f.push({table:C,shift:d}),d+=C.headBottom-C.headTop);let g=[],w=0,b=a;for(let C=0;C<4;C++){let O=Math.max(n-d-w,n*.25);b=m(a,O);let B=[],R=0;for(let L of e.tables)L.footItems.length&&L.top<b-i&&L.footTop>=b-i&&L.bottom>b+i&&(B.push({table:L,shift:R}),R+=L.footBottom-L.footTop);let j=B.length===g.length&&B.every((L,N)=>L.table===g[N]?.table);if(g=B,w=R,j)break}c.push({start:a,end:b,heads:f,headShift:d,feet:g,footShift:w}),a=b}return c.length||c.push({start:0,end:Math.max(s,1),heads:[],headShift:0,feet:[],footShift:0}),c;function m(f,d){let g=Math.min(f+d,s);for(let w of r)if(w>f+i&&w<g-i){g=w;break}if(g<s-i){let w=!0,b=0;for(;w&&b++<1e3;){w=!1;for(let C of o){if(C.top>=g)break;C.bottom-C.top>d||C.top<g-i&&C.bottom>g+i&&C.top>f+i&&(g=C.top,w=!0)}}g<=f+i&&(g=Math.min(f+d,s))}return g}}function Kt(e={}){let t=e.size??"A4",n,s;if(typeof t=="string"){let i=St[t];if(!i)throw new Error(`Unknown page size "${t}". Use one of ${Object.keys(St).join(", ")} or {width, height}.`);n=i.width,s=i.height}else n=Y(t.width),s=Y(t.height);(e.orientation??"portrait")==="landscape"&&n<s&&([n,s]=[s,n]);let o=e.margin??"15mm",r=typeof o=="string"?{top:Y(o),right:Y(o),bottom:Y(o),left:Y(o)}:{top:Y(o.top),right:Y(o.right),bottom:Y(o.bottom),left:Y(o.left)};return{width:n,height:s,...r}}async function Qt(e,t,n){let s=new dt({compress:n.compress}),o=(n.header?.heightPx??0)*.75,r=(n.footer?.heightPx??0)*.75,i=t.width-t.left-t.right,c=t.height-t.top-o,a=t.height-t.top-t.bottom-o-r;if(a<=0)throw new Error("Page content area is empty: margins + header + footer exceed the page height");let h=a/.75,m=Jt(e,h),f=m.length,d=[],g=[];for(let u=0;u<f;u++)d.push(n.header?await n.header.render(u+1,f):null),g.push(n.footer?await n.footer.render(u+1,f):null);let w=new Map,b=new Map,C=u=>{for(let x of u)if(x.type==="text"){let S=w.get(x.font);S||(S=new gt(x.font.parsed,`F${w.size+1}`),w.set(x.font,S));for(let F of x.glyphs)S.addGlyph(F.gid,F.cp)}else x.type==="image"?b.has(x.image.key)||b.set(x.image.key,{name:`Im${b.size+1}`,image:x.image}):(x.type==="group"||x.type==="clip")&&C(x.items)};C(e.items);for(let u of[...d,...g])u&&C(u.items);for(let u of w.values())u.finalize();let O={};for(let u of w.values())O[u.resourceName]=await u.embed(s);let B={};for(let u of b.values())B[u.name]=await Yt(s,u.image);let R=new Map,j={},L=u=>{let x=U(u),S=R.get(x);return S||(S=`GS${R.size+1}`,R.set(x,S),j[S]=s.add({Type:"ExtGState",ca:u,CA:u})),S},N=s.reserve(),X=[];for(let u=0;u<f;u++){let x=m[u],S=new ut,F=new Ct(S,t,w,b,L),P=x.headShift*.75,k=x.footShift*.75;S.save(),S.rect(t.left,c-a+k,i,a-P-k).clip(),F.setOrigin(c-P,x.start),F.render(e.items,x),S.restore();let A=c-P-(x.end-x.start)*.75;for(let y of x.feet){let T=(y.table.footBottom-y.table.footTop)*.75,D=A-y.shift*.75-T;S.save(),S.rect(t.left,D,i,T).clip(),F.setOrigin(D+T,y.table.footTop),F.render(y.table.footItems),S.restore()}for(let y of x.heads){S.save();let T=(y.table.headBottom-y.table.headTop)*.75;S.rect(t.left,c-y.shift*.75-T,i,T).clip(),F.setOrigin(c-y.shift*.75,y.table.headTop),F.render(y.table.headItems),S.restore()}let I=d[u];I&&(S.save(),S.rect(t.left,t.height-t.top-o,i,o).clip(),F.setOrigin(t.height-t.top,0),F.render(I.items),S.restore());let z=g[u];z&&(S.save(),S.rect(t.left,t.bottom,i,r).clip(),F.setOrigin(t.bottom+r,0),F.render(z.items),S.restore());let W=await s.addStream({},S.toBytes());X.push(s.add({Type:"Page",Parent:N,MediaBox:[0,0,t.width,t.height],Resources:{Font:O,XObject:B,ExtGState:j,ProcSet:[new K("PDF"),new K("Text"),new K("ImageC")]},Contents:W}))}s.set(N,{Type:"Pages",Kids:X,Count:X.length});let et=s.add({Type:"Catalog",Pages:N}),$=n.metadata??{},l={Producer:nt("receipt-html-to-pdf"),Creator:nt($.creator??"receipt-html-to-pdf"),CreationDate:Xt($.creationDate??new Date)};$.title&&(l.Title=nt($.title)),$.author&&(l.Author=nt($.author)),$.subject&&(l.Subject=nt($.subject)),$.keywords&&(l.Keywords=nt($.keywords));let p=s.add(l);return s.build(et,p)}function Ie(e,t){if(e.type==="text"){let s=(e.top+e.bottom)/2;return s>=t.start-.01&&s<t.end-.01}return Be(e)>t.start+.01&&Ae(e)<t.end-.01}var Ct=class{constructor(t,n,s,o,r){this.cs=t,this.geo=n,this.fonts=s,this.images=o,this.gsName=r,this.pdfTop=n.height-n.top,this.docTop=0,this.curAlpha=1}setOrigin(t,n){this.pdfTop=t,this.docTop=n}X(t){return this.geo.left+t*.75}Y(t){return this.pdfTop-(t-this.docTop)*.75}setAlpha(t){Math.abs(t-this.curAlpha)<.001||(this.cs.setGState(this.gsName(t)),this.curAlpha=t)}radiusPt(t){return(t??[0,0,0,0]).map(n=>n*.75)}clipBox(t){let n=this.cs;t.radius?n.roundedRect(this.X(t.x),this.Y(t.y+t.h),t.w*.75,t.h*.75,this.radiusPt(t.radius)):n.rect(this.X(t.x),this.Y(t.y+t.h),t.w*.75,t.h*.75),n.clip()}render(t,n){let s=this.cs;for(let o of t)if(!(n&&!Ie(o,n)))if(o.type==="rect"){if(o.w<=0||o.h<=0)continue;s.save(),this.setAlpha(o.color.a),s.fillColor(o.color.r,o.color.g,o.color.b),o.radius?s.roundedRect(this.X(o.x),this.Y(o.y+o.h),o.w*.75,o.h*.75,this.radiusPt(o.radius)).fill():s.fillRect(this.X(o.x),this.Y(o.y+o.h),o.w*.75,o.h*.75),s.restore(),this.curAlpha=1}else if(o.type==="line")s.save(),this.setAlpha(o.color.a),s.strokeColor(o.color.r,o.color.g,o.color.b),s.lineWidth(o.width*.75),o.dash&&s.dash(o.dash.map(r=>r*.75)),s.moveTo(this.X(o.x1),this.Y(o.y1)).lineTo(this.X(o.x2),this.Y(o.y2)).stroke(),s.restore(),this.curAlpha=1;else if(o.type==="stroke-rrect")s.save(),this.setAlpha(o.color.a),s.strokeColor(o.color.r,o.color.g,o.color.b),s.lineWidth(o.width*.75),o.dash&&s.dash(o.dash.map(r=>r*.75)),s.roundedRect(this.X(o.x),this.Y(o.y+o.h),o.w*.75,o.h*.75,this.radiusPt(o.radius)).stroke(),s.restore(),this.curAlpha=1;else if(o.type==="image"){let r=this.images.get(o.image.key);if(!r||o.w<=0||o.h<=0)continue;s.save(),this.setAlpha(o.alpha),o.clip&&this.clipBox(o.clip),s.image(r.name,this.X(o.x),this.Y(o.y+o.h),o.w*.75,o.h*.75),s.restore(),this.curAlpha=1}else if(o.type==="text"){let r=this.fonts.get(o.font),i=Me(o,r);s.save(),this.setAlpha(o.color.a),s.fillColor(o.color.r,o.color.g,o.color.b),s.text(r.resourceName,o.size*.75,this.X(o.x),this.Y(o.y),i),s.restore(),this.curAlpha=1}else if(o.type==="group"){let[r,i,c,a]=o.matrix,h=this.X(o.origin.x),m=this.Y(o.origin.y),f=r,d=-i,g=-c,w=a,b=h-(f*h+g*m)+o.matrix[4]*.75,C=m-(d*h+w*m)-o.matrix[5]*.75;s.save(),s.transform(f,d,g,w,b,C),this.render(o.items,n),s.restore()}else o.type==="clip"&&(s.save(),this.clipBox(o.box),this.render(o.items,n),s.restore())}};function Me(e,t){let n=[],s="";for(let o=0;o<e.glyphs.length;o++){let r=e.glyphs[o];s+=st(t.cid(r.gid));let i=e.glyphs[o+1];if(!i)break;let c=r.x+r.advance,h=-(i.x-c)/e.size*1e3;Math.abs(h)>=.5&&(n.push(s,Math.round(h*10)/10),s="")}return s&&n.push(s),n}function Ae(e){return e.type==="rect"||e.type==="stroke-rrect"||e.type==="image"?e.y:e.type==="line"?Math.min(e.y1,e.y2)-e.width/2:(e.type==="group"||e.type==="clip",e.top)}function Be(e){return e.type==="rect"||e.type==="stroke-rrect"||e.type==="image"?e.y+e.h:e.type==="line"?Math.max(e.y1,e.y2)+e.width/2:(e.type==="group"||e.type==="clip",e.bottom)}var wn="0.1.0",bt=new at;async function xn(e){if(!e||!e.family||!e.src)throw new TypeError("registerFont: { family, src } are required");(await bt.register(e)).parsed.variable&&console.warn(`[receipt-html-to-pdf] "${e.family}" is a variable font; only the default instance outlines are embedded. Use static TTF instances for other weights.`)}function Sn(){return bt.fonts.map(e=>({family:e.displayFamily,weight:e.weight,style:e.style,glyphs:e.parsed.numGlyphs}))}async function Tn(e,t={}){if(typeof document>"u")throw new Error("htmlToPdf must run in a browser (needs DOM layout)");if(bt.fonts.length===0)throw new Error("htmlToPdf: no fonts registered. Call registerFont() with at least one TrueType font first.");let n=t.onWarning??(()=>{}),s=Kt(t.page),o=(s.width-s.left-s.right)/.75,r=await xt(e,{widthPx:o,stylesheets:t.stylesheets??"inherit",mediaPrint:t.mediaPrint??!1,baseUrl:t.baseUrl,warn:n}),i={registry:bt,fontFallback:t.fontFallback??[],warn:n,textMeasure:t.textMeasure??"auto"},c={widthPx:o,stylesheets:t.stylesheets??"inherit",mediaPrint:t.mediaPrint??!1,baseUrl:t.baseUrl,warn:n};try{let a=await $t(r.root,i),h=t.header?await Zt(t.header,c,i):null,m=t.footer?await Zt(t.footer,c,i):null,f=await Qt(a,s,{compress:t.compress??!0,metadata:t.metadata,header:h,footer:m});return De(f,t.output??"blob")}finally{r.destroy()}}async function Zt(e,t,n){let s=async(i,c)=>{let a=e.replace(/\{\{\s*pageNumber\s*\}\}/g,String(i)).replace(/\{\{\s*totalPages\s*\}\}/g,String(c)),h=await xt(a,t);try{return await $t(h.root,n)}finally{h.destroy()}},o=await s(1,1),r=new Map([["1/1",o]]);return{heightPx:o.height,render:async(i,c)=>{let a=`${i}/${c}`,h=r.get(a);return h||(h=await s(i,c),r.set(a,h)),h}}}function De(e,t){if(t==="uint8array")return e;if(t==="dataurl"){let n="";for(let s=0;s<e.length;s+=32768)n+=String.fromCharCode(...e.subarray(s,s+32768));return"data:application/pdf;base64,"+btoa(n)}return new Blob([e],{type:"application/pdf"})}function $n(e,t){let n=e instanceof Blob?e:new Blob([e],{type:"application/pdf"}),s=URL.createObjectURL(n),o=document.createElement("a");o.href=s,o.download=t,document.body.appendChild(o),o.click(),o.remove(),setTimeout(()=>URL.revokeObjectURL(s),1e3)}export{$n as downloadPdf,ct as expandPrintMediaCss,Tn as htmlToPdf,Sn as listFonts,xn as registerFont,wn as version};
|
|
39
|
+
//# sourceMappingURL=receipt-html-to-pdf.min.js.map
|